From 42b0304e2571a80effe5bc4ab6fb58acfabb361d Mon Sep 17 00:00:00 2001 From: Lai Siyao Date: Thu, 12 Mar 2020 08:35:20 +0800 Subject: [PATCH] LU-13357 lod: implement striped directory .dio_lookup Add function lod_striped_lookup() for lod_striped_index_ops.dio_lookup to allow name lookup under striped directory. Currently this is used by subdir mount, which needs to lookup FID of the subdir on server side. Function lfsck_namespace_repair_dirent() should call dt_lookup() with bottom object, because child may be shard. Add sanity 247f. Signed-off-by: Lai Siyao Change-Id: Iba844d1a34a318bcbd42b00186ed6fa9d165effc Reviewed-on: https://review.whamcloud.com/37903 Tested-by: jenkins Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Alex Zhuravlev Reviewed-by: Oleg Drokin --- lustre/lfsck/lfsck_namespace.c | 2 +- lustre/lod/lod_object.c | 46 +++++++++++++++++++++++++++++++++++++++++- lustre/tests/sanity.sh | 32 +++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/lustre/lfsck/lfsck_namespace.c b/lustre/lfsck/lfsck_namespace.c index 51e45e5..cef0fe0 100644 --- a/lustre/lfsck/lfsck_namespace.c +++ b/lustre/lfsck/lfsck_namespace.c @@ -2276,7 +2276,7 @@ int lfsck_namespace_repair_dirent(const struct lu_env *env, dt_write_lock(env, parent, 0); - rc = dt_lookup(env, parent, (struct dt_rec *)&tfid, + rc = dt_lookup(env, dt_object_child(parent), (struct dt_rec *)&tfid, (const struct dt_key *)name); /* Someone has removed the bad name entry by race. */ if (rc == -ENOENT) diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index 316d7ff..d38bca0 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -367,6 +367,50 @@ static struct dt_index_operations lod_index_ops = { }; /** + * Implementation of dt_index_operations::dio_lookup + * + * Used with striped directories. + * + * \see dt_index_operations::dio_lookup() in the API description for details. + */ +static int lod_striped_lookup(const struct lu_env *env, struct dt_object *dt, + struct dt_rec *rec, const struct dt_key *key) +{ + struct lod_object *lo = lod_dt_obj(dt); + struct dt_object *next; + const char *name = (const char *)key; + + LASSERT(lo->ldo_dir_stripe_count > 0); + + if (strcmp(name, dot) == 0) { + struct lu_fid *fid = (struct lu_fid *)rec; + + *fid = *lod_object_fid(lo); + return 1; + } + + if (strcmp(name, dotdot) == 0) { + next = dt_object_child(dt); + } else { + int index; + + index = __lmv_name_to_stripe_index(lo->ldo_dir_hash_type, + lo->ldo_dir_stripe_count, + lo->ldo_dir_migrate_hash, + lo->ldo_dir_migrate_offset, + name, strlen(name), true); + if (index < 0) + return index; + + next = lo->ldo_stripe[index]; + if (!next || !dt_object_exists(next)) + return -ENODEV; + } + + return next->do_index_ops->dio_lookup(env, next, rec, key); +} + +/** * Implementation of dt_it_ops::init. * * Used with striped objects. Internally just initializes the iterator @@ -744,7 +788,7 @@ static int lod_striped_it_load(const struct lu_env *env, } static struct dt_index_operations lod_striped_index_ops = { - .dio_lookup = lod_lookup, + .dio_lookup = lod_striped_lookup, .dio_declare_insert = lod_declare_insert, .dio_insert = lod_insert, .dio_declare_delete = lod_declare_delete, diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index a25ecd4..ddf1381 100755 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -18403,6 +18403,38 @@ test_247e() { } run_test 247e "mount .. as fileset" +test_247f() { + [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs" + [ $MDS1_VERSION -lt $(version_code 2.13.52) ] && + skip "Need at least version 2.13.52" + lctl get_param -n mdc.$FSNAME-MDT0000*.import | + grep -q subtree || + skip "Fileset feature is not supported" + + mkdir $DIR/$tdir || error "mkdir $tdir failed" + $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote || + error "mkdir remote failed" + mkdir $DIR/$tdir/remote/subdir || error "mkdir remote/subdir failed" + $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped || + error "mkdir striped failed" + mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed" + + local submount=${MOUNT}_$tdir + + mkdir -p $submount || error "mkdir $submount failed" + + local dir + local fileset=$FILESET + + for dir in $tdir/remote $tdir/remote/subdir \ + $tdir/striped $tdir/striped/subdir $tdir/striped/. ; do + FILESET="$fileset/$dir" mount_client $submount || + error "mount $dir failed" + umount_client $submount + done +} +run_test 247f "mount striped or remote directory as fileset" + test_248a() { local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null) [ -z "$fast_read_sav" ] && skip "no fast read support" -- 1.8.3.1