/* * The transaction passed to this routine must have * dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, ...) called and then assigned * to a transaction group. * * Using ZAP_FLAG_HASH64 will force the ZAP to always be a FAT ZAP. * This is fine for directories today, because storing the FID in the dirent * will also require a FAT ZAP. If there is a new type of micro ZAP created * then we might need to re-evaluate the use of this flag and instead do * a conversion from the different internal ZAP hash formats being used. */ int __osd_zap_create(const struct lu_env *env, udmu_objset_t *uos, dmu_buf_t **zap_dbp, dmu_tx_t *tx, struct lu_attr *la, void *tag, zap_flags_t flags) { uint64_t oid; int rc; LASSERT(tag); spin_lock(&uos->lock); uos->objects++; spin_unlock(&uos->lock); /* Assert that the transaction has been assigned to a transaction group. */ LASSERT(tx->tx_txg != 0); oid = zap_create_flags(uos->os, 0, flags | ZAP_FLAG_HASH64, DMU_OT_DIRECTORY_CONTENTS, 12, 12, DMU_OT_SA, DN_MAX_BONUSLEN, tx); rc = -sa_buf_hold(uos->os, oid, tag, zap_dbp); if (rc) return rc; LASSERT(la->la_valid & LA_MODE); la->la_size = 2; la->la_nlink = 1; return __osd_attr_init(env, uos, oid, tx, la); }
/* * The transaction passed to this routine must have * dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT) called and then assigned * to a transaction group. */ int __osd_object_create(const struct lu_env *env, udmu_objset_t *uos, dmu_buf_t **dbp, dmu_tx_t *tx, struct lu_attr *la, void *tag) { uint64_t oid; int rc; LASSERT(tag); spin_lock(&uos->lock); uos->objects++; spin_unlock(&uos->lock); /* Assert that the transaction has been assigned to a transaction group. */ LASSERT(tx->tx_txg != 0); /* Create a new DMU object. */ oid = dmu_object_alloc(uos->os, DMU_OT_PLAIN_FILE_CONTENTS, 0, DMU_OT_SA, DN_MAX_BONUSLEN, tx); rc = -sa_buf_hold(uos->os, oid, tag, dbp); if (rc) return rc; LASSERT(la->la_valid & LA_MODE); la->la_size = 0; la->la_nlink = 1; return __osd_attr_init(env, uos, oid, tx, la); }
/* * The transaction passed to this routine must have * dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, ...) called and then assigned * to a transaction group. * * Using ZAP_FLAG_HASH64 will force the ZAP to always be a FAT ZAP. * This is fine for directories today, because storing the FID in the dirent * will also require a FAT ZAP. If there is a new type of micro ZAP created * then we might need to re-evaluate the use of this flag and instead do * 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, uint64_t parent, zap_flags_t flags) { uint64_t oid; int rc; /* Assert that the transaction has been assigned to a transaction group. */ LASSERT(tx->tx_txg != 0); oid = zap_create_flags(osd->od_os, 0, flags | ZAP_FLAG_HASH64, DMU_OT_DIRECTORY_CONTENTS, 14, /* == ZFS fzap_default_block_shift */ DN_MAX_INDBLKSHIFT, /* indirect block shift */ DMU_OT_SA, DN_MAX_BONUSLEN, tx); rc = -sa_buf_hold(osd->od_os, oid, osd_obj_tag, zap_dbp); if (rc) return rc; LASSERT(la->la_valid & LA_MODE); la->la_size = 2; la->la_nlink = 1; return __osd_attr_init(env, osd, oid, tx, la, parent); }
/* * The transaction passed to this routine must have * dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT) called and then assigned * 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, uint64_t parent) { uint64_t oid; int rc; struct osd_device *osd = osd_obj2dev(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) && fid_seq_is_local_file(fid_seq(fid)))) type = DMU_OTN_UINT8_METADATA; /* Create a new DMU object. */ oid = dmu_object_alloc(osd->od_os, type, 0, DMU_OT_SA, DN_MAX_BONUSLEN, tx); rc = -sa_buf_hold(osd->od_os, oid, osd_obj_tag, dbp); LASSERTF(rc == 0, "sa_buf_hold "LPU64" failed: %d\n", oid, rc); LASSERT(la->la_valid & LA_MODE); 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; }
/* * Concurrency: @dt is write locked. */ static int osd_object_create(const struct lu_env *env, struct dt_object *dt, struct lu_attr *attr, struct dt_allocation_hint *hint, 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; 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; struct osd_thandle *oh; dmu_buf_t *db = NULL; uint64_t zapid, parent = 0; int rc; ENTRY; /* concurrent create declarations should not see * the object inconsistent (db, attr, etc). * in regular cases acquisition should be cheap */ down_write(&obj->oo_guard); if (unlikely(dt_object_exists(dt))) GOTO(out, rc = -EEXIST); LASSERT(osd_invariant(obj)); LASSERT(dof != NULL); LASSERT(th != NULL); oh = container_of0(th, struct osd_thandle, ot_super); /* * XXX missing: Quote handling. */ LASSERT(obj->oo_db == NULL); /* to follow ZFS on-disk format we need * to initialize parent dnode properly */ if (hint != NULL && hint->dah_parent != NULL && !dt_object_remote(hint->dah_parent)) parent = 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); } 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)); 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, (attr->la_valid & LA_UID) ? attr->la_uid : 0, 1, oh->ot_tx); if (rc) CERROR("%s: failed to add "DFID" to accounting ZAP for usr %d " "(%d)\n", osd->od_svname, PFID(fid), attr->la_uid, rc); rc = -zap_increment_int(osd->od_os, osd->od_igrp_oid, (attr->la_valid & LA_GID) ? attr->la_gid : 0, 1, oh->ot_tx); if (rc) CERROR("%s: failed to add "DFID" to accounting ZAP for grp %d " "(%d)\n", osd->od_svname, PFID(fid), attr->la_gid, 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); }