Commit b1839e0e authored by wang di's avatar wang di Committed by Greg Kroah-Hartman

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: default avatarwang 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/16382Reviewed-by: default avatarAlex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: default avatarJames Simmons <uja.ornl@yahoo.com>
Reviewed-by: default avatarJohn L. Hammond <john.hammond@intel.com>
Reviewed-by: default avatarOleg Drokin <oleg.drokin@intel.com>
Signed-off-by: default avatarJames Simmons <jsimmons@infradead.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 6736cd0b
......@@ -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.
*/
......
......@@ -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;
......
......@@ -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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment