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

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/16382


Reviewed-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
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -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.
		 */
+29 −1
Original line number Diff line number Diff line
@@ -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;
+9 −2
Original line number Diff line number Diff line
@@ -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;
			}