From cab92c00bff91147ba54afad0def8bdfe22c3319 Mon Sep 17 00:00:00 2001 From: Bobi Jam Date: Wed, 8 Jan 2025 20:38:16 +0800 Subject: [PATCH] LU-18618 ofd: handle filter_fid properly on server The object's filter_fid could be changed via out_xattr_set(), then the ofd_object::ofo_ff is out of date, the old ofo_ff layout version could be a bigger value than that of the merged file, so write/punch upon this OFD object could be rejected as it prohibit operation with smaller layout version than that on the disk. Test-Parameters: testlist=sanity-flr env=ONLY=70a,ONLY_REPEAT=250 Test-Parameters: testlist=sanity-flr env=ONLY=200,ONLY_REPEAT=50 Signed-off-by: Bobi Jam Change-Id: I8bd8c1af4d7806c3d8e4ab9de5af519381d36060 Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/57678 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Qian Yingjin Reviewed-by: Oleg Drokin Reviewed-by: Alex Zhuravlev --- lustre/ofd/ofd_dev.c | 3 ++- lustre/ofd/ofd_internal.h | 3 ++- lustre/ofd/ofd_io.c | 27 +++++++++++++++++++-------- lustre/ofd/ofd_objects.c | 21 +++++++++++++-------- lustre/tests/sanity-flr.sh | 4 +++- 5 files changed, 39 insertions(+), 19 deletions(-) diff --git a/lustre/ofd/ofd_dev.c b/lustre/ofd/ofd_dev.c index a43302a..074f73fb 100644 --- a/lustre/ofd/ofd_dev.c +++ b/lustre/ofd/ofd_dev.c @@ -1210,7 +1210,8 @@ static int ofd_getattr_hdl(struct tgt_session_info *tsi) repbody->oa.o_layout_version = fo->ofo_ff.ff_layout_version + fo->ofo_ff.ff_range; - CDEBUG(D_INODE, DFID": get layout version: %u\n", + CDEBUG(D_INODE, "%s:"DFID": get layout version: %#x\n", + tsi->tsi_tgt->lut_obd->obd_name, PFID(&tsi->tsi_fid), repbody->oa.o_layout_version); } diff --git a/lustre/ofd/ofd_internal.h b/lustre/ofd/ofd_internal.h index ee93c33..b99a1505 100644 --- a/lustre/ofd/ofd_internal.h +++ b/lustre/ofd/ofd_internal.h @@ -368,7 +368,8 @@ ofd_stats_counter_init(struct lprocfs_stats *stats, struct ofd_object *ofd_object_find(const struct lu_env *env, struct ofd_device *ofd, const struct lu_fid *fid); -int ofd_object_ff_load(const struct lu_env *env, struct ofd_object *fo); +int ofd_object_ff_load(const struct lu_env *env, struct ofd_object *fo, + bool force); int ofd_object_ff_update(const struct lu_env *env, struct ofd_object *fo, const struct obdo *oa, struct filter_fid *ff); int ofd_precreate_objects(const struct lu_env *env, struct ofd_device *ofd, diff --git a/lustre/ofd/ofd_io.c b/lustre/ofd/ofd_io.c index 2ee7324..c8b78da 100644 --- a/lustre/ofd/ofd_io.c +++ b/lustre/ofd/ofd_io.c @@ -387,7 +387,7 @@ int ofd_verify_ff(const struct lu_env *env, struct ofd_object *fo, if (fo->ofo_pfid_checking) RETURN(-EINPROGRESS); - rc = ofd_object_ff_load(env, fo); + rc = ofd_object_ff_load(env, fo, false); if (rc == -ENODATA) RETURN(0); @@ -420,12 +420,15 @@ int ofd_verify_layout_version(const struct lu_env *env, struct ofd_object *fo, const struct obdo *oa) { int rc; + bool force = false; + ENTRY; if (unlikely(CFS_FAIL_CHECK(OBD_FAIL_OST_SKIP_LV_CHECK))) GOTO(out, rc = 0); - rc = ofd_object_ff_load(env, fo); +again: + rc = ofd_object_ff_load(env, fo, force); if (rc < 0) { if (rc == -ENODATA) rc = 0; @@ -437,14 +440,24 @@ int ofd_verify_layout_version(const struct lu_env *env, * that on the disk. */ if (ofd_layout_version_less(oa->o_layout_version, - fo->ofo_ff.ff_layout_version)) + fo->ofo_ff.ff_layout_version)) { + /* the object's filter_fid could be changed via + * out_xattr_set(), and the ofd_object::ofo_ff is out of date. + */ + if (!force) { + force = true; + GOTO(again, rc); + } GOTO(out, rc = -ESTALE); + } out: - CDEBUG(D_INODE, DFID " verify layout version: %u vs. %u/%u: rc = %d\n", + CDEBUG(D_INODE, + "%s:"DFID" verify layout version: %#x/%#x -> %#x, rc: %d\n", + ofd_name(ofd_obj2dev(fo)), PFID(lu_object_fid(&fo->ofo_obj.do_lu)), - oa->o_layout_version, fo->ofo_ff.ff_layout_version, - fo->ofo_ff.ff_range, rc); + fo->ofo_ff.ff_layout_version, fo->ofo_ff.ff_range, + oa->o_layout_version, rc); RETURN(rc); } @@ -1062,8 +1075,6 @@ ofd_write_attr_set(const struct lu_env *env, struct ofd_device *ofd, /* no attributes to set */ GOTO(out_unlock, rc = 0); - - /* set uid/gid/projid */ if (la->la_valid) { rc = dt_attr_set(env, dt_obj, la, th); diff --git a/lustre/ofd/ofd_objects.c b/lustre/ofd/ofd_objects.c index b835ded..fd895be 100644 --- a/lustre/ofd/ofd_objects.c +++ b/lustre/ofd/ofd_objects.c @@ -113,19 +113,21 @@ struct ofd_object *ofd_object_find(const struct lu_env *env, * * \param[in] env execution environment * \param[in] fo OFD object + * \param[in] force force to read EA XATTR_NAME_FID * * \retval 0 if successful * \retval -ENODATA if there is no such xattr * \retval negative value on error */ -int ofd_object_ff_load(const struct lu_env *env, struct ofd_object *fo) +int ofd_object_ff_load(const struct lu_env *env, struct ofd_object *fo, + bool force) { struct ofd_thread_info *info = ofd_info(env); struct filter_fid *ff = &fo->ofo_ff; struct lu_buf *buf = &info->fti_buf; int rc = 0; - if (fid_is_sane(&ff->ff_parent)) + if (fid_is_sane(&ff->ff_parent) && !force) return 0; buf->lb_buf = ff; @@ -564,13 +566,14 @@ int ofd_object_ff_update(const struct lu_env *env, struct ofd_object *fo, const struct obdo *oa, struct filter_fid *ff) { int rc = 0; + ENTRY; if (!(oa->o_valid & (OBD_MD_FLFID | OBD_MD_FLOSTLAYOUT | OBD_MD_LAYOUT_VERSION))) RETURN(0); - rc = ofd_object_ff_load(env, fo); + rc = ofd_object_ff_load(env, fo, true); if (rc < 0 && rc != -ENODATA) RETURN(rc); @@ -597,12 +600,14 @@ int ofd_object_ff_update(const struct lu_env *env, struct ofd_object *fo, ff->ff_layout = oa->o_layout; if (oa->o_valid & OBD_MD_LAYOUT_VERSION) { - CDEBUG(D_INODE, DFID": OST("DFID") layout version %u -> %u\n", + CDEBUG(D_INODE, + "%s:"DFID":"DFID" layout version %#x -> %#x, oa_valid %#llx\n", + ofd_name(ofd_obj2dev(fo)), PFID(&fo->ofo_ff.ff_parent), PFID(lu_object_fid(&fo->ofo_obj.do_lu)), - ff->ff_layout_version, oa->o_layout_version); - - /** + ff->ff_layout_version, oa->o_layout_version, + oa->o_valid); + /* * resync write from client on non-primary objects and * resync start from MDS on primary objects will contain * LU_LAYOUT_RESYNC flag in the @oa. @@ -791,7 +796,7 @@ int ofd_object_fallocate(const struct lu_env *env, struct ofd_object *fo, RETURN(rc); if (ff != NULL) { - rc = ofd_object_ff_load(env, fo); + rc = ofd_object_ff_load(env, fo, false); if (rc == -ENODATA) ff_needed = true; else if (rc < 0) diff --git a/lustre/tests/sanity-flr.sh b/lustre/tests/sanity-flr.sh index e11bb1a..86017d7 100644 --- a/lustre/tests/sanity-flr.sh +++ b/lustre/tests/sanity-flr.sh @@ -3346,7 +3346,9 @@ test_70a() { error "setstripe $tf failed" FSXNUM=${FSXNUM:-1000} - $FSX -p 1 -N $FSXNUM -S 0 -M $tf || error "fsx FLR file $tf failed" + FSXSEED=${FSXSEED:-0} + $FSX -p 1 -N $FSXNUM -S $FSXSEED -M $tf || + error "fsx FLR file $tf failed" } run_test 70a "flr mode fsx test" -- 1.8.3.1