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>

authored by Yan, Zheng and committed by Ilya Dryomov 200fd27c 641235d8

Changed files
+35
fs
ceph
+34
fs/ceph/dir.c
··· 1111 1111 valid = 1; 1112 1112 } 1113 1113 1114 + if (!valid) { 1115 + struct ceph_mds_client *mdsc = 1116 + ceph_sb_to_client(dir->i_sb)->mdsc; 1117 + struct ceph_mds_request *req; 1118 + int op, mask, err; 1119 + 1120 + op = ceph_snap(dir) == CEPH_SNAPDIR ? 1121 + CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP; 1122 + req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS); 1123 + if (!IS_ERR(req)) { 1124 + req->r_dentry = dget(dentry); 1125 + req->r_num_caps = 2; 1126 + 1127 + mask = CEPH_STAT_CAP_INODE | CEPH_CAP_AUTH_SHARED; 1128 + if (ceph_security_xattr_wanted(dir)) 1129 + mask |= CEPH_CAP_XATTR_SHARED; 1130 + req->r_args.getattr.mask = mask; 1131 + 1132 + req->r_locked_dir = dir; 1133 + err = ceph_mdsc_do_request(mdsc, NULL, req); 1134 + if (err == 0 || err == -ENOENT) { 1135 + if (dentry == req->r_dentry) { 1136 + valid = !d_unhashed(dentry); 1137 + } else { 1138 + d_invalidate(req->r_dentry); 1139 + err = -EAGAIN; 1140 + } 1141 + } 1142 + ceph_mdsc_put_request(req); 1143 + dout("d_revalidate %p lookup result=%d\n", 1144 + dentry, err); 1145 + } 1146 + } 1147 + 1114 1148 dout("d_revalidate %p %s\n", dentry, valid ? "valid" : "invalid"); 1115 1149 if (valid) { 1116 1150 ceph_dentry_lru_touch(dentry);
+1
fs/ceph/inode.c
··· 1265 1265 dout(" %p links to %p %llx.%llx, not %llx.%llx\n", 1266 1266 dn, d_inode(dn), ceph_vinop(d_inode(dn)), 1267 1267 ceph_vinop(in)); 1268 + d_invalidate(dn); 1268 1269 have_lease = false; 1269 1270 } 1270 1271