Whamcloud - gitweb
LU-14642 flr: abolish MDS transfer layout version to OST 43/45443/7
authorBobi Jam <bobijam@whamcloud.com>
Mon, 25 Oct 2021 08:45:29 +0000 (16:45 +0800)
committerBobi Jam <bobijam@whamcloud.com>
Sat, 18 Dec 2021 17:24:17 +0000 (01:24 +0800)
Quit setting layout version to OST object from MDS, and client
write request will carry the new layout version and OST object
rejects old layout version write and update new layout version
accordingly.

Signed-off-by: Bobi Jam <bobijam@whamcloud.com>
Change-Id: I655044f69a4509a2b0cfe99f86de2ce4ee846979

12 files changed:
lustre/include/obd_support.h
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/llite/file.c
lustre/lod/lod_internal.h
lustre/lod/lod_object.c
lustre/lod/lod_qos.c
lustre/mdd/mdd_object.c
lustre/ofd/ofd_internal.h
lustre/ofd/ofd_io.c
lustre/ofd/ofd_objects.c
lustre/osp/osp_sync.c
lustre/tests/sanity-flr.sh

index 5716784..4fa30e3 100644 (file)
@@ -680,7 +680,7 @@ extern char obd_jobid_var[];
 /* FLR */
 #define OBD_FAIL_FLR_GLIMPSE_IMMUTABLE         0x1A00
 #define OBD_FAIL_FLR_LV_DELAY                  0x1A01
-#define OBD_FAIL_FLR_LV_INC                    0x1A02
+#define OBD_FAIL_FLR_LV_INC                    0x1A02 /* not used */
 #define OBD_FAIL_FLR_RANDOM_PICK_MIRROR        0x1A03
 
 /* DT */
index bb5d3e6..e535325 100644 (file)
@@ -882,10 +882,6 @@ enum lov_comp_md_entry_flags {
 #define LCME_TEMPLATE_FLAGS    (LCME_FL_PREF_RW | LCME_FL_NOSYNC | \
                                 LCME_FL_EXTENSION)
 
