Whamcloud - gitweb
LU-10248 mdd: set PFID for swap and merge layout 92/30292/5
authorJinshan Xiong <jinshan.xiong@intel.com>
Thu, 16 Nov 2017 22:05:06 +0000 (22:05 +0000)
committerOleg Drokin <oleg.drokin@intel.com>
Sun, 17 Dec 2017 06:20:22 +0000 (06:20 +0000)
It should update PFID for the OST objects if the layout has been
moved to another file. So far only swap and merge layout would
have this requirement.

Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Change-Id: Ic2fd7d7a88cd0ef4501d2f02baf58dd177e07973
Reviewed-on: https://review.whamcloud.com/30292
Tested-by: Jenkins
Reviewed-by: Fan Yong <fan.yong@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/lod/lod_object.c
lustre/mdd/mdd_object.c
lustre/tests/sanity-flr.sh
lustre/tests/sanity.sh
lustre/tests/test-framework.sh

index bdffb85..bf56b50 100644 (file)
@@ -2133,6 +2133,7 @@ lod_obj_stripe_replace_parent_fid_cb(const struct lu_env *env,
                                     struct lod_obj_stripe_cb_data *data)
 {
        struct lod_thread_info *info = lod_env_info(env);
+       struct lod_layout_component *comp = &lo->ldo_comp_entries[comp_idx];
        struct filter_fid *ff = &info->lti_ff;
        struct lu_buf *buf = &info->lti_buf;
        int rc;
@@ -2140,15 +2141,28 @@ lod_obj_stripe_replace_parent_fid_cb(const struct lu_env *env,
        buf->lb_buf = ff;
        buf->lb_len = sizeof(*ff);
        rc = dt_xattr_get(env, dt, buf, XATTR_NAME_FID);
-       if (rc == -ENODATA)
-               return 0;
-
-       if (rc < 0)
+       if (rc < 0) {
+               if (rc == -ENODATA)
+                       return 0;
                return rc;
+       }
+
+       filter_fid_le_to_cpu(ff, ff, sizeof(*ff));
+       if (lu_fid_eq(lu_object_fid(&lo->ldo_obj.do_lu), &ff->ff_parent) &&
+           ff->ff_layout.ol_comp_id == comp->llc_id)
+               return 0;
 
+       /* rewrite filter_fid */
+       memset(ff, 0, sizeof(*ff));
        ff->ff_parent = *lu_object_fid(&lo->ldo_obj.do_lu);
        ff->ff_parent.f_ver = stripe_idx;
-       fid_cpu_to_le(&ff->ff_parent, &ff->ff_parent);
+       ff->ff_layout.ol_stripe_size = comp->llc_stripe_size;
+       ff->ff_layout.ol_stripe_count = comp->llc_stripe_count;
+       ff->ff_layout.ol_comp_id = comp->llc_id;
+       ff->ff_layout.ol_comp_start = comp->llc_extent.e_start;
+       ff->ff_layout.ol_comp_end = comp->llc_extent.e_end;
+       filter_fid_cpu_to_le(ff, ff, sizeof(*ff));
+
        if (data->locd_declare)
                rc = lod_sub_declare_xattr_set(env, dt, buf, XATTR_NAME_FID,
                                               LU_XATTR_REPLACE, th);
index e15141e..fe246d1 100644 (file)
@@ -1084,6 +1084,40 @@ free:
        return rc;
 }
 
+static int mdd_object_pfid_replace(const struct lu_env *env,
+                                  struct mdd_object *o)
+{
+       struct mdd_device *mdd = mdo2mdd(&o->mod_obj);
+       struct thandle *handle;
+       int rc;
+
+       handle = mdd_trans_create(env, mdd);
+       if (IS_ERR(handle))
+               RETURN(PTR_ERR(handle));
+
+       handle->th_complex = 1;
+
+       /* it doesn't need to track the PFID update via llog, because LFSCK
+        * will repair it even it goes wrong */
+       rc = mdd_declare_xattr_set(env, mdd, o, NULL, XATTR_NAME_FID,
+                                  0, handle);
+       if (rc)
+               GOTO(out, rc);
+
+       rc = mdd_trans_start(env, mdd, handle);
+       if (rc != 0)
+               GOTO(out, rc);
+
+       rc = mdo_xattr_set(env, o, NULL, XATTR_NAME_FID, 0, handle);
+       if (rc)
+               GOTO(out, rc);
+
+out:
+       mdd_trans_stop(env, mdd, rc, handle);
+       return rc;
+}
+
+
 static int mdd_declare_xattr_del(const struct lu_env *env,
                                 struct mdd_device *mdd,
                                 struct mdd_object *obj,
@@ -1162,22 +1196,23 @@ static int mdd_xattr_merge(const struct lu_env *env, struct md_object *md_obj,
                GOTO(out, rc);
 
        rc = mdo_xattr_del(env, vic, XATTR_NAME_LOV, handle);
-       if (rc) /* wtf? */
-               int rc2;
+       if (rc) /* wtf? */
+               GOTO(out_restore, rc);
 
-               rc2 = mdo_xattr_set(env, obj, buf, XATTR_NAME_LOV,
-                                   LU_XATTR_REPLACE, handle);
+       (void)mdd_changelog_data_store(env, mdd, CL_LAYOUT, 0, obj, handle);
+       (void)mdd_changelog_data_store(env, mdd, CL_LAYOUT, 0, vic, handle);
+       EXIT;
+
+out_restore:
+       if (rc) {
+               int rc2 = mdo_xattr_set(env, obj, buf, XATTR_NAME_LOV,
+                                       LU_XATTR_REPLACE, handle);
                if (rc2)
                        CERROR("%s: failed to rollback of layout of: "DFID
                               ": %d, file state unknown\n",
                               mdd_obj_dev_name(obj), PFID(mdo2fid(obj)), rc2);
-               GOTO(out, rc);
        }
 
-       (void)mdd_changelog_data_store(env, mdd, CL_LAYOUT, 0, obj, handle);
-       (void)mdd_changelog_data_store(env, mdd, CL_LAYOUT, 0, vic, handle);
-       EXIT;
-
 out:
        mdd_trans_stop(env, mdd, rc, handle);
        mdd_write_unlock(env, obj);
@@ -1185,6 +1220,9 @@ out:
        lu_buf_free(buf);
        lu_buf_free(buf_vic);
 
+       if (!rc)
+               (void) mdd_object_pfid_replace(env, obj);
+
        return rc;
 }
 
@@ -1797,7 +1835,20 @@ static int mdd_swap_layouts(const struct lu_env *env, struct md_object *obj1,
                else
                        rc = mdo_xattr_del(env, snd_o, XATTR_NAME_LOV, handle);
        }
+       if (rc != 0)
+               GOTO(out_restore, rc);
+
+       /* Issue one changelog record per file */
+       rc = mdd_changelog_data_store(env, mdd, CL_LAYOUT, 0, fst_o, handle);
+       if (rc)
+               GOTO(stop, rc);
+
+       rc = mdd_changelog_data_store(env, mdd, CL_LAYOUT, 0, snd_o, handle);
+       if (rc)
+               GOTO(stop, rc);
+       EXIT;
 
+out_restore:
        if (rc != 0) {
                int steps = 0;
 
@@ -1836,19 +1887,8 @@ static int mdd_swap_layouts(const struct lu_env *env, struct md_object *obj1,
                         */
                        LBUG();
                }
-               GOTO(stop, rc);
        }
 
-       /* Issue one changelog record per file */
-       rc = mdd_changelog_data_store(env, mdd, CL_LAYOUT, 0, fst_o, handle);
-       if (rc)
-               GOTO(stop, rc);
-
-       rc = mdd_changelog_data_store(env, mdd, CL_LAYOUT, 0, snd_o, handle);
-       if (rc)
-               GOTO(stop, rc);
-       EXIT;
-
 stop:
        rc = mdd_trans_stop(env, mdd, rc, handle);
 
@@ -1859,6 +1899,11 @@ stop:
        lu_buf_free(snd_buf);
        lu_buf_free(fst_hsm_buf);
        lu_buf_free(snd_hsm_buf);
+
+       if (!rc) {
+               (void) mdd_object_pfid_replace(env, fst_o);
+               (void) mdd_object_pfid_replace(env, snd_o);
+       }
        return rc;
 }
 
index abf81d5..ba90384 100644 (file)
@@ -381,6 +381,8 @@ test_0d() {
                verify_comp_extent $tf ${ids[$i]} 0 EOF
        done
 
+       lfsck_verify_pfid $tf || error "PFID is not set"
+
        # create a mirrored file and extend it
        $LFS mirror create -N $tf-1 || error "create mirrored file $tf-1 failed"
        $LFS mirror create -N $tf-2 || error "create mirrored file $tf-2 failed"
index 73211a3..d66fa79 100755 (executable)
@@ -12266,6 +12266,8 @@ test_184a() {
 
        cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
        cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
+
+       lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
 }
 run_test 184a "Basic layout swap"
 
index cb9d21a..113ea76 100755 (executable)
@@ -8420,3 +8420,27 @@ get_layout_param()
        local param=$($LFS getstripe -d $1 | parse_layout_param)
        echo "$param"
 }
+
+lfsck_verify_pfid()
+{
+       local f
+       local rc=0
+
+       # Cancel locks before setting lfsck_verify_pfid so that errors are more
+        # controllable
+       cancel_lru_locks mdc
+       cancel_lru_locks osc
+        
+       # make sure PFID is set correctly for files
+       do_nodes $(comma_list $(osts_nodes)) \
+              "$LCTL set_param -n obdfilter.${FSNAME}-OST*.lfsck_verify_pfid=1"
+
+       for f in "$@"; do
+               cat $f &> /dev/nullA ||
+                       { rc=$?; echo "verify $f failed"; break; }
+       done
+
+       do_nodes $(comma_list $(osts_nodes)) \
+              "$LCTL set_param -n obdfilter.${FSNAME}-OST*.lfsck_verify_pfid=0"
+       return $rc
+}