diff options
author | Yan, Zheng <zheng.z.yan@intel.com> | 2014-03-01 10:09:05 -0500 |
---|---|---|
committer | Yan, Zheng <zheng.z.yan@intel.com> | 2014-04-02 22:33:53 -0400 |
commit | 8996f4f23db735f0f3bab34352188b1ab21d7d7f (patch) | |
tree | cc9d5da9af62a94511ca6e08a8642ac0843b9f9b /fs/ceph/export.c | |
parent | 9017c2ec78c730fb3ecd703d44e4a9061de2ba52 (diff) |
ceph: fix ceph_fh_to_parent()
ceph_fh_to_parent() returns dentry that corresponds to the 'ino' field
of struct ceph_nfs_confh. This is wrong, it should return dentry that
corresponds to the 'parent_ino' field.
Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Reviewed-by: Sage Weil <sage@inktank.com>
Diffstat (limited to 'fs/ceph/export.c')
-rw-r--r-- | fs/ceph/export.c | 42 |
1 files changed, 9 insertions, 33 deletions
diff --git a/fs/ceph/export.c b/fs/ceph/export.c index 9c28b6abe885..eb66408ff236 100644 --- a/fs/ceph/export.c +++ b/fs/ceph/export.c | |||
@@ -181,48 +181,24 @@ struct dentry *ceph_get_parent(struct dentry *child) | |||
181 | } | 181 | } |
182 | 182 | ||
183 | /* | 183 | /* |
184 | * get parent, if possible. | 184 | * convert regular fh to parent |
185 | * | ||
186 | * FIXME: we could do better by querying the mds to discover the | ||
187 | * parent. | ||
188 | */ | 185 | */ |
189 | static struct dentry *ceph_fh_to_parent(struct super_block *sb, | 186 | static struct dentry *ceph_fh_to_parent(struct super_block *sb, |
190 | struct fid *fid, | 187 | struct fid *fid, |
191 | int fh_len, int fh_type) | 188 | int fh_len, int fh_type) |
192 | { | 189 | { |
193 | struct ceph_nfs_confh *cfh = (void *)fid->raw; | 190 | struct ceph_nfs_confh *cfh = (void *)fid->raw; |
194 | struct ceph_vino vino; | ||
195 | struct inode *inode; | ||
196 | struct dentry *dentry; | 191 | struct dentry *dentry; |
197 | int err; | ||
198 | 192 | ||
199 | if (fh_type == 1) | 193 | if (fh_type != FILEID_INO32_GEN_PARENT) |
200 | return ERR_PTR(-ESTALE); | 194 | return NULL; |
201 | if (fh_len < sizeof(*cfh) / 4) | 195 | if (fh_len < sizeof(*cfh) / 4) |
202 | return ERR_PTR(-ESTALE); | 196 | return NULL; |
203 | |||
204 | pr_debug("fh_to_parent %llx/%d\n", cfh->parent_ino, | ||
205 | cfh->parent_name_hash); | ||
206 | |||
207 | vino.ino = cfh->ino; | ||
208 | vino.snap = CEPH_NOSNAP; | ||
209 | inode = ceph_find_inode(sb, vino); | ||
210 | if (!inode) | ||
211 | return ERR_PTR(-ESTALE); | ||
212 | 197 | ||
213 | dentry = d_obtain_alias(inode); | 198 | dout("fh_to_parent %llx\n", cfh->parent_ino); |
214 | if (IS_ERR(dentry)) { | 199 | dentry = __get_parent(sb, NULL, cfh->ino); |
215 | pr_err("fh_to_parent %llx -- inode %p but ENOMEM\n", | 200 | if (IS_ERR(dentry) && PTR_ERR(dentry) == -ENOENT) |
216 | cfh->ino, inode); | 201 | dentry = __fh_to_dentry(sb, cfh->parent_ino); |
217 | iput(inode); | ||
218 | return dentry; | ||
219 | } | ||
220 | err = ceph_init_dentry(dentry); | ||
221 | if (err < 0) { | ||
222 | iput(inode); | ||
223 | return ERR_PTR(err); | ||
224 | } | ||
225 | dout("fh_to_parent %llx %p dentry %p\n", cfh->ino, inode, dentry); | ||
226 | return dentry; | 202 | return dentry; |
227 | } | 203 | } |
228 | 204 | ||