aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ceph
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2014-03-01 09:11:45 -0500
committerYan, Zheng <zheng.z.yan@intel.com>2014-04-02 22:33:53 -0400
commit9017c2ec78c730fb3ecd703d44e4a9061de2ba52 (patch)
treed0c15467898545ee127ad8f93d059f7d83503bd4 /fs/ceph
parent4f32b42dca660208c7556e13ebd84c510ad91840 (diff)
ceph: add get_parent() NFS export callback
The callback uses LOOKUPPARENT MDS request to find parent. Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com> Reviewed-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/export.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/fs/ceph/export.c b/fs/ceph/export.c
index 976d3411d5ed..9c28b6abe885 100644
--- a/fs/ceph/export.c
+++ b/fs/ceph/export.c
@@ -121,6 +121,65 @@ static struct dentry *ceph_fh_to_dentry(struct super_block *sb,
121 return __fh_to_dentry(sb, fh->ino); 121 return __fh_to_dentry(sb, fh->ino);
122} 122}
123 123
124static struct dentry *__get_parent(struct super_block *sb,
125 struct dentry *child, u64 ino)
126{
127 struct ceph_mds_client *mdsc = ceph_sb_to_client(sb)->mdsc;
128 struct ceph_mds_request *req;
129 struct inode *inode;
130 struct dentry *dentry;
131 int err;
132
133 req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPPARENT,
134 USE_ANY_MDS);
135 if (IS_ERR(req))
136 return ERR_CAST(req);
137
138 if (child) {
139 req->r_inode = child->d_inode;
140 ihold(child->d_inode);
141 } else {
142 req->r_ino1 = (struct ceph_vino) {
143 .ino = ino,
144 .snap = CEPH_NOSNAP,
145 };
146 }
147 req->r_num_caps = 1;
148 err = ceph_mdsc_do_request(mdsc, NULL, req);
149 inode = req->r_target_inode;
150 if (inode)
151 ihold(inode);
152 ceph_mdsc_put_request(req);
153 if (!inode)
154 return ERR_PTR(-ENOENT);
155
156 dentry = d_obtain_alias(inode);
157 if (IS_ERR(dentry)) {
158 iput(inode);
159 return dentry;
160 }
161 err = ceph_init_dentry(dentry);
162 if (err < 0) {
163 dput(dentry);
164 return ERR_PTR(err);
165 }
166 dout("__get_parent ino %llx parent %p ino %llx.%llx\n",
167 child ? ceph_ino(child->d_inode) : ino,
168 dentry, ceph_vinop(inode));
169 return dentry;
170}
171
172struct dentry *ceph_get_parent(struct dentry *child)
173{
174 /* don't re-export snaps */
175 if (ceph_snap(child->d_inode) != CEPH_NOSNAP)
176 return ERR_PTR(-EINVAL);
177
178 dout("get_parent %p ino %llx.%llx\n",
179 child, ceph_vinop(child->d_inode));
180 return __get_parent(child->d_sb, child, 0);
181}
182
124/* 183/*
125 * get parent, if possible. 184 * get parent, if possible.
126 * 185 *
@@ -171,4 +230,5 @@ const struct export_operations ceph_export_ops = {
171 .encode_fh = ceph_encode_fh, 230 .encode_fh = ceph_encode_fh,
172 .fh_to_dentry = ceph_fh_to_dentry, 231 .fh_to_dentry = ceph_fh_to_dentry,
173 .fh_to_parent = ceph_fh_to_parent, 232 .fh_to_parent = ceph_fh_to_parent,
233 .get_parent = ceph_get_parent,
174}; 234};