staging: lustre: lmv: revalidate the dentry for striped dir

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>
This commit is contained in:
wang di 2016-11-10 12:30:40 -05:00 committed by Greg Kroah-Hartman
parent 6736cd0b4b
commit b1839e0e6c
3 changed files with 45 additions and 3 deletions

View 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.
*/

View 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;

View 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;
}