Whamcloud - gitweb
Revert "LU-7898 osd: remove unnecessary declarations"
[fs/lustre-release.git] / lustre / osd-zfs / osd_object.c
index ef912ad..bd1fac2 100644 (file)
@@ -504,6 +504,7 @@ static int osd_declare_object_destroy(const struct lu_env *env,
                                      struct dt_object *dt,
                                      struct thandle *th)
 {
+       char                    *buf = osd_oti_get(env)->oti_str;
        const struct lu_fid     *fid = lu_object_fid(&dt->do_lu);
        struct osd_object       *obj = osd_dt_obj(dt);
        struct osd_device       *osd = osd_obj2dev(obj);
@@ -519,14 +520,17 @@ static int osd_declare_object_destroy(const struct lu_env *env,
        LASSERT(oh->ot_tx != NULL);
 
        /* declare that we'll remove object from fid-dnode mapping */
-       zapid = osd_get_name_n_idx(env, osd, fid, NULL, 0);
-       dmu_tx_hold_zap(oh->ot_tx, zapid, FALSE, NULL);
+       zapid = osd_get_name_n_idx(env, osd, fid, buf);
+       dmu_tx_hold_bonus(oh->ot_tx, zapid);
+       dmu_tx_hold_zap(oh->ot_tx, zapid, FALSE, buf);
 
        osd_declare_xattrs_destroy(env, obj, oh);
 
        /* declare that we'll remove object from inode accounting ZAPs */
-       dmu_tx_hold_zap(oh->ot_tx, osd->od_iusr_oid, FALSE, NULL);
-       dmu_tx_hold_zap(oh->ot_tx, osd->od_igrp_oid, FALSE, NULL);
+       dmu_tx_hold_bonus(oh->ot_tx, osd->od_iusr_oid);
+       dmu_tx_hold_zap(oh->ot_tx, osd->od_iusr_oid, FALSE, buf);
+       dmu_tx_hold_bonus(oh->ot_tx, osd->od_igrp_oid);
+       dmu_tx_hold_zap(oh->ot_tx, osd->od_igrp_oid, FALSE, buf);
 
        /* one less inode */
        rc = osd_declare_quota(env, osd, obj->oo_attr.la_uid,
@@ -553,8 +557,7 @@ static int osd_declare_object_destroy(const struct lu_env *env,
 static int osd_object_destroy(const struct lu_env *env,
                              struct dt_object *dt, struct thandle *th)
 {
-       struct osd_thread_info  *info = osd_oti_get(env);
-       char                    *buf = info->oti_str;
+       char                    *buf = osd_oti_get(env)->oti_str;
        struct osd_object       *obj = osd_dt_obj(dt);
        struct osd_device       *osd = osd_obj2dev(obj);
        const struct lu_fid     *fid = lu_object_fid(&dt->do_lu);
@@ -575,7 +578,7 @@ static int osd_object_destroy(const struct lu_env *env,
        LASSERT(oh->ot_tx != NULL);
 
        /* remove obj ref from index dir (it depends) */
-       zapid = osd_get_name_n_idx(env, osd, fid, buf, sizeof(info->oti_str));
+       zapid = osd_get_name_n_idx(env, osd, fid, buf);
        rc = -zap_remove(osd->od_os, zapid, buf, oh->ot_tx);
        if (rc) {
                CERROR("%s: zap_remove(%s) failed: rc = %d\n",
@@ -843,14 +846,13 @@ static int osd_declare_attr_set(const struct lu_env *env,
                                struct thandle *handle)
 {
        struct osd_thread_info  *info = osd_oti_get(env);
+       char                    *buf = osd_oti_get(env)->oti_str;
        struct osd_object       *obj = osd_dt_obj(dt);
        struct osd_device       *osd = osd_obj2dev(obj);
-       dmu_tx_hold_t           *txh;
        struct osd_thandle      *oh;
        uint64_t                 bspace;
        uint32_t                 blksize;
        int                      rc = 0;
-       bool                     found;
        ENTRY;
 
 
@@ -865,39 +867,20 @@ static int osd_declare_attr_set(const struct lu_env *env,
 
        LASSERT(obj->oo_sa_hdl != NULL);
        LASSERT(oh->ot_tx != NULL);
-       /* regular attributes are part of the bonus buffer */
-       /* let's check whether this object is already part of
-        * transaction.. */
-       found = false;
-       for (txh = list_head(&oh->ot_tx->tx_holds); txh;
-            txh = list_next(&oh->ot_tx->tx_holds, txh)) {
-               if (txh->txh_dnode == NULL)
-                       continue;
-               if (txh->txh_dnode->dn_object != obj->oo_db->db_object)
-                       continue;
-               /* this object is part of the transaction already
-                * we don't need to declare bonus again */
-               found = true;
-               break;
-       }
-       if (!found)
-               dmu_tx_hold_bonus(oh->ot_tx, obj->oo_db->db_object);
+       dmu_tx_hold_sa(oh->ot_tx, obj->oo_sa_hdl, 0);
        if (oh->ot_tx->tx_err != 0)
                GOTO(out, rc = -oh->ot_tx->tx_err);
 
-       if (attr && attr->la_valid & LA_FLAGS) {
-               /* LMA is usually a part of bonus, no need to declare
-                * anything else */
-       }
+       sa_object_size(obj->oo_sa_hdl, &blksize, &bspace);
+       bspace = toqb(bspace * blksize);
 
-       if (attr && (attr->la_valid & (LA_UID | LA_GID))) {
-               sa_object_size(obj->oo_sa_hdl, &blksize, &bspace);
-               bspace = toqb(bspace * blksize);
-       }
+       __osd_xattr_declare_set(env, obj, sizeof(struct lustre_mdt_attrs),
+                               XATTR_NAME_LMA, oh);
 
        if (attr && attr->la_valid & LA_UID) {
                /* account for user inode tracking ZAP update */
-               dmu_tx_hold_zap(oh->ot_tx, osd->od_iusr_oid, FALSE, NULL);
+               dmu_tx_hold_bonus(oh->ot_tx, osd->od_iusr_oid);
+               dmu_tx_hold_zap(oh->ot_tx, osd->od_iusr_oid, TRUE, buf);
 
                /* quota enforcement for user */
                if (attr->la_uid != obj->oo_attr.la_uid) {
@@ -911,7 +894,8 @@ static int osd_declare_attr_set(const struct lu_env *env,
        }
        if (attr && attr->la_valid & LA_GID) {
                /* account for user inode tracking ZAP update */
-               dmu_tx_hold_zap(oh->ot_tx, osd->od_igrp_oid, FALSE, NULL);
+               dmu_tx_hold_bonus(oh->ot_tx, osd->od_igrp_oid);
+               dmu_tx_hold_zap(oh->ot_tx, osd->od_igrp_oid, TRUE, buf);
 
                /* quota enforcement for group */
                if (attr->la_gid != obj->oo_attr.la_gid) {
@@ -1137,12 +1121,13 @@ static int osd_declare_object_create(const struct lu_env *env,
                                     struct dt_object_format *dof,
                                     struct thandle *handle)
 {
+       char                    *buf = osd_oti_get(env)->oti_str;
        const struct lu_fid     *fid = lu_object_fid(&dt->do_lu);
        struct osd_object       *obj = osd_dt_obj(dt);
        struct osd_device       *osd = osd_obj2dev(obj);
        struct osd_thandle      *oh;
        uint64_t                 zapid;
-       int                      rc, dnode_size;
+       int                      rc;
        ENTRY;
 
        LASSERT(dof);
@@ -1162,26 +1147,18 @@ static int osd_declare_object_create(const struct lu_env *env,
        oh = container_of0(handle, struct osd_thandle, ot_super);
        LASSERT(oh->ot_tx != NULL);
 
-       /* this is the minimum set of EAs on every Lustre object */
-       obj->oo_ea_in_bonus = ZFS_SA_BASE_ATTR_SIZE +
-                               sizeof(__u64) + /* VBR VERSION */
-                               sizeof(struct lustre_mdt_attrs); /* LMA */
-       /* reserve 32 bytes for extra stuff like ACLs */
-       dnode_size = size_roundup_power2(obj->oo_ea_in_bonus + 32);
-
        switch (dof->dof_type) {
                case DFT_DIR:
                        dt->do_index_ops = &osd_dir_ops;
                case DFT_INDEX:
                        /* for zap create */
-                       dmu_tx_hold_zap(oh->ot_tx, DMU_NEW_OBJECT, FALSE, NULL);
-                       dmu_tx_hold_sa_create(oh->ot_tx, dnode_size);
+                       dmu_tx_hold_zap(oh->ot_tx, DMU_NEW_OBJECT, 1, NULL);
                        break;
                case DFT_REGULAR:
                case DFT_SYM:
                case DFT_NODE:
                        /* first, we'll create new object */
-                       dmu_tx_hold_sa_create(oh->ot_tx, dnode_size);
+                       dmu_tx_hold_bonus(oh->ot_tx, DMU_NEW_OBJECT);
                        break;
 
                default:
@@ -1190,12 +1167,20 @@ static int osd_declare_object_create(const struct lu_env *env,
        }
 
        /* and we'll add it to some mapping */
-       zapid = osd_get_name_n_idx(env, osd, fid, NULL, 0);
-       dmu_tx_hold_zap(oh->ot_tx, zapid, TRUE, NULL);
+       zapid = osd_get_name_n_idx(env, osd, fid, buf);
+       dmu_tx_hold_bonus(oh->ot_tx, zapid);
+       dmu_tx_hold_zap(oh->ot_tx, zapid, TRUE, buf);
 
        /* we will also update inode accounting ZAPs */
-       dmu_tx_hold_zap(oh->ot_tx, osd->od_iusr_oid, FALSE, NULL);
-       dmu_tx_hold_zap(oh->ot_tx, osd->od_igrp_oid, FALSE, NULL);
+       dmu_tx_hold_bonus(oh->ot_tx, osd->od_iusr_oid);
+       dmu_tx_hold_zap(oh->ot_tx, osd->od_iusr_oid, TRUE, buf);
+       dmu_tx_hold_bonus(oh->ot_tx, osd->od_igrp_oid);
+       dmu_tx_hold_zap(oh->ot_tx, osd->od_igrp_oid, TRUE, buf);
+
+       dmu_tx_hold_sa_create(oh->ot_tx, ZFS_SA_BASE_ATTR_SIZE);
+
+       __osd_xattr_declare_set(env, obj, sizeof(struct lustre_mdt_attrs),
+                               XATTR_NAME_LMA, oh);
 
        rc = osd_declare_quota(env, osd, attr->la_uid, attr->la_gid, 1, oh,
                               false, NULL, false);
@@ -1203,9 +1188,10 @@ static int osd_declare_object_create(const struct lu_env *env,
 }
 
 int __osd_attr_init(const struct lu_env *env, struct osd_device *osd,
-                   sa_handle_t *sa_hdl, dmu_tx_t *tx,
-                   struct lu_attr *la, uint64_t parent)
+                   uint64_t oid, dmu_tx_t *tx, struct lu_attr *la,
+                   uint64_t parent)
 {
+       sa_handle_t     *sa_hdl;
        sa_bulk_attr_t  *bulk = osd_oti_get(env)->oti_attr_bulk;
        struct osa_attr *osa = &osd_oti_get(env)->oti_osa;
        uint64_t         gen;
@@ -1214,10 +1200,9 @@ int __osd_attr_init(const struct lu_env *env, struct osd_device *osd,
        int              cnt;
        int              rc;
 
-       LASSERT(sa_hdl);
-
-       gen = dmu_tx_get_txg(tx);
        gethrestime(&now);
+       gen = dmu_tx_get_txg(tx);
+
        ZFS_TIME_ENCODE(&now, crtime);
 
        osa->atime[0] = la->la_atime;
@@ -1231,6 +1216,11 @@ int __osd_attr_init(const struct lu_env *env, struct osd_device *osd,
        osa->flags = attrs_fs2zfs(la->la_flags);
        osa->size  = la->la_size;
 
+       /* Now add in all of the "SA" attributes */
+       rc = -sa_handle_get(osd->od_os, oid, NULL, SA_HDL_PRIVATE, &sa_hdl);
+       if (rc)
+               return rc;
+
        /*
         * we need to create all SA below upon object create.
         *
@@ -1259,6 +1249,7 @@ int __osd_attr_init(const struct lu_env *env, struct osd_device *osd,
 
        rc = -sa_replace_all_by_template(sa_hdl, bulk, cnt, tx);
 
+       sa_handle_destroy(sa_hdl);
        return rc;
 }
 
@@ -1268,7 +1259,8 @@ int __osd_attr_init(const struct lu_env *env, struct osd_device *osd,
  * to a transaction group.
  */
 int __osd_object_create(const struct lu_env *env, struct osd_object *obj,
-                       dmu_buf_t **dbp, dmu_tx_t *tx, struct lu_attr *la)
+                       dmu_buf_t **dbp, dmu_tx_t *tx, struct lu_attr *la,
+                       uint64_t parent)
 {
        uint64_t             oid;
        int                  rc;
@@ -1276,6 +1268,10 @@ int __osd_object_create(const struct lu_env *env, struct osd_object *obj,
        const struct lu_fid *fid = lu_object_fid(&obj->oo_dt.do_lu);
        dmu_object_type_t    type = DMU_OT_PLAIN_FILE_CONTENTS;
 
+       /* Assert that the transaction has been assigned to a
+          transaction group. */
+       LASSERT(tx->tx_txg != 0);
+
        /* Use DMU_OTN_UINT8_METADATA for local objects so their data blocks
         * would get an additional ditto copy */
        if (unlikely(S_ISREG(la->la_mode) &&
@@ -1291,6 +1287,14 @@ int __osd_object_create(const struct lu_env *env, struct osd_object *obj,
        la->la_size = 0;
        la->la_nlink = 1;
 
+       rc = __osd_attr_init(env, osd, oid, tx, la, parent);
+       if (rc != 0) {
+               sa_buf_rele(*dbp, osd_obj_tag);
+               *dbp = NULL;
+               dmu_object_free(osd->od_os, oid, tx);
+               return rc;
+       }
+
        return 0;
 }
 
@@ -1306,7 +1310,7 @@ int __osd_object_create(const struct lu_env *env, struct osd_object *obj,
  * a conversion from the different internal ZAP hash formats being used. */
 int __osd_zap_create(const struct lu_env *env, struct osd_device *osd,
                     dmu_buf_t **zap_dbp, dmu_tx_t *tx,
-                    struct lu_attr *la, zap_flags_t flags)
+                    struct lu_attr *la, uint64_t parent, zap_flags_t flags)
 {
        uint64_t oid;
        int      rc;
@@ -1325,14 +1329,16 @@ int __osd_zap_create(const struct lu_env *env, struct osd_device *osd,
        if (rc)
                return rc;
 
+       LASSERT(la->la_valid & LA_MODE);
        la->la_size = 2;
        la->la_nlink = 1;
 
-       return 0;
+       return __osd_attr_init(env, osd, oid, tx, la, parent);
 }
 
 static dmu_buf_t *osd_mkidx(const struct lu_env *env, struct osd_object *obj,
-                           struct lu_attr *la, struct osd_thandle *oh)
+                           struct lu_attr *la, uint64_t parent,
+                           struct osd_thandle *oh)
 {
        dmu_buf_t *db;
        int        rc;
@@ -1342,7 +1348,7 @@ static dmu_buf_t *osd_mkidx(const struct lu_env *env, struct osd_object *obj,
         * We set ZAP_FLAG_UINT64_KEY to let ZFS know than we are going to use
         * binary keys */
        LASSERT(S_ISREG(la->la_mode));
-       rc = __osd_zap_create(env, osd_obj2dev(obj), &db, oh->ot_tx, la,
+       rc = __osd_zap_create(env, osd_obj2dev(obj), &db, oh->ot_tx, la, parent,
                              ZAP_FLAG_UINT64_KEY);
        if (rc)
                return ERR_PTR(rc);
@@ -1350,20 +1356,23 @@ static dmu_buf_t *osd_mkidx(const struct lu_env *env, struct osd_object *obj,
 }
 
 static dmu_buf_t *osd_mkdir(const struct lu_env *env, struct osd_object *obj,
-                           struct lu_attr *la, struct osd_thandle *oh)
+                           struct lu_attr *la, uint64_t parent,
+                           struct osd_thandle *oh)
 {
        dmu_buf_t *db;
        int        rc;
 
        LASSERT(S_ISDIR(la->la_mode));
-       rc = __osd_zap_create(env, osd_obj2dev(obj), &db, oh->ot_tx, la, 0);
+       rc = __osd_zap_create(env, osd_obj2dev(obj), &db,
+                             oh->ot_tx, la, parent, 0);
        if (rc)
                return ERR_PTR(rc);
        return db;
 }
 
 static dmu_buf_t *osd_mkreg(const struct lu_env *env, struct osd_object *obj,
-                           struct lu_attr *la, struct osd_thandle *oh)
+                           struct lu_attr *la, uint64_t parent,
+                           struct osd_thandle *oh)
 {
        const struct lu_fid *fid = lu_object_fid(&obj->oo_dt.do_lu);
        dmu_buf_t           *db;
@@ -1371,7 +1380,7 @@ static dmu_buf_t *osd_mkreg(const struct lu_env *env, struct osd_object *obj,
        struct osd_device *osd = osd_obj2dev(obj);
 
        LASSERT(S_ISREG(la->la_mode));
-       rc = __osd_object_create(env, obj, &db, oh->ot_tx, la);
+       rc = __osd_object_create(env, obj, &db, oh->ot_tx, la, parent);
        if (rc)
                return ERR_PTR(rc);
 
@@ -1393,28 +1402,31 @@ static dmu_buf_t *osd_mkreg(const struct lu_env *env, struct osd_object *obj,
 }
 
 static dmu_buf_t *osd_mksym(const struct lu_env *env, struct osd_object *obj,
-                           struct lu_attr *la, struct osd_thandle *oh)
+                           struct lu_attr *la, uint64_t parent,
+                           struct osd_thandle *oh)
 {
        dmu_buf_t *db;
        int        rc;
 
        LASSERT(S_ISLNK(la->la_mode));
-       rc = __osd_object_create(env, obj, &db, oh->ot_tx, la);
+       rc = __osd_object_create(env, obj, &db, oh->ot_tx, la, parent);
        if (rc)
                return ERR_PTR(rc);
        return db;
 }
 
 static dmu_buf_t *osd_mknod(const struct lu_env *env, struct osd_object *obj,
-                           struct lu_attr *la, struct osd_thandle *oh)
+                           struct lu_attr *la, uint64_t parent,
+                           struct osd_thandle *oh)
 {
        dmu_buf_t *db;
        int        rc;
 
+       la->la_valid = LA_MODE;
        if (S_ISCHR(la->la_mode) || S_ISBLK(la->la_mode))
                la->la_valid |= LA_RDEV;
 
-       rc = __osd_object_create(env, obj, &db, oh->ot_tx, la);
+       rc = __osd_object_create(env, obj, &db, oh->ot_tx, la, parent);
        if (rc)
                return ERR_PTR(rc);
        return db;
@@ -1423,6 +1435,7 @@ static dmu_buf_t *osd_mknod(const struct lu_env *env, struct osd_object *obj,
 typedef dmu_buf_t *(*osd_obj_type_f)(const struct lu_env *env,
                                     struct osd_object *obj,
                                     struct lu_attr *la,
+                                    uint64_t parent,
                                     struct osd_thandle *oh);
 
 static osd_obj_type_f osd_create_type_f(enum dt_format_type type)
@@ -1453,6 +1466,28 @@ static osd_obj_type_f osd_create_type_f(enum dt_format_type type)
 }
 
 /*
+ * Primitives for directory (i.e. ZAP) handling
+ */
+static inline int osd_init_lma(const struct lu_env *env, struct osd_object *obj,
+                              const struct lu_fid *fid, struct osd_thandle *oh)
+{
+       struct osd_thread_info  *info = osd_oti_get(env);
+       struct lustre_mdt_attrs *lma = &info->oti_mdt_attrs;
+       struct lu_buf            buf;
+       int rc;
+
+       lustre_lma_init(lma, fid, 0, 0);
+       lustre_lma_swab(lma);
+       buf.lb_buf = lma;
+       buf.lb_len = sizeof(*lma);
+
+       rc = osd_xattr_set_internal(env, obj, &buf, XATTR_NAME_LMA,
+                                   LU_XATTR_CREATE, oh);
+
+       return rc;
+}
+
+/*
  * Concurrency: @dt is write locked.
  */
 static int osd_object_create(const struct lu_env *env, struct dt_object *dt,
@@ -1461,16 +1496,14 @@ static int osd_object_create(const struct lu_env *env, struct dt_object *dt,
                             struct dt_object_format *dof,
                             struct thandle *th)
 {
-       struct osd_thread_info  *info = osd_oti_get(env);
-       struct lustre_mdt_attrs *lma = &info->oti_mdt_attrs;
-       struct zpl_direntry     *zde = &info->oti_zde.lzd_reg;
+       struct zpl_direntry     *zde = &osd_oti_get(env)->oti_zde.lzd_reg;
        const struct lu_fid     *fid = lu_object_fid(&dt->do_lu);
        struct osd_object       *obj = osd_dt_obj(dt);
        struct osd_device       *osd = osd_obj2dev(obj);
-       char                    *buf = info->oti_str;
+       char                    *buf = osd_oti_get(env)->oti_str;
        struct osd_thandle      *oh;
-       dmu_buf_t               *db = NULL;
-       uint64_t                 zapid, parent = 0;
+       dmu_buf_t               *db;
+       uint64_t                 zapid;
        int                      rc;
 
        ENTRY;
@@ -1497,68 +1530,25 @@ static int osd_object_create(const struct lu_env *env, struct dt_object *dt,
 
        /* to follow ZFS on-disk format we need
         * to initialize parent dnode properly */
+       zapid = 0;
        if (hint != NULL && hint->dah_parent != NULL &&
            !dt_object_remote(hint->dah_parent))
-               parent = osd_dt_obj(hint->dah_parent)->oo_db->db_object;
+               zapid = osd_dt_obj(hint->dah_parent)->oo_db->db_object;
 
-       /* we may fix some attributes, better do not change the source */
-       obj->oo_attr = *attr;
-       obj->oo_attr.la_valid |= LA_SIZE | LA_NLINK | LA_TYPE;
-
-       db = osd_create_type_f(dof->dof_type)(env, obj, &obj->oo_attr, oh);
-       if (IS_ERR(db)) {
-               rc = PTR_ERR(db);
-               db = NULL;
-               GOTO(out, rc);
-       }
+       db = osd_create_type_f(dof->dof_type)(env, obj, attr, zapid, oh);
+       if (IS_ERR(db))
+               GOTO(out, rc = PTR_ERR(db));
 
        zde->zde_pad = 0;
        zde->zde_dnode = db->db_object;
        zde->zde_type = IFTODT(attr->la_mode & S_IFMT);
 
-       zapid = osd_get_name_n_idx(env, osd, fid, buf, sizeof(info->oti_str));
+       zapid = osd_get_name_n_idx(env, osd, fid, buf);
 
        rc = -zap_add(osd->od_os, zapid, buf, 8, 1, zde, oh->ot_tx);
        if (rc)
                GOTO(out, rc);
 
-       /* Now add in all of the "SA" attributes */
-       rc = -sa_handle_get(osd->od_os, db->db_object, NULL,
-                           SA_HDL_PRIVATE, &obj->oo_sa_hdl);
-       if (rc)
-               GOTO(out, rc);
-
-       /* configure new osd object */
-       obj->oo_db = db;
-       parent = parent != 0 ? parent : zapid;
-       rc = __osd_attr_init(env, osd, obj->oo_sa_hdl, oh->ot_tx,
-                            &obj->oo_attr, parent);
-       if (rc)
-               GOTO(out, rc);
-
-       /* XXX: oo_lma_flags */
-       obj->oo_dt.do_lu.lo_header->loh_attr |= obj->oo_attr.la_mode & S_IFMT;
-       smp_mb();
-       obj->oo_dt.do_lu.lo_header->loh_attr |= LOHA_EXISTS;
-       if (likely(!fid_is_acct(lu_object_fid(&obj->oo_dt.do_lu))))
-               /* no body operations for accounting objects */
-               obj->oo_dt.do_body_ops = &osd_body_ops;
-
-       rc = -nvlist_alloc(&obj->oo_sa_xattr, NV_UNIQUE_NAME, KM_SLEEP);
-       if (rc)
-               GOTO(out, rc);
-
-       /* initialize LMA */
-       lustre_lma_init(lma, lu_object_fid(&obj->oo_dt.do_lu), 0, 0);
-       lustre_lma_swab(lma);
-       rc = -nvlist_add_byte_array(obj->oo_sa_xattr, XATTR_NAME_LMA,
-                                   (uchar_t *)lma, sizeof(*lma));
-       if (rc)
-               GOTO(out, rc);
-       rc = __osd_sa_xattr_update(env, obj, oh);
-       if (rc)
-               GOTO(out, rc);
-
        /* Add new object to inode accounting.
         * Errors are not considered as fatal */
        rc = -zap_increment_int(osd->od_os, osd->od_iusr_oid,
@@ -1574,12 +1564,18 @@ static int osd_object_create(const struct lu_env *env, struct dt_object *dt,
                CERROR("%s: failed to add "DFID" to accounting ZAP for grp %d "
                        "(%d)\n", osd->od_svname, PFID(fid), attr->la_gid, rc);
 
+       /* configure new osd object */
+       obj->oo_db = db;
+       rc = osd_object_init0(env, obj);
+       LASSERT(ergo(rc == 0, dt_object_exists(dt)));
+       LASSERT(osd_invariant(obj));
+
+       rc = osd_init_lma(env, obj, fid, oh);
+       if (rc != 0)
+               CERROR("%s: can not set LMA on "DFID": rc = %d\n",
+                      osd->od_svname, PFID(fid), rc);
+
 out:
-       if (unlikely(rc && db)) {
-               dmu_object_free(osd->od_os, db->db_object, oh->ot_tx);
-               sa_buf_rele(db, osd_obj_tag);
-               obj->oo_db = NULL;
-       }
        up_write(&obj->oo_guard);
        RETURN(rc);
 }