Whamcloud - gitweb
LU-6831 lmv: revalidate the dentry for striped dir 20/15720/2
authorwang di <di.wang@intel.com>
Thu, 23 Jul 2015 09:24:47 +0000 (02:24 -0700)
committerOleg Drokin <oleg.drokin@intel.com>
Fri, 7 Aug 2015 23:48:14 +0000 (23:48 +0000)
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>
Change-Id: I410940473d123796f75607d39153240b7d3f737b
Reviewed-on: http://review.whamcloud.com/15720
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: James Simmons <uja.ornl@yahoo.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/llite/file.c
lustre/llite/llite_lib.c
lustre/lmv/lmv_intent.c

index b10ef2e..92640cc 100644 (file)
@@ -3092,6 +3092,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 != NULL)
+                       return 0;
+
                /* This path cannot be hit for regular files unless in
                 * case of obscure races, so no need to to validate
                 * size. */
index 10a9928..775fe80 100644 (file)
@@ -1325,13 +1325,41 @@ static int ll_update_lsm_md(struct inode *inode, struct lustre_md *md)
 
        /* set the directory layout */
        if (lli->lli_lsm_md == NULL) {
+               struct cl_attr  *attr;
 
                rc = ll_init_lsm_md(inode, md);
                if (rc != 0)
                        RETURN(rc);
 
                lli->lli_lsm_md = lsm;
-               /* set lsm_md to NULL, so the following free lustre_md
+
+               OBD_ALLOC_PTR(attr);
+               if (attr == NULL)
+                       RETURN(-ENOMEM);
+
+               /* validate the lsm */
+               rc = md_merge_attr(ll_i2mdexp(inode), lsm, attr,
+                                  ll_md_blocking_ast);
+               if (rc != 0) {
+                       OBD_FREE_PTR(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;
+
+               OBD_FREE_PTR(attr);
+
+
+                       /* set lsm_md to NULL, so the following free lustre_md
                 * will not free this lsm */
                md->lmv = NULL;
                CDEBUG(D_INODE, "Set lsm %p magic %x to "DFID"\n", lsm,
index 9d16714..cdefb3d 100644 (file)
@@ -227,8 +227,13 @@ int lmv_revalidate_slaves(struct obd_export *exp,
                                                      &RMF_MDT_BODY);
                        LASSERT(body != NULL);
                        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 bad 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));
@@ -239,10 +244,9 @@ int lmv_revalidate_slaves(struct obd_export *exp,
                                        it.d.lustre.it_lock_mode = 0;
                                }
 
-                               GOTO(cleanup, rc = -EIO);
+                               GOTO(cleanup, rc = -ENOENT);
                        }
 
-
                        i_size_write(inode, body->mbo_size);
                        inode->i_blocks = body->mbo_blocks;
                        set_nlink(inode, body->mbo_nlink);