From a17909a92da74cb26fb9bf2824f968b2adf0897e Mon Sep 17 00:00:00 2001 From: wang di Date: Thu, 23 Jul 2015 02:24:47 -0700 Subject: [PATCH] LU-6831 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 Change-Id: I410940473d123796f75607d39153240b7d3f737b Reviewed-on: http://review.whamcloud.com/15720 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Alex Zhuravlev Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- lustre/llite/file.c | 7 +++++++ lustre/llite/llite_lib.c | 30 +++++++++++++++++++++++++++++- lustre/lmv/lmv_intent.c | 12 ++++++++---- 3 files changed, 44 insertions(+), 5 deletions(-) diff --git a/lustre/llite/file.c b/lustre/llite/file.c index b10ef2e..92640cc 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -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. */ diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 10a9928..775fe80 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -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, diff --git a/lustre/lmv/lmv_intent.c b/lustre/lmv/lmv_intent.c index 9d16714..cdefb3d 100644 --- a/lustre/lmv/lmv_intent.c +++ b/lustre/lmv/lmv_intent.c @@ -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); -- 1.8.3.1