aboutsummaryrefslogtreecommitdiffstats
path: root/fs/exportfs/expfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/exportfs/expfs.c')
-rw-r--r--fs/exportfs/expfs.c41
1 files changed, 25 insertions, 16 deletions
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 352465312398..109ab5e44eca 100644
--- a/fs/exportfs/expfs.c
+++ b/fs/exportfs/expfs.c
@@ -1,4 +1,13 @@
1 1/*
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
9 * take a look at Documentation/filesystems/Exporting.
10 */
2#include <linux/exportfs.h> 11#include <linux/exportfs.h>
3#include <linux/fs.h> 12#include <linux/fs.h>
4#include <linux/file.h> 13#include <linux/file.h>
@@ -9,19 +18,19 @@
9#define dprintk(fmt, args...) do{}while(0) 18#define dprintk(fmt, args...) do{}while(0)
10 19
11 20
12static int get_name(struct dentry *dentry, char *name, 21static int get_name(struct vfsmount *mnt, struct dentry *dentry, char *name,
13 struct dentry *child); 22 struct dentry *child);
14 23
15 24
16static int exportfs_get_name(struct dentry *dir, char *name, 25static int exportfs_get_name(struct vfsmount *mnt, struct dentry *dir,
17 struct dentry *child) 26 char *name, struct dentry *child)
18{ 27{
19 const struct export_operations *nop = dir->d_sb->s_export_op; 28 const struct export_operations *nop = dir->d_sb->s_export_op;
20 29
21 if (nop->get_name) 30 if (nop->get_name)
22 return nop->get_name(dir, name, child); 31 return nop->get_name(dir, name, child);
23 else 32 else
24 return get_name(dir, name, child); 33 return get_name(mnt, dir, name, child);
25} 34}
26 35
27/* 36/*
@@ -85,7 +94,7 @@ find_disconnected_root(struct dentry *dentry)
85 * It may already be, as the flag isn't always updated when connection happens. 94 * It may already be, as the flag isn't always updated when connection happens.
86 */ 95 */
87static int 96static int
88reconnect_path(struct super_block *sb, struct dentry *target_dir) 97reconnect_path(struct vfsmount *mnt, struct dentry *target_dir)
89{ 98{
90 char nbuf[NAME_MAX+1]; 99 char nbuf[NAME_MAX+1];
91 int noprogress = 0; 100 int noprogress = 0;
@@ -108,7 +117,7 @@ reconnect_path(struct super_block *sb, struct dentry *target_dir)
108 pd->d_flags &= ~DCACHE_DISCONNECTED; 117 pd->d_flags &= ~DCACHE_DISCONNECTED;
109 spin_unlock(&pd->d_lock); 118 spin_unlock(&pd->d_lock);
110 noprogress = 0; 119 noprogress = 0;
111 } else if (pd == sb->s_root) { 120 } else if (pd == mnt->mnt_sb->s_root) {
112 printk(KERN_ERR "export: Eeek filesystem root is not connected, impossible\n"); 121 printk(KERN_ERR "export: Eeek filesystem root is not connected, impossible\n");
113 spin_lock(&pd->d_lock); 122 spin_lock(&pd->d_lock);
114 pd->d_flags &= ~DCACHE_DISCONNECTED; 123 pd->d_flags &= ~DCACHE_DISCONNECTED;
@@ -134,8 +143,8 @@ reconnect_path(struct super_block *sb, struct dentry *target_dir)
134 struct dentry *npd; 143 struct dentry *npd;
135 144
136 mutex_lock(&pd->d_inode->i_mutex); 145 mutex_lock(&pd->d_inode->i_mutex);
137 if (sb->s_export_op->get_parent) 146 if (mnt->mnt_sb->s_export_op->get_parent)
138 ppd = sb->s_export_op->get_parent(pd); 147 ppd = mnt->mnt_sb->s_export_op->get_parent(pd);
139 mutex_unlock(&pd->d_inode->i_mutex); 148 mutex_unlock(&pd->d_inode->i_mutex);
140 149
141 if (IS_ERR(ppd)) { 150 if (IS_ERR(ppd)) {
@@ -148,7 +157,7 @@ reconnect_path(struct super_block *sb, struct dentry *target_dir)
148 157
149 dprintk("%s: find name of %lu in %lu\n", __FUNCTION__, 158 dprintk("%s: find name of %lu in %lu\n", __FUNCTION__,
150 pd->d_inode->i_ino, ppd->d_inode->i_ino); 159 pd->d_inode->i_ino, ppd->d_inode->i_ino);
151 err = exportfs_get_name(ppd, nbuf, pd); 160 err = exportfs_get_name(mnt, ppd, nbuf, pd);
152 if (err) { 161 if (err) {
153 dput(ppd); 162 dput(ppd);
154 dput(pd); 163 dput(pd);
@@ -238,8 +247,8 @@ static int filldir_one(void * __buf, const char * name, int len,
238 * calls readdir on the parent until it finds an entry with 247 * calls readdir on the parent until it finds an entry with
239 * the same inode number as the child, and returns that. 248 * the same inode number as the child, and returns that.
240 */ 249 */
241static int get_name(struct dentry *dentry, char *name, 250static int get_name(struct vfsmount *mnt, struct dentry *dentry,
242 struct dentry *child) 251 char *name, struct dentry *child)
243{ 252{
244 struct inode *dir = dentry->d_inode; 253 struct inode *dir = dentry->d_inode;
245 int error; 254 int error;
@@ -255,7 +264,7 @@ static int get_name(struct dentry *dentry, char *name,
255 /* 264 /*
256 * Open the directory ... 265 * Open the directory ...
257 */ 266 */
258 file = dentry_open(dget(dentry), NULL, O_RDONLY); 267 file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY);
259 error = PTR_ERR(file); 268 error = PTR_ERR(file);
260 if (IS_ERR(file)) 269 if (IS_ERR(file))
261 goto out; 270 goto out;
@@ -372,7 +381,7 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
372 * filesystem root. 381 * filesystem root.
373 */ 382 */
374 if (result->d_flags & DCACHE_DISCONNECTED) { 383 if (result->d_flags & DCACHE_DISCONNECTED) {
375 err = reconnect_path(mnt->mnt_sb, result); 384 err = reconnect_path(mnt, result);
376 if (err) 385 if (err)
377 goto err_result; 386 goto err_result;
378 } 387 }
@@ -424,7 +433,7 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
424 * connected to the filesystem root. The VFS really doesn't 433 * connected to the filesystem root. The VFS really doesn't
425 * like disconnected directories.. 434 * like disconnected directories..
426 */ 435 */
427 err = reconnect_path(mnt->mnt_sb, target_dir); 436 err = reconnect_path(mnt, target_dir);
428 if (err) { 437 if (err) {
429 dput(target_dir); 438 dput(target_dir);
430 goto err_result; 439 goto err_result;
@@ -435,7 +444,7 @@ struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
435 * dentry for the inode we're after, make sure that our 444 * dentry for the inode we're after, make sure that our
436 * inode is actually connected to the parent. 445 * inode is actually connected to the parent.
437 */ 446 */
438 err = exportfs_get_name(target_dir, nbuf, result); 447 err = exportfs_get_name(mnt, target_dir, nbuf, result);
439 if (!err) { 448 if (!err) {
440 mutex_lock(&target_dir->d_inode->i_mutex); 449 mutex_lock(&target_dir->d_inode->i_mutex);
441 nresult = lookup_one_len(nbuf, target_dir, 450 nresult = lookup_one_len(nbuf, target_dir,