Whamcloud - gitweb
LU-2304 lov: check enq flags when matching top lock
authorJinshan Xiong <jinshan.xiong@intel.com>
Thu, 13 Dec 2012 01:17:47 +0000 (17:17 -0800)
committerOleg Drokin <green@whamcloud.com>
Fri, 14 Dec 2012 19:23:20 +0000 (14:23 -0500)
cld_enq_flags must be checked when matching top lock, otherwise
if a sublock is missing then it will be reenqueued with wrong enq
flags.

For LU-2304, a previous truncate to zero lock(with CEF_DISCARD_DATA)
flags was matched by not-to-zero truncate and then wrongly reenqueued
with discard flag. This caused dirty pages to be discarded on the
other clients.

Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Change-Id: I0575509b3ec30982fe7e5a7ff018ff4dd3dbe911
Reviewed-on: http://review.whamcloud.com/4818
Tested-by: Hudson
Reviewed-by: Bobi Jam <bobijam@gmail.com>
Tested-by: Maloo <whamcloud.maloo@gmail.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/ldlm/ldlm_request.c
lustre/llite/llite_lib.c
lustre/llite/vvp_io.c
lustre/lov/lov_lock.c
lustre/osc/osc_lock.c

index d1f54da..edd6191 100644 (file)
@@ -830,7 +830,9 @@ int ldlm_cli_enqueue(struct obd_export *exp, struct ptlrpc_request **reqp,
 
                 if (einfo->ei_type == LDLM_EXTENT)
                         lock->l_req_extent = policy->l_extent;
-                LDLM_DEBUG(lock, "client-side enqueue START");
+
+                LDLM_DEBUG(lock, "client-side enqueue START, flags %x\n",
+                          *flags);
         }
 
         /* lock not sent to server yet */
index 639e9f5..7526bbe 100644 (file)
@@ -1307,8 +1307,11 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr)
         int rc = 0, rc1 = 0;
         ENTRY;
 
-        CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu valid %x\n", inode->i_ino,
+        CDEBUG(D_VFSTRACE,
+               "Setattr inode %p/fid:"DFID" from %llu to %llu, valid %x\n",
+               inode, PFID(&lli->lli_fid), i_size_read(inode), attr->ia_size,
                attr->ia_valid);
+
         ll_stats_ops_tally(ll_i2sbi(inode), LPROC_LL_SETATTR, 1);
 
         if (ia_valid & ATTR_SIZE) {
index 6497488..bc9397d 100644 (file)
@@ -299,10 +299,10 @@ static int vvp_io_setattr_iter_init(const struct lu_env *env,
 static int vvp_io_setattr_lock(const struct lu_env *env,
                                const struct cl_io_slice *ios)
 {
-        struct ccc_io      *cio       = ccc_env_io(env);
-        struct cl_io       *io        = ios->cis_io;
-        size_t              new_size;
-        __u32               enqflags = 0;
+       struct ccc_io *cio = ccc_env_io(env);
+       struct cl_io  *io  = ios->cis_io;
+       __u64 new_size;
+       __u32 enqflags = 0;
 
         if (cl_io_is_trunc(io)) {
                 new_size = io->u.ci_setattr.sa_attr.lvb_size;
index b9b308f..1bc4e6a 100644 (file)
@@ -984,6 +984,11 @@ static int lov_lock_fits_into(const struct lu_env *env,
 
         ENTRY;
 
+       /* for top lock, it's necessary to match enq flags otherwise it will
+        * run into problem if a sublock is missing and reenqueue. */
+       if (need->cld_enq_flags != lov->lls_orig.cld_enq_flags)
+               return 0;
+
         if (need->cld_mode == CLM_GROUP)
                 /*
                  * always allow to match group lock.
index e30e309..f6d73f5 100644 (file)
@@ -1638,6 +1638,9 @@ int osc_lock_init(const struct lu_env *env,
                if (clk->ols_locklessable && !(enqflags & CEF_DISCARD_DATA))
                        clk->ols_flags |= LDLM_FL_DENY_ON_CONTENTION;
 
+               LDLM_DEBUG_NOLOCK("lock %p, osc lock %p, flags %x\n",
+                               lock, clk, clk->ols_flags);
+
                 result = 0;
         } else
                 result = -ENOMEM;