diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 3b8bc382f8dce63e5e835a5299c972ef6c34fb25..cd254c503142bca445c0e584913ce33be04a5c2a 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -471,6 +471,15 @@ Details : decrease the amount of synchronous RPC between clients and servers by canceling conflicing lock before the operation on the client side and packing thier handles into the main operation RPC to server. +Severity : enhancement +Bugzilla : 4900 +Description: Async OSC create to avoid the blocking unnecessarily. +Details : If a OST has no remain object, system will block on the creating + when need to create a new object on this OST. Now, ways use + pre-created objects when available, instead of blocking on an + empty osc while others are not empty. If we must block, we block + for the shortest possible period of time. + -------------------------------------------------------------------------------- 2007-05-03 Cluster File Systems, Inc. <info@clusterfs.com> @@ -509,6 +518,7 @@ Details : The __iget() symbol export is missing. To avoid the need for * bug fixes + Severity : enhancement Bugzilla : 8007 Description: MountConf diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 56d89184097269e1be75b5ca3647a0f5c1f99c31..9446c160dfa385f2c18bcb88d070bf353c9e2a08 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -1066,6 +1066,7 @@ struct obd_ops { int (*o_preallocate)(struct lustre_handle *, obd_count *req, obd_id *ids); /* FIXME: add fid capability support for create & destroy! */ + int (*o_precreate)(struct obd_export *exp, int need_create); int (*o_create)(struct obd_export *exp, struct obdo *oa, struct lov_stripe_md **ea, struct obd_trans_info *oti); int (*o_destroy)(struct obd_export *exp, struct obdo *oa, diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index fb023077aee64ccf7763aafb0380584ecc8d8ed0..90662fe805a47cad2f482f140220f351523afabd 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -632,6 +632,18 @@ static inline int obd_checkmd(struct obd_export *exp, RETURN(rc); } +static inline int obd_precreate(struct obd_export *exp, int need_create) +{ + int rc; + ENTRY; + + EXP_CHECK_DT_OP(exp, precreate); + OBD_COUNTER_INCREMENT(exp->exp_obd, precreate); + + rc = OBP(exp->exp_obd, precreate)(exp, need_create); + RETURN(rc); +} + static inline int obd_create(struct obd_export *exp, struct obdo *obdo, struct lov_stripe_md **ea, struct obd_trans_info *oti) diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index 0bc0904e2e9356094ba242f136176f12be9aeae1..1bfe62d61f604cae24d3acbc3f59e7e08411a7c0 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -111,6 +111,7 @@ extern int obd_race_state; #define OBD_FAIL_MDS_WRITEPAGE_NET 0x13a #define OBD_FAIL_MDS_WRITEPAGE_PACK 0x13b #define OBD_FAIL_MDS_LLOG_CREATE_FAILED 0x13c +#define OBD_FAIL_MDS_OSC_PRECREATE 0x13d #define OBD_FAIL_OST 0x200 #define OBD_FAIL_OST_CONNECT_NET 0x201 diff --git a/lustre/lov/lov_internal.h b/lustre/lov/lov_internal.h index 5ded7e18daaf02f2b02ff42ed3830fb368eef26c..a8711e022acee70cdf5cc753ed3964260a8eadcc 100644 --- a/lustre/lov/lov_internal.h +++ b/lustre/lov/lov_internal.h @@ -147,6 +147,8 @@ int lov_stripe_intersects(struct lov_stripe_md *lsm, int stripeno, int lov_stripe_number(struct lov_stripe_md *lsm, obd_off lov_off); /* lov_qos.c */ +#define LOV_USES_ASSIGNED_STRIPE 0 +#define LOV_USES_DEFAULT_STRIPE 1 int qos_add_tgt(struct obd_device *obd, __u32 index); int qos_del_tgt(struct obd_device *obd, __u32 index); void qos_shrink_lsm(struct lov_request_set *set); diff --git a/lustre/lov/lov_qos.c b/lustre/lov/lov_qos.c index 9ab0f3b7bef3ad0c7d1ef2c3a226ebb64007c677..866d2602d61476461a253be17f2f702501dd5dca 100644 --- a/lustre/lov/lov_qos.c +++ b/lustre/lov/lov_qos.c @@ -37,8 +37,7 @@ #include <obd_lov.h> #include "lov_internal.h" - -/* #define QOS_DEBUG 1 */ +/* #define QOS_DEBUG 1 */ #define D_QOS D_OTHER #define TGT_BAVAIL(i) (lov->lov_tgts[i]->ltd_exp->exp_obd->obd_osfs.os_bavail * \ @@ -55,7 +54,7 @@ int qos_add_tgt(struct obd_device *obd, __u32 index) ENTRY; /* We only need this QOS struct on MDT, not clients - but we may not - have registered the LOV's observer yet, so there's no way to know */ + have registered the LOV's observer yet, so there's no way to know */ if (!exp || !exp->exp_connection) { CERROR("Missing connection\n"); RETURN(-ENOTCONN); @@ -498,19 +497,29 @@ int qos_remedy_create(struct lov_request_set *set, struct lov_request *req) RETURN(rc); } +static int min_stripe_count(int stripe_cnt, int flags) +{ + return (flags & LOV_USES_DEFAULT_STRIPE ? + stripe_cnt - (stripe_cnt / 4) : stripe_cnt); +} + #define LOV_CREATE_RESEED_MULT 4 #define LOV_CREATE_RESEED_MIN 1000 /* Allocate objects on osts with round-robin algorithm */ -static int alloc_rr(struct lov_obd *lov, int *idx_arr, int *stripe_cnt) +static int alloc_rr(struct lov_obd *lov, int *idx_arr, int *stripe_cnt, + int flags) { unsigned array_idx, ost_count = lov->desc.ld_tgt_count; unsigned ost_active_count = lov->desc.ld_active_tgt_count; - int i, *idx_pos = idx_arr; + int i, *idx_pos; __u32 ost_idx; + int ost_start_idx_temp; + int speed = 0; + int stripe_cnt_min = min_stripe_count(*stripe_cnt, flags); ENTRY; i = qos_calc_rr(lov); - if (i) + if (i) RETURN(i); if (--lov->lov_start_count <= 0) { @@ -518,40 +527,61 @@ static int alloc_rr(struct lov_obd *lov, int *idx_arr, int *stripe_cnt) lov->lov_start_count = (LOV_CREATE_RESEED_MIN / max(ost_active_count, 1U) + LOV_CREATE_RESEED_MULT) * max(ost_active_count, 1U); - } else if (*stripe_cnt >= ost_active_count || + } else if (stripe_cnt_min >= ost_active_count || lov->lov_start_idx > ost_count) { /* If we have allocated from all of the OSTs, slowly precess the next start */ lov->lov_start_idx %= ost_count; ++lov->lov_offset_idx; } + down_read(&lov->lov_qos.lq_rw_sem); + ost_start_idx_temp = lov->lov_start_idx; + +repeat_find: array_idx = (lov->lov_start_idx + lov->lov_offset_idx) % ost_count; + idx_pos = idx_arr; #ifdef QOS_DEBUG CDEBUG(D_QOS, "want %d startidx %d startcnt %d offset %d arrayidx %d\n", - *stripe_cnt, lov->lov_start_idx, lov->lov_start_count, + stripe_cnt_min, lov->lov_start_idx, lov->lov_start_count, lov->lov_offset_idx, array_idx); #endif - down_read(&lov->lov_qos.lq_rw_sem); for (i = 0; i < ost_count; i++, array_idx=(array_idx + 1) % ost_count) { ++lov->lov_start_idx; ost_idx = lov->lov_qos.lq_rr_array[array_idx]; #ifdef QOS_DEBUG CDEBUG(D_QOS, "#%d strt %d act %d strp %d ary %d idx %d\n", - i, lov->lov_start_idx, + i, lov->lov_start_idx, ((ost_idx != LOV_QOS_EMPTY) && lov->lov_tgts[ost_idx]) ? lov->lov_tgts[ost_idx]->ltd_active : 0, idx_pos - idx_arr, array_idx, ost_idx); #endif - if ((ost_idx == LOV_QOS_EMPTY) || !lov->lov_tgts[ost_idx] || - !lov->lov_tgts[ost_idx]->ltd_active) + if ((ost_idx == LOV_QOS_EMPTY) || !lov->lov_tgts[ost_idx] || + !lov->lov_tgts[ost_idx]->ltd_active) + continue; + /* Fail Check before osc_precreate() is called + so we can only 'fail' single OSC. */ + if (OBD_FAIL_CHECK(OBD_FAIL_MDS_OSC_PRECREATE) && ost_idx == 0) + continue; + + /* Drop slow OSCs if we can */ + if (obd_precreate(lov->lov_tgts[ost_idx]->ltd_exp, speed == 0) > + speed) continue; + *idx_pos = ost_idx; idx_pos++; /* We have enough stripes */ - if (idx_pos - idx_arr == *stripe_cnt) + if (idx_pos - idx_arr == *stripe_cnt) break; } + if ((speed < 2) && (idx_pos - idx_arr < stripe_cnt_min)) { + /* Try again, allowing slower OSCs */ + speed++; + lov->lov_start_idx = ost_start_idx_temp; + goto repeat_find; + } + up_read(&lov->lov_qos.lq_rw_sem); *stripe_cnt = idx_pos - idx_arr; @@ -563,21 +593,41 @@ static int alloc_specific(struct lov_obd *lov, struct lov_stripe_md *lsm, int *idx_arr) { unsigned ost_idx, ost_count = lov->desc.ld_tgt_count; - int i, *idx_pos = idx_arr; + int i, *idx_pos; + int speed = 0; ENTRY; +repeat_find: + idx_pos = idx_arr; ost_idx = lsm->lsm_oinfo[0]->loi_ost_idx; for (i = 0; i < ost_count; i++, ost_idx = (ost_idx + 1) % ost_count) { if (!lov->lov_tgts[ost_idx] || !lov->lov_tgts[ost_idx]->ltd_active) { continue; } + + /* Fail Check before osc_precreate() is called + so we can only 'fail' single OSC. */ + if (OBD_FAIL_CHECK(OBD_FAIL_MDS_OSC_PRECREATE) && ost_idx == 0) + continue; + + /* Drop slow OSCs if we can */ + if (obd_precreate(lov->lov_tgts[ost_idx]->ltd_exp, speed == 0) > + speed) + continue; + *idx_pos = ost_idx; idx_pos++; - /* got enough ost */ + /* We have enough stripes */ if (idx_pos - idx_arr == lsm->lsm_stripe_count) RETURN(0); } + if (speed < 2) { + /* Try again, allowing slower OSCs */ + speed++; + goto repeat_find; + } + /* If we were passed specific striping params, then a failure to * meet those requirements is an error, since we can't reallocate * that memory (it might be part of a larger array or something). @@ -593,7 +643,8 @@ static int alloc_specific(struct lov_obd *lov, struct lov_stripe_md *lsm, - free space - network resources (shared OSS's) */ -static int alloc_qos(struct obd_export *exp, int *idx_arr, int *stripe_cnt) +static int alloc_qos(struct obd_export *exp, int *idx_arr, int *stripe_cnt, + int flags) { struct lov_obd *lov = &exp->exp_obd->u.lov; static time_t last_warn = 0; @@ -601,8 +652,12 @@ static int alloc_qos(struct obd_export *exp, int *idx_arr, int *stripe_cnt) __u64 total_bavail, total_weight = 0; __u32 ost_count; int nfound, good_osts, i, warn = 0, rc = 0; + int stripe_cnt_min = min_stripe_count(*stripe_cnt, flags); ENTRY; - + + if (stripe_cnt_min < 1) + GOTO(out, rc = -EINVAL); + lov_getref(exp->exp_obd); /* Detect -EAGAIN early, before expensive lock is taken. */ @@ -658,6 +713,14 @@ static int alloc_qos(struct obd_export *exp, int *idx_arr, int *stripe_cnt) continue; } + /* Fail Check before osc_precreate() is called + so we can only 'fail' single OSC. */ + if (OBD_FAIL_CHECK(OBD_FAIL_MDS_OSC_PRECREATE) && i == 0) + continue; + + if (obd_precreate(lov->lov_tgts[i]->ltd_exp, 1) >= 2) + continue; + lov->lov_tgts[i]->ltd_qos.ltq_usable = 1; qos_calc_weight(lov, i); total_bavail += bavail; @@ -665,17 +728,20 @@ static int alloc_qos(struct obd_export *exp, int *idx_arr, int *stripe_cnt) good_osts++; } - + if (!total_bavail) GOTO(out_up_write, rc = -ENOSPC); - - /* if we don't have enough good OSTs, we reduce the stripe count. */ + + if (good_osts < stripe_cnt_min) + GOTO(out_up_write, rc = -EAGAIN); + + /* We have enough osts */ if (good_osts < *stripe_cnt) *stripe_cnt = good_osts; - if (!*stripe_cnt) + if (!*stripe_cnt) GOTO(out_up_write, rc = -EAGAIN); - + /* Find enough OSTs with weighted random allocation. */ nfound = 0; while (nfound < *stripe_cnt) { @@ -713,6 +779,7 @@ static int alloc_qos(struct obd_export *exp, int *idx_arr, int *stripe_cnt) if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_qos.ltq_usable) continue; + cur_weight += lov->lov_tgts[i]->ltd_qos.ltq_weight; if (cur_weight >= rand) { #ifdef QOS_DEBUG @@ -738,7 +805,7 @@ out_up_write: out: if (rc == -EAGAIN) - rc = alloc_rr(lov, idx_arr, stripe_cnt); + rc = alloc_rr(lov, idx_arr, stripe_cnt, flags); lov_putref(exp->exp_obd); RETURN(rc); @@ -746,7 +813,7 @@ out: /* return new alloced stripe count on success */ static int alloc_idx_array(struct obd_export *exp, struct lov_stripe_md *lsm, - int newea, int **idx_arr, int *arr_cnt) + int newea, int **idx_arr, int *arr_cnt, int flags) { struct lov_obd *lov = &exp->exp_obd->u.lov; int stripe_cnt = lsm->lsm_stripe_count; @@ -763,7 +830,7 @@ static int alloc_idx_array(struct obd_export *exp, struct lov_stripe_md *lsm, if (newea || lsm->lsm_oinfo[0]->loi_ost_idx >= lov->desc.ld_tgt_count) - rc = alloc_qos(exp, tmp_arr, &stripe_cnt); + rc = alloc_qos(exp, tmp_arr, &stripe_cnt, flags); else rc = alloc_specific(lov, lsm, tmp_arr); @@ -792,13 +859,14 @@ int qos_prep_create(struct obd_export *exp, struct lov_request_set *set) struct obd_trans_info *oti = set->set_oti; int i, stripes, rc = 0, newea = 0; int *idx_arr, idx_cnt = 0; + int flag = LOV_USES_ASSIGNED_STRIPE; ENTRY; LASSERT(src_oa->o_valid & OBD_MD_FLID); LASSERT(src_oa->o_valid & OBD_MD_FLGROUP); if (set->set_oi->oi_md == NULL) { - int stripe_cnt = lov_get_stripecnt(lov, 0); + int stripes_def = lov_get_stripecnt(lov, 0); /* If the MDS file was truncated up to some size, stripe over * enough OSTs to allow the file to be created at that size. @@ -821,10 +889,11 @@ int qos_prep_create(struct obd_export *exp, struct lov_request_set *set) } lov_putref(exp->exp_obd); - if (stripes < stripe_cnt) - stripes = stripe_cnt; + if (stripes < stripes_def) + stripes = stripes_def; } else { - stripes = stripe_cnt; + flag = LOV_USES_DEFAULT_STRIPE; + stripes = stripes_def; } rc = lov_alloc_memmd(&set->set_oi->oi_md, stripes, @@ -833,8 +902,8 @@ int qos_prep_create(struct obd_export *exp, struct lov_request_set *set) LOV_MAGIC); if (rc < 0) GOTO(out_err, rc); - rc = 0; newea = 1; + rc = 0; } lsm = set->set_oi->oi_md; @@ -848,7 +917,7 @@ int qos_prep_create(struct obd_export *exp, struct lov_request_set *set) lsm->lsm_pattern = lov->desc.ld_pattern; } - stripes = alloc_idx_array(exp, lsm, newea, &idx_arr, &idx_cnt); + stripes = alloc_idx_array(exp, lsm, newea, &idx_arr, &idx_cnt, flag); if (stripes <= 0) GOTO(out_err, rc = stripes ? stripes : -EIO); LASSERTF(stripes <= lsm->lsm_stripe_count,"requested %d allocated %d\n", diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c index 6f9d903229968f8b5f18a746069fecb4f501e2a7..4a7fa3ea6c764ca91b1ac20e912a861f79bbc44b 100644 --- a/lustre/obdclass/lprocfs_status.c +++ b/lustre/obdclass/lprocfs_status.c @@ -854,6 +854,7 @@ void lprocfs_init_ops_stats(int num_private_stats, struct lprocfs_stats *stats) LPROCFS_OBD_OP_INIT(num_private_stats, stats, unpackmd); LPROCFS_OBD_OP_INIT(num_private_stats, stats, checkmd); LPROCFS_OBD_OP_INIT(num_private_stats, stats, preallocate); + LPROCFS_OBD_OP_INIT(num_private_stats, stats, precreate); LPROCFS_OBD_OP_INIT(num_private_stats, stats, create); LPROCFS_OBD_OP_INIT(num_private_stats, stats, destroy); LPROCFS_OBD_OP_INIT(num_private_stats, stats, setattr); diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index 42d9ffa0f708582471443ba2e8e72b493fd95451..81530b225b18658780cfabf0b9cdab9735b77be9 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -3321,6 +3321,8 @@ static int filter_precreate(struct obd_device *obd, struct obdo *oa, LASSERT(down_trylock(&filter->fo_create_locks[group]) != 0); + OBD_FAIL_TIMEOUT(OBD_FAIL_TGT_DELAY_PRECREATE, obd_timeout / 2); + if ((oa->o_valid & OBD_MD_FLFLAGS) && (oa->o_flags & OBD_FL_RECREATE_OBJS)) { recreate_obj = 1; diff --git a/lustre/osc/osc_create.c b/lustre/osc/osc_create.c index cd0d3730ef9d7e321d037a5d4ae156323b2e78f0..696215095186e14b50cff2b51b957d2c187d3f0d 100644 --- a/lustre/osc/osc_create.c +++ b/lustre/osc/osc_create.c @@ -234,6 +234,51 @@ int oscc_recovering(struct osc_creator *oscc) return recov; } +/* decide if the OST has remaining object, return value : + 0 : the OST has remaining object, and don't need to do precreate. + 1 : the OST has no remaining object, and will send a RPC for precreate. + 2 : the OST has no remaining object, and will not get any for + a potentially very long time + 1000 : unusable + */ +int osc_precreate(struct obd_export *exp, int need_create) +{ + struct osc_creator *oscc = &exp->exp_obd->u.cli.cl_oscc; + struct obd_import *imp = exp->exp_imp_reverse; + ENTRY; + + LASSERT(oscc != NULL); + if (imp != NULL && imp->imp_deactive) + RETURN(1000); + + if (oscc->oscc_last_id < oscc->oscc_next_id) { + spin_lock(&oscc->oscc_lock); + if (oscc->oscc_flags & OSCC_FLAG_NOSPC) { + spin_unlock(&oscc->oscc_lock); + RETURN(1000); + } + if (oscc->oscc_flags & OSCC_FLAG_SYNC_IN_PROGRESS) { + spin_unlock(&oscc->oscc_lock); + RETURN(1); + } + if (oscc->oscc_flags & OSCC_FLAG_RECOVERING) { + spin_unlock(&oscc->oscc_lock); + RETURN(2); + } + spin_unlock(&oscc->oscc_lock); + + if (oscc->oscc_flags & OSCC_FLAG_CREATING) + RETURN(1); + + if (!need_create) + RETURN(1); + + oscc_internal_create(oscc); + RETURN(1); + } + RETURN(0); +} + int osc_create(struct obd_export *exp, struct obdo *oa, struct lov_stripe_md **ea, struct obd_trans_info *oti) { diff --git a/lustre/osc/osc_internal.h b/lustre/osc/osc_internal.h index 18148c80534b2b420c2b7fecd43c4bd1678dd44b..e3e6013f13ee8359dc266d1ee9d535bc91615fe3 100644 --- a/lustre/osc/osc_internal.h +++ b/lustre/osc/osc_internal.h @@ -54,6 +54,7 @@ struct osc_cache_waiter { #define OSCC_FLAG_LOW 0x10 #define OSCC_FLAG_EXITING 0x20 +int osc_precreate(struct obd_export *exp, int need_create); int osc_create(struct obd_export *exp, struct obdo *oa, struct lov_stripe_md **ea, struct obd_trans_info *oti); int osc_real_create(struct obd_export *exp, struct obdo *oa, diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index 16b78f97948b457f149cbab59c007676e5a47974..c2335740eb938d93ac5bef0f3411407f3dfb0220 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -3744,6 +3744,7 @@ struct obd_ops osc_obd_ops = { .o_statfs_async = osc_statfs_async, .o_packmd = osc_packmd, .o_unpackmd = osc_unpackmd, + .o_precreate = osc_precreate, .o_create = osc_create, .o_destroy = osc_destroy, .o_getattr = osc_getattr, diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index 260023012f3d37f6bd24522fb341376501816e7b..195319f6e074085a539fb97443efc5f29507b856 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -1187,6 +1187,48 @@ test_27x() { # bug 10997 } run_test 27x "check lfs setstripe -c -s -i options =============" +test_27u() { # bug 4900 + [ "$OSTCOUNT" -lt "2" -o -z "$MDS" ] && echo "skip $TESTNAME" && return + #define OBD_FAIL_MDS_OSC_PRECREATE 0x13d + + sysctl -w lustre.fail_loc=0x13d + mkdir -p $DIR/d27u + createmany -o $DIR/d27u/t- 1000 + sysctl -w lustre.fail_loc=0 + + $LFS getstripe $DIR/d27u > $TMP/files + OBJS=`cat $TMP/files | awk -vobjs=0 '($1 == 0) { objs += 1 } END { print objs;}'` + unlinkmany $DIR/d27u/t- 1000 + [ $OBJS -gt 0 ] && \ + error "Found $OBJS objects were created on OST-0" || pass +} +run_test 27u "skip object creation on OSC w/o objects ==========" + +test_27v() { # bug 4900 + [ "$OSTCOUNT" -lt "2" -o -z "$MDS" ] && echo "skip $TESTNAME" && return + exhaust_all_precreations + + mkdir -p $DIR/$tdir + lfs setstripe $DIR/$tdir 0 -1 1 # 1 stripe / file + + touch $DIR/$tdir/$tfile + #define OBD_FAIL_TGT_DELAY_PRECREATE 0x705 + sysctl -w lustre.fail_loc=0x705 + START=`date +%s` + for F in `seq 1 32`; do + touch $DIR/$tdir/$tfile.$F + done + sysctl -w lustre.fail_loc=0 + + FINISH=`date +%s` + TIMEOUT=`sysctl -n lustre.timeout` + [ $((FINISH - START)) -ge $((TIMEOUT / 2)) ] && \ + error "$FINISH - $START >= $TIMEOUT / 2" + + reset_enospc +} +run_test 27v "skip object creation on slow OST =================" + test_28() { mkdir $DIR/d28 $CREATETEST $DIR/d28/ct || error @@ -2796,7 +2838,7 @@ test_65j() { # bug6367 cleanup -f || error "failed to unmount" setup fi - $SETSTRIPE -d $MOUNT + $SETSTRIPE -d $MOUNT || error "setstripe failed" } run_test 65j "set default striping on root directory (bug 6367)=" @@ -2830,9 +2872,9 @@ test_65k() { # bug11679 run_test 65k "validate manual striping works properly with deactivated OSCs" test_65l() { # bug 12836 - mkdir -p $DIR/$tdir - $LFS setstripe $DIR/$tdir 65536 -1 -1 - $LFS find -mtime -1 $DIR + mkdir -p $DIR/$tdir/test_dir + $LFS setstripe $DIR/$tdir/test_dir 65536 -1 -1 + $LFS find -mtime -1 $DIR/$tdir } run_test 65l "lfs find on -1 stripe dir ========================"