Whamcloud - gitweb
LU-9344 test: hung with sendfile_grouplock test12() 46/26646/9
authorBobi Jam <bobijam.xu@intel.com>
Sat, 15 Apr 2017 03:57:18 +0000 (11:57 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Fri, 28 Apr 2017 20:36:24 +0000 (20:36 +0000)
This is a makeshift fix.

When we hold a group lock of a file, there should no data written to
the file, since during the write IO, the file's layout could possibly
change, and the write IO will try to update its layout, which could
be blocked by itself.

Signed-off-by: Bobi Jam <bobijam.xu@intel.com>
Change-Id: Ia24310d509e8a93c3c1d849c54eacf789f40bfb8
Reviewed-on: https://review.whamcloud.com/26646
Tested-by: Jenkins
Reviewed-by: Jinshan Xiong <jinshan.xiong@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
lustre/include/cl_object.h
lustre/llite/file.c
lustre/lod/lod_object.c
lustre/lov/lov_internal.h
lustre/lov/lov_object.c
lustre/tests/sendfile_grouplock.c

index dba3ef3..66c4ddc 100644 (file)
@@ -288,6 +288,8 @@ struct cl_layout {
        size_t          cl_size;
        /** Layout generation. */
        u32             cl_layout_gen;
+       /** whether layout is a composite one */
+       bool            cl_is_composite;
 };
 
 /**
index 180f288..bf8e826 100644 (file)
@@ -1710,11 +1710,12 @@ static int ll_lov_setstripe(struct inode *inode, struct file *file,
 static int
 ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg)
 {
-        struct ll_inode_info   *lli = ll_i2info(inode);
-        struct ll_file_data    *fd = LUSTRE_FPRIVATE(file);
-       struct ll_grouplock     grouplock;
-        int                     rc;
-        ENTRY;
+       struct ll_inode_info *lli = ll_i2info(inode);
+       struct cl_object *obj = lli->lli_clob;
+       struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
+       struct ll_grouplock grouplock;
+       int rc;
+       ENTRY;
 
        if (arg == 0) {
                CWARN("group id for group lock must not be 0\n");
@@ -1734,6 +1735,31 @@ ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg)
        LASSERT(fd->fd_grouplock.lg_lock == NULL);
        spin_unlock(&lli->lli_lock);
 
+       /**
+        * XXX: group lock needs to protect all OST objects while PFL
+        * can add new OST objects during the IO, so we'd instantiate
+        * all OST objects before getting its group lock.
+        */
+       if (obj) {
+               struct lu_env *env;
+               __u16 refcheck;
+               struct cl_layout cl = {
+                       .cl_is_composite = false,
+               };
+
+               env = cl_env_get(&refcheck);
+               if (IS_ERR(env))
+                       RETURN(PTR_ERR(env));
+
+               rc = cl_object_layout_get(env, obj, &cl);
+               if (!rc && cl.cl_is_composite)
+                       rc = ll_layout_write_intent(inode, 0, OBD_OBJECT_EOF);
+
+               cl_env_put(env, &refcheck);
+               if (rc)
+                       RETURN(rc);
+       }
+
        rc = cl_get_grouplock(ll_i2info(inode)->lli_clob,
                              arg, (file->f_flags & O_NONBLOCK), &grouplock);
        if (rc)
index a7bce5a..d7fad3e 100644 (file)
@@ -4947,8 +4947,9 @@ static int lod_declare_layout_change(const struct lu_env *env,
 
        /* Make sure defined layout covers the requested write range. */
        lod_comp = &lo->ldo_comp_entries[lo->ldo_comp_cnt - 1];
-       if ((lod_comp->llc_extent.e_end != OBD_OBJECT_EOF &&
-            lod_comp->llc_extent.e_end < layout->li_end)) {
+       if (lo->ldo_comp_cnt > 1 &&
+           lod_comp->llc_extent.e_end != OBD_OBJECT_EOF &&
+           lod_comp->llc_extent.e_end < layout->li_end) {
                CDEBUG(replay ? D_ERROR : D_LAYOUT,
                       "%s: the defined layout [0, %#llx) does not covers "
                       "the write range [%#llx, %#llx).\n",
index 548fd50..ae81569 100644 (file)
@@ -349,4 +349,10 @@ static inline bool lsm_entry_inited(const struct lov_stripe_md *lsm, int index)
 {
        return lsme_inited(lsm->lsm_entries[index]);
 }
+
+static inline bool lsm_is_composite(__u32 magic)
+{
+       return !!(magic & LOV_MAGIC_COMP_V1);
+}
+
 #endif
index bb974e9..3a9eb87 100644 (file)
@@ -1637,6 +1637,7 @@ static int lov_object_layout_get(const struct lu_env *env,
 
        cl->cl_size = lov_comp_md_size(lsm);
        cl->cl_layout_gen = lsm->lsm_layout_gen;
+       cl->cl_is_composite = lsm_is_composite(lsm->lsm_magic);
 
        rc = lov_lsm_pack(lsm, buf->lb_buf, buf->lb_len);
        lov_lsm_put(lsm);
index 2cdc479..76174f1 100644 (file)
@@ -266,6 +266,17 @@ static int sendfile_copy(const char *source, int source_gid,
 
        }
 
+       if (dest_gid != 0) {
+               rc = llapi_group_unlock(fd_out, dest_gid);
+               ASSERTF(rc == 0, "cannot clear group lock %d for '%s': %s",
+                       dest_gid, dest, strerror(-rc));
+       }
+       if (source_gid != 0) {
+               rc = llapi_group_unlock(fd_in, source_gid);
+               ASSERTF(rc == 0, "cannot clear group lock %d for '%s': %s",
+                       source_gid, source, strerror(-rc));
+       }
+
        close(fd_out);
        close(fd_in);