blob: d32ead9026f0568ffb340175017515cd64b63078 [file] [log] [blame]
Christoph Hellwige38f9812007-10-21 16:42:19 -07001/*
2 * Copyright (C) Neil Brown 2002
3 * Copyright (C) Christoph Hellwig 2007
4 *
5 * This file contains the code mapping from inodes to NFS file handles,
6 * and for mapping back from file handles to dentries.
7 *
8 * For details on why we do all the strange and hairy things in here
J. Bruce Fieldsdc7a0812009-10-27 14:41:35 -04009 * take a look at Documentation/filesystems/nfs/Exporting.
Christoph Hellwige38f9812007-10-21 16:42:19 -070010 */
Christoph Hellwiga5694252007-07-17 04:04:28 -070011#include <linux/exportfs.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070012#include <linux/fs.h>
13#include <linux/file.h>
14#include <linux/module.h>
Christoph Hellwigd37065c2007-07-17 04:04:30 -070015#include <linux/mount.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070016#include <linux/namei.h>
David Howells745ca242008-11-14 10:39:22 +110017#include <linux/sched.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070018
Linus Torvalds1da177e2005-04-16 15:20:36 -070019#define dprintk(fmt, args...) do{}while(0)
20
Christoph Hellwig10f11c32007-07-17 04:04:31 -070021
Al Viro765927b2012-06-26 21:58:53 +040022static int get_name(const struct path *path, char *name, struct dentry *child);
Christoph Hellwig10f11c32007-07-17 04:04:31 -070023
24
Christoph Hellwige38f9812007-10-21 16:42:19 -070025static int exportfs_get_name(struct vfsmount *mnt, struct dentry *dir,
26 char *name, struct dentry *child)
Christoph Hellwig10f11c32007-07-17 04:04:31 -070027{
Christoph Hellwig39655162007-10-21 16:42:17 -070028 const struct export_operations *nop = dir->d_sb->s_export_op;
Al Viro765927b2012-06-26 21:58:53 +040029 struct path path = {.mnt = mnt, .dentry = dir};
Christoph Hellwig10f11c32007-07-17 04:04:31 -070030
31 if (nop->get_name)
32 return nop->get_name(dir, name, child);
33 else
Al Viro765927b2012-06-26 21:58:53 +040034 return get_name(&path, name, child);
Christoph Hellwig10f11c32007-07-17 04:04:31 -070035}
36
Christoph Hellwigfb66a192007-07-17 04:04:32 -070037/*
38 * Check if the dentry or any of it's aliases is acceptable.
39 */
Christoph Hellwige2f99012006-01-18 17:43:52 -080040static struct dentry *
41find_acceptable_alias(struct dentry *result,
42 int (*acceptable)(void *context, struct dentry *dentry),
43 void *context)
44{
45 struct dentry *dentry, *toput = NULL;
Nick Piggin873feea2011-01-07 17:50:06 +110046 struct inode *inode;
Christoph Hellwige2f99012006-01-18 17:43:52 -080047
Christoph Hellwigfb66a192007-07-17 04:04:32 -070048 if (acceptable(context, result))
49 return result;
50
Nick Piggin873feea2011-01-07 17:50:06 +110051 inode = result->d_inode;
52 spin_lock(&inode->i_lock);
Sasha Levinb67bfe02013-02-27 17:06:00 -080053 hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
Nick Piggindc0474b2011-01-07 17:49:43 +110054 dget(dentry);
Nick Piggin873feea2011-01-07 17:50:06 +110055 spin_unlock(&inode->i_lock);
Christoph Hellwige2f99012006-01-18 17:43:52 -080056 if (toput)
57 dput(toput);
58 if (dentry != result && acceptable(context, dentry)) {
59 dput(result);
60 return dentry;
61 }
Nick Piggin873feea2011-01-07 17:50:06 +110062 spin_lock(&inode->i_lock);
Christoph Hellwige2f99012006-01-18 17:43:52 -080063 toput = dentry;
64 }
Nick Piggin873feea2011-01-07 17:50:06 +110065 spin_unlock(&inode->i_lock);
Christoph Hellwige2f99012006-01-18 17:43:52 -080066
67 if (toput)
68 dput(toput);
69 return NULL;
70}
71
Christoph Hellwigdd90b502007-07-17 04:04:32 -070072/*
73 * Find root of a disconnected subtree and return a reference to it.
74 */
75static struct dentry *
76find_disconnected_root(struct dentry *dentry)
77{
78 dget(dentry);
Christoph Hellwig0461ee22010-10-13 11:56:37 -040079 while (!IS_ROOT(dentry)) {
80 struct dentry *parent = dget_parent(dentry);
81
82 if (!(parent->d_flags & DCACHE_DISCONNECTED)) {
83 dput(parent);
84 break;
85 }
86
Christoph Hellwigdd90b502007-07-17 04:04:32 -070087 dput(dentry);
88 dentry = parent;
Christoph Hellwigdd90b502007-07-17 04:04:32 -070089 }
Christoph Hellwigdd90b502007-07-17 04:04:32 -070090 return dentry;
91}
92
J. Bruce Fieldsa056cc82013-10-16 21:09:30 -040093static bool dentry_connected(struct dentry *dentry)
94{
95 dget(dentry);
96 while (dentry->d_flags & DCACHE_DISCONNECTED) {
97 struct dentry *parent = dget_parent(dentry);
98
99 dput(dentry);
100 if (IS_ROOT(dentry)) {
101 dput(parent);
102 return false;
103 }
104 dentry = parent;
105 }
106 dput(dentry);
107 return true;
108}
109
J. Bruce Fields0dbc0182013-09-09 16:15:13 -0400110static void clear_disconnected(struct dentry *dentry)
111{
112 dget(dentry);
113 while (dentry->d_flags & DCACHE_DISCONNECTED) {
114 struct dentry *parent = dget_parent(dentry);
115
116 WARN_ON_ONCE(IS_ROOT(dentry));
117
118 spin_lock(&dentry->d_lock);
119 dentry->d_flags &= ~DCACHE_DISCONNECTED;
120 spin_unlock(&dentry->d_lock);
121
122 dput(dentry);
123 dentry = parent;
124 }
125 dput(dentry);
126}
127
Christoph Hellwig019ab802007-07-17 04:04:33 -0700128/*
J. Bruce Fieldsbbf7a8a2013-10-17 11:13:00 -0400129 * Reconnect a directory dentry with its parent.
130 *
131 * This can return a dentry, or NULL, or an error.
132 *
133 * In the first case the returned dentry is the parent of the given
134 * dentry, and may itself need to be reconnected to its parent.
135 *
136 * In the NULL case, a concurrent VFS operation has either renamed or
137 * removed this directory. The concurrent operation has reconnected our
138 * dentry, so we no longer need to.
139 */
140static struct dentry *reconnect_one(struct vfsmount *mnt,
141 struct dentry *dentry, char *nbuf)
142{
143 struct dentry *parent;
144 struct dentry *tmp;
145 int err;
146
147 parent = ERR_PTR(-EACCES);
148 mutex_lock(&dentry->d_inode->i_mutex);
149 if (mnt->mnt_sb->s_export_op->get_parent)
150 parent = mnt->mnt_sb->s_export_op->get_parent(dentry);
151 mutex_unlock(&dentry->d_inode->i_mutex);
152
153 if (IS_ERR(parent)) {
154 dprintk("%s: get_parent of %ld failed, err %d\n",
155 __func__, dentry->d_inode->i_ino, PTR_ERR(parent));
156 return parent;
157 }
158
159 dprintk("%s: find name of %lu in %lu\n", __func__,
160 dentry->d_inode->i_ino, parent->d_inode->i_ino);
161 err = exportfs_get_name(mnt, parent, nbuf, dentry);
162 if (err == -ENOENT)
163 goto out_reconnected;
164 if (err)
165 goto out_err;
166 dprintk("%s: found name: %s\n", __func__, nbuf);
167 mutex_lock(&parent->d_inode->i_mutex);
168 tmp = lookup_one_len(nbuf, parent, strlen(nbuf));
169 mutex_unlock(&parent->d_inode->i_mutex);
170 if (IS_ERR(tmp)) {
171 dprintk("%s: lookup failed: %d\n", __func__, PTR_ERR(tmp));
172 goto out_err;
173 }
174 if (tmp != dentry) {
175 dput(tmp);
176 goto out_reconnected;
177 }
178 dput(tmp);
179 if (IS_ROOT(dentry)) {
180 err = -ESTALE;
181 goto out_err;
182 }
183 return parent;
184
185out_err:
186 dput(parent);
187 return ERR_PTR(err);
188out_reconnected:
189 dput(parent);
190 /*
191 * Someone must have renamed our entry into another parent, in
192 * which case it has been reconnected by the rename.
193 *
194 * Or someone removed it entirely, in which case filehandle
195 * lookup will succeed but the directory is now IS_DEAD and
196 * subsequent operations on it will fail.
197 *
198 * Alternatively, maybe there was no race at all, and the
199 * filesystem is just corrupt and gave us a parent that doesn't
200 * actually contain any entry pointing to this inode. So,
201 * double check that this worked and return -ESTALE if not:
202 */
203 if (!dentry_connected(dentry))
204 return ERR_PTR(-ESTALE);
205 return NULL;
206}
207
208/*
Christoph Hellwig019ab802007-07-17 04:04:33 -0700209 * Make sure target_dir is fully connected to the dentry tree.
210 *
J. Bruce Fields78cee9a2013-10-22 20:59:19 -0400211 * On successful return, DCACHE_DISCONNECTED will be cleared on
212 * target_dir, and target_dir->d_parent->...->d_parent will reach the
213 * root of the filesystem.
214 *
215 * Whenever DCACHE_DISCONNECTED is unset, target_dir is fully connected.
216 * But the converse is not true: target_dir may have DCACHE_DISCONNECTED
217 * set but already be connected. In that case we'll verify the
218 * connection to root and then clear the flag.
219 *
220 * Note that target_dir could be removed by a concurrent operation. In
221 * that case reconnect_path may still succeed with target_dir fully
222 * connected, but further operations using the filehandle will fail when
223 * necessary (due to S_DEAD being set on the directory).
Christoph Hellwig019ab802007-07-17 04:04:33 -0700224 */
225static int
Al Virof3f8e172008-08-11 12:39:47 -0400226reconnect_path(struct vfsmount *mnt, struct dentry *target_dir, char *nbuf)
Christoph Hellwig019ab802007-07-17 04:04:33 -0700227{
Christoph Hellwig019ab802007-07-17 04:04:33 -0700228 int err = -ESTALE;
229
J. Bruce Fieldse4b70eb2013-10-16 21:20:19 -0400230 while (target_dir->d_flags & DCACHE_DISCONNECTED) {
Christoph Hellwig019ab802007-07-17 04:04:33 -0700231 struct dentry *pd = find_disconnected_root(target_dir);
232
Christoph Hellwig854ff5c2013-10-16 15:48:53 -0400233 BUG_ON(pd == mnt->mnt_sb->s_root);
234
Christoph Hellwig019ab802007-07-17 04:04:33 -0700235 if (!IS_ROOT(pd)) {
236 /* must have found a connected parent - great */
J. Bruce Fields0dbc0182013-09-09 16:15:13 -0400237 clear_disconnected(target_dir);
238 dput(pd);
239 break;
Christoph Hellwig019ab802007-07-17 04:04:33 -0700240 } else {
J. Bruce Fieldsbbf7a8a2013-10-17 11:13:00 -0400241 struct dentry *parent;
Christoph Hellwig019ab802007-07-17 04:04:33 -0700242 /*
243 * We have hit the top of a disconnected path, try to
244 * find parent and connect.
Christoph Hellwig019ab802007-07-17 04:04:33 -0700245 */
J. Bruce Fieldsbbf7a8a2013-10-17 11:13:00 -0400246 parent = reconnect_one(mnt, pd, nbuf);
247 if (!parent)
J. Bruce Fieldsa056cc82013-10-16 21:09:30 -0400248 goto out_reconnected;
J. Bruce Fieldsbbf7a8a2013-10-17 11:13:00 -0400249 if (IS_ERR(parent)) {
250 err = PTR_ERR(parent);
Christoph Hellwig019ab802007-07-17 04:04:33 -0700251 break;
252 }
J. Bruce Fieldsbbf7a8a2013-10-17 11:13:00 -0400253 dput(parent);
Christoph Hellwig019ab802007-07-17 04:04:33 -0700254 }
255 dput(pd);
256 }
257
258 if (target_dir->d_flags & DCACHE_DISCONNECTED) {
259 /* something went wrong - oh-well */
260 if (!err)
261 err = -ESTALE;
262 return err;
263 }
264
265 return 0;
J. Bruce Fieldsa056cc82013-10-16 21:09:30 -0400266out_reconnected:
J. Bruce Fieldsa056cc82013-10-16 21:09:30 -0400267 clear_disconnected(target_dir);
268 return 0;
Christoph Hellwig019ab802007-07-17 04:04:33 -0700269}
270
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271struct getdents_callback {
Al Viro5c0ba4e2013-05-15 13:52:59 -0400272 struct dir_context ctx;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 char *name; /* name that was found. It already points to a
274 buffer NAME_MAX+1 is size */
J. Bruce Fields950ee952013-09-10 11:41:12 -0400275 u64 ino; /* the inum we are looking for */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276 int found; /* inode matched? */
277 int sequence; /* sequence counter */
278};
279
280/*
281 * A rather strange filldir function to capture
282 * the name matching the specified inode number.
283 */
284static int filldir_one(void * __buf, const char * name, int len,
David Howellsafefdbb2006-10-03 01:13:46 -0700285 loff_t pos, u64 ino, unsigned int d_type)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286{
287 struct getdents_callback *buf = __buf;
288 int result = 0;
289
290 buf->sequence++;
Al Virodfc59e2c2013-09-06 16:55:36 -0400291 if (buf->ino == ino && len <= NAME_MAX) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700292 memcpy(buf->name, name, len);
293 buf->name[len] = '\0';
294 buf->found = 1;
295 result = -1;
296 }
297 return result;
298}
299
300/**
301 * get_name - default export_operations->get_name function
302 * @dentry: the directory in which to find a name
303 * @name: a pointer to a %NAME_MAX+1 char buffer to store the name
304 * @child: the dentry for the child directory.
305 *
306 * calls readdir on the parent until it finds an entry with
307 * the same inode number as the child, and returns that.
308 */
Al Viro765927b2012-06-26 21:58:53 +0400309static int get_name(const struct path *path, char *name, struct dentry *child)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700310{
David Howells745ca242008-11-14 10:39:22 +1100311 const struct cred *cred = current_cred();
Al Viro765927b2012-06-26 21:58:53 +0400312 struct inode *dir = path->dentry->d_inode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700313 int error;
314 struct file *file;
J. Bruce Fields950ee952013-09-10 11:41:12 -0400315 struct kstat stat;
316 struct path child_path = {
317 .mnt = path->mnt,
318 .dentry = child,
319 };
Al Viroac6614b2013-05-22 22:22:04 -0400320 struct getdents_callback buffer = {
321 .ctx.actor = filldir_one,
322 .name = name,
Al Viroac6614b2013-05-22 22:22:04 -0400323 };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700324
325 error = -ENOTDIR;
326 if (!dir || !S_ISDIR(dir->i_mode))
327 goto out;
328 error = -EINVAL;
329 if (!dir->i_fop)
330 goto out;
331 /*
J. Bruce Fields950ee952013-09-10 11:41:12 -0400332 * inode->i_ino is unsigned long, kstat->ino is u64, so the
333 * former would be insufficient on 32-bit hosts when the
334 * filesystem supports 64-bit inode numbers. So we need to
335 * actually call ->getattr, not just read i_ino:
336 */
337 error = vfs_getattr_nosec(&child_path, &stat);
338 if (error)
339 return error;
340 buffer.ino = stat.ino;
341 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 * Open the directory ...
343 */
Al Viro765927b2012-06-26 21:58:53 +0400344 file = dentry_open(path, O_RDONLY, cred);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700345 error = PTR_ERR(file);
346 if (IS_ERR(file))
347 goto out;
348
349 error = -EINVAL;
Al Viro2233f312013-05-22 21:44:23 -0400350 if (!file->f_op->iterate)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 goto out_close;
352
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 buffer.sequence = 0;
354 while (1) {
355 int old_seq = buffer.sequence;
356
Al Viro5c0ba4e2013-05-15 13:52:59 -0400357 error = iterate_dir(file, &buffer.ctx);
Al Viro53c9c5c2008-08-24 07:29:52 -0400358 if (buffer.found) {
359 error = 0;
360 break;
361 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362
363 if (error < 0)
364 break;
365
Linus Torvalds1da177e2005-04-16 15:20:36 -0700366 error = -ENOENT;
367 if (old_seq == buffer.sequence)
368 break;
369 }
370
371out_close:
372 fput(file);
373out:
374 return error;
375}
376
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377/**
378 * export_encode_fh - default export_operations->encode_fh function
Al Virob0b03822012-04-02 14:34:06 -0400379 * @inode: the object to encode
Linus Torvalds1da177e2005-04-16 15:20:36 -0700380 * @fh: where to store the file handle fragment
381 * @max_len: maximum length to store there
Al Virob0b03822012-04-02 14:34:06 -0400382 * @parent: parent directory inode, if wanted
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 *
384 * This default encode_fh function assumes that the 32 inode number
385 * is suitable for locating an inode, and that the generation number
386 * can be used to check that it is still valid. It places them in the
387 * filehandle fragment where export_decode_fh expects to find them.
388 */
Al Virob0b03822012-04-02 14:34:06 -0400389static int export_encode_fh(struct inode *inode, struct fid *fid,
390 int *max_len, struct inode *parent)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700391{
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 int len = *max_len;
Christoph Hellwig6e91ea22007-10-21 16:42:03 -0700393 int type = FILEID_INO32_GEN;
Aneesh Kumar K.V5fe0c232011-01-29 18:43:25 +0530394
Al Virob0b03822012-04-02 14:34:06 -0400395 if (parent && (len < 4)) {
Aneesh Kumar K.V5fe0c232011-01-29 18:43:25 +0530396 *max_len = 4;
Namjae Jeon216b6cb2012-08-29 10:10:10 -0400397 return FILEID_INVALID;
Aneesh Kumar K.V5fe0c232011-01-29 18:43:25 +0530398 } else if (len < 2) {
399 *max_len = 2;
Namjae Jeon216b6cb2012-08-29 10:10:10 -0400400 return FILEID_INVALID;
Aneesh Kumar K.V5fe0c232011-01-29 18:43:25 +0530401 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
403 len = 2;
Christoph Hellwig6e91ea22007-10-21 16:42:03 -0700404 fid->i32.ino = inode->i_ino;
405 fid->i32.gen = inode->i_generation;
Al Virob0b03822012-04-02 14:34:06 -0400406 if (parent) {
Christoph Hellwig6e91ea22007-10-21 16:42:03 -0700407 fid->i32.parent_ino = parent->i_ino;
408 fid->i32.parent_gen = parent->i_generation;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409 len = 4;
Christoph Hellwig6e91ea22007-10-21 16:42:03 -0700410 type = FILEID_INO32_GEN_PARENT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 }
412 *max_len = len;
413 return type;
414}
415
Cyrill Gorcunov711c7bf2012-12-17 16:05:08 -0800416int exportfs_encode_inode_fh(struct inode *inode, struct fid *fid,
417 int *max_len, struct inode *parent)
418{
419 const struct export_operations *nop = inode->i_sb->s_export_op;
420
421 if (nop && nop->encode_fh)
422 return nop->encode_fh(inode, fid->raw, max_len, parent);
423
424 return export_encode_fh(inode, fid, max_len, parent);
425}
426EXPORT_SYMBOL_GPL(exportfs_encode_inode_fh);
427
Christoph Hellwig6e91ea22007-10-21 16:42:03 -0700428int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, int *max_len,
Christoph Hellwigd37065c2007-07-17 04:04:30 -0700429 int connectable)
430{
Christoph Hellwig10f11c32007-07-17 04:04:31 -0700431 int error;
Al Virob0b03822012-04-02 14:34:06 -0400432 struct dentry *p = NULL;
433 struct inode *inode = dentry->d_inode, *parent = NULL;
Christoph Hellwigd37065c2007-07-17 04:04:30 -0700434
Al Virob0b03822012-04-02 14:34:06 -0400435 if (connectable && !S_ISDIR(inode->i_mode)) {
436 p = dget_parent(dentry);
437 /*
438 * note that while p might've ceased to be our parent already,
439 * it's still pinned by and still positive.
440 */
441 parent = p->d_inode;
442 }
Cyrill Gorcunov711c7bf2012-12-17 16:05:08 -0800443
444 error = exportfs_encode_inode_fh(inode, fid, max_len, parent);
Al Virob0b03822012-04-02 14:34:06 -0400445 dput(p);
Christoph Hellwig10f11c32007-07-17 04:04:31 -0700446
447 return error;
Christoph Hellwigd37065c2007-07-17 04:04:30 -0700448}
449EXPORT_SYMBOL_GPL(exportfs_encode_fh);
450
Christoph Hellwig6e91ea22007-10-21 16:42:03 -0700451struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
452 int fh_len, int fileid_type,
453 int (*acceptable)(void *, struct dentry *), void *context)
Christoph Hellwigd37065c2007-07-17 04:04:30 -0700454{
Christoph Hellwig39655162007-10-21 16:42:17 -0700455 const struct export_operations *nop = mnt->mnt_sb->s_export_op;
Christoph Hellwig25961102007-10-21 16:42:05 -0700456 struct dentry *result, *alias;
Al Virof3f8e172008-08-11 12:39:47 -0400457 char nbuf[NAME_MAX+1];
Christoph Hellwig25961102007-10-21 16:42:05 -0700458 int err;
Christoph Hellwigd37065c2007-07-17 04:04:30 -0700459
Christoph Hellwig25961102007-10-21 16:42:05 -0700460 /*
Christoph Hellwig25961102007-10-21 16:42:05 -0700461 * Try to get any dentry for the given file handle from the filesystem.
462 */
Aneesh Kumar K.Vbecfd1f2011-01-29 18:43:26 +0530463 if (!nop || !nop->fh_to_dentry)
464 return ERR_PTR(-ESTALE);
Christoph Hellwig25961102007-10-21 16:42:05 -0700465 result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type);
J. Bruce Fieldsa4f4d6d2008-12-08 18:24:18 -0500466 if (!result)
467 result = ERR_PTR(-ESTALE);
Christoph Hellwig25961102007-10-21 16:42:05 -0700468 if (IS_ERR(result))
469 return result;
470
471 if (S_ISDIR(result->d_inode->i_mode)) {
472 /*
473 * This request is for a directory.
474 *
475 * On the positive side there is only one dentry for each
476 * directory inode. On the negative side this implies that we
477 * to ensure our dentry is connected all the way up to the
478 * filesystem root.
479 */
480 if (result->d_flags & DCACHE_DISCONNECTED) {
Al Virof3f8e172008-08-11 12:39:47 -0400481 err = reconnect_path(mnt, result, nbuf);
Christoph Hellwig25961102007-10-21 16:42:05 -0700482 if (err)
483 goto err_result;
484 }
485
486 if (!acceptable(context, result)) {
487 err = -EACCES;
488 goto err_result;
489 }
490
491 return result;
492 } else {
493 /*
494 * It's not a directory. Life is a little more complicated.
495 */
496 struct dentry *target_dir, *nresult;
Christoph Hellwig25961102007-10-21 16:42:05 -0700497
498 /*
499 * See if either the dentry we just got from the filesystem
500 * or any alias for it is acceptable. This is always true
501 * if this filesystem is exported without the subtreecheck
502 * option. If the filesystem is exported with the subtree
503 * check option there's a fair chance we need to look at
504 * the parent directory in the file handle and make sure
505 * it's connected to the filesystem root.
506 */
507 alias = find_acceptable_alias(result, acceptable, context);
508 if (alias)
509 return alias;
510
511 /*
512 * Try to extract a dentry for the parent directory from the
513 * file handle. If this fails we'll have to give up.
514 */
515 err = -ESTALE;
516 if (!nop->fh_to_parent)
517 goto err_result;
518
519 target_dir = nop->fh_to_parent(mnt->mnt_sb, fid,
520 fh_len, fileid_type);
J. Bruce Fieldsa4f4d6d2008-12-08 18:24:18 -0500521 if (!target_dir)
522 goto err_result;
Christoph Hellwig25961102007-10-21 16:42:05 -0700523 err = PTR_ERR(target_dir);
524 if (IS_ERR(target_dir))
525 goto err_result;
526
527 /*
528 * And as usual we need to make sure the parent directory is
529 * connected to the filesystem root. The VFS really doesn't
530 * like disconnected directories..
531 */
Al Virof3f8e172008-08-11 12:39:47 -0400532 err = reconnect_path(mnt, target_dir, nbuf);
Christoph Hellwig25961102007-10-21 16:42:05 -0700533 if (err) {
534 dput(target_dir);
535 goto err_result;
536 }
537
538 /*
539 * Now that we've got both a well-connected parent and a
540 * dentry for the inode we're after, make sure that our
541 * inode is actually connected to the parent.
542 */
Christoph Hellwige38f9812007-10-21 16:42:19 -0700543 err = exportfs_get_name(mnt, target_dir, nbuf, result);
Christoph Hellwig25961102007-10-21 16:42:05 -0700544 if (!err) {
545 mutex_lock(&target_dir->d_inode->i_mutex);
546 nresult = lookup_one_len(nbuf, target_dir,
547 strlen(nbuf));
548 mutex_unlock(&target_dir->d_inode->i_mutex);
549 if (!IS_ERR(nresult)) {
550 if (nresult->d_inode) {
551 dput(result);
552 result = nresult;
553 } else
554 dput(nresult);
555 }
556 }
557
558 /*
559 * At this point we are done with the parent, but it's pinned
560 * by the child dentry anyway.
561 */
562 dput(target_dir);
563
564 /*
565 * And finally make sure the dentry is actually acceptable
566 * to NFSD.
567 */
568 alias = find_acceptable_alias(result, acceptable, context);
569 if (!alias) {
570 err = -EACCES;
571 goto err_result;
572 }
573
574 return alias;
575 }
576
577 err_result:
578 dput(result);
579 return ERR_PTR(err);
Christoph Hellwigd37065c2007-07-17 04:04:30 -0700580}
581EXPORT_SYMBOL_GPL(exportfs_decode_fh);
582
Linus Torvalds1da177e2005-04-16 15:20:36 -0700583MODULE_LICENSE("GPL");