From 34e7d46234e5c957e1e815c5267b13fe610a9d8d Mon Sep 17 00:00:00 2001 From: wang di Date: Thu, 15 Jan 2015 16:23:44 -0800 Subject: [PATCH] LU-5523 mdt: add --index option to default dir stripe Add --index option to default dirstripe EA. If MDT find out the client send the create req to the wrong MDT because of default stripeEA, it will return -EREMOTE, then client will retrieve default stripeEA through xattr cache, and re-create the object. Add delete default dirstripeEA (-d) to delete dir default stripeEA. Add ldo_dir_def_striping_cached and ldo_def_striping_cached to means if default striping EA has been cached in ldo_object. And ldo_striping_cached means if the object's own striping has been loaded from disk. Signed-off-by: wang di Change-Id: Ic2896e9050f1581344db9368b8f7b25bfded3d7d Reviewed-on: http://review.whamcloud.com/13360 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Lai Siyao Reviewed-by: Oleg Drokin --- lustre/include/obd.h | 3 ++ lustre/llite/llite_internal.h | 8 +++ lustre/llite/llite_lib.c | 7 ++- lustre/llite/namei.c | 43 +++++++++++++++-- lustre/llite/xattr.c | 1 - lustre/lmv/lmv_obd.c | 5 ++ lustre/lod/lod_internal.h | 7 +-- lustre/lod/lod_lov.c | 3 ++ lustre/lod/lod_object.c | 102 ++++++++++++++++++++++++--------------- lustre/mdt/mdt_reint.c | 12 +++++ lustre/tests/sanity.sh | 110 +++++++++++++++++++++++++++++++----------- lustre/utils/lfs.c | 27 +++++++++-- 12 files changed, 248 insertions(+), 80 deletions(-) diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 3f3d2fa..cea637d 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -834,6 +834,9 @@ struct md_op_data { /* File object data version for HSM release, on client */ __u64 op_data_version; struct lustre_handle op_lease_handle; + + /* default stripe offset */ + __u32 op_default_stripe_offset; }; struct md_callback { diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index da5f369..fc9f234 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -208,6 +208,12 @@ struct ll_inode_info { unsigned int lli_sa_generation; /* directory stripe information */ struct lmv_stripe_md *lli_lsm_md; + /* default directory stripe offset. This is extracted + * from the "dmv" xattr in order to decide which MDT to + * create a subdirectory on. The MDS itself fetches + * "dmv" and gets the rest of the default layout itself + * (count, hash, etc). */ + __u32 lli_def_stripe_offset; }; /* for non-directory */ @@ -1506,6 +1512,8 @@ int ll_layout_restore(struct inode *inode, loff_t start, __u64 length); int ll_xattr_init(void); void ll_xattr_fini(void); +int ll_getxattr_common(struct inode *inode, const char *name, + void *buffer, size_t size, __u64 valid); int ll_page_sync_io(const struct lu_env *env, struct cl_io *io, struct cl_page *page, enum cl_req_type crt); diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 889e857..fca1a7d 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -971,6 +971,7 @@ void ll_lli_init(struct ll_inode_info *lli) spin_lock_init(&lli->lli_sa_lock); lli->lli_opendir_pid = 0; lli->lli_sa_enabled = 0; + lli->lli_def_stripe_offset = -1; } else { mutex_init(&lli->lli_size_mutex); lli->lli_symlink_name = NULL; @@ -2531,8 +2532,12 @@ struct md_op_data * ll_prep_md_op_data(struct md_op_data *op_data, ll_i2gids(op_data->op_suppgids, i1, i2); op_data->op_fid1 = *ll_inode2fid(i1); op_data->op_capa1 = ll_mdscapa_get(i1); - if (S_ISDIR(i1->i_mode)) + op_data->op_default_stripe_offset = -1; + if (S_ISDIR(i1->i_mode)) { op_data->op_mea1 = ll_i2info(i1)->lli_lsm_md; + op_data->op_default_stripe_offset = + ll_i2info(i1)->lli_def_stripe_offset; + } if (i2) { op_data->op_fid2 = *ll_inode2fid(i2); diff --git a/lustre/llite/namei.c b/lustre/llite/namei.c index 97ea1f1..6329551 100644 --- a/lustre/llite/namei.c +++ b/lustre/llite/namei.c @@ -213,6 +213,8 @@ int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc, } if (bits & MDS_INODELOCK_XATTR) { + if (S_ISDIR(inode->i_mode)) + ll_i2info(inode)->lli_def_stripe_offset = -1; ll_xattr_cache_destroy(inode); bits &= ~MDS_INODELOCK_XATTR; } @@ -918,6 +920,7 @@ static int ll_new_node(struct inode *dir, struct dentry *dchild, if (unlikely(tgt != NULL)) tgt_len = strlen(tgt) + 1; +again: op_data = ll_prep_md_op_data(NULL, dir, NULL, name->name, name->len, 0, opc, NULL); if (IS_ERR(op_data)) @@ -928,8 +931,41 @@ static int ll_new_node(struct inode *dir, struct dentry *dchild, from_kgid(&init_user_ns, current_fsgid()), cfs_curproc_cap_pack(), rdev, &request); ll_finish_md_op_data(op_data); - if (err) - GOTO(err_exit, err); + if (err) { + /* If the client doesn't know where to create a subdirectory (or + * in case of a race that sends the RPC to the wrong MDS), the + * MDS will return -EREMOTE and the client will fetch the layout + * for the directory, either from the local xattr cache or the + * MDS, then create the directory on the right MDT. */ + if (err == -EREMOTE) { + struct lmv_user_md *lum; + int rc; + + ptlrpc_req_finished(request); + request = NULL; + + OBD_ALLOC_PTR(lum); + if (lum == NULL) + GOTO(err_exit, err = -ENOMEM); + + rc = ll_getxattr_common(dir, XATTR_NAME_DEFAULT_LMV, + lum, sizeof(*lum), + OBD_MD_FLXATTR); + if (rc < 0) { + OBD_FREE_PTR(lum); + if (rc == -ENODATA) + GOTO(err_exit, err); + else + GOTO(err_exit, rc); + } + + ll_i2info(dir)->lli_def_stripe_offset = + le32_to_cpu(lum->lum_stripe_offset); + OBD_FREE_PTR(lum); + goto again; + } + GOTO(err_exit, err); + } ll_update_times(request, dir); @@ -941,7 +977,8 @@ static int ll_new_node(struct inode *dir, struct dentry *dchild, EXIT; err_exit: - ptlrpc_req_finished(request); + if (request != NULL) + ptlrpc_req_finished(request); return err; } diff --git a/lustre/llite/xattr.c b/lustre/llite/xattr.c index 3302caa..18429ab 100644 --- a/lustre/llite/xattr.c +++ b/lustre/llite/xattr.c @@ -287,7 +287,6 @@ int ll_removexattr(struct dentry *dentry, const char *name) OBD_MD_FLXATTRRM); } -static int ll_getxattr_common(struct inode *inode, const char *name, void *buffer, size_t size, __u64 valid) { diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index f0dccda..c13e91a 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -1250,6 +1250,11 @@ static int lmv_placement_policy(struct obd_device *obd, RETURN(0); } + if (op_data->op_default_stripe_offset != -1) { + *mds = op_data->op_default_stripe_offset; + RETURN(0); + } + /** * If stripe_offset is provided during setdirstripe * (setdirstripe -i xx), xx MDS will be choosen. diff --git a/lustre/lod/lod_internal.h b/lustre/lod/lod_internal.h index 48bd2d4..3d6fa6d 100644 --- a/lustre/lod/lod_internal.h +++ b/lustre/lod/lod_internal.h @@ -224,8 +224,8 @@ struct lod_dir_stripe_info { __u32 ldsi_def_hash_type; __u32 ldsi_hash_type; - unsigned int ldsi_striping_cached:1, - ldsi_def_striping_set:1, + unsigned int ldsi_def_striping_set:1, + ldsi_def_striping_cached:1, ldsi_striped:1; }; @@ -251,6 +251,7 @@ struct lod_object { unsigned int ldo_stripes_allocated:16, ldo_striping_cached:1, ldo_def_striping_set:1, + ldo_def_striping_cached:1, /* ldo_dir_slave_stripe indicate this is a slave stripe of * a striped dir */ ldo_dir_slave_stripe:1; @@ -264,9 +265,9 @@ struct lod_object { #define ldo_dir_def_stripenr ldo_dir_stripe->ldsi_def_stripenr #define ldo_dir_hash_type ldo_dir_stripe->ldsi_hash_type #define ldo_dir_def_hash_type ldo_dir_stripe->ldsi_def_hash_type -#define ldo_dir_striping_cached ldo_dir_stripe->ldsi_striping_cached #define ldo_dir_striped ldo_dir_stripe->ldsi_striped #define ldo_dir_def_striping_set ldo_dir_stripe->ldsi_def_striping_set +#define ldo_dir_def_striping_cached ldo_dir_stripe->ldsi_def_striping_cached #define ldo_dir_def_stripe_offset ldo_dir_stripe->ldsi_def_stripe_offset struct lod_it { diff --git a/lustre/lod/lod_lov.c b/lustre/lod/lod_lov.c index 47eefff..c1fcdb8 100644 --- a/lustre/lod/lod_lov.c +++ b/lustre/lod/lod_lov.c @@ -989,6 +989,9 @@ int lod_load_striping_locked(const struct lu_env *env, struct lod_object *lo) */ rc = lod_parse_dir_striping(env, lo, buf); } + + if (rc == 0) + lo->ldo_striping_cached = 1; out: RETURN(rc); } diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index a2d2256..fc9802c 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -1433,7 +1433,7 @@ static int lod_xattr_get(const struct lu_env *env, struct dt_object *dt, /** * Verify LVM EA. * - * Checks that the magic and the number of the stripes are sane. + * Checks that the magic of the stripe is sane. * * \param[in] lod lod device * \param[in] lum a buffer storing LMV EA to verify @@ -1444,22 +1444,16 @@ static int lod_xattr_get(const struct lu_env *env, struct dt_object *dt, static int lod_verify_md_striping(struct lod_device *lod, const struct lmv_user_md_v1 *lum) { - int rc = 0; - ENTRY; - - if (unlikely(le32_to_cpu(lum->lum_magic) != LMV_USER_MAGIC)) - GOTO(out, rc = -EINVAL); - - if (unlikely(le32_to_cpu(lum->lum_stripe_count) == 0)) - GOTO(out, rc = -EINVAL); -out: - if (rc != 0) + if (unlikely(le32_to_cpu(lum->lum_magic) != LMV_USER_MAGIC)) { CERROR("%s: invalid lmv_user_md: magic = %x, " "stripe_offset = %d, stripe_count = %u: rc = %d\n", lod2obd(lod)->obd_name, le32_to_cpu(lum->lum_magic), (int)le32_to_cpu(lum->lum_stripe_offset), - le32_to_cpu(lum->lum_stripe_count), rc); - return rc; + le32_to_cpu(lum->lum_stripe_count), -EINVAL); + return -EINVAL; + } + + return 0; } /** @@ -1528,7 +1522,6 @@ static int lod_prep_lmv_md(const struct lu_env *env, struct dt_object *dt, lmm1->lmv_master_mdt_index = cpu_to_le32(mdtidx); lmv_buf->lb_buf = info->lti_ea_store; lmv_buf->lb_len = sizeof(*lmm1); - lo->ldo_dir_striping_cached = 1; RETURN(rc); } @@ -1839,7 +1832,7 @@ next: GOTO(out_put, rc); /* probably nothing to inherite */ - if (lo->ldo_striping_cached && + if (lo->ldo_def_striping_set && !LOVEA_DELETE_VALUES(lo->ldo_def_stripe_size, lo->ldo_def_stripenr, lo->ldo_def_stripe_offset, @@ -2131,13 +2124,13 @@ static int lod_declare_xattr_set(const struct lu_env *env, */ static void lod_lov_stripe_cache_clear(struct lod_object *lo) { - lo->ldo_striping_cached = 0; lo->ldo_def_striping_set = 0; + lo->ldo_def_striping_cached = 0; lod_object_set_pool(lo, NULL); lo->ldo_def_stripe_size = 0; lo->ldo_def_stripenr = 0; if (lo->ldo_dir_stripe != NULL) - lo->ldo_dir_striping_cached = 0; + lo->ldo_dir_def_striping_cached = 0; } /** @@ -2364,10 +2357,7 @@ static int lod_xattr_set_default_lmv_on_dir(const struct lu_env *env, RETURN(-ENOMEM); } - l->ldo_dir_striping_cached = 0; - l->ldo_dir_def_striping_set = 1; - l->ldo_dir_def_stripenr = le32_to_cpu(lum->lum_stripe_count); - + l->ldo_dir_def_striping_cached = 0; RETURN(rc); } @@ -2471,7 +2461,7 @@ static int lod_xattr_set_lmv(const struct lu_env *env, struct dt_object *dt, if (rc != 0) RETURN(rc); - if (lo->ldo_striping_cached && + if (lo->ldo_def_striping_set && !LOVEA_DELETE_VALUES(lo->ldo_def_stripe_size, lo->ldo_def_stripenr, lo->ldo_def_stripe_offset, @@ -2635,7 +2625,7 @@ static int lod_dir_striping_create_internal(const struct lu_env *env, } /* Transfer default LMV striping from the parent */ - if (lo->ldo_dir_striping_cached && + if (lo->ldo_dir_def_striping_set && !LMVEA_DELETE_VALUES(lo->ldo_dir_def_stripenr, lo->ldo_dir_def_stripe_offset)) { struct lmv_user_md_v1 *v1 = info->lti_ea_store; @@ -2672,7 +2662,7 @@ static int lod_dir_striping_create_internal(const struct lu_env *env, } /* Transfer default LOV striping from the parent */ - if (lo->ldo_striping_cached && + if (lo->ldo_def_striping_set && !LOVEA_DELETE_VALUES(lo->ldo_def_stripe_size, lo->ldo_def_stripenr, lo->ldo_def_stripe_offset, @@ -2727,7 +2717,14 @@ static int lod_dir_striping_create(const struct lu_env *env, struct dt_object_format *dof, struct thandle *th) { - return lod_dir_striping_create_internal(env, dt, attr, dof, th, false); + struct lod_object *lo = lod_dt_obj(dt); + int rc; + + rc = lod_dir_striping_create_internal(env, dt, attr, dof, th, false); + if (rc == 0) + lo->ldo_striping_cached = 1; + + return rc; } /** @@ -2916,7 +2913,7 @@ static int lod_cache_parent_lov_striping(const struct lu_env *env, if (rc < (typeof(rc))sizeof(struct lov_user_md)) { /* don't lookup for non-existing or invalid striping */ lp->ldo_def_striping_set = 0; - lp->ldo_striping_cached = 1; + lp->ldo_def_striping_cached = 1; lp->ldo_def_stripe_size = 0; lp->ldo_def_stripenr = 0; lp->ldo_def_stripe_offset = (typeof(v1->lmm_stripe_offset))(-1); @@ -2946,7 +2943,7 @@ static int lod_cache_parent_lov_striping(const struct lu_env *env, lp->ldo_def_stripenr = v1->lmm_stripe_count; lp->ldo_def_stripe_size = v1->lmm_stripe_size; lp->ldo_def_stripe_offset = v1->lmm_stripe_offset; - lp->ldo_striping_cached = 1; + lp->ldo_def_striping_cached = 1; lp->ldo_def_striping_set = 1; if (v1->lmm_magic == LOV_USER_MAGIC_V3) { /* XXX: sanity check here */ @@ -2991,7 +2988,7 @@ static int lod_cache_parent_lmv_striping(const struct lu_env *env, if (rc < (typeof(rc))sizeof(struct lmv_user_md)) { /* don't lookup for non-existing or invalid striping */ lp->ldo_dir_def_striping_set = 0; - lp->ldo_dir_striping_cached = 1; + lp->ldo_dir_def_striping_cached = 1; lp->ldo_dir_def_stripenr = 0; lp->ldo_dir_def_stripe_offset = (typeof(v1->lum_stripe_offset))(-1); @@ -3006,7 +3003,7 @@ static int lod_cache_parent_lmv_striping(const struct lu_env *env, lp->ldo_dir_def_stripe_offset = le32_to_cpu(v1->lum_stripe_offset); lp->ldo_dir_def_hash_type = le32_to_cpu(v1->lum_hash_type); lp->ldo_dir_def_striping_set = 1; - lp->ldo_dir_striping_cached = 1; + lp->ldo_dir_def_striping_cached = 1; EXIT; unlock: @@ -3037,11 +3034,7 @@ static int lod_cache_parent_striping(const struct lu_env *env, int rc = 0; ENTRY; - rc = lod_load_striping(env, lp); - if (rc != 0) - RETURN(rc); - - if (!lp->ldo_striping_cached) { + if (!lp->ldo_def_striping_cached) { /* we haven't tried to get default striping for * the directory yet, let's cache it in the object */ rc = lod_cache_parent_lov_striping(env, lp); @@ -3049,7 +3042,12 @@ static int lod_cache_parent_striping(const struct lu_env *env, RETURN(rc); } - if (S_ISDIR(child_mode) && !lp->ldo_dir_striping_cached) + /* If the parent is on the remote MDT, we should always + * try to refresh the default stripeEA cache, because we + * do not cache default striping information for remote + * object. */ + if (S_ISDIR(child_mode) && (!lp->ldo_dir_def_striping_cached || + dt_object_remote(&lp->ldo_obj))) rc = lod_cache_parent_lmv_striping(env, lp); RETURN(rc); @@ -3116,6 +3114,7 @@ static void lod_ah_init(const struct lu_env *env, return; } + LASSERT(lp != NULL); if (lp->ldo_dir_stripe == NULL) { OBD_ALLOC_PTR(lp->ldo_dir_stripe); if (lp->ldo_dir_stripe == NULL) @@ -3127,14 +3126,14 @@ static void lod_ah_init(const struct lu_env *env, return; /* transfer defaults to new directory */ - if (lp->ldo_striping_cached) { + if (lp->ldo_def_striping_set) { if (lp->ldo_pool) lod_object_set_pool(lc, lp->ldo_pool); lc->ldo_def_stripenr = lp->ldo_def_stripenr; lc->ldo_def_stripe_size = lp->ldo_def_stripe_size; lc->ldo_def_stripe_offset = lp->ldo_def_stripe_offset; - lc->ldo_striping_cached = 1; lc->ldo_def_striping_set = 1; + lc->ldo_def_striping_cached = 1; CDEBUG(D_OTHER, "inherite EA sz:%d off:%d nr:%d\n", (int)lc->ldo_def_stripe_size, (int)lc->ldo_def_stripe_offset, @@ -3142,14 +3141,14 @@ static void lod_ah_init(const struct lu_env *env, } /* transfer dir defaults to new directory */ - if (lp->ldo_dir_striping_cached) { + if (lp->ldo_dir_def_striping_set) { lc->ldo_dir_def_stripenr = lp->ldo_dir_def_stripenr; lc->ldo_dir_def_stripe_offset = lp->ldo_dir_def_stripe_offset; lc->ldo_dir_def_hash_type = lp->ldo_dir_def_hash_type; - lc->ldo_dir_striping_cached = 1; lc->ldo_dir_def_striping_set = 1; + lc->ldo_dir_def_striping_cached = 1; CDEBUG(D_INFO, "inherit default EA nr:%d off:%d t%u\n", (int)lc->ldo_dir_def_stripenr, (int)lc->ldo_dir_def_stripe_offset, @@ -3432,6 +3431,24 @@ static int lod_declare_object_create(const struct lu_env *env, rc = lod_declare_striped_object(env, dt, attr, NULL, th); } else if (dof->dof_type == DFT_DIR) { + struct seq_server_site *ss; + + ss = lu_site2seq(dt->do_lu.lo_dev->ld_site); + + /* If the parent has default stripeEA, and client + * did not find it before sending create request, + * then MDT will return -EREMOTE, and client will + * retrieve the default stripeEA and re-create the + * sub directory. + * + * Note: if dah_eadata != NULL, it means creating the + * striped directory with specified stripeEA, then it + * should ignore the default stripeEA */ + if ((hint == NULL || hint->dah_eadata == NULL) && + lo->ldo_dir_stripe_offset != -1 && + lo->ldo_dir_stripe_offset != ss->ss_node_id) + GOTO(out, rc = -EREMOTE); + /* Orphan object (like migrating object) does not have * lod_dir_stripe, see lod_ah_init */ if (lo->ldo_dir_stripe != NULL) @@ -3479,8 +3496,12 @@ int lod_striping_create(const struct lu_env *env, struct dt_object *dt, if (rc) break; } - if (rc == 0) + + if (rc == 0) { rc = lod_generate_and_set_lovea(env, lo, th); + if (rc == 0) + lo->ldo_striping_cached = 1; + } RETURN(rc); } @@ -4098,6 +4119,7 @@ void lod_object_free_striping(const struct lu_env *env, struct lod_object *lo) lo->ldo_stripe = NULL; lo->ldo_stripes_allocated = 0; } + lo->ldo_striping_cached = 0; lo->ldo_stripenr = 0; lo->ldo_pattern = 0; } diff --git a/lustre/mdt/mdt_reint.c b/lustre/mdt/mdt_reint.c index aa17d09..9d3f468 100644 --- a/lustre/mdt/mdt_reint.c +++ b/lustre/mdt/mdt_reint.c @@ -769,14 +769,26 @@ static int mdt_reint_setattr(struct mdt_thread_info *info, GOTO(out_put, rc); } else if ((ma->ma_valid & MA_LMV) && (ma->ma_valid & MA_INODE)) { struct lu_buf *buf = &info->mti_buf; + struct mdt_lock_handle *lh; if (ma->ma_attr.la_valid != 0) GOTO(out_put, rc = -EPROTO); + lh = &info->mti_lh[MDT_LH_PARENT]; + mdt_lock_reg_init(lh, LCK_PW); + + rc = mdt_object_lock(info, mo, lh, + MDS_INODELOCK_XATTR, + MDT_LOCAL_LOCK); + if (rc != 0) + GOTO(out_put, rc); + buf->lb_buf = ma->ma_lmv; buf->lb_len = ma->ma_lmv_size; rc = mo_xattr_set(info->mti_env, mdt_object_child(mo), buf, XATTR_NAME_DEFAULT_LMV, 0); + + mdt_object_unlock(info, mo, lh, rc); if (rc) GOTO(out_put, rc); } else { diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 18fb399..79535c2d 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -13157,55 +13157,111 @@ test_300f() { } run_test 300f "check rename cross striped directory" +test_300_check_default_striped_dir() +{ + local dirname=$1 + local default_count=$2 + local default_index=$3 + local stripe_count + local stripe_index + local dir_stripe_index + local dir + + echo "checking $dirname $default_count $default_index" + $LFS setdirstripe -D -c $default_count -i $default_index \ + -t all_char $DIR/$tdir/$dirname || + error "set default stripe on striped dir error" + stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname) + [ $stripe_count -eq $default_count ] || + error "expect $default_count get $stripe_count for $dirname" + + stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname) + [ $stripe_index -eq $default_index ] || + error "expect $default_index get $stripe_index for $dirname" + + mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} || + error "create dirs failed" + for dir in $(find $DIR/$tdir/$dirname/*); do + stripe_count=$($LFS getdirstripe -c $dir) + [ $stripe_count -eq $default_count ] || + error "stripe count $default_count != $stripe_count for $dir" + + stripe_index=$($LFS getdirstripe -i $dir) + [ $default_index -eq -1 -o $stripe_index -eq $default_index ] || + error "$stripe_index != $default_index for $dir" + + #check default stripe + stripe_count=$($LFS getdirstripe -D -c $dir) + [ $stripe_count -eq $default_count ] || + error "default count $default_count != $stripe_count for $dir" + + stripe_index=$($LFS getdirstripe -D -i $dir) + [ $stripe_index -eq $default_index ] || + error "default index $default_index != $stripe_index for $dir" + done + rmdir $DIR/$tdir/$dirname/* || error "rmdir failed" +} + test_300g() { [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return - local stripe_count local dir + local stripe_count + local stripe_index mkdir $DIR/$tdir - $LFS setdirstripe -i 0 -c $MDSCOUNT -t all_char \ - $DIR/$tdir/striped_dir || - error "set striped dir error" - - $LFS setdirstripe -D -c $MDSCOUNT -t all_char $DIR/$tdir/striped_dir || - error "set default stripe on striped dir error" + mkdir $DIR/$tdir/normal_dir - stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/striped_dir) - [ $stripe_count -eq $MDSCOUNT ] || - error "default stripe wrong expect $MDSCOUNT get $stripe_count" + test_300_check_default_striped_dir normal_dir $MDSCOUNT 1 + test_300_check_default_striped_dir normal_dir 1 0 + test_300_check_default_striped_dir normal_dir 2 1 + test_300_check_default_striped_dir normal_dir 2 -1 - mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4} + #delete default stripe information + echo "delete default stripeEA" + $LFS setdirstripe -d $DIR/$tdir/normal_dir || + error "set default stripe on striped dir error" - for dir in $(find $DIR/$tdir/striped_dir/*); do + mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4} + for dir in $(find $DIR/$tdir/normal_dir/*); do stripe_count=$($LFS getdirstripe -c $dir) - [ $stripe_count -eq $MDSCOUNT ] || - error "expect $MDSCOUNT get $stripe_count for $dir" + [ $stripe_count -eq 0 ] || + error "expect 1 get $stripe_count for $dir" + stripe_index=$($LFS getdirstripe -i $dir) + [ $stripe_index -eq 0 ] || + error "expect 0 get $stripe_index for $dir" done +} +run_test 300g "check default striped directory for normal directory" - rmdir $DIR/$tdir/striped_dir/* || error "rmdir1 failed" - #change default stripe count to 2 - $LFS setdirstripe -D -c 2 -t all_char $DIR/$tdir/striped_dir || - error "set default stripe on striped dir error" +test_300h() { + [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return + local dir + local stripe_count - mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4} + mkdir $DIR/$tdir + $LFS setdirstripe -i 0 -c $MDSCOUNT -t all_char \ + $DIR/$tdir/striped_dir || + error "set striped dir error" - rmdir $DIR/$tdir/striped_dir/* || error "rmdir2 failed" + test_300_check_default_striped_dir striped_dir $MDSCOUNT 1 + test_300_check_default_striped_dir striped_dir 1 0 + test_300_check_default_striped_dir striped_dir 2 1 + test_300_check_default_striped_dir striped_dir 2 -1 - #change default stripe count to 1 - $LFS setdirstripe -D -c 1 -t all_char $DIR/$tdir/striped_dir || + #delete default stripe information + $LFS setdirstripe -d $DIR/$tdir/striped_dir || error "set default stripe on striped dir error" mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4} for dir in $(find $DIR/$tdir/striped_dir/*); do stripe_count=$($LFS getdirstripe -c $dir) - [ $stripe_count -eq 1 ] || + [ $stripe_count -eq 0 ] || error "expect 1 get $stripe_count for $dir" done - rmdir $DIR/$tdir/striped_dir/* || error "rmdir3 failed" } -run_test 300g "check default striped directory for striped directory" +run_test 300h "check default striped directory for striped directory" -test_300h() { +test_300i() { [ $PARALLEL == "yes" ] && skip "skip parallel run" && return [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return local stripe_count @@ -13243,7 +13299,7 @@ test_300h() { return 0 } -run_test 300h "client handle unknown hash type striped directory" +run_test 300i "client handle unknown hash type striped directory" test_400a() { # LU-1606, was conf-sanity test_74 local extra_flags='' diff --git a/lustre/utils/lfs.c b/lustre/utils/lfs.c index 539c591..f2668ae 100644 --- a/lustre/utils/lfs.c +++ b/lustre/utils/lfs.c @@ -1628,12 +1628,14 @@ static int lfs_setdirstripe(int argc, char **argv) char *stripe_count_opt = NULL; char *stripe_hash_opt = NULL; char *mode_opt = NULL; - int default_stripe = 0; + bool default_stripe = false; mode_t mode = S_IRWXU | S_IRWXG | S_IRWXO; mode_t previous_mode = 0; + bool delete = false; struct option long_opts[] = { {"count", required_argument, 0, 'c'}, + {"delete", no_argument, 0, 'd'}, {"index", required_argument, 0, 'i'}, {"mode", required_argument, 0, 'm'}, {"hash-type", required_argument, 0, 't'}, @@ -1641,7 +1643,7 @@ static int lfs_setdirstripe(int argc, char **argv) {0, 0, 0, 0} }; - while ((c = getopt_long(argc, argv, "c:Di:m:t:", long_opts, + while ((c = getopt_long(argc, argv, "c:dDi:m:t:", long_opts, NULL)) >= 0) { switch (c) { case 0: @@ -1650,8 +1652,12 @@ static int lfs_setdirstripe(int argc, char **argv) case 'c': stripe_count_opt = optarg; break; + case 'd': + delete = true; + default_stripe = true; + break; case 'D': - default_stripe = 1; + default_stripe = true; break; case 'i': stripe_offset_opt = optarg; @@ -1676,7 +1682,7 @@ static int lfs_setdirstripe(int argc, char **argv) return CMD_HELP; } - if (stripe_offset_opt == NULL && stripe_count_opt == NULL) { + if (!delete && stripe_offset_opt == NULL && stripe_count_opt == NULL) { fprintf(stderr, "error: %s: missing stripe offset and count.\n", argv[0]); return CMD_HELP; @@ -1692,6 +1698,17 @@ static int lfs_setdirstripe(int argc, char **argv) } } + if (delete) { + if (stripe_offset_opt != NULL || stripe_count_opt != NULL) { + fprintf(stderr, "error: %s: cannot specify -d with -s," + " or -i options.\n", argv[0]); + return CMD_HELP; + } else { + stripe_count = 0; + } + } + + if (mode_opt != NULL) { mode = strtoul(mode_opt, &end, 8); if (*end != '\0') { @@ -1725,7 +1742,7 @@ static int lfs_setdirstripe(int argc, char **argv) dname = argv[optind]; do { - if (default_stripe == 1) { + if (default_stripe) { result = llapi_dir_set_default_lmv_stripe(dname, stripe_offset, stripe_count, hash_type, NULL); -- 1.8.3.1