Whamcloud - gitweb
LU-6581 mdt: Transfer layout only if layout lock is granted 26/14726/3
authorwang di <di.wang@intel.com>
Wed, 6 May 2015 15:45:20 +0000 (08:45 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Fri, 5 Jun 2015 02:56:23 +0000 (02:56 +0000)
Make sure that only valid layout is transferred;
Client also checks if lock is granted before trusting the layout;
Restore change LU-3299 commit 03a6a8b1 because it breaks the
assumption that l_lvb_data is immutable once assigned;
Comment fixups.

Signed-off-by: wang di <di.wang@intel.com>
Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com>
Change-Id: If18e022131c5015e40e0408cdd0168df237e4338
Reviewed-on: http://review.whamcloud.com/14726
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: jacques-Charles Lafoucriere <jacques-charles.lafoucriere@cea.fr>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/ldlm/ldlm_lockd.c
lustre/llite/file.c
lustre/mdc/mdc_locks.c
lustre/mdt/mdt_lvb.c

index 9e31e16..4c70b58 100644 (file)
@@ -1786,22 +1786,6 @@ static void ldlm_handle_cp_callback(struct ptlrpc_request *req,
                                           lock->l_lvb_len, lvb_len);
                                GOTO(out, rc = -EINVAL);
                        }
-               } else if (ldlm_has_layout(lock)) { /* for layout lock, lvb has
-                                                    * variable length */
-                       void *lvb_data;
-
-                       OBD_ALLOC_LARGE(lvb_data, lvb_len);
-                       if (lvb_data == NULL) {
-                               LDLM_ERROR(lock, "No memory: %d.\n", lvb_len);
-                               GOTO(out, rc = -ENOMEM);
-                       }
-
-                       lock_res_and_lock(lock);
-                       LASSERT(lock->l_lvb_data == NULL);
-                       lock->l_lvb_type = LVB_T_LAYOUT;
-                       lock->l_lvb_data = lvb_data;
-                       lock->l_lvb_len = lvb_len;
-                       unlock_res_and_lock(lock);
                }
        }
 
index ffbdc92..a42533e 100644 (file)
@@ -3658,7 +3658,7 @@ static int ll_layout_fetch(struct inode *inode, struct ldlm_lock *lock)
               PFID(ll_inode2fid(inode)), ldlm_is_lvb_ready(lock),
               lock->l_lvb_data, lock->l_lvb_len);
 
-       if ((lock->l_lvb_data != NULL) && ldlm_is_lvb_ready(lock))
+       if (lock->l_lvb_data != NULL)
                RETURN(0);
 
        /* if layout lock was granted right away, the layout is returned
@@ -3694,13 +3694,17 @@ static int ll_layout_fetch(struct inode *inode, struct ldlm_lock *lock)
 
        memcpy(lvbdata, lmm, lmmsize);
        lock_res_and_lock(lock);
-       if (lock->l_lvb_data != NULL)
-               OBD_FREE_LARGE(lock->l_lvb_data, lock->l_lvb_len);
-
-       lock->l_lvb_data = lvbdata;
-       lock->l_lvb_len = lmmsize;
+       if (unlikely(lock->l_lvb_data == NULL)) {
+               lock->l_lvb_type = LVB_T_LAYOUT;
+               lock->l_lvb_data = lvbdata;
+               lock->l_lvb_len = lmmsize;
+               lvbdata = NULL;
+       }
        unlock_res_and_lock(lock);
 
+       if (lvbdata != NULL)
+               OBD_FREE_LARGE(lvbdata, lmmsize);
+
        EXIT;
 
 out:
@@ -3750,10 +3754,9 @@ static int ll_layout_lock_set(struct lustre_handle *lockh, ldlm_mode_t mode,
        if (rc < 0)
                GOTO(out, rc);
 
-       /* for layout lock, lmm is returned in lock's lvb.
+       /* for layout lock, lmm is stored in lock's lvb.
         * lvb_data is immutable if the lock is held so it's safe to access it
-        * without res lock. See the description in ldlm_lock_decref_internal()
-        * for the condition to free lvb_data of layout lock */
+        * without res lock. */
        if (lock->l_lvb_data != NULL) {
                rc = obd_unpackmd(sbi->ll_dt_exp, &md.lsm,
                                  lock->l_lvb_data, lock->l_lvb_len);
index 40f41ca..7715281 100644 (file)
@@ -735,9 +735,14 @@ static int mdc_finish_enqueue(struct obd_export *exp,
                }
        }
 
-       /* fill in stripe data for layout lock */
+       /* fill in stripe data for layout lock.
+        * LU-6581: trust layout data only if layout lock is granted. The MDT
+        * has stopped sending layout unless the layout lock is granted. The
+        * client still does this checking in case it's talking with an old
+        * server. - Jinshan */
        lock = ldlm_handle2lock(lockh);
-       if (lock != NULL && ldlm_has_layout(lock) && lvb_data != NULL) {
+       if (lock != NULL && ldlm_has_layout(lock) && lvb_data != NULL &&
+           !(lockrep->lock_flags & LDLM_FL_BLOCKED_MASK)) {
                void *lmm;
 
                LDLM_DEBUG(lock, "layout lock returned by: %s, lvb_len: %d\n",
index d81b21f..22cc7ce 100644 (file)
@@ -114,7 +114,8 @@ static int mdt_lvbo_fill(struct ldlm_lock *lock, void *lvb, int lvblen)
                RETURN(rc);
        }
 
-       if (!ldlm_has_layout(lock))
+       /* Only fill layout if layout lock is granted */
+       if (!ldlm_has_layout(lock) || lock->l_granted_mode != lock->l_req_mode)
                RETURN(0);
 
        /* layout lock will be granted to client, fill in lvb with layout */