-/* the highest bit in obdo::o_layout_version is used to mark if the file is
- * being resynced. */
-#define LU_LAYOUT_RESYNC       LCME_FL_NEG
-
 /* lcme_id can be specified as certain flags, and the the first
  * bit of lcme_id is used to indicate that the ID is representing
  * certain LCME_FL_* but not a real ID. Which implies we can have
@@ -897,6 +893,15 @@ enum lcme_id {
        LCME_ID_NOT_ID  = LCME_FL_NEG
 };
 
+/* layout version equals to lcme_id, except some bits have special meanings */
+enum layout_version_flags {
+       /* layout version reaches the high water mark to be increased to
+        * circularly reuse the smallest value */
+       LU_LAYOUT_HIGEN         = 0x40000000,
+       /* the highest bit is used to mark if the file is being resynced */
+       LU_LAYOUT_RESYNC        = 0x80000000,
+};
+
 #define LCME_ID_MASK   LCME_ID_MAX
 
 struct lov_comp_md_entry_v1 {
index 21fb0b4..18544f5 100644 (file)
@@ -3592,6 +3592,7 @@ static long ll_file_unlock_lease(struct file *file, struct ll_ioc_lease *ioc,
        bool lease_broken = false;
        fmode_t fmode = 0;
        enum mds_op_bias bias = 0;
+       int fdv;
        struct file *layout_file = NULL;
        void *data = NULL;
        size_t data_size = 0;
@@ -3628,16 +3629,15 @@ static long ll_file_unlock_lease(struct file *file, struct ll_ioc_lease *ioc,
                bias = MDS_CLOSE_RESYNC_DONE;
                break;
        case LL_LEASE_LAYOUT_MERGE: {
-               int fd;
 
                if (ioc->lil_count != 1)
                        GOTO(out_lease_close, rc = -EINVAL);
 
                arg += sizeof(*ioc);
-               if (copy_from_user(&fd, (void __user *)arg, sizeof(__u32)))
+               if (copy_from_user(&fdv, (void __user *)arg, sizeof(__u32)))
                        GOTO(out_lease_close, rc = -EFAULT);
 
-               layout_file = fget(fd);
+               layout_file = fget(fdv);
                if (!layout_file)
                        GOTO(out_lease_close, rc = -EBADF);
 
@@ -3650,7 +3650,6 @@ static long ll_file_unlock_lease(struct file *file, struct ll_ioc_lease *ioc,
                break;
        }
        case LL_LEASE_LAYOUT_SPLIT: {
-               int fdv;
                int mirror_id;
 
                if (ioc->lil_count != 2)
@@ -3721,28 +3720,23 @@ out_lease_close:
        EXIT;
 
 out:
-       switch (ioc->lil_flags) {
-       case LL_LEASE_RESYNC_DONE:
-               if (data)
-                       OBD_FREE(data, data_size);
-               break;
-       case LL_LEASE_LAYOUT_MERGE:
-       case LL_LEASE_LAYOUT_SPLIT:
-               if (layout_file)
-                       fput(layout_file);
+       if (ioc->lil_flags == LL_LEASE_RESYNC_DONE && data)
+               OBD_FREE(data, data_size);
 
-               ll_layout_refresh(inode, &fd->fd_layout_version);
-               break;
-       case LL_LEASE_PCC_ATTACH:
+       if (layout_file)
+               fput(layout_file);
+
+       if (ioc->lil_flags == LL_LEASE_PCC_ATTACH) {
                if (!rc)
                        rc = rc2;
                rc = pcc_readwrite_attach_fini(file, inode,
                                               param.pa_layout_gen,
                                               lease_broken, rc,
                                               attached);
-               break;
        }
 
+       ll_layout_refresh(inode, &fd->fd_layout_version);
+
        if (!rc)
                rc = ll_lease_type_from_fmode(fmode);
        RETURN(rc);
index 61d5199..77987e7 100644 (file)
@@ -390,8 +390,10 @@ static inline void lod_obj_inc_layout_gen(struct lod_object *lo)
        lo->ldo_layout_gen++;
        lo->ldo_layout_gen |= preserve;
        /* Zero is not a valid generation */
-       if (unlikely((lo->ldo_layout_gen & LCME_ID_MASK) == 0))
+       if (unlikely((lo->ldo_layout_gen & LCME_ID_MASK) == 0)) {
                lo->ldo_layout_gen++;
+               lo->ldo_layout_gen &= ~LU_LAYOUT_RESYNC;
+       }
 }
 
 struct lod_it {
index bf4a5bd..ff917a1 100644 (file)
@@ -3277,7 +3277,6 @@ static int lod_declare_layout_merge(const struct lu_env *env,
                struct thandle *th)
 {
        struct lod_thread_info *info = lod_env_info(env);
-       struct lu_attr *layout_attr = &info->lti_layout_attr;
        struct lu_buf *buf = &info->lti_buf;
        struct lod_object *lo = lod_dt_obj(dt);
        struct lov_comp_md_v1 *lcm;
@@ -3411,6 +3410,8 @@ static int lod_declare_layout_merge(const struct lu_env *env,
        }
 
        /* fixup layout information */
+       lod_obj_inc_layout_gen(lo);
+       lcm->lcm_layout_gen = cpu_to_le32(lo->ldo_layout_gen);
        lcm->lcm_size = cpu_to_le32(size);
        lcm->lcm_entry_count = cpu_to_le16(cur_entry_count + merge_entry_count);
        lcm->lcm_mirror_count = cpu_to_le16(mirror_count);
@@ -3421,23 +3422,6 @@ static int lod_declare_layout_merge(const struct lu_env *env,
        if (rc)
                GOTO(out, rc);
 
-       lod_obj_inc_layout_gen(lo);
-       lcm->lcm_layout_gen = cpu_to_le32(lo->ldo_layout_gen);
-
-       /* transfer layout version to OST objects. */
-       if (lo->ldo_mirror_count > 1) {
-               struct lod_obj_stripe_cb_data data = { {0} };
-
-               layout_attr->la_valid = LA_LAYOUT_VERSION;
-               layout_attr->la_layout_version = 0;
-               data.locd_attr = layout_attr;
-               data.locd_declare = true;
-               data.locd_stripe_cb = lod_obj_stripe_attr_set_cb;
-               rc = lod_obj_for_each_stripe(env, lo, th, &data);
-               if (rc)
-                       GOTO(out, rc);
-       }
-
        rc = lod_sub_declare_xattr_set(env, dt_object_child(dt), buf,
                                        XATTR_NAME_LOV, LU_XATTR_REPLACE, th);
 
@@ -3453,8 +3437,6 @@ static int lod_declare_layout_split(const struct lu_env *env,
                struct dt_object *dt, const struct lu_buf *mbuf,
                struct thandle *th)
 {
-       struct lod_thread_info *info = lod_env_info(env);
-       struct lu_attr *layout_attr = &info->lti_layout_attr;
        struct lod_object *lo = lod_dt_obj(dt);
        struct lov_comp_md_v1 *lcm = mbuf->lb_buf;
        int rc;
@@ -3468,21 +3450,6 @@ static int lod_declare_layout_split(const struct lu_env *env,
        /* fix on-disk layout gen */
        lcm->lcm_layout_gen = cpu_to_le32(lo->ldo_layout_gen);
 
-
-       /* transfer layout version to OST objects. */
-       if (lo->ldo_mirror_count > 1) {
-               struct lod_obj_stripe_cb_data data = { {0} };
-
-               layout_attr->la_valid = LA_LAYOUT_VERSION;
-               layout_attr->la_layout_version = 0;
-               data.locd_attr = layout_attr;
-               data.locd_declare = true;
-               data.locd_stripe_cb = lod_obj_stripe_attr_set_cb;
-               rc = lod_obj_for_each_stripe(env, lo, th, &data);
-               if (rc)
-                       RETURN(rc);
-       }
-
        rc = lod_sub_declare_xattr_set(env, dt_object_child(dt), mbuf,
                                       XATTR_NAME_LOV, LU_XATTR_REPLACE, th);
        RETURN(rc);
@@ -4777,9 +4744,7 @@ static int lod_xattr_set(const struct lu_env *env,
                         const char *name, int fl, struct thandle *th)
 {
        struct dt_object *next = dt_object_child(dt);
-       struct lu_attr *layout_attr = &lod_env_info(env)->lti_layout_attr;
        struct lod_object *lo = lod_dt_obj(dt);
-       struct lod_obj_stripe_cb_data data = { {0} };
        int rc = 0;
 
        ENTRY;
@@ -4882,21 +4847,6 @@ static int lod_xattr_set(const struct lu_env *env,
                        rc = lod_striping_reload(env, lo, buf, LVF_ALL_STALE);
                        if (rc)
                                RETURN(rc);
-
-                       if (lo->ldo_mirror_count > 1 &&
-                           layout_attr->la_valid & LA_LAYOUT_VERSION) {
-                               /* mirror split */
-                               layout_attr->la_layout_version =
-                                               lo->ldo_layout_gen;
-                               data.locd_attr = layout_attr;
-                               data.locd_declare = false;
-                               data.locd_stripe_cb =
-                                               lod_obj_stripe_attr_set_cb;
-                               rc = lod_obj_for_each_stripe(env, lo, th,
-                                                            &data);
-                               if (rc)
-                                       RETURN(rc);
-                       }
                } else if (fl & LU_XATTR_PURGE) {
                        rc = lod_layout_purge(env, dt, buf, th);
                } else if (dt_object_remote(dt)) {
@@ -4929,21 +4879,6 @@ static int lod_xattr_set(const struct lu_env *env,
                        rc = lod_striped_create(env, dt, NULL, NULL, th);
                        if (rc)
                                RETURN(rc);
-
-                       if (fl & LU_XATTR_MERGE && lo->ldo_mirror_count > 1 &&
-                           layout_attr->la_valid & LA_LAYOUT_VERSION) {
-                               /* mirror merge exec phase */
-                               layout_attr->la_layout_version =
-                                               lo->ldo_layout_gen;
-                               data.locd_attr = layout_attr;
-                               data.locd_declare = false;
-                               data.locd_stripe_cb =
-                                               lod_obj_stripe_attr_set_cb;
-                               rc = lod_obj_for_each_stripe(env, lo, th,
-                                                            &data);
-                               if (rc)
-                                       RETURN(rc);
-                       }
                }
                RETURN(rc);
        } else if (strcmp(name, XATTR_NAME_FID) == 0) {
@@ -7625,7 +7560,6 @@ static int lod_declare_update_rdonly(const struct lu_env *env,
                struct thandle *th)
 {
        struct lod_thread_info *info = lod_env_info(env);
-       struct lu_attr *layout_attr = &info->lti_layout_attr;
        struct lod_layout_component *lod_comp;
        struct lu_extent extent = { 0 };
        int rc;
@@ -7736,25 +7670,11 @@ static int lod_declare_update_rdonly(const struct lu_env *env,
         * This way it can make sure that the layout version is
         * monotonously increased in this writing era. */
        lod_obj_inc_layout_gen(lo);
-       if (lo->ldo_layout_gen > (LCME_ID_MAX >> 1)) {
-               __u32 layout_version;
-
-               get_random_bytes(&layout_version, sizeof(layout_version));
-               lo->ldo_layout_gen = layout_version & 0xffff;
-       }
 
        rc = lod_declare_instantiate_components(env, lo, th, 0);
        if (rc)
                GOTO(out, rc);
 
-       layout_attr->la_valid = LA_LAYOUT_VERSION;
-       layout_attr->la_layout_version = 0; /* set current version */
-       if (mlc->mlc_opc == MD_LAYOUT_RESYNC)
-               layout_attr->la_layout_version = LU_LAYOUT_RESYNC;
-       rc = lod_declare_attr_set(env, &lo->ldo_obj, layout_attr, th);
-       if (rc)
-               GOTO(out, rc);
-
 out:
        if (rc)
                lod_striping_free(env, lo);
@@ -7766,7 +7686,6 @@ static int lod_declare_update_write_pending(const struct lu_env *env,
                struct thandle *th)
 {
        struct lod_thread_info *info = lod_env_info(env);
-       struct lu_attr *layout_attr = &info->lti_layout_attr;
        struct lod_layout_component *lod_comp;
        struct lu_extent extent = { 0 };
        int primary = -1;
@@ -7898,19 +7817,6 @@ static int lod_declare_update_write_pending(const struct lu_env *env,
        if (rc)
                GOTO(out, rc);
 
-       /* 3. transfer layout version to OST objects.
-        * transfer new layout version to OST objects so that stale writes
-        * can be denied. It also ends an era of writing by setting
-        * LU_LAYOUT_RESYNC. Normal client can never use this bit to
-        * send write RPC; only resync RPCs could do it. */
-       layout_attr->la_valid = LA_LAYOUT_VERSION;
-       layout_attr->la_layout_version = 0; /* set current version */
-       if (mlc->mlc_opc == MD_LAYOUT_RESYNC)
-               layout_attr->la_layout_version = LU_LAYOUT_RESYNC;
-       rc = lod_declare_attr_set(env, &lo->ldo_obj, layout_attr, th);
-       if (rc)
-               GOTO(out, rc);
-
        lod_obj_inc_layout_gen(lo);
 out:
        if (rc)
@@ -7923,7 +7829,6 @@ static int lod_declare_update_sync_pending(const struct lu_env *env,
                struct thandle *th)
 {
        struct lod_thread_info  *info = lod_env_info(env);
-       struct lu_attr *layout_attr = &info->lti_layout_attr;
        unsigned sync_components = 0;
        unsigned resync_components = 0;
        int i;
@@ -7996,12 +7901,6 @@ static int lod_declare_update_sync_pending(const struct lu_env *env,
        lo->ldo_flr_state = LCM_FL_RDONLY;
        lod_obj_inc_layout_gen(lo);
 
-       layout_attr->la_valid = LA_LAYOUT_VERSION;
-       layout_attr->la_layout_version = 0; /* set current version */
-       rc = lod_declare_attr_set(env, &lo->ldo_obj, layout_attr, th);
-       if (rc)
-               GOTO(out, rc);
-
        info->lti_buf.lb_len = lod_comp_md_size(lo, false);
        rc = lod_sub_declare_xattr_set(env, lod_object_child(lo),
                                       &info->lti_buf, XATTR_NAME_LOV, 0, th);
@@ -8675,8 +8574,6 @@ static int lod_layout_change(const struct lu_env *env, struct dt_object *dt,
                             struct md_layout_change *mlc, struct thandle *th)
 {
        struct lu_attr *attr = &lod_env_info(env)->lti_attr;
-       struct lu_attr *layout_attr = &lod_env_info(env)->lti_layout_attr;
-       struct lod_object *lo = lod_dt_obj(dt);
        int rc;
 
        ENTRY;
@@ -8688,10 +8585,6 @@ static int lod_layout_change(const struct lu_env *env, struct dt_object *dt,
        }
 
        rc = lod_striped_create(env, dt, attr, NULL, th);
-       if (!rc && layout_attr->la_valid & LA_LAYOUT_VERSION) {
-               layout_attr->la_layout_version |= lo->ldo_layout_gen;
-               rc = lod_attr_set(env, dt, layout_attr, th);
-       }
 
        RETURN(rc);
 }
index f6571f3..fbc3fa2 100644 (file)
@@ -2602,6 +2602,7 @@ put_ldts:
                        }
                        lod_comp->llc_stripe_count = 0;
                } else {
+                       lod_comp->llc_layout_gen = 0;
                        lod_comp->llc_stripe = stripe;
                        lod_comp->llc_ost_indices = ost_indices;
                        lod_comp->llc_stripes_allocated = stripe_len;
index e266977..3b80b57 100644 (file)
@@ -1648,7 +1648,7 @@ 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? */
+       if (rc)
                GOTO(out_restore, rc);
 
        (void)mdd_changelog_data_store(env, mdd, CL_LAYOUT, 0, obj, handle,
index 12da352..f147664 100644 (file)
@@ -504,4 +504,21 @@ static inline int ofd_validate_seq(struct obd_export *exp, __u64 seq)
        return 0;
 }
 
+/* whether the requestion IO contains older layout version than that on the
+ * disk. */
+static inline bool ofd_layout_version_less(__u32 req_version,
+                                          __u32 ondisk_version)
+{
+       __u32 req = req_version & ~LU_LAYOUT_RESYNC;
+       __u32 ondisk = ondisk_version & ~LU_LAYOUT_RESYNC;
+
+       /**
+        * request layout version could be circularly increased to the samllest
+        * value, in that case @req < @ondisk but @req does not have the high
+        * end bit set while @ondisk does.
+        */
+       return (req < ondisk) &&
+               ((req & LU_LAYOUT_HIGEN) == (ondisk & LU_LAYOUT_HIGEN));
+}
+
 #endif /* _OFD_INTERNAL_H */
index 3b96d63..b6e6d4a 100644 (file)
@@ -439,7 +439,6 @@ int ofd_verify_ff(const struct lu_env *env, struct ofd_object *fo,
 int ofd_verify_layout_version(const struct lu_env *env,
                              struct ofd_object *fo, const struct obdo *oa)
 {
-       __u32 layout_version;
        int rc;
        ENTRY;
 
@@ -449,25 +448,18 @@ int ofd_verify_layout_version(const struct lu_env *env,
        rc = ofd_object_ff_load(env, fo);
        if (rc < 0) {
                if (rc == -ENODATA)
-                       rc = -EINPROGRESS;
+                       rc = 0;
                GOTO(out, rc);
        }
 
-       layout_version = fo->ofo_ff.ff_layout_version;
-       if (oa->o_layout_version >= layout_version &&
-           oa->o_layout_version <= layout_version + fo->ofo_ff.ff_range)
-               GOTO(out, rc = 0);
-
-       /* normal traffic, decide if to return ESTALE or EINPROGRESS */
-       layout_version &= ~LU_LAYOUT_RESYNC;
-
-       /* this update is not legitimate */
-       if ((oa->o_layout_version & ~LU_LAYOUT_RESYNC) <= layout_version)
-               GOTO(out, rc = -ESTALE);
-
-       /* layout version may not be transmitted yet */
-       if ((oa->o_layout_version & ~LU_LAYOUT_RESYNC) > layout_version)
-               GOTO(out, rc = -EINPROGRESS);
+       /**
+        * this update is not legitimate, whose layout version is older than
+        * that on the disk.
+        */
+       if (ofd_layout_version_less(oa->o_layout_version,
+                                   fo->ofo_ff.ff_layout_version +
+                                   fo->ofo_ff.ff_range))
+               RETURN(-ESTALE);
 
        EXIT;
 
index 41fe74b..2bb3adc 100644 (file)
@@ -607,8 +607,9 @@ int ofd_object_ff_update(const struct lu_env *env, struct ofd_object *fo,
                        ff->ff_range = 0;
                }
 
-               /* it's not allowed to change it to a smaller value */
-               if (oa->o_layout_version < ff->ff_layout_version)
+               /*it's not allowed to change it to a smaller value */
+               if (ofd_layout_version_less(oa->o_layout_version,
+                                           ff->ff_layout_version))
                        RETURN(-EINVAL);
 
                if (ff->ff_layout_version == 0 ||
index 2f1db6b..8d3ea09 100644 (file)
@@ -767,13 +767,6 @@ static int osp_sync_new_setattr_job(struct osp_device *d,
        else
                body->oa.o_valid |= rec->lsr_valid;
 
-       if (body->oa.o_valid & OBD_MD_LAYOUT_VERSION) {
-               OBD_FAIL_TIMEOUT(OBD_FAIL_FLR_LV_DELAY, cfs_fail_val);
-               if (unlikely(OBD_FAIL_CHECK(OBD_FAIL_FLR_LV_INC)))
-                       body->oa.o_layout_version = LU_LAYOUT_RESYNC |
-                                       (body->oa.o_layout_version + 1);
-       }
-
        osp_sync_send_new_rpc(d, llh, h, req);
        RETURN(0);
 }
index fd811a2..8f59aeb 100644 (file)
@@ -1414,7 +1414,7 @@ verify_ost_layout_version() {
        # layout version from OST objects
        local olv=$($MULTIOP $tf oXc | awk '/ostlayoutversion/{print $2}')
 
-       [ $flv -eq $olv ] || error "layout version mismatch: $flv vs. $olv"
+       (( flv >= olv )) || error "layout version mismatch: $flv vs. $olv"
 }
 
 create_file_36() {
@@ -1429,7 +1429,7 @@ create_file_36() {
        done
 }
 
-test_36() {
+test_36a() {
        local tf=$DIR/$tfile
 
        stack_trap "rm -f $tf $tf-2 $tf-3"
@@ -1464,27 +1464,60 @@ test_36() {
        local st=$(date +%s)
        $MULTIOP $tf-2 oO_WRONLY:w1024Yc || error "write mirrored file error"
 
-       [ $(date +%s) -ge $((st+delay_sec)) ] ||
-               error "write finished before layout version is transmitted"
-
        # verify OST layout version
        verify_ost_layout_version $tf
 
        do_facet $mds_facet $LCTL set_param fail_loc=0
+}
+run_test 36a "write to mirrored files"
 
-       # test case 3
-       mds_idx=mds$(($($LFS getstripe -m $tf-3) + 1))
+test_36b() {
+       local tf=$DIR/$tfile
 
-       #define OBD_FAIL_FLR_LV_INC 0x1A02
-       do_facet $mds_facet $LCTL set_param fail_loc=0x1A02
+       (( OSTCOUNT < 2 )) && skip "need >= 2 OSTs" && return
 
-       # write open file should return error
-       $MULTIOP $tf-3 oO_WRONLY:O_SYNC:w1024c &&
-               error "write a mirrored file succeeded" || true
+       # create 2 mirrors using different OSTs
+       $LFS setstripe -N -c1 -i0 --flags=prefer -N -c1 -i1 $tf ||
+               error "create mirrored file"
 
-       do_facet $mds_facet $LCTL set_param fail_loc=0
+       # write 1M data to one mirror
+       dd if=/dev/zero of=$tf bs=1M count=1 || error "write file error"
+       sync
+
+       # set prefer mirror to another mirror
+       $LFS setstripe --comp-set -I0x10001 --comp-flags=^prefer $tf ||
+               error "clear prefer mirror error"
+       $LFS setstripe --comp-set -I0x20002 --comp-flags=prefer $tf ||
+               error "set prefer mirror error"
+
+       # the second write should not hung
+       dd if=/dev/zero of=$tf bs=1M count=1 || error "write file error"
+}
+run_test 36b "write should not hung when prefered mirror is stale"
+
+test_36c() {
+       local tf=$DIR/$tfile
+
+       (( OSTCOUNT < 2 )) && skip "need >= 2 OSTs" && return
+
+       # create 2 mirrors using different OSTs
+       $LFS setstripe -N -c1 -i0 --flags=prefer -N -c1 -i1 $tf ||
+               error "create mirrored file"
+
+       # write it in the background
+       dd if=/dev/zero of=$tf bs=1M count=600 &
+       local pid=$!
+
+       sleep 1
+
+       $LFS setstripe --comp-set -I0x10001 --comp-flags=^prefer $tf ||
+               error "clear prefer mirror error"
+       $LFS setstripe --comp-set -I0x20002 --comp-flags=prefer $tf ||
+               error "set prefer mirror error"
+
+       wait $pid
 }
-run_test 36 "write to mirrored files"
+run_test 36c "change prefer mirror during write shouldn't hung"
 
 create_files_37() {
        local tf
@@ -2524,6 +2557,8 @@ run_test 50A "mirror split update layout generation"
 test_50a() {
        $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
                skip "OST does not support SEEK_HOLE"
+       [ "$FSTYPE" != "zfs" ] ||
+               skip "lseek for ZFS is not accurate if obj is not committed"
 
        local file=$DIR/$tdir/$tfile
        local offset
@@ -2622,6 +2657,8 @@ run_test 50a "mirror extend/copy preserves sparseness"
 test_50b() {
        $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
                skip "OST does not support SEEK_HOLE"
+       [ "$FSTYPE" != "zfs" ] ||
+               skip "lseek for ZFS is not accurate if obj is not committed"
 
        local file=$DIR/$tdir/$tfile
        local offset
@@ -2734,6 +2771,8 @@ test_50d() {
                skip "OST does not support SEEK_HOLE"
        (( $LINUX_VERSION_CODE > $(version_code 3.0.0) )) ||
                skip "client kernel does not support SEEK_HOLE"
+       [ "$FSTYPE" != "zfs" ] ||
+               skip "lseek for ZFS is not accurate if obj is not committed"
 
        local file=$DIR/$tdir/$tfile
        local offset