Whamcloud - gitweb
LU-15284 llite: access lli_lsm_md with lock in all places 55/46355/4
authorLai Siyao <lai.siyao@whamcloud.com>
Fri, 28 Jan 2022 05:08:41 +0000 (00:08 -0500)
committerOleg Drokin <green@whamcloud.com>
Mon, 30 May 2022 19:03:58 +0000 (19:03 +0000)
lli_lsm_md should be accessed with lock in all places. Among all the
changes, ll_rease_page() is inside lock already, except statahead
code.

Test-Parameters: mdscount=2 mdtcount=4 testlist=racer,racer,racer
Signed-off-by: Lai Siyao <lai.siyao@whamcloud.com>
Change-Id: I1e09402812ce51ce7ab80d9529d488cb5b2879ee
Reviewed-on: https://review.whamcloud.com/46355
Reviewed-by: Mike Pershin <mpershin@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: John L. Hammond <jhammond@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/llite/dir.c
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/namei.c
lustre/llite/statahead.c
lustre/lmv/lmv_obd.c

index fedc5bb..e827894 100644 (file)
@@ -167,7 +167,8 @@ void ll_release_page(struct inode *inode, struct page *page,
 
        /* Always remove the page for striped dir, because the page is
         * built from temporarily in LMV layer */
-       if (inode && ll_dir_striped(inode)) {
+       if (inode && S_ISDIR(inode->i_mode) &&
+           lmv_dir_striped(ll_i2info(inode)->lli_lsm_md)) {
                __free_page(page);
                return;
        }
index c9666be..066d209 100644 (file)
@@ -5170,12 +5170,14 @@ static int ll_merge_md_attr(struct inode *inode)
        struct cl_attr attr = { 0 };
        int rc;
 
-       LASSERT(lli->lli_lsm_md != NULL);
-
-       if (!lmv_dir_striped(lli->lli_lsm_md))
+       if (!lli->lli_lsm_md)
                RETURN(0);
 
        down_read(&lli->lli_lsm_sem);
+       if (!lmv_dir_striped(lli->lli_lsm_md)) {
+               up_read(&lli->lli_lsm_sem);
+               RETURN(0);
+       }
        rc = md_merge_attr(ll_i2mdexp(inode), ll_i2info(inode)->lli_lsm_md,
                           &attr, ll_md_blocking_ast);
        up_read(&lli->lli_lsm_sem);
index e11927c..1318639 100644 (file)
@@ -1395,9 +1395,22 @@ static inline struct lu_fid *ll_inode2fid(struct inode *inode)
 
 static inline bool ll_dir_striped(struct inode *inode)
 {
+       struct ll_inode_info *lli;
+       bool rc;
+
        LASSERT(inode);
-       return S_ISDIR(inode->i_mode) &&
-              lmv_dir_striped(ll_i2info(inode)->lli_lsm_md);
+       if (!S_ISDIR(inode->i_mode))
+               return false;
+
+       lli = ll_i2info(inode);
+       if (!lli->lli_lsm_md)
+               return false;
+
+       down_read(&lli->lli_lsm_sem);
+       rc = lmv_dir_striped(lli->lli_lsm_md);
+       up_read(&lli->lli_lsm_sem);
+
+       return rc;
 }
 
 static inline loff_t ll_file_maxbytes(struct inode *inode)
index c16b67d..2456745 100644 (file)
@@ -1717,21 +1717,21 @@ static int ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
        }
 
        rc = ll_init_lsm_md(inode, md);
-       up_write(&lli->lli_lsm_sem);
-
-       if (rc)
+       if (rc) {
+               up_write(&lli->lli_lsm_sem);
                RETURN(rc);
+       }
+
+       /* md_merge_attr() may take long, since lsm is already set, switch to
+        * read lock.
+        */
+       downgrade_write(&lli->lli_lsm_sem);
 
        /* set md->lmv to NULL, so the following free lustre_md will not free
         * this lsm.
         */
        md->lmv = NULL;
 
-       /* md_merge_attr() may take long, since lsm is already set, switch to
-        * read lock.
-        */
-       down_read(&lli->lli_lsm_sem);
-
        if (!lmv_dir_striped(lli->lli_lsm_md))
                GOTO(unlock, rc = 0);
 
index 68981dc..1b4034b 100644 (file)
@@ -784,14 +784,17 @@ static int ll_lookup_it_finish(struct ptlrpc_request *request,
                struct lookup_intent parent_it = {
                                        .it_op = IT_GETATTR,
                                        .it_lock_handle = 0 };
-               struct lu_fid   fid = ll_i2info(parent)->lli_fid;
+               struct ll_inode_info *lli = ll_i2info(parent);
+               struct lu_fid fid = lli->lli_fid;
 
                /* If it is striped directory, get the real stripe parent */
                if (unlikely(ll_dir_striped(parent))) {
+                       down_read(&lli->lli_lsm_sem);
                        rc = md_get_fid_from_lsm(ll_i2mdexp(parent),
-                                                ll_i2info(parent)->lli_lsm_md,
+                                                lli->lli_lsm_md,
                                                 (*de)->d_name.name,
                                                 (*de)->d_name.len, &fid);
+                       up_read(&lli->lli_lsm_sem);
                        if (rc != 0)
                                GOTO(out, rc);
                }
index 5922daa..c5a9a36 100644 (file)
@@ -1189,8 +1189,10 @@ static int ll_statahead_thread(void *arg)
                }
 
                pos = le64_to_cpu(dp->ldp_hash_end);
+               down_read(&lli->lli_lsm_sem);
                ll_release_page(dir, page,
                                le32_to_cpu(dp->ldp_flags) & LDF_COLLIDE);
+               up_read(&lli->lli_lsm_sem);
 
                if (sa_low_hit(sai)) {
                        rc = -EFAULT;
index 51adfa8..3a1405b 100644 (file)
@@ -3727,7 +3727,8 @@ static int lmv_get_fid_from_lsm(struct obd_export *exp,
 {
        const struct lmv_oinfo *oinfo;
 
-       LASSERT(lmv_dir_striped(lsm));
+       if (!lmv_dir_striped(lsm))
+               RETURN(-ESTALE);
 
        oinfo = lsm_name_to_stripe_info(lsm, name, namelen, false);
        if (IS_ERR(oinfo))