aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph/export.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ceph/export.c')
-rw-r--r--fs/ceph/export.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/fs/ceph/export.c b/fs/ceph/export.c
index e38423e82f2e..f67b687550de 100644
--- a/fs/ceph/export.c
+++ b/fs/ceph/export.c
@@ -1,10 +1,11 @@
1#include "ceph_debug.h" 1#include <linux/ceph/ceph_debug.h>
2 2
3#include <linux/exportfs.h> 3#include <linux/exportfs.h>
4#include <linux/slab.h> 4#include <linux/slab.h>
5#include <asm/unaligned.h> 5#include <asm/unaligned.h>
6 6
7#include "super.h" 7#include "super.h"
8#include "mds_client.h"
8 9
9/* 10/*
10 * NFS export support 11 * NFS export support
@@ -58,7 +59,7 @@ static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len,
58 dout("encode_fh %p connectable\n", dentry); 59 dout("encode_fh %p connectable\n", dentry);
59 cfh->ino = ceph_ino(dentry->d_inode); 60 cfh->ino = ceph_ino(dentry->d_inode);
60 cfh->parent_ino = ceph_ino(parent->d_inode); 61 cfh->parent_ino = ceph_ino(parent->d_inode);
61 cfh->parent_name_hash = parent->d_name.hash; 62 cfh->parent_name_hash = ceph_dentry_hash(parent);
62 *max_len = connected_handle_length; 63 *max_len = connected_handle_length;
63 type = 2; 64 type = 2;
64 } else if (*max_len >= handle_length) { 65 } else if (*max_len >= handle_length) {
@@ -85,6 +86,7 @@ static int ceph_encode_fh(struct dentry *dentry, u32 *rawfh, int *max_len,
85static struct dentry *__fh_to_dentry(struct super_block *sb, 86static struct dentry *__fh_to_dentry(struct super_block *sb,
86 struct ceph_nfs_fh *fh) 87 struct ceph_nfs_fh *fh)
87{ 88{
89 struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
88 struct inode *inode; 90 struct inode *inode;
89 struct dentry *dentry; 91 struct dentry *dentry;
90 struct ceph_vino vino; 92 struct ceph_vino vino;
@@ -94,8 +96,24 @@ static struct dentry *__fh_to_dentry(struct super_block *sb,
94 vino.ino = fh->ino; 96 vino.ino = fh->ino;
95 vino.snap = CEPH_NOSNAP; 97 vino.snap = CEPH_NOSNAP;
96 inode = ceph_find_inode(sb, vino); 98 inode = ceph_find_inode(sb, vino);
97 if (!inode) 99 if (!inode) {
98 return ERR_PTR(-ESTALE); 100 struct ceph_mds_request *req;
101
102 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPINO,
103 USE_ANY_MDS);
104 if (IS_ERR(req))
105 return ERR_CAST(req);
106
107 req->r_ino1 = vino;
108 req->r_num_caps = 1;
109 err = ceph_mdsc_do_request(mdsc, NULL, req);
110 inode = req->r_target_inode;
111 if (inode)
112 ihold(inode);
113 ceph_mdsc_put_request(req);
114 if (!inode)
115 return ERR_PTR(-ESTALE);
116 }
99 117
100 dentry = d_obtain_alias(inode); 118 dentry = d_obtain_alias(inode);
101 if (IS_ERR(dentry)) { 119 if (IS_ERR(dentry)) {
@@ -120,7 +138,7 @@ static struct dentry *__fh_to_dentry(struct super_block *sb,
120static struct dentry *__cfh_to_dentry(struct super_block *sb, 138static struct dentry *__cfh_to_dentry(struct super_block *sb,
121 struct ceph_nfs_confh *cfh) 139 struct ceph_nfs_confh *cfh)
122{ 140{
123 struct ceph_mds_client *mdsc = &ceph_sb_to_client(sb)->mdsc; 141 struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
124 struct inode *inode; 142 struct inode *inode;
125 struct dentry *dentry; 143 struct dentry *dentry;
126 struct ceph_vino vino; 144 struct ceph_vino vino;
@@ -147,8 +165,10 @@ static struct dentry *__cfh_to_dentry(struct super_block *sb,
147 snprintf(req->r_path2, 16, "%d", cfh->parent_name_hash); 165 snprintf(req->r_path2, 16, "%d", cfh->parent_name_hash);
148 req->r_num_caps = 1; 166 req->r_num_caps = 1;
149 err = ceph_mdsc_do_request(mdsc, NULL, req); 167 err = ceph_mdsc_do_request(mdsc, NULL, req);
168 inode = req->r_target_inode;
169 if (inode)
170 ihold(inode);
150 ceph_mdsc_put_request(req); 171 ceph_mdsc_put_request(req);
151 inode = ceph_find_inode(sb, vino);
152 if (!inode) 172 if (!inode)
153 return ERR_PTR(err ? err : -ESTALE); 173 return ERR_PTR(err ? err : -ESTALE);
154 } 174 }