summary refs log tree commit diff
path: root/fs/ceph
diff options
context:
space:
mode:
authorSage Weil <sage@newdream.net>2011-04-06 09:31:40 -0700
committerSage Weil <sage@newdream.net>2011-05-24 11:52:05 -0700
commit3c454cf21645bc96668e286f6352ac2c4c895fa2 (patch)
tree9ad5d408a07819d3e1155fb98df44c92f86a0eb5 /fs/ceph
parentaedfec59eed37d1ff7ce09b303b668234e9a7f8e (diff)
downloadlinux-3c454cf21645bc96668e286f6352ac2c4c895fa2.tar.gz
ceph: use LOOKUPINO to make unconnected nfs fh more reliable
If we are unable to locate an inode by ino, ask the MDS using the new
LOOKUPINO command.

Signed-off-by: Sage Weil <sage@newdream.net>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/export.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/fs/ceph/export.c b/fs/ceph/export.c
index e41056174bf8..f1828af09912 100644
--- a/fs/ceph/export.c
+++ b/fs/ceph/export.c
@@ -86,6 +86,7 @@ static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len,
 static struct dentry *__fh_to_dentry(struct super_block *sb,
 				     struct ceph_nfs_fh *fh)
 {
+	struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
 	struct inode *inode;
 	struct dentry *dentry;
 	struct ceph_vino vino;
@@ -95,8 +96,22 @@ static struct dentry *__fh_to_dentry(struct super_block *sb,
 	vino.ino = fh->ino;
 	vino.snap = CEPH_NOSNAP;
 	inode = ceph_find_inode(sb, vino);
-	if (!inode)
-		return ERR_PTR(-ESTALE);
+	if (!inode) {
+		struct ceph_mds_request *req;
+
+		req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPINO,
+					       USE_ANY_MDS);
+		if (IS_ERR(req))
+			return ERR_CAST(req);
+
+		req->r_ino1 = vino;
+		req->r_num_caps = 1;
+		err = ceph_mdsc_do_request(mdsc, NULL, req);
+		ceph_mdsc_put_request(req);
+		inode = ceph_find_inode(sb, vino);
+		if (!inode)
+			return ERR_PTR(-ESTALE);
+	}
 
 	dentry = d_obtain_alias(inode);
 	if (IS_ERR(dentry)) {