staging: lustre: lmv: revalidate the dentry for striped dir
authorwang di <di.wang@intel.com>
Thu, 10 Nov 2016 17:30:40 +0000 (12:30 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Nov 2016 15:13:58 +0000 (16:13 +0100)
If there are bad stripe during striped dir revalidation,
most likely due the race between close(unlink) and
getattr, then let's revalidate the dentry, instead of
return error, like normal directory.

Signed-off-by: wang di <di.wang@intel.com>
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-6831
Reviewed-on: http://review.whamcloud.com/15720
Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-7078
Reviewed-on: http://review.whamcloud.com/16382
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-by: John L. Hammond <john.hammond@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
Signed-off-by: James Simmons <jsimmons@infradead.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/lustre/lustre/llite/file.c
drivers/staging/lustre/lustre/llite/llite_lib.c
drivers/staging/lustre/lustre/lmv/lmv_intent.c

index 7886840328d0cb8783e8628ac07200cfab6217fc..73a680e86c4fbfb4c2dbc156623678df08dd9dad 100644 (file)
@@ -2674,6 +2674,13 @@ static int ll_inode_revalidate_fini(struct inode *inode, int rc)
        /* Already unlinked. Just update nlink and return success */
        if (rc == -ENOENT) {
                clear_nlink(inode);
+               /* If it is striped directory, and there is bad stripe
+                * Let's revalidate the dentry again, instead of returning
+                * error
+                */
+               if (S_ISDIR(inode->i_mode) && ll_i2info(inode)->lli_lsm_md)
+                       return 0;
+
                /* This path cannot be hit for regular files unless in
                 * case of obscure races, so no need to validate size.
                 */
index 154282ea211d8b55d4d3e10975bd216a8266e961..ff8608cd32eb492bf78515367f5a731686393317 100644 (file)
@@ -1203,16 +1203,44 @@ static int ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
 
        /* set the directory layout */
        if (!lli->lli_lsm_md) {
+               struct cl_attr *attr;
+
                rc = ll_init_lsm_md(inode, md);
                if (rc)
                        return rc;
 
-               lli->lli_lsm_md = lsm;
                /*
                 * set lsm_md to NULL, so the following free lustre_md
                 * will not free this lsm
                 */
                md->lmv = NULL;
+               lli->lli_lsm_md = lsm;
+
+               attr = kzalloc(sizeof(*attr), GFP_NOFS);
+               if (!attr)
+                       return -ENOMEM;
+
+               /* validate the lsm */
+               rc = md_merge_attr(ll_i2mdexp(inode), lsm, attr,
+                                  ll_md_blocking_ast);
+               if (rc) {
+                       kfree(attr);
+                       return rc;
+               }
+
+               if (md->body->mbo_valid & OBD_MD_FLNLINK)
+                       md->body->mbo_nlink = attr->cat_nlink;
+               if (md->body->mbo_valid & OBD_MD_FLSIZE)
+                       md->body->mbo_size = attr->cat_size;
+               if (md->body->mbo_valid & OBD_MD_FLATIME)
+                       md->body->mbo_atime = attr->cat_atime;
+               if (md->body->mbo_valid & OBD_MD_FLCTIME)
+                       md->body->mbo_ctime = attr->cat_ctime;
+               if (md->body->mbo_valid & OBD_MD_FLMTIME)
+                       md->body->mbo_mtime = attr->cat_mtime;
+
+               kfree(attr);
+
                CDEBUG(D_INODE, "Set lsm %p magic %x to "DFID"\n", lsm,
                       lsm->lsm_md_magic, PFID(ll_inode2fid(inode)));
                return 0;
index 9f4e826bb0af7b56fc7501bfacb9cd08cd0711b6..b1071cf5a70c7323e7207e6c0252a2b4d3cbf629 100644 (file)
@@ -223,7 +223,14 @@ int lmv_revalidate_slaves(struct obd_export *exp,
                        LASSERT(body);
 
                        if (unlikely(body->mbo_nlink < 2)) {
-                               CERROR("%s: nlink %d < 2 corrupt stripe %d "DFID":" DFID"\n",
+                               /*
+                                * If this is bad stripe, most likely due
+                                * to the race between close(unlink) and
+                                * getattr, let's return -EONENT, so llite
+                                * will revalidate the dentry see
+                                * ll_inode_revalidate_fini()
+                                */
+                               CDEBUG(D_INODE, "%s: nlink %d < 2 corrupt stripe %d "DFID":" DFID"\n",
                                       obd->obd_name, body->mbo_nlink, i,
                                       PFID(&lsm->lsm_md_oinfo[i].lmo_fid),
                                       PFID(&lsm->lsm_md_oinfo[0].lmo_fid));
@@ -233,7 +240,7 @@ int lmv_revalidate_slaves(struct obd_export *exp,
                                        it.it_lock_mode = 0;
                                }
 
-                               rc = -EIO;
+                               rc = -ENOENT;
                                goto cleanup;
                        }