[prev in list] [next in list] [prev in thread] [next in thread] 

List:       git-commits-head
Subject:    ceph: use lookup request to revalidate dentry
From:       "Linux Kernel Mailing List" <linux-kernel () vger ! kernel ! org>
Date:       2016-03-26 23:04:45
Message-ID: 20160326230445.0B630660FBE () gitolite ! kernel ! org
[Download RAW message or body]

Web:        https://git.kernel.org/torvalds/c/200fd27c8fa2ba8bb4529033967b69a7cbfa2c2e
Commit:     200fd27c8fa2ba8bb4529033967b69a7cbfa2c2e
Parent:     641235d8f823574961d225bdbfaef299842aa38c
Refname:    refs/heads/master
Author:     Yan, Zheng <zyan@redhat.com>
AuthorDate: Thu Mar 17 14:41:59 2016 +0800
Committer:  Ilya Dryomov <idryomov@gmail.com>
CommitDate: Fri Mar 25 18:51:56 2016 +0100

    ceph: use lookup request to revalidate dentry
    
    If dentry has no lease, ceph_d_revalidate() previously return 0.
    This causes VFS to invalidate the dentry and create a new dentry
    for later lookup. Invalidating a dentry also detach any underneath
    mount points. So mount point inside cephfs can disapear mystically
    (even the mount point is not modified by other hosts).
    
    The fix is using lookup request to revalidate dentry without lease.
    This can partly solve the mount points disapear issue (as long as
    the mount point is not modified by other hosts)
    
    Signed-off-by: Yan, Zheng <zyan@redhat.com>
---
 fs/ceph/dir.c   | 34 ++++++++++++++++++++++++++++++++++
 fs/ceph/inode.c |  1 +
 2 files changed, 35 insertions(+)

diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index c37820b..d6c13f9 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -1111,6 +1111,40 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags)
 			valid = 1;
 	}
 
+	if (!valid) {
+		struct ceph_mds_client *mdsc =
+			ceph_sb_to_client(dir->i_sb)->mdsc;
+		struct ceph_mds_request *req;
+		int op, mask, err;
+
+		op = ceph_snap(dir) == CEPH_SNAPDIR ?
+			CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP;
+		req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS);
+		if (!IS_ERR(req)) {
+			req->r_dentry = dget(dentry);
+			req->r_num_caps = 2;
+
+			mask = CEPH_STAT_CAP_INODE | CEPH_CAP_AUTH_SHARED;
+			if (ceph_security_xattr_wanted(dir))
+				mask |= CEPH_CAP_XATTR_SHARED;
+			req->r_args.getattr.mask = mask;
+
+			req->r_locked_dir = dir;
+			err = ceph_mdsc_do_request(mdsc, NULL, req);
+			if (err == 0 || err == -ENOENT) {
+				if (dentry == req->r_dentry) {
+					valid = !d_unhashed(dentry);
+				} else {
+					d_invalidate(req->r_dentry);
+					err = -EAGAIN;
+				}
+			}
+			ceph_mdsc_put_request(req);
+			dout("d_revalidate %p lookup result=%d\n",
+			     dentry, err);
+		}
+	}
+
 	dout("d_revalidate %p %s\n", dentry, valid ? "valid" : "invalid");
 	if (valid) {
 		ceph_dentry_lru_touch(dentry);
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 8b136dc..ed58b16 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -1265,6 +1265,7 @@ retry_lookup:
 			dout(" %p links to %p %llx.%llx, not %llx.%llx\n",
 			     dn, d_inode(dn), ceph_vinop(d_inode(dn)),
 			     ceph_vinop(in));
+			d_invalidate(dn);
 			have_lease = false;
 		}
 
--
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic