Whamcloud - gitweb
LU-18618 ofd: handle filter_fid properly on server 78/57678/31
authorBobi Jam <bobijam@whamcloud.com>
Wed, 8 Jan 2025 12:38:16 +0000 (20:38 +0800)
committerOleg Drokin <green@whamcloud.com>
Fri, 28 Feb 2025 08:12:25 +0000 (08:12 +0000)
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 <bobijam@whamcloud.com>
Change-Id: I8bd8c1af4d7806c3d8e4ab9de5af519381d36060
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/57678
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Qian Yingjin <qian@ddn.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
Reviewed-by: Alex Zhuravlev <bzzz@whamcloud.com>
lustre/ofd/ofd_dev.c
lustre/ofd/ofd_internal.h
lustre/ofd/ofd_io.c
lustre/ofd/ofd_objects.c
lustre/tests/sanity-flr.sh

index a43302a..074f73f 100644 (file)
@@ -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);
                }
index ee93c33..b99a150 100644 (file)
@@ -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,
index 2ee7324..c8b78da 100644 (file)
@@ -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);
index b835ded..fd895be 100644 (file)
@@ -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)
index e11bb1a..86017d7 100644 (file)
@@ -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"