aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/buffer.c3
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/export.c2
-rw-r--r--fs/dcache.c4
-rw-r--r--fs/debugfs/inode.c2
-rw-r--r--fs/ecryptfs/crypto.c16
-rw-r--r--fs/ecryptfs/keystore.c3
-rw-r--r--fs/efs/namei.c36
-rw-r--r--fs/efs/super.c5
-rw-r--r--fs/exportfs/expfs.c360
-rw-r--r--fs/ext2/dir.c44
-rw-r--r--fs/ext2/super.c36
-rw-r--r--fs/ext3/super.c37
-rw-r--r--fs/ext4/super.c37
-rw-r--r--fs/fat/inode.c26
-rw-r--r--fs/gfs2/ops_export.c83
-rw-r--r--fs/gfs2/ops_fstype.h2
-rw-r--r--fs/inotify.c43
-rw-r--r--fs/isofs/export.c69
-rw-r--r--fs/isofs/isofs.h2
-rw-r--r--fs/jfs/jfs_inode.h7
-rw-r--r--fs/jfs/namei.c35
-rw-r--r--fs/jfs/super.c7
-rw-r--r--fs/libfs.c88
-rw-r--r--fs/namei.c10
-rw-r--r--fs/namespace.c22
-rw-r--r--fs/nfs/proc.c1
-rw-r--r--fs/nfs/unlink.c2
-rw-r--r--fs/nfsd/export.c8
-rw-r--r--fs/nfsd/nfs4recover.c8
-rw-r--r--fs/nfsd/nfsfh.c67
-rw-r--r--fs/ntfs/namei.c77
-rw-r--r--fs/ntfs/ntfs.h2
-rw-r--r--fs/ocfs2/export.c67
-rw-r--r--fs/ocfs2/export.h2
-rw-r--r--fs/open.c4
-rw-r--r--fs/pnode.h1
-rw-r--r--fs/proc/base.c46
-rw-r--r--fs/reiserfs/inode.c62
-rw-r--r--fs/reiserfs/super.c6
-rw-r--r--fs/xattr.c8
-rw-r--r--fs/xfs/linux-2.6/xfs_export.c206
-rw-r--r--fs/xfs/linux-2.6/xfs_export.h50
-rw-r--r--fs/xfs/linux-2.6/xfs_super.h2
44 files changed, 851 insertions, 749 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index 76403b1764c5..7249e014819e 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2563,7 +2563,7 @@ int nobh_write_end(struct file *file, struct address_space *mapping,
2563 struct page *page, void *fsdata) 2563 struct page *page, void *fsdata)
2564{ 2564{
2565 struct inode *inode = page->mapping->host; 2565 struct inode *inode = page->mapping->host;
2566 struct buffer_head *head = NULL; 2566 struct buffer_head *head = fsdata;
2567 struct buffer_head *bh; 2567 struct buffer_head *bh;
2568 2568
2569 if (!PageMappedToDisk(page)) { 2569 if (!PageMappedToDisk(page)) {
@@ -2584,7 +2584,6 @@ int nobh_write_end(struct file *file, struct address_space *mapping,
2584 unlock_page(page); 2584 unlock_page(page);
2585 page_cache_release(page); 2585 page_cache_release(page);
2586 2586
2587 head = fsdata;
2588 while (head) { 2587 while (head) {
2589 bh = head; 2588 bh = head;
2590 head = head->b_this_page; 2589 head = head->b_this_page;
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 0a3ee5a322b0..5574ba3ab1f9 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -103,7 +103,7 @@ extern int cifs_ioctl(struct inode *inode, struct file *filep,
103 unsigned int command, unsigned long arg); 103 unsigned int command, unsigned long arg);
104 104
105#ifdef CONFIG_CIFS_EXPERIMENTAL 105#ifdef CONFIG_CIFS_EXPERIMENTAL
106extern struct export_operations cifs_export_ops; 106extern const struct export_operations cifs_export_ops;
107#endif /* EXPERIMENTAL */ 107#endif /* EXPERIMENTAL */
108 108
109#define CIFS_VERSION "1.51" 109#define CIFS_VERSION "1.51"
diff --git a/fs/cifs/export.c b/fs/cifs/export.c
index d614b91caeca..75949d6a5f1b 100644
--- a/fs/cifs/export.c
+++ b/fs/cifs/export.c
@@ -53,7 +53,7 @@ static struct dentry *cifs_get_parent(struct dentry *dentry)
53 return ERR_PTR(-EACCES); 53 return ERR_PTR(-EACCES);
54} 54}
55 55
56struct export_operations cifs_export_ops = { 56const struct export_operations cifs_export_ops = {
57 .get_parent = cifs_get_parent, 57 .get_parent = cifs_get_parent,
58/* Following five export operations are unneeded so far and can default: 58/* Following five export operations are unneeded so far and can default:
59 .get_dentry = 59 .get_dentry =
diff --git a/fs/dcache.c b/fs/dcache.c
index 5489b2d98a00..d9ca1e5ceb92 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -38,7 +38,7 @@ int sysctl_vfs_cache_pressure __read_mostly = 100;
38EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); 38EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure);
39 39
40 __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock); 40 __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock);
41static __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock); 41__cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
42 42
43EXPORT_SYMBOL(dcache_lock); 43EXPORT_SYMBOL(dcache_lock);
44 44
@@ -1479,6 +1479,8 @@ static void switch_names(struct dentry *dentry, struct dentry *target)
1479 * dentry:internal, target:external. Steal target's 1479 * dentry:internal, target:external. Steal target's
1480 * storage and make target internal. 1480 * storage and make target internal.
1481 */ 1481 */
1482 memcpy(target->d_iname, dentry->d_name.name,
1483 dentry->d_name.len + 1);
1482 dentry->d_name.name = target->d_name.name; 1484 dentry->d_name.name = target->d_name.name;
1483 target->d_name.name = target->d_iname; 1485 target->d_name.name = target->d_iname;
1484 } 1486 }
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 11be8a325e26..6a713b33992f 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -413,7 +413,7 @@ struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
413 d_move(old_dentry, dentry); 413 d_move(old_dentry, dentry);
414 fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name, 414 fsnotify_move(old_dir->d_inode, new_dir->d_inode, old_name,
415 old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode), 415 old_dentry->d_name.name, S_ISDIR(old_dentry->d_inode->i_mode),
416 NULL, old_dentry->d_inode); 416 NULL, old_dentry);
417 fsnotify_oldname_free(old_name); 417 fsnotify_oldname_free(old_name);
418 unlock_rename(new_dir, old_dir); 418 unlock_rename(new_dir, old_dir);
419 dput(dentry); 419 dput(dentry);
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 1ae90ef2c74d..0a9882edf562 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -283,7 +283,7 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
283 pg = virt_to_page(addr); 283 pg = virt_to_page(addr);
284 offset = offset_in_page(addr); 284 offset = offset_in_page(addr);
285 if (sg) { 285 if (sg) {
286 sg[i].page = pg; 286 sg_set_page(&sg[i], pg);
287 sg[i].offset = offset; 287 sg[i].offset = offset;
288 } 288 }
289 remainder_of_page = PAGE_CACHE_SIZE - offset; 289 remainder_of_page = PAGE_CACHE_SIZE - offset;
@@ -713,10 +713,13 @@ ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
713{ 713{
714 struct scatterlist src_sg, dst_sg; 714 struct scatterlist src_sg, dst_sg;
715 715
716 src_sg.page = src_page; 716 sg_init_table(&src_sg, 1);
717 sg_init_table(&dst_sg, 1);
718
719 sg_set_page(&src_sg, src_page);
717 src_sg.offset = src_offset; 720 src_sg.offset = src_offset;
718 src_sg.length = size; 721 src_sg.length = size;
719 dst_sg.page = dst_page; 722 sg_set_page(&dst_sg, dst_page);
720 dst_sg.offset = dst_offset; 723 dst_sg.offset = dst_offset;
721 dst_sg.length = size; 724 dst_sg.length = size;
722 return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv); 725 return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
@@ -742,10 +745,13 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
742{ 745{
743 struct scatterlist src_sg, dst_sg; 746 struct scatterlist src_sg, dst_sg;
744 747
745 src_sg.page = src_page; 748 sg_init_table(&src_sg, 1);
749 sg_init_table(&dst_sg, 1);
750
751 sg_set_page(&src_sg, src_page);
746 src_sg.offset = src_offset; 752 src_sg.offset = src_offset;
747 src_sg.length = size; 753 src_sg.length = size;
748 dst_sg.page = dst_page; 754 sg_set_page(&dst_sg, dst_page);
749 dst_sg.offset = dst_offset; 755 dst_sg.offset = dst_offset;
750 dst_sg.length = size; 756 dst_sg.length = size;
751 return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv); 757 return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index 89d9710dd63d..263fed88c0ca 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -1040,6 +1040,9 @@ decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
1040 }; 1040 };
1041 int rc = 0; 1041 int rc = 0;
1042 1042
1043 sg_init_table(&dst_sg, 1);
1044 sg_init_table(&src_sg, 1);
1045
1043 if (unlikely(ecryptfs_verbosity > 0)) { 1046 if (unlikely(ecryptfs_verbosity > 0)) {
1044 ecryptfs_printk( 1047 ecryptfs_printk(
1045 KERN_DEBUG, "Session key encryption key (size [%d]):\n", 1048 KERN_DEBUG, "Session key encryption key (size [%d]):\n",
diff --git a/fs/efs/namei.c b/fs/efs/namei.c
index 5276b19423c1..f7f407075be1 100644
--- a/fs/efs/namei.c
+++ b/fs/efs/namei.c
@@ -10,6 +10,8 @@
10#include <linux/string.h> 10#include <linux/string.h>
11#include <linux/efs_fs.h> 11#include <linux/efs_fs.h>
12#include <linux/smp_lock.h> 12#include <linux/smp_lock.h>
13#include <linux/exportfs.h>
14
13 15
14static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) { 16static efs_ino_t efs_find_entry(struct inode *inode, const char *name, int len) {
15 struct buffer_head *bh; 17 struct buffer_head *bh;
@@ -75,13 +77,10 @@ struct dentry *efs_lookup(struct inode *dir, struct dentry *dentry, struct namei
75 return NULL; 77 return NULL;
76} 78}
77 79
78struct dentry *efs_get_dentry(struct super_block *sb, void *vobjp) 80static struct inode *efs_nfs_get_inode(struct super_block *sb, u64 ino,
81 u32 generation)
79{ 82{
80 __u32 *objp = vobjp;
81 unsigned long ino = objp[0];
82 __u32 generation = objp[1];
83 struct inode *inode; 83 struct inode *inode;
84 struct dentry *result;
85 84
86 if (ino == 0) 85 if (ino == 0)
87 return ERR_PTR(-ESTALE); 86 return ERR_PTR(-ESTALE);
@@ -91,20 +90,25 @@ struct dentry *efs_get_dentry(struct super_block *sb, void *vobjp)
91 90
92 if (is_bad_inode(inode) || 91 if (is_bad_inode(inode) ||
93 (generation && inode->i_generation != generation)) { 92 (generation && inode->i_generation != generation)) {
94 result = ERR_PTR(-ESTALE); 93 iput(inode);
95 goto out_iput; 94 return ERR_PTR(-ESTALE);
96 } 95 }
97 96
98 result = d_alloc_anon(inode); 97 return inode;
99 if (!result) { 98}
100 result = ERR_PTR(-ENOMEM);
101 goto out_iput;
102 }
103 return result;
104 99
105 out_iput: 100struct dentry *efs_fh_to_dentry(struct super_block *sb, struct fid *fid,
106 iput(inode); 101 int fh_len, int fh_type)
107 return result; 102{
103 return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
104 efs_nfs_get_inode);
105}
106
107struct dentry *efs_fh_to_parent(struct super_block *sb, struct fid *fid,
108 int fh_len, int fh_type)
109{
110 return generic_fh_to_parent(sb, fid, fh_len, fh_type,
111 efs_nfs_get_inode);
108} 112}
109 113
110struct dentry *efs_get_parent(struct dentry *child) 114struct dentry *efs_get_parent(struct dentry *child)
diff --git a/fs/efs/super.c b/fs/efs/super.c
index 25d0326c5f1c..c79bc627f107 100644
--- a/fs/efs/super.c
+++ b/fs/efs/super.c
@@ -113,8 +113,9 @@ static const struct super_operations efs_superblock_operations = {
113 .remount_fs = efs_remount, 113 .remount_fs = efs_remount,
114}; 114};
115 115
116static struct export_operations efs_export_ops = { 116static const struct export_operations efs_export_ops = {
117 .get_dentry = efs_get_dentry, 117 .fh_to_dentry = efs_fh_to_dentry,
118 .fh_to_parent = efs_fh_to_parent,
118 .get_parent = efs_get_parent, 119 .get_parent = efs_get_parent,
119}; 120};
120 121
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c
index 8adb32a9387a..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,32 +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 struct dentry *exportfs_get_dentry(struct super_block *sb, void *obj) 25static int exportfs_get_name(struct vfsmount *mnt, struct dentry *dir,
26 char *name, struct dentry *child)
17{ 27{
18 struct dentry *result = ERR_PTR(-ESTALE); 28 const struct export_operations *nop = dir->d_sb->s_export_op;
19
20 if (sb->s_export_op->get_dentry) {
21 result = sb->s_export_op->get_dentry(sb, obj);
22 if (!result)
23 result = ERR_PTR(-ESTALE);
24 }
25
26 return result;
27}
28
29static int exportfs_get_name(struct dentry *dir, char *name,
30 struct dentry *child)
31{
32 struct export_operations *nop = dir->d_sb->s_export_op;
33 29
34 if (nop->get_name) 30 if (nop->get_name)
35 return nop->get_name(dir, name, child); 31 return nop->get_name(dir, name, child);
36 else 32 else
37 return get_name(dir, name, child); 33 return get_name(mnt, dir, name, child);
38} 34}
39 35
40/* 36/*
@@ -98,7 +94,7 @@ find_disconnected_root(struct dentry *dentry)
98 * 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.
99 */ 95 */
100static int 96static int
101reconnect_path(struct super_block *sb, struct dentry *target_dir) 97reconnect_path(struct vfsmount *mnt, struct dentry *target_dir)
102{ 98{
103 char nbuf[NAME_MAX+1]; 99 char nbuf[NAME_MAX+1];
104 int noprogress = 0; 100 int noprogress = 0;
@@ -121,7 +117,7 @@ reconnect_path(struct super_block *sb, struct dentry *target_dir)
121 pd->d_flags &= ~DCACHE_DISCONNECTED; 117 pd->d_flags &= ~DCACHE_DISCONNECTED;
122 spin_unlock(&pd->d_lock); 118 spin_unlock(&pd->d_lock);
123 noprogress = 0; 119 noprogress = 0;
124 } else if (pd == sb->s_root) { 120 } else if (pd == mnt->mnt_sb->s_root) {
125 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");
126 spin_lock(&pd->d_lock); 122 spin_lock(&pd->d_lock);
127 pd->d_flags &= ~DCACHE_DISCONNECTED; 123 pd->d_flags &= ~DCACHE_DISCONNECTED;
@@ -147,8 +143,8 @@ reconnect_path(struct super_block *sb, struct dentry *target_dir)
147 struct dentry *npd; 143 struct dentry *npd;
148 144
149 mutex_lock(&pd->d_inode->i_mutex); 145 mutex_lock(&pd->d_inode->i_mutex);
150 if (sb->s_export_op->get_parent) 146 if (mnt->mnt_sb->s_export_op->get_parent)
151 ppd = sb->s_export_op->get_parent(pd); 147 ppd = mnt->mnt_sb->s_export_op->get_parent(pd);
152 mutex_unlock(&pd->d_inode->i_mutex); 148 mutex_unlock(&pd->d_inode->i_mutex);
153 149
154 if (IS_ERR(ppd)) { 150 if (IS_ERR(ppd)) {
@@ -161,7 +157,7 @@ reconnect_path(struct super_block *sb, struct dentry *target_dir)
161 157
162 dprintk("%s: find name of %lu in %lu\n", __FUNCTION__, 158 dprintk("%s: find name of %lu in %lu\n", __FUNCTION__,
163 pd->d_inode->i_ino, ppd->d_inode->i_ino); 159 pd->d_inode->i_ino, ppd->d_inode->i_ino);
164 err = exportfs_get_name(ppd, nbuf, pd); 160 err = exportfs_get_name(mnt, ppd, nbuf, pd);
165 if (err) { 161 if (err) {
166 dput(ppd); 162 dput(ppd);
167 dput(pd); 163 dput(pd);
@@ -214,125 +210,6 @@ reconnect_path(struct super_block *sb, struct dentry *target_dir)
214 return 0; 210 return 0;
215} 211}
216 212
217/**
218 * find_exported_dentry - helper routine to implement export_operations->decode_fh
219 * @sb: The &super_block identifying the filesystem
220 * @obj: An opaque identifier of the object to be found - passed to
221 * get_inode
222 * @parent: An optional opqaue identifier of the parent of the object.
223 * @acceptable: A function used to test possible &dentries to see if they are
224 * acceptable
225 * @context: A parameter to @acceptable so that it knows on what basis to
226 * judge.
227 *
228 * find_exported_dentry is the central helper routine to enable file systems
229 * to provide the decode_fh() export_operation. It's main task is to take
230 * an &inode, find or create an appropriate &dentry structure, and possibly
231 * splice this into the dcache in the correct place.
232 *
233 * The decode_fh() operation provided by the filesystem should call
234 * find_exported_dentry() with the same parameters that it received except
235 * that instead of the file handle fragment, pointers to opaque identifiers
236 * for the object and optionally its parent are passed. The default decode_fh
237 * routine passes one pointer to the start of the filehandle fragment, and
238 * one 8 bytes into the fragment. It is expected that most filesystems will
239 * take this approach, though the offset to the parent identifier may well be
240 * different.
241 *
242 * find_exported_dentry() will call get_dentry to get an dentry pointer from
243 * the file system. If any &dentry in the d_alias list is acceptable, it will
244 * be returned. Otherwise find_exported_dentry() will attempt to splice a new
245 * &dentry into the dcache using get_name() and get_parent() to find the
246 * appropriate place.
247 */
248
249struct dentry *
250find_exported_dentry(struct super_block *sb, void *obj, void *parent,
251 int (*acceptable)(void *context, struct dentry *de),
252 void *context)
253{
254 struct dentry *result, *alias;
255 int err = -ESTALE;
256
257 /*
258 * Attempt to find the inode.
259 */
260 result = exportfs_get_dentry(sb, obj);
261 if (IS_ERR(result))
262 return result;
263
264 if (S_ISDIR(result->d_inode->i_mode)) {
265 if (!(result->d_flags & DCACHE_DISCONNECTED)) {
266 if (acceptable(context, result))
267 return result;
268 err = -EACCES;
269 goto err_result;
270 }
271
272 err = reconnect_path(sb, result);
273 if (err)
274 goto err_result;
275 } else {
276 struct dentry *target_dir, *nresult;
277 char nbuf[NAME_MAX+1];
278
279 alias = find_acceptable_alias(result, acceptable, context);
280 if (alias)
281 return alias;
282
283 if (parent == NULL)
284 goto err_result;
285
286 target_dir = exportfs_get_dentry(sb,parent);
287 if (IS_ERR(target_dir)) {
288 err = PTR_ERR(target_dir);
289 goto err_result;
290 }
291
292 err = reconnect_path(sb, target_dir);
293 if (err) {
294 dput(target_dir);
295 goto err_result;
296 }
297
298 /*
299 * As we weren't after a directory, have one more step to go.
300 */
301 err = exportfs_get_name(target_dir, nbuf, result);
302 if (!err) {
303 mutex_lock(&target_dir->d_inode->i_mutex);
304 nresult = lookup_one_len(nbuf, target_dir,
305 strlen(nbuf));
306 mutex_unlock(&target_dir->d_inode->i_mutex);
307 if (!IS_ERR(nresult)) {
308 if (nresult->d_inode) {
309 dput(result);
310 result = nresult;
311 } else
312 dput(nresult);
313 }
314 }
315 dput(target_dir);
316 }
317
318 alias = find_acceptable_alias(result, acceptable, context);
319 if (alias)
320 return alias;
321
322 /* drat - I just cannot find anything acceptable */
323 dput(result);
324 /* It might be justifiable to return ESTALE here,
325 * but the filehandle at-least looks reasonable good
326 * and it may just be a permission problem, so returning
327 * -EACCESS is safer
328 */
329 return ERR_PTR(-EACCES);
330
331 err_result:
332 dput(result);
333 return ERR_PTR(err);
334}
335
336struct getdents_callback { 213struct getdents_callback {
337 char *name; /* name that was found. It already points to a 214 char *name; /* name that was found. It already points to a
338 buffer NAME_MAX+1 is size */ 215 buffer NAME_MAX+1 is size */
@@ -370,8 +247,8 @@ static int filldir_one(void * __buf, const char * name, int len,
370 * calls readdir on the parent until it finds an entry with 247 * calls readdir on the parent until it finds an entry with
371 * the same inode number as the child, and returns that. 248 * the same inode number as the child, and returns that.
372 */ 249 */
373static int get_name(struct dentry *dentry, char *name, 250static int get_name(struct vfsmount *mnt, struct dentry *dentry,
374 struct dentry *child) 251 char *name, struct dentry *child)
375{ 252{
376 struct inode *dir = dentry->d_inode; 253 struct inode *dir = dentry->d_inode;
377 int error; 254 int error;
@@ -387,7 +264,7 @@ static int get_name(struct dentry *dentry, char *name,
387 /* 264 /*
388 * Open the directory ... 265 * Open the directory ...
389 */ 266 */
390 file = dentry_open(dget(dentry), NULL, O_RDONLY); 267 file = dentry_open(dget(dentry), mntget(mnt), O_RDONLY);
391 error = PTR_ERR(file); 268 error = PTR_ERR(file);
392 if (IS_ERR(file)) 269 if (IS_ERR(file))
393 goto out; 270 goto out;
@@ -434,100 +311,177 @@ out:
434 * can be used to check that it is still valid. It places them in the 311 * can be used to check that it is still valid. It places them in the
435 * filehandle fragment where export_decode_fh expects to find them. 312 * filehandle fragment where export_decode_fh expects to find them.
436 */ 313 */
437static int export_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, 314static int export_encode_fh(struct dentry *dentry, struct fid *fid,
438 int connectable) 315 int *max_len, int connectable)
439{ 316{
440 struct inode * inode = dentry->d_inode; 317 struct inode * inode = dentry->d_inode;
441 int len = *max_len; 318 int len = *max_len;
442 int type = 1; 319 int type = FILEID_INO32_GEN;
443 320
444 if (len < 2 || (connectable && len < 4)) 321 if (len < 2 || (connectable && len < 4))
445 return 255; 322 return 255;
446 323
447 len = 2; 324 len = 2;
448 fh[0] = inode->i_ino; 325 fid->i32.ino = inode->i_ino;
449 fh[1] = inode->i_generation; 326 fid->i32.gen = inode->i_generation;
450 if (connectable && !S_ISDIR(inode->i_mode)) { 327 if (connectable && !S_ISDIR(inode->i_mode)) {
451 struct inode *parent; 328 struct inode *parent;
452 329
453 spin_lock(&dentry->d_lock); 330 spin_lock(&dentry->d_lock);
454 parent = dentry->d_parent->d_inode; 331 parent = dentry->d_parent->d_inode;
455 fh[2] = parent->i_ino; 332 fid->i32.parent_ino = parent->i_ino;
456 fh[3] = parent->i_generation; 333 fid->i32.parent_gen = parent->i_generation;
457 spin_unlock(&dentry->d_lock); 334 spin_unlock(&dentry->d_lock);
458 len = 4; 335 len = 4;
459 type = 2; 336 type = FILEID_INO32_GEN_PARENT;
460 } 337 }
461 *max_len = len; 338 *max_len = len;
462 return type; 339 return type;
463} 340}
464 341
465 342int exportfs_encode_fh(struct dentry *dentry, struct fid *fid, int *max_len,
466/**
467 * export_decode_fh - default export_operations->decode_fh function
468 * @sb: The superblock
469 * @fh: pointer to the file handle fragment
470 * @fh_len: length of file handle fragment
471 * @acceptable: function for testing acceptability of dentrys
472 * @context: context for @acceptable
473 *
474 * This is the default decode_fh() function.
475 * a fileid_type of 1 indicates that the filehandlefragment
476 * just contains an object identifier understood by get_dentry.
477 * a fileid_type of 2 says that there is also a directory
478 * identifier 8 bytes in to the filehandlefragement.
479 */
480static struct dentry *export_decode_fh(struct super_block *sb, __u32 *fh, int fh_len,
481 int fileid_type,
482 int (*acceptable)(void *context, struct dentry *de),
483 void *context)
484{
485 __u32 parent[2];
486 parent[0] = parent[1] = 0;
487 if (fh_len < 2 || fileid_type > 2)
488 return NULL;
489 if (fileid_type == 2) {
490 if (fh_len > 2) parent[0] = fh[2];
491 if (fh_len > 3) parent[1] = fh[3];
492 }
493 return find_exported_dentry(sb, fh, parent,
494 acceptable, context);
495}
496
497int exportfs_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,
498 int connectable) 343 int connectable)
499{ 344{
500 struct export_operations *nop = dentry->d_sb->s_export_op; 345 const struct export_operations *nop = dentry->d_sb->s_export_op;
501 int error; 346 int error;
502 347
503 if (nop->encode_fh) 348 if (nop->encode_fh)
504 error = nop->encode_fh(dentry, fh, max_len, connectable); 349 error = nop->encode_fh(dentry, fid->raw, max_len, connectable);
505 else 350 else
506 error = export_encode_fh(dentry, fh, max_len, connectable); 351 error = export_encode_fh(dentry, fid, max_len, connectable);
507 352
508 return error; 353 return error;
509} 354}
510EXPORT_SYMBOL_GPL(exportfs_encode_fh); 355EXPORT_SYMBOL_GPL(exportfs_encode_fh);
511 356
512struct dentry *exportfs_decode_fh(struct vfsmount *mnt, __u32 *fh, int fh_len, 357struct dentry *exportfs_decode_fh(struct vfsmount *mnt, struct fid *fid,
513 int fileid_type, int (*acceptable)(void *, struct dentry *), 358 int fh_len, int fileid_type,
514 void *context) 359 int (*acceptable)(void *, struct dentry *), void *context)
515{ 360{
516 struct export_operations *nop = mnt->mnt_sb->s_export_op; 361 const struct export_operations *nop = mnt->mnt_sb->s_export_op;
517 struct dentry *result; 362 struct dentry *result, *alias;
363 int err;
518 364
519 if (nop->decode_fh) { 365 /*
520 result = nop->decode_fh(mnt->mnt_sb, fh, fh_len, fileid_type, 366 * Try to get any dentry for the given file handle from the filesystem.
521 acceptable, context); 367 */
368 result = nop->fh_to_dentry(mnt->mnt_sb, fid, fh_len, fileid_type);
369 if (!result)
370 result = ERR_PTR(-ESTALE);
371 if (IS_ERR(result))
372 return result;
373
374 if (S_ISDIR(result->d_inode->i_mode)) {
375 /*
376 * This request is for a directory.
377 *
378 * On the positive side there is only one dentry for each
379 * directory inode. On the negative side this implies that we
380 * to ensure our dentry is connected all the way up to the
381 * filesystem root.
382 */
383 if (result->d_flags & DCACHE_DISCONNECTED) {
384 err = reconnect_path(mnt, result);
385 if (err)
386 goto err_result;
387 }
388
389 if (!acceptable(context, result)) {
390 err = -EACCES;
391 goto err_result;
392 }
393
394 return result;
522 } else { 395 } else {
523 result = export_decode_fh(mnt->mnt_sb, fh, fh_len, fileid_type, 396 /*
524 acceptable, context); 397 * It's not a directory. Life is a little more complicated.
398 */
399 struct dentry *target_dir, *nresult;
400 char nbuf[NAME_MAX+1];
401
402 /*
403 * See if either the dentry we just got from the filesystem
404 * or any alias for it is acceptable. This is always true
405 * if this filesystem is exported without the subtreecheck
406 * option. If the filesystem is exported with the subtree
407 * check option there's a fair chance we need to look at
408 * the parent directory in the file handle and make sure
409 * it's connected to the filesystem root.
410 */
411 alias = find_acceptable_alias(result, acceptable, context);
412 if (alias)
413 return alias;
414
415 /*
416 * Try to extract a dentry for the parent directory from the
417 * file handle. If this fails we'll have to give up.
418 */
419 err = -ESTALE;
420 if (!nop->fh_to_parent)
421 goto err_result;
422
423 target_dir = nop->fh_to_parent(mnt->mnt_sb, fid,
424 fh_len, fileid_type);
425 if (!target_dir)
426 goto err_result;
427 err = PTR_ERR(target_dir);
428 if (IS_ERR(target_dir))
429 goto err_result;
430
431 /*
432 * And as usual we need to make sure the parent directory is
433 * connected to the filesystem root. The VFS really doesn't
434 * like disconnected directories..
435 */
436 err = reconnect_path(mnt, target_dir);
437 if (err) {
438 dput(target_dir);
439 goto err_result;
440 }
441
442 /*
443 * Now that we've got both a well-connected parent and a
444 * dentry for the inode we're after, make sure that our
445 * inode is actually connected to the parent.
446 */
447 err = exportfs_get_name(mnt, target_dir, nbuf, result);
448 if (!err) {
449 mutex_lock(&target_dir->d_inode->i_mutex);
450 nresult = lookup_one_len(nbuf, target_dir,
451 strlen(nbuf));
452 mutex_unlock(&target_dir->d_inode->i_mutex);
453 if (!IS_ERR(nresult)) {
454 if (nresult->d_inode) {
455 dput(result);
456 result = nresult;
457 } else
458 dput(nresult);
459 }
460 }
461
462 /*
463 * At this point we are done with the parent, but it's pinned
464 * by the child dentry anyway.
465 */
466 dput(target_dir);
467
468 /*
469 * And finally make sure the dentry is actually acceptable
470 * to NFSD.
471 */
472 alias = find_acceptable_alias(result, acceptable, context);
473 if (!alias) {
474 err = -EACCES;
475 goto err_result;
476 }
477
478 return alias;
525 } 479 }
526 480
527 return result; 481 err_result:
482 dput(result);
483 return ERR_PTR(err);
528} 484}
529EXPORT_SYMBOL_GPL(exportfs_decode_fh); 485EXPORT_SYMBOL_GPL(exportfs_decode_fh);
530 486
531EXPORT_SYMBOL(find_exported_dentry);
532
533MODULE_LICENSE("GPL"); 487MODULE_LICENSE("GPL");
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 05d9342bb64e..d868e26c15eb 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -28,6 +28,24 @@
28 28
29typedef struct ext2_dir_entry_2 ext2_dirent; 29typedef struct ext2_dir_entry_2 ext2_dirent;
30 30
31static inline unsigned ext2_rec_len_from_disk(__le16 dlen)
32{
33 unsigned len = le16_to_cpu(dlen);
34
35 if (len == EXT2_MAX_REC_LEN)
36 return 1 << 16;
37 return len;
38}
39
40static inline __le16 ext2_rec_len_to_disk(unsigned len)
41{
42 if (len == (1 << 16))
43 return cpu_to_le16(EXT2_MAX_REC_LEN);
44 else if (len > (1 << 16))
45 BUG();
46 return cpu_to_le16(len);
47}
48
31/* 49/*
32 * ext2 uses block-sized chunks. Arguably, sector-sized ones would be 50 * ext2 uses block-sized chunks. Arguably, sector-sized ones would be
33 * more robust, but we have what we have 51 * more robust, but we have what we have
@@ -106,7 +124,7 @@ static void ext2_check_page(struct page *page)
106 } 124 }
107 for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) { 125 for (offs = 0; offs <= limit - EXT2_DIR_REC_LEN(1); offs += rec_len) {
108 p = (ext2_dirent *)(kaddr + offs); 126 p = (ext2_dirent *)(kaddr + offs);
109 rec_len = le16_to_cpu(p->rec_len); 127 rec_len = ext2_rec_len_from_disk(p->rec_len);
110 128
111 if (rec_len < EXT2_DIR_REC_LEN(1)) 129 if (rec_len < EXT2_DIR_REC_LEN(1))
112 goto Eshort; 130 goto Eshort;
@@ -204,7 +222,8 @@ static inline int ext2_match (int len, const char * const name,
204 */ 222 */
205static inline ext2_dirent *ext2_next_entry(ext2_dirent *p) 223static inline ext2_dirent *ext2_next_entry(ext2_dirent *p)
206{ 224{
207 return (ext2_dirent *)((char*)p + le16_to_cpu(p->rec_len)); 225 return (ext2_dirent *)((char *)p +
226 ext2_rec_len_from_disk(p->rec_len));
208} 227}
209 228
210static inline unsigned 229static inline unsigned
@@ -316,7 +335,7 @@ ext2_readdir (struct file * filp, void * dirent, filldir_t filldir)
316 return 0; 335 return 0;
317 } 336 }
318 } 337 }
319 filp->f_pos += le16_to_cpu(de->rec_len); 338 filp->f_pos += ext2_rec_len_from_disk(de->rec_len);
320 } 339 }
321 ext2_put_page(page); 340 ext2_put_page(page);
322 } 341 }
@@ -425,7 +444,7 @@ void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
425{ 444{
426 loff_t pos = page_offset(page) + 445 loff_t pos = page_offset(page) +
427 (char *) de - (char *) page_address(page); 446 (char *) de - (char *) page_address(page);
428 unsigned len = le16_to_cpu(de->rec_len); 447 unsigned len = ext2_rec_len_from_disk(de->rec_len);
429 int err; 448 int err;
430 449
431 lock_page(page); 450 lock_page(page);
@@ -482,7 +501,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
482 /* We hit i_size */ 501 /* We hit i_size */
483 name_len = 0; 502 name_len = 0;
484 rec_len = chunk_size; 503 rec_len = chunk_size;
485 de->rec_len = cpu_to_le16(chunk_size); 504 de->rec_len = ext2_rec_len_to_disk(chunk_size);
486 de->inode = 0; 505 de->inode = 0;
487 goto got_it; 506 goto got_it;
488 } 507 }
@@ -496,7 +515,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
496 if (ext2_match (namelen, name, de)) 515 if (ext2_match (namelen, name, de))
497 goto out_unlock; 516 goto out_unlock;
498 name_len = EXT2_DIR_REC_LEN(de->name_len); 517 name_len = EXT2_DIR_REC_LEN(de->name_len);
499 rec_len = le16_to_cpu(de->rec_len); 518 rec_len = ext2_rec_len_from_disk(de->rec_len);
500 if (!de->inode && rec_len >= reclen) 519 if (!de->inode && rec_len >= reclen)
501 goto got_it; 520 goto got_it;
502 if (rec_len >= name_len + reclen) 521 if (rec_len >= name_len + reclen)
@@ -518,8 +537,8 @@ got_it:
518 goto out_unlock; 537 goto out_unlock;
519 if (de->inode) { 538 if (de->inode) {
520 ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len); 539 ext2_dirent *de1 = (ext2_dirent *) ((char *) de + name_len);
521 de1->rec_len = cpu_to_le16(rec_len - name_len); 540 de1->rec_len = ext2_rec_len_to_disk(rec_len - name_len);
522 de->rec_len = cpu_to_le16(name_len); 541 de->rec_len = ext2_rec_len_to_disk(name_len);
523 de = de1; 542 de = de1;
524 } 543 }
525 de->name_len = namelen; 544 de->name_len = namelen;
@@ -550,7 +569,8 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
550 struct inode *inode = mapping->host; 569 struct inode *inode = mapping->host;
551 char *kaddr = page_address(page); 570 char *kaddr = page_address(page);
552 unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); 571 unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
553 unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len); 572 unsigned to = ((char *)dir - kaddr) +
573 ext2_rec_len_from_disk(dir->rec_len);
554 loff_t pos; 574 loff_t pos;
555 ext2_dirent * pde = NULL; 575 ext2_dirent * pde = NULL;
556 ext2_dirent * de = (ext2_dirent *) (kaddr + from); 576 ext2_dirent * de = (ext2_dirent *) (kaddr + from);
@@ -574,7 +594,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
574 &page, NULL); 594 &page, NULL);
575 BUG_ON(err); 595 BUG_ON(err);
576 if (pde) 596 if (pde)
577 pde->rec_len = cpu_to_le16(to - from); 597 pde->rec_len = ext2_rec_len_to_disk(to - from);
578 dir->inode = 0; 598 dir->inode = 0;
579 err = ext2_commit_chunk(page, pos, to - from); 599 err = ext2_commit_chunk(page, pos, to - from);
580 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; 600 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
@@ -610,14 +630,14 @@ int ext2_make_empty(struct inode *inode, struct inode *parent)
610 memset(kaddr, 0, chunk_size); 630 memset(kaddr, 0, chunk_size);
611 de = (struct ext2_dir_entry_2 *)kaddr; 631 de = (struct ext2_dir_entry_2 *)kaddr;
612 de->name_len = 1; 632 de->name_len = 1;
613 de->rec_len = cpu_to_le16(EXT2_DIR_REC_LEN(1)); 633 de->rec_len = ext2_rec_len_to_disk(EXT2_DIR_REC_LEN(1));
614 memcpy (de->name, ".\0\0", 4); 634 memcpy (de->name, ".\0\0", 4);
615 de->inode = cpu_to_le32(inode->i_ino); 635 de->inode = cpu_to_le32(inode->i_ino);
616 ext2_set_de_type (de, inode); 636 ext2_set_de_type (de, inode);
617 637
618 de = (struct ext2_dir_entry_2 *)(kaddr + EXT2_DIR_REC_LEN(1)); 638 de = (struct ext2_dir_entry_2 *)(kaddr + EXT2_DIR_REC_LEN(1));
619 de->name_len = 2; 639 de->name_len = 2;
620 de->rec_len = cpu_to_le16(chunk_size - EXT2_DIR_REC_LEN(1)); 640 de->rec_len = ext2_rec_len_to_disk(chunk_size - EXT2_DIR_REC_LEN(1));
621 de->inode = cpu_to_le32(parent->i_ino); 641 de->inode = cpu_to_le32(parent->i_ino);
622 memcpy (de->name, "..\0", 4); 642 memcpy (de->name, "..\0", 4);
623 ext2_set_de_type (de, inode); 643 ext2_set_de_type (de, inode);
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 77bd5f9262f9..154e25f13d77 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -311,13 +311,10 @@ static const struct super_operations ext2_sops = {
311#endif 311#endif
312}; 312};
313 313
314static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp) 314static struct inode *ext2_nfs_get_inode(struct super_block *sb,
315 u64 ino, u32 generation)
315{ 316{
316 __u32 *objp = vobjp;
317 unsigned long ino = objp[0];
318 __u32 generation = objp[1];
319 struct inode *inode; 317 struct inode *inode;
320 struct dentry *result;
321 318
322 if (ino < EXT2_FIRST_INO(sb) && ino != EXT2_ROOT_INO) 319 if (ino < EXT2_FIRST_INO(sb) && ino != EXT2_ROOT_INO)
323 return ERR_PTR(-ESTALE); 320 return ERR_PTR(-ESTALE);
@@ -338,15 +335,21 @@ static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp)
338 iput(inode); 335 iput(inode);
339 return ERR_PTR(-ESTALE); 336 return ERR_PTR(-ESTALE);
340 } 337 }
341 /* now to find a dentry. 338 return inode;
342 * If possible, get a well-connected one 339}
343 */ 340
344 result = d_alloc_anon(inode); 341static struct dentry *ext2_fh_to_dentry(struct super_block *sb, struct fid *fid,
345 if (!result) { 342 int fh_len, int fh_type)
346 iput(inode); 343{
347 return ERR_PTR(-ENOMEM); 344 return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
348 } 345 ext2_nfs_get_inode);
349 return result; 346}
347
348static struct dentry *ext2_fh_to_parent(struct super_block *sb, struct fid *fid,
349 int fh_len, int fh_type)
350{
351 return generic_fh_to_parent(sb, fid, fh_len, fh_type,
352 ext2_nfs_get_inode);
350} 353}
351 354
352/* Yes, most of these are left as NULL!! 355/* Yes, most of these are left as NULL!!
@@ -354,9 +357,10 @@ static struct dentry *ext2_get_dentry(struct super_block *sb, void *vobjp)
354 * systems, but can be improved upon. 357 * systems, but can be improved upon.
355 * Currently only get_parent is required. 358 * Currently only get_parent is required.
356 */ 359 */
357static struct export_operations ext2_export_ops = { 360static const struct export_operations ext2_export_ops = {
361 .fh_to_dentry = ext2_fh_to_dentry,
362 .fh_to_parent = ext2_fh_to_parent,
358 .get_parent = ext2_get_parent, 363 .get_parent = ext2_get_parent,
359 .get_dentry = ext2_get_dentry,
360}; 364};
361 365
362static unsigned long get_sb_block(void **data) 366static unsigned long get_sb_block(void **data)
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index 81868c0bc40e..de55da9e28ba 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -631,13 +631,10 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs)
631} 631}
632 632
633 633
634static struct dentry *ext3_get_dentry(struct super_block *sb, void *vobjp) 634static struct inode *ext3_nfs_get_inode(struct super_block *sb,
635 u64 ino, u32 generation)
635{ 636{
636 __u32 *objp = vobjp;
637 unsigned long ino = objp[0];
638 __u32 generation = objp[1];
639 struct inode *inode; 637 struct inode *inode;
640 struct dentry *result;
641 638
642 if (ino < EXT3_FIRST_INO(sb) && ino != EXT3_ROOT_INO) 639 if (ino < EXT3_FIRST_INO(sb) && ino != EXT3_ROOT_INO)
643 return ERR_PTR(-ESTALE); 640 return ERR_PTR(-ESTALE);
@@ -660,15 +657,22 @@ static struct dentry *ext3_get_dentry(struct super_block *sb, void *vobjp)
660 iput(inode); 657 iput(inode);
661 return ERR_PTR(-ESTALE); 658 return ERR_PTR(-ESTALE);
662 } 659 }
663 /* now to find a dentry. 660
664 * If possible, get a well-connected one 661 return inode;
665 */ 662}
666 result = d_alloc_anon(inode); 663
667 if (!result) { 664static struct dentry *ext3_fh_to_dentry(struct super_block *sb, struct fid *fid,
668 iput(inode); 665 int fh_len, int fh_type)
669 return ERR_PTR(-ENOMEM); 666{
670 } 667 return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
671 return result; 668 ext3_nfs_get_inode);
669}
670
671static struct dentry *ext3_fh_to_parent(struct super_block *sb, struct fid *fid,
672 int fh_len, int fh_type)
673{
674 return generic_fh_to_parent(sb, fid, fh_len, fh_type,
675 ext3_nfs_get_inode);
672} 676}
673 677
674#ifdef CONFIG_QUOTA 678#ifdef CONFIG_QUOTA
@@ -737,9 +741,10 @@ static const struct super_operations ext3_sops = {
737#endif 741#endif
738}; 742};
739 743
740static struct export_operations ext3_export_ops = { 744static const struct export_operations ext3_export_ops = {
745 .fh_to_dentry = ext3_fh_to_dentry,
746 .fh_to_parent = ext3_fh_to_parent,
741 .get_parent = ext3_get_parent, 747 .get_parent = ext3_get_parent,
742 .get_dentry = ext3_get_dentry,
743}; 748};
744 749
745enum { 750enum {
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index b11e9e2bcd01..8031dc0e24e5 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -686,13 +686,10 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs)
686} 686}
687 687
688 688
689static struct dentry *ext4_get_dentry(struct super_block *sb, void *vobjp) 689static struct inode *ext4_nfs_get_inode(struct super_block *sb,
690 u64 ino, u32 generation)
690{ 691{
691 __u32 *objp = vobjp;
692 unsigned long ino = objp[0];
693 __u32 generation = objp[1];
694 struct inode *inode; 692 struct inode *inode;
695 struct dentry *result;
696 693
697 if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO) 694 if (ino < EXT4_FIRST_INO(sb) && ino != EXT4_ROOT_INO)
698 return ERR_PTR(-ESTALE); 695 return ERR_PTR(-ESTALE);
@@ -715,15 +712,22 @@ static struct dentry *ext4_get_dentry(struct super_block *sb, void *vobjp)
715 iput(inode); 712 iput(inode);
716 return ERR_PTR(-ESTALE); 713 return ERR_PTR(-ESTALE);
717 } 714 }
718 /* now to find a dentry. 715
719 * If possible, get a well-connected one 716 return inode;
720 */ 717}
721 result = d_alloc_anon(inode); 718
722 if (!result) { 719static struct dentry *ext4_fh_to_dentry(struct super_block *sb, struct fid *fid,
723 iput(inode); 720 int fh_len, int fh_type)
724 return ERR_PTR(-ENOMEM); 721{
725 } 722 return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
726 return result; 723 ext4_nfs_get_inode);
724}
725
726static struct dentry *ext4_fh_to_parent(struct super_block *sb, struct fid *fid,
727 int fh_len, int fh_type)
728{
729 return generic_fh_to_parent(sb, fid, fh_len, fh_type,
730 ext4_nfs_get_inode);
727} 731}
728 732
729#ifdef CONFIG_QUOTA 733#ifdef CONFIG_QUOTA
@@ -792,9 +796,10 @@ static const struct super_operations ext4_sops = {
792#endif 796#endif
793}; 797};
794 798
795static struct export_operations ext4_export_ops = { 799static const struct export_operations ext4_export_ops = {
800 .fh_to_dentry = ext4_fh_to_dentry,
801 .fh_to_parent = ext4_fh_to_parent,
796 .get_parent = ext4_get_parent, 802 .get_parent = ext4_get_parent,
797 .get_dentry = ext4_get_dentry,
798}; 803};
799 804
800enum { 805enum {
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index c0c5e9c55b58..920a576e1c25 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -653,24 +653,15 @@ static const struct super_operations fat_sops = {
653 * of i_logstart is used to store the directory entry offset. 653 * of i_logstart is used to store the directory entry offset.
654 */ 654 */
655 655
656static struct dentry * 656static struct dentry *fat_fh_to_dentry(struct super_block *sb,
657fat_decode_fh(struct super_block *sb, __u32 *fh, int len, int fhtype, 657 struct fid *fid, int fh_len, int fh_type)
658 int (*acceptable)(void *context, struct dentry *de),
659 void *context)
660{
661 if (fhtype != 3)
662 return ERR_PTR(-ESTALE);
663 if (len < 5)
664 return ERR_PTR(-ESTALE);
665
666 return sb->s_export_op->find_exported_dentry(sb, fh, NULL, acceptable, context);
667}
668
669static struct dentry *fat_get_dentry(struct super_block *sb, void *inump)
670{ 658{
671 struct inode *inode = NULL; 659 struct inode *inode = NULL;
672 struct dentry *result; 660 struct dentry *result;
673 __u32 *fh = inump; 661 u32 *fh = fid->raw;
662
663 if (fh_len < 5 || fh_type != 3)
664 return NULL;
674 665
675 inode = iget(sb, fh[0]); 666 inode = iget(sb, fh[0]);
676 if (!inode || is_bad_inode(inode) || inode->i_generation != fh[1]) { 667 if (!inode || is_bad_inode(inode) || inode->i_generation != fh[1]) {
@@ -783,10 +774,9 @@ out:
783 return parent; 774 return parent;
784} 775}
785 776
786static struct export_operations fat_export_ops = { 777static const struct export_operations fat_export_ops = {
787 .decode_fh = fat_decode_fh,
788 .encode_fh = fat_encode_fh, 778 .encode_fh = fat_encode_fh,
789 .get_dentry = fat_get_dentry, 779 .fh_to_dentry = fat_fh_to_dentry,
790 .get_parent = fat_get_parent, 780 .get_parent = fat_get_parent,
791}; 781};
792 782
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
index e2d1347796a9..b9da62348a87 100644
--- a/fs/gfs2/ops_export.c
+++ b/fs/gfs2/ops_export.c
@@ -31,40 +31,6 @@
31#define GFS2_LARGE_FH_SIZE 8 31#define GFS2_LARGE_FH_SIZE 8
32#define GFS2_OLD_FH_SIZE 10 32#define GFS2_OLD_FH_SIZE 10
33 33
34static struct dentry *gfs2_decode_fh(struct super_block *sb,
35 __u32 *p,
36 int fh_len,
37 int fh_type,
38 int (*acceptable)(void *context,
39 struct dentry *dentry),
40 void *context)
41{
42 __be32 *fh = (__force __be32 *)p;
43 struct gfs2_inum_host inum, parent;
44
45 memset(&parent, 0, sizeof(struct gfs2_inum));
46
47 switch (fh_len) {
48 case GFS2_LARGE_FH_SIZE:
49 case GFS2_OLD_FH_SIZE:
50 parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32;
51 parent.no_formal_ino |= be32_to_cpu(fh[5]);
52 parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32;
53 parent.no_addr |= be32_to_cpu(fh[7]);
54 case GFS2_SMALL_FH_SIZE:
55 inum.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32;
56 inum.no_formal_ino |= be32_to_cpu(fh[1]);
57 inum.no_addr = ((u64)be32_to_cpu(fh[2])) << 32;
58 inum.no_addr |= be32_to_cpu(fh[3]);
59 break;
60 default:
61 return NULL;
62 }
63
64 return gfs2_export_ops.find_exported_dentry(sb, &inum, &parent,
65 acceptable, context);
66}
67
68static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len, 34static int gfs2_encode_fh(struct dentry *dentry, __u32 *p, int *len,
69 int connectable) 35 int connectable)
70{ 36{
@@ -189,10 +155,10 @@ static struct dentry *gfs2_get_parent(struct dentry *child)
189 return dentry; 155 return dentry;
190} 156}
191 157
192static struct dentry *gfs2_get_dentry(struct super_block *sb, void *inum_obj) 158static struct dentry *gfs2_get_dentry(struct super_block *sb,
159 struct gfs2_inum_host *inum)
193{ 160{
194 struct gfs2_sbd *sdp = sb->s_fs_info; 161 struct gfs2_sbd *sdp = sb->s_fs_info;
195 struct gfs2_inum_host *inum = inum_obj;
196 struct gfs2_holder i_gh, ri_gh, rgd_gh; 162 struct gfs2_holder i_gh, ri_gh, rgd_gh;
197 struct gfs2_rgrpd *rgd; 163 struct gfs2_rgrpd *rgd;
198 struct inode *inode; 164 struct inode *inode;
@@ -289,11 +255,50 @@ fail:
289 return ERR_PTR(error); 255 return ERR_PTR(error);
290} 256}
291 257
292struct export_operations gfs2_export_ops = { 258static struct dentry *gfs2_fh_to_dentry(struct super_block *sb, struct fid *fid,
293 .decode_fh = gfs2_decode_fh, 259 int fh_len, int fh_type)
260{
261 struct gfs2_inum_host this;
262 __be32 *fh = (__force __be32 *)fid->raw;
263
264 switch (fh_type) {
265 case GFS2_SMALL_FH_SIZE:
266 case GFS2_LARGE_FH_SIZE:
267 case GFS2_OLD_FH_SIZE:
268 this.no_formal_ino = ((u64)be32_to_cpu(fh[0])) << 32;
269 this.no_formal_ino |= be32_to_cpu(fh[1]);
270 this.no_addr = ((u64)be32_to_cpu(fh[2])) << 32;
271 this.no_addr |= be32_to_cpu(fh[3]);
272 return gfs2_get_dentry(sb, &this);
273 default:
274 return NULL;
275 }
276}
277
278static struct dentry *gfs2_fh_to_parent(struct super_block *sb, struct fid *fid,
279 int fh_len, int fh_type)
280{
281 struct gfs2_inum_host parent;
282 __be32 *fh = (__force __be32 *)fid->raw;
283
284 switch (fh_type) {
285 case GFS2_LARGE_FH_SIZE:
286 case GFS2_OLD_FH_SIZE:
287 parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32;
288 parent.no_formal_ino |= be32_to_cpu(fh[5]);
289 parent.no_addr = ((u64)be32_to_cpu(fh[6])) << 32;
290 parent.no_addr |= be32_to_cpu(fh[7]);
291 return gfs2_get_dentry(sb, &parent);
292 default:
293 return NULL;
294 }
295}
296
297const struct export_operations gfs2_export_ops = {
294 .encode_fh = gfs2_encode_fh, 298 .encode_fh = gfs2_encode_fh,
299 .fh_to_dentry = gfs2_fh_to_dentry,
300 .fh_to_parent = gfs2_fh_to_parent,
295 .get_name = gfs2_get_name, 301 .get_name = gfs2_get_name,
296 .get_parent = gfs2_get_parent, 302 .get_parent = gfs2_get_parent,
297 .get_dentry = gfs2_get_dentry,
298}; 303};
299 304
diff --git a/fs/gfs2/ops_fstype.h b/fs/gfs2/ops_fstype.h
index 407029b3b2b3..da8490511836 100644
--- a/fs/gfs2/ops_fstype.h
+++ b/fs/gfs2/ops_fstype.h
@@ -14,6 +14,6 @@
14 14
15extern struct file_system_type gfs2_fs_type; 15extern struct file_system_type gfs2_fs_type;
16extern struct file_system_type gfs2meta_fs_type; 16extern struct file_system_type gfs2meta_fs_type;
17extern struct export_operations gfs2_export_ops; 17extern const struct export_operations gfs2_export_ops;
18 18
19#endif /* __OPS_FSTYPE_DOT_H__ */ 19#endif /* __OPS_FSTYPE_DOT_H__ */
diff --git a/fs/inotify.c b/fs/inotify.c
index 7457501b9565..2c5b92152876 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -667,6 +667,49 @@ out:
667EXPORT_SYMBOL_GPL(inotify_add_watch); 667EXPORT_SYMBOL_GPL(inotify_add_watch);
668 668
669/** 669/**
670 * inotify_clone_watch - put the watch next to existing one
671 * @old: already installed watch
672 * @new: new watch
673 *
674 * Caller must hold the inotify_mutex of inode we are dealing with;
675 * it is expected to remove the old watch before unlocking the inode.
676 */
677s32 inotify_clone_watch(struct inotify_watch *old, struct inotify_watch *new)
678{
679 struct inotify_handle *ih = old->ih;
680 int ret = 0;
681
682 new->mask = old->mask;
683 new->ih = ih;
684
685 mutex_lock(&ih->mutex);
686
687 /* Initialize a new watch */
688 ret = inotify_handle_get_wd(ih, new);
689 if (unlikely(ret))
690 goto out;
691 ret = new->wd;
692
693 get_inotify_handle(ih);
694
695 new->inode = igrab(old->inode);
696
697 list_add(&new->h_list, &ih->watches);
698 list_add(&new->i_list, &old->inode->inotify_watches);
699out:
700 mutex_unlock(&ih->mutex);
701 return ret;
702}
703
704void inotify_evict_watch(struct inotify_watch *watch)
705{
706 get_inotify_watch(watch);
707 mutex_lock(&watch->ih->mutex);
708 inotify_remove_watch_locked(watch->ih, watch);
709 mutex_unlock(&watch->ih->mutex);
710}
711
712/**
670 * inotify_rm_wd - remove a watch from an inotify instance 713 * inotify_rm_wd - remove a watch from an inotify instance
671 * @ih: inotify handle 714 * @ih: inotify handle
672 * @wd: watch descriptor to remove 715 * @wd: watch descriptor to remove
diff --git a/fs/isofs/export.c b/fs/isofs/export.c
index 4af856a7fda7..29f9753ae5e5 100644
--- a/fs/isofs/export.c
+++ b/fs/isofs/export.c
@@ -42,16 +42,6 @@ isofs_export_iget(struct super_block *sb,
42 return result; 42 return result;
43} 43}
44 44
45static struct dentry *
46isofs_export_get_dentry(struct super_block *sb, void *vobjp)
47{
48 __u32 *objp = vobjp;
49 unsigned long block = objp[0];
50 unsigned long offset = objp[1];
51 __u32 generation = objp[2];
52 return isofs_export_iget(sb, block, offset, generation);
53}
54
55/* This function is surprisingly simple. The trick is understanding 45/* This function is surprisingly simple. The trick is understanding
56 * that "child" is always a directory. So, to find its parent, you 46 * that "child" is always a directory. So, to find its parent, you
57 * simply need to find its ".." entry, normalize its block and offset, 47 * simply need to find its ".." entry, normalize its block and offset,
@@ -182,43 +172,44 @@ isofs_export_encode_fh(struct dentry *dentry,
182 return type; 172 return type;
183} 173}
184 174
175struct isofs_fid {
176 u32 block;
177 u16 offset;
178 u16 parent_offset;
179 u32 generation;
180 u32 parent_block;
181 u32 parent_generation;
182};
185 183
186static struct dentry * 184static struct dentry *isofs_fh_to_dentry(struct super_block *sb,
187isofs_export_decode_fh(struct super_block *sb, 185 struct fid *fid, int fh_len, int fh_type)
188 __u32 *fh32,
189 int fh_len,
190 int fileid_type,
191 int (*acceptable)(void *context, struct dentry *de),
192 void *context)
193{ 186{
194 __u16 *fh16 = (__u16*)fh32; 187 struct isofs_fid *ifid = (struct isofs_fid *)fid;
195 __u32 child[3]; /* The child is what triggered all this. */
196 __u32 parent[3]; /* The parent is just along for the ride. */
197 188
198 if (fh_len < 3 || fileid_type > 2) 189 if (fh_len < 3 || fh_type > 2)
199 return NULL; 190 return NULL;
200 191
201 child[0] = fh32[0]; 192 return isofs_export_iget(sb, ifid->block, ifid->offset,
202 child[1] = fh16[2]; /* fh16 [sic] */ 193 ifid->generation);
203 child[2] = fh32[2];
204
205 parent[0] = 0;
206 parent[1] = 0;
207 parent[2] = 0;
208 if (fileid_type == 2) {
209 if (fh_len > 2) parent[0] = fh32[3];
210 parent[1] = fh16[3]; /* fh16 [sic] */
211 if (fh_len > 4) parent[2] = fh32[4];
212 }
213
214 return sb->s_export_op->find_exported_dentry(sb, child, parent,
215 acceptable, context);
216} 194}
217 195
196static struct dentry *isofs_fh_to_parent(struct super_block *sb,
197 struct fid *fid, int fh_len, int fh_type)
198{
199 struct isofs_fid *ifid = (struct isofs_fid *)fid;
200
201 if (fh_type != 2)
202 return NULL;
203
204 return isofs_export_iget(sb,
205 fh_len > 2 ? ifid->parent_block : 0,
206 ifid->parent_offset,
207 fh_len > 4 ? ifid->parent_generation : 0);
208}
218 209
219struct export_operations isofs_export_ops = { 210const struct export_operations isofs_export_ops = {
220 .decode_fh = isofs_export_decode_fh,
221 .encode_fh = isofs_export_encode_fh, 211 .encode_fh = isofs_export_encode_fh,
222 .get_dentry = isofs_export_get_dentry, 212 .fh_to_dentry = isofs_fh_to_dentry,
213 .fh_to_parent = isofs_fh_to_parent,
223 .get_parent = isofs_export_get_parent, 214 .get_parent = isofs_export_get_parent,
224}; 215};
diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h
index a07e67b1ea7f..f3213f9f89af 100644
--- a/fs/isofs/isofs.h
+++ b/fs/isofs/isofs.h
@@ -178,4 +178,4 @@ isofs_normalize_block_and_offset(struct iso_directory_record* de,
178extern const struct inode_operations isofs_dir_inode_operations; 178extern const struct inode_operations isofs_dir_inode_operations;
179extern const struct file_operations isofs_dir_operations; 179extern const struct file_operations isofs_dir_operations;
180extern const struct address_space_operations isofs_symlink_aops; 180extern const struct address_space_operations isofs_symlink_aops;
181extern struct export_operations isofs_export_ops; 181extern const struct export_operations isofs_export_ops;
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index f0ec72b263f1..8e2cf2cde185 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -18,6 +18,8 @@
18#ifndef _H_JFS_INODE 18#ifndef _H_JFS_INODE
19#define _H_JFS_INODE 19#define _H_JFS_INODE
20 20
21struct fid;
22
21extern struct inode *ialloc(struct inode *, umode_t); 23extern struct inode *ialloc(struct inode *, umode_t);
22extern int jfs_fsync(struct file *, struct dentry *, int); 24extern int jfs_fsync(struct file *, struct dentry *, int);
23extern int jfs_ioctl(struct inode *, struct file *, 25extern int jfs_ioctl(struct inode *, struct file *,
@@ -32,7 +34,10 @@ extern void jfs_truncate_nolock(struct inode *, loff_t);
32extern void jfs_free_zero_link(struct inode *); 34extern void jfs_free_zero_link(struct inode *);
33extern struct dentry *jfs_get_parent(struct dentry *dentry); 35extern struct dentry *jfs_get_parent(struct dentry *dentry);
34extern void jfs_get_inode_flags(struct jfs_inode_info *); 36extern void jfs_get_inode_flags(struct jfs_inode_info *);
35extern struct dentry *jfs_get_dentry(struct super_block *sb, void *vobjp); 37extern struct dentry *jfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
38 int fh_len, int fh_type);
39extern struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
40 int fh_len, int fh_type);
36extern void jfs_set_inode_flags(struct inode *); 41extern void jfs_set_inode_flags(struct inode *);
37extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int); 42extern int jfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
38 43
diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c
index 932797ba433b..4e0a8493cef6 100644
--- a/fs/jfs/namei.c
+++ b/fs/jfs/namei.c
@@ -20,6 +20,7 @@
20#include <linux/fs.h> 20#include <linux/fs.h>
21#include <linux/ctype.h> 21#include <linux/ctype.h>
22#include <linux/quotaops.h> 22#include <linux/quotaops.h>
23#include <linux/exportfs.h>
23#include "jfs_incore.h" 24#include "jfs_incore.h"
24#include "jfs_superblock.h" 25#include "jfs_superblock.h"
25#include "jfs_inode.h" 26#include "jfs_inode.h"
@@ -1477,13 +1478,10 @@ static struct dentry *jfs_lookup(struct inode *dip, struct dentry *dentry, struc
1477 return dentry; 1478 return dentry;
1478} 1479}
1479 1480
1480struct dentry *jfs_get_dentry(struct super_block *sb, void *vobjp) 1481static struct inode *jfs_nfs_get_inode(struct super_block *sb,
1482 u64 ino, u32 generation)
1481{ 1483{
1482 __u32 *objp = vobjp;
1483 unsigned long ino = objp[0];
1484 __u32 generation = objp[1];
1485 struct inode *inode; 1484 struct inode *inode;
1486 struct dentry *result;
1487 1485
1488 if (ino == 0) 1486 if (ino == 0)
1489 return ERR_PTR(-ESTALE); 1487 return ERR_PTR(-ESTALE);
@@ -1493,20 +1491,25 @@ struct dentry *jfs_get_dentry(struct super_block *sb, void *vobjp)
1493 1491
1494 if (is_bad_inode(inode) || 1492 if (is_bad_inode(inode) ||
1495 (generation && inode->i_generation != generation)) { 1493 (generation && inode->i_generation != generation)) {
1496 result = ERR_PTR(-ESTALE); 1494 iput(inode);
1497 goto out_iput; 1495 return ERR_PTR(-ESTALE);
1498 } 1496 }
1499 1497
1500 result = d_alloc_anon(inode); 1498 return inode;
1501 if (!result) { 1499}
1502 result = ERR_PTR(-ENOMEM);
1503 goto out_iput;
1504 }
1505 return result;
1506 1500
1507 out_iput: 1501struct dentry *jfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
1508 iput(inode); 1502 int fh_len, int fh_type)
1509 return result; 1503{
1504 return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
1505 jfs_nfs_get_inode);
1506}
1507
1508struct dentry *jfs_fh_to_parent(struct super_block *sb, struct fid *fid,
1509 int fh_len, int fh_type)
1510{
1511 return generic_fh_to_parent(sb, fid, fh_len, fh_type,
1512 jfs_nfs_get_inode);
1510} 1513}
1511 1514
1512struct dentry *jfs_get_parent(struct dentry *dentry) 1515struct dentry *jfs_get_parent(struct dentry *dentry)
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index cff60c171943..314bb4ff1ba8 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -48,7 +48,7 @@ MODULE_LICENSE("GPL");
48static struct kmem_cache * jfs_inode_cachep; 48static struct kmem_cache * jfs_inode_cachep;
49 49
50static const struct super_operations jfs_super_operations; 50static const struct super_operations jfs_super_operations;
51static struct export_operations jfs_export_operations; 51static const struct export_operations jfs_export_operations;
52static struct file_system_type jfs_fs_type; 52static struct file_system_type jfs_fs_type;
53 53
54#define MAX_COMMIT_THREADS 64 54#define MAX_COMMIT_THREADS 64
@@ -737,8 +737,9 @@ static const struct super_operations jfs_super_operations = {
737#endif 737#endif
738}; 738};
739 739
740static struct export_operations jfs_export_operations = { 740static const struct export_operations jfs_export_operations = {
741 .get_dentry = jfs_get_dentry, 741 .fh_to_dentry = jfs_fh_to_dentry,
742 .fh_to_parent = jfs_fh_to_parent,
742 .get_parent = jfs_get_parent, 743 .get_parent = jfs_get_parent,
743}; 744};
744 745
diff --git a/fs/libfs.c b/fs/libfs.c
index ae51481e45e5..6e68b700958d 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -8,6 +8,7 @@
8#include <linux/mount.h> 8#include <linux/mount.h>
9#include <linux/vfs.h> 9#include <linux/vfs.h>
10#include <linux/mutex.h> 10#include <linux/mutex.h>
11#include <linux/exportfs.h>
11 12
12#include <asm/uaccess.h> 13#include <asm/uaccess.h>
13 14
@@ -678,6 +679,93 @@ out:
678 return ret; 679 return ret;
679} 680}
680 681
682/*
683 * This is what d_alloc_anon should have been. Once the exportfs
684 * argument transition has been finished I will update d_alloc_anon
685 * to this prototype and this wrapper will go away. --hch
686 */
687static struct dentry *exportfs_d_alloc(struct inode *inode)
688{
689 struct dentry *dentry;
690
691 if (!inode)
692 return NULL;
693 if (IS_ERR(inode))
694 return ERR_PTR(PTR_ERR(inode));
695
696 dentry = d_alloc_anon(inode);
697 if (!dentry) {
698 iput(inode);
699 dentry = ERR_PTR(-ENOMEM);
700 }
701 return dentry;
702}
703
704/**
705 * generic_fh_to_dentry - generic helper for the fh_to_dentry export operation
706 * @sb: filesystem to do the file handle conversion on
707 * @fid: file handle to convert
708 * @fh_len: length of the file handle in bytes
709 * @fh_type: type of file handle
710 * @get_inode: filesystem callback to retrieve inode
711 *
712 * This function decodes @fid as long as it has one of the well-known
713 * Linux filehandle types and calls @get_inode on it to retrieve the
714 * inode for the object specified in the file handle.
715 */
716struct dentry *generic_fh_to_dentry(struct super_block *sb, struct fid *fid,
717 int fh_len, int fh_type, struct inode *(*get_inode)
718 (struct super_block *sb, u64 ino, u32 gen))
719{
720 struct inode *inode = NULL;
721
722 if (fh_len < 2)
723 return NULL;
724
725 switch (fh_type) {
726 case FILEID_INO32_GEN:
727 case FILEID_INO32_GEN_PARENT:
728 inode = get_inode(sb, fid->i32.ino, fid->i32.gen);
729 break;
730 }
731
732 return exportfs_d_alloc(inode);
733}
734EXPORT_SYMBOL_GPL(generic_fh_to_dentry);
735
736/**
737 * generic_fh_to_dentry - generic helper for the fh_to_parent export operation
738 * @sb: filesystem to do the file handle conversion on
739 * @fid: file handle to convert
740 * @fh_len: length of the file handle in bytes
741 * @fh_type: type of file handle
742 * @get_inode: filesystem callback to retrieve inode
743 *
744 * This function decodes @fid as long as it has one of the well-known
745 * Linux filehandle types and calls @get_inode on it to retrieve the
746 * inode for the _parent_ object specified in the file handle if it
747 * is specified in the file handle, or NULL otherwise.
748 */
749struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid,
750 int fh_len, int fh_type, struct inode *(*get_inode)
751 (struct super_block *sb, u64 ino, u32 gen))
752{
753 struct inode *inode = NULL;
754
755 if (fh_len <= 2)
756 return NULL;
757
758 switch (fh_type) {
759 case FILEID_INO32_GEN_PARENT:
760 inode = get_inode(sb, fid->i32.parent_ino,
761 (fh_len > 3 ? fid->i32.parent_gen : 0));
762 break;
763 }
764
765 return exportfs_d_alloc(inode);
766}
767EXPORT_SYMBOL_GPL(generic_fh_to_parent);
768
681EXPORT_SYMBOL(dcache_dir_close); 769EXPORT_SYMBOL(dcache_dir_close);
682EXPORT_SYMBOL(dcache_dir_lseek); 770EXPORT_SYMBOL(dcache_dir_lseek);
683EXPORT_SYMBOL(dcache_dir_open); 771EXPORT_SYMBOL(dcache_dir_open);
diff --git a/fs/namei.c b/fs/namei.c
index 1e5c71669164..3b993db26cee 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1174,7 +1174,7 @@ static int fastcall do_path_lookup(int dfd, const char *name,
1174out: 1174out:
1175 if (unlikely(!retval && !audit_dummy_context() && nd->dentry && 1175 if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
1176 nd->dentry->d_inode)) 1176 nd->dentry->d_inode))
1177 audit_inode(name, nd->dentry->d_inode); 1177 audit_inode(name, nd->dentry);
1178out_fail: 1178out_fail:
1179 return retval; 1179 return retval;
1180 1180
@@ -1214,7 +1214,7 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
1214 retval = path_walk(name, nd); 1214 retval = path_walk(name, nd);
1215 if (unlikely(!retval && !audit_dummy_context() && nd->dentry && 1215 if (unlikely(!retval && !audit_dummy_context() && nd->dentry &&
1216 nd->dentry->d_inode)) 1216 nd->dentry->d_inode))
1217 audit_inode(name, nd->dentry->d_inode); 1217 audit_inode(name, nd->dentry);
1218 1218
1219 return retval; 1219 return retval;
1220 1220
@@ -1469,7 +1469,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
1469 return -ENOENT; 1469 return -ENOENT;
1470 1470
1471 BUG_ON(victim->d_parent->d_inode != dir); 1471 BUG_ON(victim->d_parent->d_inode != dir);
1472 audit_inode_child(victim->d_name.name, victim->d_inode, dir); 1472 audit_inode_child(victim->d_name.name, victim, dir);
1473 1473
1474 error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); 1474 error = permission(dir,MAY_WRITE | MAY_EXEC, NULL);
1475 if (error) 1475 if (error)
@@ -1783,7 +1783,7 @@ do_last:
1783 * It already exists. 1783 * It already exists.
1784 */ 1784 */
1785 mutex_unlock(&dir->d_inode->i_mutex); 1785 mutex_unlock(&dir->d_inode->i_mutex);
1786 audit_inode(pathname, path.dentry->d_inode); 1786 audit_inode(pathname, path.dentry);
1787 1787
1788 error = -EEXIST; 1788 error = -EEXIST;
1789 if (flag & O_EXCL) 1789 if (flag & O_EXCL)
@@ -2562,7 +2562,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
2562 if (!error) { 2562 if (!error) {
2563 const char *new_name = old_dentry->d_name.name; 2563 const char *new_name = old_dentry->d_name.name;
2564 fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir, 2564 fsnotify_move(old_dir, new_dir, old_name, new_name, is_dir,
2565 new_dentry->d_inode, old_dentry->d_inode); 2565 new_dentry->d_inode, old_dentry);
2566 } 2566 }
2567 fsnotify_oldname_free(old_name); 2567 fsnotify_oldname_free(old_name);
2568 2568
diff --git a/fs/namespace.c b/fs/namespace.c
index 860752998fb3..06083885b21e 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -246,7 +246,7 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
246 list_add(&mnt->mnt_slave, &old->mnt_slave_list); 246 list_add(&mnt->mnt_slave, &old->mnt_slave_list);
247 mnt->mnt_master = old; 247 mnt->mnt_master = old;
248 CLEAR_MNT_SHARED(mnt); 248 CLEAR_MNT_SHARED(mnt);
249 } else { 249 } else if (!(flag & CL_PRIVATE)) {
250 if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old)) 250 if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old))
251 list_add(&mnt->mnt_share, &old->mnt_share); 251 list_add(&mnt->mnt_share, &old->mnt_share);
252 if (IS_MNT_SLAVE(old)) 252 if (IS_MNT_SLAVE(old))
@@ -746,6 +746,26 @@ Enomem:
746 return NULL; 746 return NULL;
747} 747}
748 748
749struct vfsmount *collect_mounts(struct vfsmount *mnt, struct dentry *dentry)
750{
751 struct vfsmount *tree;
752 down_read(&namespace_sem);
753 tree = copy_tree(mnt, dentry, CL_COPY_ALL | CL_PRIVATE);
754 up_read(&namespace_sem);
755 return tree;
756}
757
758void drop_collected_mounts(struct vfsmount *mnt)
759{
760 LIST_HEAD(umount_list);
761 down_read(&namespace_sem);
762 spin_lock(&vfsmount_lock);
763 umount_tree(mnt, 0, &umount_list);
764 spin_unlock(&vfsmount_lock);
765 up_read(&namespace_sem);
766 release_mounts(&umount_list);
767}
768
749/* 769/*
750 * @source_mnt : mount tree to be attached 770 * @source_mnt : mount tree to be attached
751 * @nd : place the mount tree @source_mnt is attached 771 * @nd : place the mount tree @source_mnt is attached
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 97669ed05500..4f80d88e9fee 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -211,6 +211,7 @@ nfs_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
211 nfs_fattr_init(&fattr); 211 nfs_fattr_init(&fattr);
212 dprintk("NFS call create %s\n", dentry->d_name.name); 212 dprintk("NFS call create %s\n", dentry->d_name.name);
213 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0); 213 status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
214 nfs_mark_for_revalidate(dir);
214 if (status == 0) 215 if (status == 0)
215 status = nfs_instantiate(dentry, &fhandle, &fattr); 216 status = nfs_instantiate(dentry, &fhandle, &fattr);
216 dprintk("NFS reply create: %d\n", status); 217 dprintk("NFS reply create: %d\n", status);
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index ce558c2e4d53..233ad38161f9 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -171,7 +171,7 @@ static int nfs_call_unlink(struct dentry *dentry, struct nfs_unlinkdata *data)
171 if (parent == NULL) 171 if (parent == NULL)
172 goto out_free; 172 goto out_free;
173 dir = parent->d_inode; 173 dir = parent->d_inode;
174 if (nfs_copy_dname(dentry, data) == 0) 174 if (nfs_copy_dname(dentry, data) != 0)
175 goto out_dput; 175 goto out_dput;
176 /* Non-exclusive lock protects against concurrent lookup() calls */ 176 /* Non-exclusive lock protects against concurrent lookup() calls */
177 spin_lock(&dir->i_lock); 177 spin_lock(&dir->i_lock);
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 04b266729802..66d0aeb32a47 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -386,15 +386,13 @@ static int check_export(struct inode *inode, int flags, unsigned char *uuid)
386 dprintk("exp_export: export of non-dev fs without fsid\n"); 386 dprintk("exp_export: export of non-dev fs without fsid\n");
387 return -EINVAL; 387 return -EINVAL;
388 } 388 }
389 if (!inode->i_sb->s_export_op) { 389
390 if (!inode->i_sb->s_export_op ||
391 !inode->i_sb->s_export_op->fh_to_dentry) {
390 dprintk("exp_export: export of invalid fs type.\n"); 392 dprintk("exp_export: export of invalid fs type.\n");
391 return -EINVAL; 393 return -EINVAL;
392 } 394 }
393 395
394 /* Ok, we can export it */;
395 if (!inode->i_sb->s_export_op->find_exported_dentry)
396 inode->i_sb->s_export_op->find_exported_dentry =
397 find_exported_dentry;
398 return 0; 396 return 0;
399 397
400} 398}
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index ebd03cc07479..6f03918018a3 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -88,7 +88,7 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
88{ 88{
89 struct xdr_netobj cksum; 89 struct xdr_netobj cksum;
90 struct hash_desc desc; 90 struct hash_desc desc;
91 struct scatterlist sg[1]; 91 struct scatterlist sg;
92 __be32 status = nfserr_resource; 92 __be32 status = nfserr_resource;
93 93
94 dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n", 94 dprintk("NFSD: nfs4_make_rec_clidname for %.*s\n",
@@ -102,11 +102,9 @@ nfs4_make_rec_clidname(char *dname, struct xdr_netobj *clname)
102 if (cksum.data == NULL) 102 if (cksum.data == NULL)
103 goto out; 103 goto out;
104 104
105 sg[0].page = virt_to_page(clname->data); 105 sg_init_one(&sg, clname->data, clname->len);
106 sg[0].offset = offset_in_page(clname->data);
107 sg[0].length = clname->len;
108 106
109 if (crypto_hash_digest(&desc, sg, sg->length, cksum.data)) 107 if (crypto_hash_digest(&desc, &sg, sg.length, cksum.data))
110 goto out; 108 goto out;
111 109
112 md5_to_hex(dname, cksum.data); 110 md5_to_hex(dname, cksum.data);
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 7011d62acfc8..4f712e970584 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -115,8 +115,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
115 dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp)); 115 dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));
116 116
117 if (!fhp->fh_dentry) { 117 if (!fhp->fh_dentry) {
118 __u32 *datap=NULL; 118 struct fid *fid = NULL, sfid;
119 __u32 tfh[3]; /* filehandle fragment for oldstyle filehandles */
120 int fileid_type; 119 int fileid_type;
121 int data_left = fh->fh_size/4; 120 int data_left = fh->fh_size/4;
122 121
@@ -128,7 +127,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
128 127
129 if (fh->fh_version == 1) { 128 if (fh->fh_version == 1) {
130 int len; 129 int len;
131 datap = fh->fh_auth;
132 if (--data_left<0) goto out; 130 if (--data_left<0) goto out;
133 switch (fh->fh_auth_type) { 131 switch (fh->fh_auth_type) {
134 case 0: break; 132 case 0: break;
@@ -144,9 +142,11 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
144 fh->fh_fsid[1] = fh->fh_fsid[2]; 142 fh->fh_fsid[1] = fh->fh_fsid[2];
145 } 143 }
146 if ((data_left -= len)<0) goto out; 144 if ((data_left -= len)<0) goto out;
147 exp = rqst_exp_find(rqstp, fh->fh_fsid_type, datap); 145 exp = rqst_exp_find(rqstp, fh->fh_fsid_type,
148 datap += len; 146 fh->fh_auth);
147 fid = (struct fid *)(fh->fh_auth + len);
149 } else { 148 } else {
149 __u32 tfh[2];
150 dev_t xdev; 150 dev_t xdev;
151 ino_t xino; 151 ino_t xino;
152 if (fh->fh_size != NFS_FHSIZE) 152 if (fh->fh_size != NFS_FHSIZE)
@@ -190,22 +190,22 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
190 error = nfserr_badhandle; 190 error = nfserr_badhandle;
191 191
192 if (fh->fh_version != 1) { 192 if (fh->fh_version != 1) {
193 tfh[0] = fh->ofh_ino; 193 sfid.i32.ino = fh->ofh_ino;
194 tfh[1] = fh->ofh_generation; 194 sfid.i32.gen = fh->ofh_generation;
195 tfh[2] = fh->ofh_dirino; 195 sfid.i32.parent_ino = fh->ofh_dirino;
196 datap = tfh; 196 fid = &sfid;
197 data_left = 3; 197 data_left = 3;
198 if (fh->ofh_dirino == 0) 198 if (fh->ofh_dirino == 0)
199 fileid_type = 1; 199 fileid_type = FILEID_INO32_GEN;
200 else 200 else
201 fileid_type = 2; 201 fileid_type = FILEID_INO32_GEN_PARENT;
202 } else 202 } else
203 fileid_type = fh->fh_fileid_type; 203 fileid_type = fh->fh_fileid_type;
204 204
205 if (fileid_type == 0) 205 if (fileid_type == FILEID_ROOT)
206 dentry = dget(exp->ex_dentry); 206 dentry = dget(exp->ex_dentry);
207 else { 207 else {
208 dentry = exportfs_decode_fh(exp->ex_mnt, datap, 208 dentry = exportfs_decode_fh(exp->ex_mnt, fid,
209 data_left, fileid_type, 209 data_left, fileid_type,
210 nfsd_acceptable, exp); 210 nfsd_acceptable, exp);
211 } 211 }
@@ -286,16 +286,21 @@ out:
286 * an inode. In this case a call to fh_update should be made 286 * an inode. In this case a call to fh_update should be made
287 * before the fh goes out on the wire ... 287 * before the fh goes out on the wire ...
288 */ 288 */
289static inline int _fh_update(struct dentry *dentry, struct svc_export *exp, 289static void _fh_update(struct svc_fh *fhp, struct svc_export *exp,
290 __u32 *datap, int *maxsize) 290 struct dentry *dentry)
291{ 291{
292 if (dentry == exp->ex_dentry) { 292 if (dentry != exp->ex_dentry) {
293 *maxsize = 0; 293 struct fid *fid = (struct fid *)
294 return 0; 294 (fhp->fh_handle.fh_auth + fhp->fh_handle.fh_size/4 - 1);
295 } 295 int maxsize = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
296 int subtreecheck = !(exp->ex_flags & NFSEXP_NOSUBTREECHECK);
296 297
297 return exportfs_encode_fh(dentry, datap, maxsize, 298 fhp->fh_handle.fh_fileid_type =
298 !(exp->ex_flags & NFSEXP_NOSUBTREECHECK)); 299 exportfs_encode_fh(dentry, fid, &maxsize, subtreecheck);
300 fhp->fh_handle.fh_size += maxsize * 4;
301 } else {
302 fhp->fh_handle.fh_fileid_type = FILEID_ROOT;
303 }
299} 304}
300 305
301/* 306/*
@@ -457,12 +462,8 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
457 datap += len/4; 462 datap += len/4;
458 fhp->fh_handle.fh_size = 4 + len; 463 fhp->fh_handle.fh_size = 4 + len;
459 464
460 if (inode) { 465 if (inode)
461 int size = (fhp->fh_maxsize-len-4)/4; 466 _fh_update(fhp, exp, dentry);
462 fhp->fh_handle.fh_fileid_type =
463 _fh_update(dentry, exp, datap, &size);
464 fhp->fh_handle.fh_size += size*4;
465 }
466 if (fhp->fh_handle.fh_fileid_type == 255) 467 if (fhp->fh_handle.fh_fileid_type == 255)
467 return nfserr_opnotsupp; 468 return nfserr_opnotsupp;
468 } 469 }
@@ -479,7 +480,6 @@ __be32
479fh_update(struct svc_fh *fhp) 480fh_update(struct svc_fh *fhp)
480{ 481{
481 struct dentry *dentry; 482 struct dentry *dentry;
482 __u32 *datap;
483 483
484 if (!fhp->fh_dentry) 484 if (!fhp->fh_dentry)
485 goto out_bad; 485 goto out_bad;
@@ -490,15 +490,10 @@ fh_update(struct svc_fh *fhp)
490 if (fhp->fh_handle.fh_version != 1) { 490 if (fhp->fh_handle.fh_version != 1) {
491 _fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle); 491 _fh_update_old(dentry, fhp->fh_export, &fhp->fh_handle);
492 } else { 492 } else {
493 int size; 493 if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT)
494 if (fhp->fh_handle.fh_fileid_type != 0)
495 goto out; 494 goto out;
496 datap = fhp->fh_handle.fh_auth+ 495
497 fhp->fh_handle.fh_size/4 -1; 496 _fh_update(fhp, fhp->fh_export, dentry);
498 size = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
499 fhp->fh_handle.fh_fileid_type =
500 _fh_update(dentry, fhp->fh_export, datap, &size);
501 fhp->fh_handle.fh_size += size*4;
502 if (fhp->fh_handle.fh_fileid_type == 255) 497 if (fhp->fh_handle.fh_fileid_type == 255)
503 return nfserr_opnotsupp; 498 return nfserr_opnotsupp;
504 } 499 }
diff --git a/fs/ntfs/namei.c b/fs/ntfs/namei.c
index e93c6142b23c..e1781c8b1650 100644
--- a/fs/ntfs/namei.c
+++ b/fs/ntfs/namei.c
@@ -450,58 +450,40 @@ try_next:
450 return parent_dent; 450 return parent_dent;
451} 451}
452 452
453/** 453static struct inode *ntfs_nfs_get_inode(struct super_block *sb,
454 * ntfs_get_dentry - find a dentry for the inode from a file handle sub-fragment 454 u64 ino, u32 generation)
455 * @sb: super block identifying the mounted ntfs volume
456 * @fh: the file handle sub-fragment
457 *
458 * Find a dentry for the inode given a file handle sub-fragment. This function
459 * is called from fs/exportfs/expfs.c::find_exported_dentry() which in turn is
460 * called from the default ->decode_fh() which is export_decode_fh() in the
461 * same file. The code is closely based on the default ->get_dentry() helper
462 * fs/exportfs/expfs.c::get_object().
463 *
464 * The @fh contains two 32-bit unsigned values, the first one is the inode
465 * number and the second one is the inode generation.
466 *
467 * Return the dentry on success or the error code on error (IS_ERR() is true).
468 */
469static struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh)
470{ 455{
471 struct inode *vi; 456 struct inode *inode;
472 struct dentry *dent;
473 unsigned long ino = ((u32 *)fh)[0];
474 u32 gen = ((u32 *)fh)[1];
475 457
476 ntfs_debug("Entering for inode 0x%lx, generation 0x%x.", ino, gen); 458 inode = ntfs_iget(sb, ino);
477 vi = ntfs_iget(sb, ino); 459 if (!IS_ERR(inode)) {
478 if (IS_ERR(vi)) { 460 if (is_bad_inode(inode) || inode->i_generation != generation) {
479 ntfs_error(sb, "Failed to get inode 0x%lx.", ino); 461 iput(inode);
480 return (struct dentry *)vi; 462 inode = ERR_PTR(-ESTALE);
481 } 463 }
482 if (unlikely(is_bad_inode(vi) || vi->i_generation != gen)) {
483 /* We didn't find the right inode. */
484 ntfs_error(sb, "Inode 0x%lx, bad count: %d %d or version 0x%x "
485 "0x%x.", vi->i_ino, vi->i_nlink,
486 atomic_read(&vi->i_count), vi->i_generation,
487 gen);
488 iput(vi);
489 return ERR_PTR(-ESTALE);
490 }
491 /* Now find a dentry. If possible, get a well-connected one. */
492 dent = d_alloc_anon(vi);
493 if (unlikely(!dent)) {
494 iput(vi);
495 return ERR_PTR(-ENOMEM);
496 } 464 }
497 ntfs_debug("Done for inode 0x%lx, generation 0x%x.", ino, gen); 465
498 return dent; 466 return inode;
467}
468
469static struct dentry *ntfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
470 int fh_len, int fh_type)
471{
472 return generic_fh_to_dentry(sb, fid, fh_len, fh_type,
473 ntfs_nfs_get_inode);
474}
475
476static struct dentry *ntfs_fh_to_parent(struct super_block *sb, struct fid *fid,
477 int fh_len, int fh_type)
478{
479 return generic_fh_to_parent(sb, fid, fh_len, fh_type,
480 ntfs_nfs_get_inode);
499} 481}
500 482
501/** 483/**
502 * Export operations allowing NFS exporting of mounted NTFS partitions. 484 * Export operations allowing NFS exporting of mounted NTFS partitions.
503 * 485 *
504 * We use the default ->decode_fh() and ->encode_fh() for now. Note that they 486 * We use the default ->encode_fh() for now. Note that they
505 * use 32 bits to store the inode number which is an unsigned long so on 64-bit 487 * use 32 bits to store the inode number which is an unsigned long so on 64-bit
506 * architectures is usually 64 bits so it would all fail horribly on huge 488 * architectures is usually 64 bits so it would all fail horribly on huge
507 * volumes. I guess we need to define our own encode and decode fh functions 489 * volumes. I guess we need to define our own encode and decode fh functions
@@ -517,10 +499,9 @@ static struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh)
517 * allowing the inode number 0 which is used in NTFS for the system file $MFT 499 * allowing the inode number 0 which is used in NTFS for the system file $MFT
518 * and due to using iget() whereas NTFS needs ntfs_iget(). 500 * and due to using iget() whereas NTFS needs ntfs_iget().
519 */ 501 */
520struct export_operations ntfs_export_ops = { 502const struct export_operations ntfs_export_ops = {
521 .get_parent = ntfs_get_parent, /* Find the parent of a given 503 .get_parent = ntfs_get_parent, /* Find the parent of a given
522 directory. */ 504 directory. */
523 .get_dentry = ntfs_get_dentry, /* Find a dentry for the inode 505 .fh_to_dentry = ntfs_fh_to_dentry,
524 given a file handle 506 .fh_to_parent = ntfs_fh_to_parent,
525 sub-fragment. */
526}; 507};
diff --git a/fs/ntfs/ntfs.h b/fs/ntfs/ntfs.h
index d73f5a9ac341..d6a340bf80fc 100644
--- a/fs/ntfs/ntfs.h
+++ b/fs/ntfs/ntfs.h
@@ -69,7 +69,7 @@ extern const struct inode_operations ntfs_dir_inode_ops;
69extern const struct file_operations ntfs_empty_file_ops; 69extern const struct file_operations ntfs_empty_file_ops;
70extern const struct inode_operations ntfs_empty_inode_ops; 70extern const struct inode_operations ntfs_empty_inode_ops;
71 71
72extern struct export_operations ntfs_export_ops; 72extern const struct export_operations ntfs_export_ops;
73 73
74/** 74/**
75 * NTFS_SB - return the ntfs volume given a vfs super block 75 * NTFS_SB - return the ntfs volume given a vfs super block
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index c3bbc198f9ce..535bfa9568a4 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -45,9 +45,9 @@ struct ocfs2_inode_handle
45 u32 ih_generation; 45 u32 ih_generation;
46}; 46};
47 47
48static struct dentry *ocfs2_get_dentry(struct super_block *sb, void *vobjp) 48static struct dentry *ocfs2_get_dentry(struct super_block *sb,
49 struct ocfs2_inode_handle *handle)
49{ 50{
50 struct ocfs2_inode_handle *handle = vobjp;
51 struct inode *inode; 51 struct inode *inode;
52 struct dentry *result; 52 struct dentry *result;
53 53
@@ -194,54 +194,37 @@ bail:
194 return type; 194 return type;
195} 195}
196 196
197static struct dentry *ocfs2_decode_fh(struct super_block *sb, u32 *fh_in, 197static struct dentry *ocfs2_fh_to_dentry(struct super_block *sb,
198 int fh_len, int fileid_type, 198 struct fid *fid, int fh_len, int fh_type)
199 int (*acceptable)(void *context,
200 struct dentry *de),
201 void *context)
202{ 199{
203 struct ocfs2_inode_handle handle, parent; 200 struct ocfs2_inode_handle handle;
204 struct dentry *ret = NULL;
205 __le32 *fh = (__force __le32 *) fh_in;
206
207 mlog_entry("(0x%p, 0x%p, %d, %d, 0x%p, 0x%p)\n",
208 sb, fh, fh_len, fileid_type, acceptable, context);
209
210 if (fh_len < 3 || fileid_type > 2)
211 goto bail;
212
213 if (fileid_type == 2) {
214 if (fh_len < 6)
215 goto bail;
216
217 parent.ih_blkno = (u64)le32_to_cpu(fh[3]) << 32;
218 parent.ih_blkno |= (u64)le32_to_cpu(fh[4]);
219 parent.ih_generation = le32_to_cpu(fh[5]);
220 201
221 mlog(0, "Decoding parent: blkno: %llu, generation: %u\n", 202 if (fh_len < 3 || fh_type > 2)
222 (unsigned long long)parent.ih_blkno, 203 return NULL;
223 parent.ih_generation);
224 }
225 204
226 handle.ih_blkno = (u64)le32_to_cpu(fh[0]) << 32; 205 handle.ih_blkno = (u64)le32_to_cpu(fid->raw[0]) << 32;
227 handle.ih_blkno |= (u64)le32_to_cpu(fh[1]); 206 handle.ih_blkno |= (u64)le32_to_cpu(fid->raw[1]);
228 handle.ih_generation = le32_to_cpu(fh[2]); 207 handle.ih_generation = le32_to_cpu(fid->raw[2]);
208 return ocfs2_get_dentry(sb, &handle);
209}
229 210
230 mlog(0, "Encoding fh: blkno: %llu, generation: %u\n", 211static struct dentry *ocfs2_fh_to_parent(struct super_block *sb,
231 (unsigned long long)handle.ih_blkno, handle.ih_generation); 212 struct fid *fid, int fh_len, int fh_type)
213{
214 struct ocfs2_inode_handle parent;
232 215
233 ret = ocfs2_export_ops.find_exported_dentry(sb, &handle, &parent, 216 if (fh_type != 2 || fh_len < 6)
234 acceptable, context); 217 return NULL;
235 218
236bail: 219 parent.ih_blkno = (u64)le32_to_cpu(fid->raw[3]) << 32;
237 mlog_exit_ptr(ret); 220 parent.ih_blkno |= (u64)le32_to_cpu(fid->raw[4]);
238 return ret; 221 parent.ih_generation = le32_to_cpu(fid->raw[5]);
222 return ocfs2_get_dentry(sb, &parent);
239} 223}
240 224
241struct export_operations ocfs2_export_ops = { 225const struct export_operations ocfs2_export_ops = {
242 .decode_fh = ocfs2_decode_fh,
243 .encode_fh = ocfs2_encode_fh, 226 .encode_fh = ocfs2_encode_fh,
244 227 .fh_to_dentry = ocfs2_fh_to_dentry,
228 .fh_to_parent = ocfs2_fh_to_parent,
245 .get_parent = ocfs2_get_parent, 229 .get_parent = ocfs2_get_parent,
246 .get_dentry = ocfs2_get_dentry,
247}; 230};
diff --git a/fs/ocfs2/export.h b/fs/ocfs2/export.h
index e08bed9e45a0..41a738678c37 100644
--- a/fs/ocfs2/export.h
+++ b/fs/ocfs2/export.h
@@ -28,6 +28,6 @@
28 28
29#include <linux/exportfs.h> 29#include <linux/exportfs.h>
30 30
31extern struct export_operations ocfs2_export_ops; 31extern const struct export_operations ocfs2_export_ops;
32 32
33#endif /* OCFS2_EXPORT_H */ 33#endif /* OCFS2_EXPORT_H */
diff --git a/fs/open.c b/fs/open.c
index 75385144df7d..3b69c53e1837 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -569,7 +569,7 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
569 dentry = file->f_path.dentry; 569 dentry = file->f_path.dentry;
570 inode = dentry->d_inode; 570 inode = dentry->d_inode;
571 571
572 audit_inode(NULL, inode); 572 audit_inode(NULL, dentry);
573 573
574 err = -EROFS; 574 err = -EROFS;
575 if (IS_RDONLY(inode)) 575 if (IS_RDONLY(inode))
@@ -727,7 +727,7 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
727 goto out; 727 goto out;
728 728
729 dentry = file->f_path.dentry; 729 dentry = file->f_path.dentry;
730 audit_inode(NULL, dentry->d_inode); 730 audit_inode(NULL, dentry);
731 error = chown_common(dentry, user, group); 731 error = chown_common(dentry, user, group);
732 fput(file); 732 fput(file);
733out: 733out:
diff --git a/fs/pnode.h b/fs/pnode.h
index d45bd8ec36bf..f249be2fee7a 100644
--- a/fs/pnode.h
+++ b/fs/pnode.h
@@ -22,6 +22,7 @@
22#define CL_COPY_ALL 0x04 22#define CL_COPY_ALL 0x04
23#define CL_MAKE_SHARED 0x08 23#define CL_MAKE_SHARED 0x08
24#define CL_PROPAGATION 0x10 24#define CL_PROPAGATION 0x10
25#define CL_PRIVATE 0x20
25 26
26static inline void set_mnt_shared(struct vfsmount *mnt) 27static inline void set_mnt_shared(struct vfsmount *mnt)
27{ 28{
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 39a3d7c969c5..aeaf0d0f2f51 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -2255,27 +2255,6 @@ static const struct inode_operations proc_tgid_base_inode_operations = {
2255 .setattr = proc_setattr, 2255 .setattr = proc_setattr,
2256}; 2256};
2257 2257
2258/**
2259 * proc_flush_task - Remove dcache entries for @task from the /proc dcache.
2260 *
2261 * @task: task that should be flushed.
2262 *
2263 * Looks in the dcache for
2264 * /proc/@pid
2265 * /proc/@tgid/task/@pid
2266 * if either directory is present flushes it and all of it'ts children
2267 * from the dcache.
2268 *
2269 * It is safe and reasonable to cache /proc entries for a task until
2270 * that task exits. After that they just clog up the dcache with
2271 * useless entries, possibly causing useful dcache entries to be
2272 * flushed instead. This routine is proved to flush those useless
2273 * dcache entries at process exit time.
2274 *
2275 * NOTE: This routine is just an optimization so it does not guarantee
2276 * that no dcache entries will exist at process exit time it
2277 * just makes it very unlikely that any will persist.
2278 */
2279static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid) 2258static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid)
2280{ 2259{
2281 struct dentry *dentry, *leader, *dir; 2260 struct dentry *dentry, *leader, *dir;
@@ -2322,10 +2301,29 @@ out:
2322 return; 2301 return;
2323} 2302}
2324 2303
2325/* 2304/**
2326 * when flushing dentries from proc one need to flush them from global 2305 * proc_flush_task - Remove dcache entries for @task from the /proc dcache.
2306 * @task: task that should be flushed.
2307 *
2308 * When flushing dentries from proc, one needs to flush them from global
2327 * proc (proc_mnt) and from all the namespaces' procs this task was seen 2309 * proc (proc_mnt) and from all the namespaces' procs this task was seen
2328 * in. this call is supposed to make all this job. 2310 * in. This call is supposed to do all of this job.
2311 *
2312 * Looks in the dcache for
2313 * /proc/@pid
2314 * /proc/@tgid/task/@pid
2315 * if either directory is present flushes it and all of it'ts children
2316 * from the dcache.
2317 *
2318 * It is safe and reasonable to cache /proc entries for a task until
2319 * that task exits. After that they just clog up the dcache with
2320 * useless entries, possibly causing useful dcache entries to be
2321 * flushed instead. This routine is proved to flush those useless
2322 * dcache entries at process exit time.
2323 *
2324 * NOTE: This routine is just an optimization so it does not guarantee
2325 * that no dcache entries will exist at process exit time it
2326 * just makes it very unlikely that any will persist.
2329 */ 2327 */
2330 2328
2331void proc_flush_task(struct task_struct *task) 2329void proc_flush_task(struct task_struct *task)
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index a991af96f3f0..231fd5ccadc5 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -1515,19 +1515,20 @@ struct inode *reiserfs_iget(struct super_block *s, const struct cpu_key *key)
1515 return inode; 1515 return inode;
1516} 1516}
1517 1517
1518struct dentry *reiserfs_get_dentry(struct super_block *sb, void *vobjp) 1518static struct dentry *reiserfs_get_dentry(struct super_block *sb,
1519 u32 objectid, u32 dir_id, u32 generation)
1520
1519{ 1521{
1520 __u32 *data = vobjp;
1521 struct cpu_key key; 1522 struct cpu_key key;
1522 struct dentry *result; 1523 struct dentry *result;
1523 struct inode *inode; 1524 struct inode *inode;
1524 1525
1525 key.on_disk_key.k_objectid = data[0]; 1526 key.on_disk_key.k_objectid = objectid;
1526 key.on_disk_key.k_dir_id = data[1]; 1527 key.on_disk_key.k_dir_id = dir_id;
1527 reiserfs_write_lock(sb); 1528 reiserfs_write_lock(sb);
1528 inode = reiserfs_iget(sb, &key); 1529 inode = reiserfs_iget(sb, &key);
1529 if (inode && !IS_ERR(inode) && data[2] != 0 && 1530 if (inode && !IS_ERR(inode) && generation != 0 &&
1530 data[2] != inode->i_generation) { 1531 generation != inode->i_generation) {
1531 iput(inode); 1532 iput(inode);
1532 inode = NULL; 1533 inode = NULL;
1533 } 1534 }
@@ -1544,14 +1545,9 @@ struct dentry *reiserfs_get_dentry(struct super_block *sb, void *vobjp)
1544 return result; 1545 return result;
1545} 1546}
1546 1547
1547struct dentry *reiserfs_decode_fh(struct super_block *sb, __u32 * data, 1548struct dentry *reiserfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
1548 int len, int fhtype, 1549 int fh_len, int fh_type)
1549 int (*acceptable) (void *contect,
1550 struct dentry * de),
1551 void *context)
1552{ 1550{
1553 __u32 obj[3], parent[3];
1554
1555 /* fhtype happens to reflect the number of u32s encoded. 1551 /* fhtype happens to reflect the number of u32s encoded.
1556 * due to a bug in earlier code, fhtype might indicate there 1552 * due to a bug in earlier code, fhtype might indicate there
1557 * are more u32s then actually fitted. 1553 * are more u32s then actually fitted.
@@ -1564,32 +1560,28 @@ struct dentry *reiserfs_decode_fh(struct super_block *sb, __u32 * data,
1564 * 6 - as above plus generation of directory 1560 * 6 - as above plus generation of directory
1565 * 6 does not fit in NFSv2 handles 1561 * 6 does not fit in NFSv2 handles
1566 */ 1562 */
1567 if (fhtype > len) { 1563 if (fh_type > fh_len) {
1568 if (fhtype != 6 || len != 5) 1564 if (fh_type != 6 || fh_len != 5)
1569 reiserfs_warning(sb, 1565 reiserfs_warning(sb,
1570 "nfsd/reiserfs, fhtype=%d, len=%d - odd", 1566 "nfsd/reiserfs, fhtype=%d, len=%d - odd",
1571 fhtype, len); 1567 fh_type, fh_len);
1572 fhtype = 5; 1568 fh_type = 5;
1573 } 1569 }
1574 1570
1575 obj[0] = data[0]; 1571 return reiserfs_get_dentry(sb, fid->raw[0], fid->raw[1],
1576 obj[1] = data[1]; 1572 (fh_type == 3 || fh_type >= 5) ? fid->raw[2] : 0);
1577 if (fhtype == 3 || fhtype >= 5) 1573}
1578 obj[2] = data[2];
1579 else
1580 obj[2] = 0; /* generation number */
1581 1574
1582 if (fhtype >= 4) { 1575struct dentry *reiserfs_fh_to_parent(struct super_block *sb, struct fid *fid,
1583 parent[0] = data[fhtype >= 5 ? 3 : 2]; 1576 int fh_len, int fh_type)
1584 parent[1] = data[fhtype >= 5 ? 4 : 3]; 1577{
1585 if (fhtype == 6) 1578 if (fh_type < 4)
1586 parent[2] = data[5]; 1579 return NULL;
1587 else 1580
1588 parent[2] = 0; 1581 return reiserfs_get_dentry(sb,
1589 } 1582 (fh_type >= 5) ? fid->raw[3] : fid->raw[2],
1590 return sb->s_export_op->find_exported_dentry(sb, obj, 1583 (fh_type >= 5) ? fid->raw[4] : fid->raw[3],
1591 fhtype < 4 ? NULL : parent, 1584 (fh_type == 6) ? fid->raw[5] : 0);
1592 acceptable, context);
1593} 1585}
1594 1586
1595int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp, 1587int reiserfs_encode_fh(struct dentry *dentry, __u32 * data, int *lenp,
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 98c3781bc069..5cd85fe5df5d 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -661,11 +661,11 @@ static struct quotactl_ops reiserfs_qctl_operations = {
661}; 661};
662#endif 662#endif
663 663
664static struct export_operations reiserfs_export_ops = { 664static const struct export_operations reiserfs_export_ops = {
665 .encode_fh = reiserfs_encode_fh, 665 .encode_fh = reiserfs_encode_fh,
666 .decode_fh = reiserfs_decode_fh, 666 .fh_to_dentry = reiserfs_fh_to_dentry,
667 .fh_to_parent = reiserfs_fh_to_parent,
667 .get_parent = reiserfs_get_parent, 668 .get_parent = reiserfs_get_parent,
668 .get_dentry = reiserfs_get_dentry,
669}; 669};
670 670
671/* this struct is used in reiserfs_getopt () for containing the value for those 671/* this struct is used in reiserfs_getopt () for containing the value for those
diff --git a/fs/xattr.c b/fs/xattr.c
index a44fd92caca3..6645b7313b33 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -267,7 +267,7 @@ sys_fsetxattr(int fd, char __user *name, void __user *value,
267 if (!f) 267 if (!f)
268 return error; 268 return error;
269 dentry = f->f_path.dentry; 269 dentry = f->f_path.dentry;
270 audit_inode(NULL, dentry->d_inode); 270 audit_inode(NULL, dentry);
271 error = setxattr(dentry, name, value, size, flags); 271 error = setxattr(dentry, name, value, size, flags);
272 fput(f); 272 fput(f);
273 return error; 273 return error;
@@ -349,7 +349,7 @@ sys_fgetxattr(int fd, char __user *name, void __user *value, size_t size)
349 f = fget(fd); 349 f = fget(fd);
350 if (!f) 350 if (!f)
351 return error; 351 return error;
352 audit_inode(NULL, f->f_path.dentry->d_inode); 352 audit_inode(NULL, f->f_path.dentry);
353 error = getxattr(f->f_path.dentry, name, value, size); 353 error = getxattr(f->f_path.dentry, name, value, size);
354 fput(f); 354 fput(f);
355 return error; 355 return error;
@@ -422,7 +422,7 @@ sys_flistxattr(int fd, char __user *list, size_t size)
422 f = fget(fd); 422 f = fget(fd);
423 if (!f) 423 if (!f)
424 return error; 424 return error;
425 audit_inode(NULL, f->f_path.dentry->d_inode); 425 audit_inode(NULL, f->f_path.dentry);
426 error = listxattr(f->f_path.dentry, list, size); 426 error = listxattr(f->f_path.dentry, list, size);
427 fput(f); 427 fput(f);
428 return error; 428 return error;
@@ -485,7 +485,7 @@ sys_fremovexattr(int fd, char __user *name)
485 if (!f) 485 if (!f)
486 return error; 486 return error;
487 dentry = f->f_path.dentry; 487 dentry = f->f_path.dentry;
488 audit_inode(NULL, dentry->d_inode); 488 audit_inode(NULL, dentry);
489 error = removexattr(dentry, name); 489 error = removexattr(dentry, name);
490 fput(f); 490 fput(f);
491 return error; 491 return error;
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c
index 3586c7a28d2c..15bd4948832c 100644
--- a/fs/xfs/linux-2.6/xfs_export.c
+++ b/fs/xfs/linux-2.6/xfs_export.c
@@ -33,62 +33,25 @@
33static struct dentry dotdot = { .d_name.name = "..", .d_name.len = 2, }; 33static struct dentry dotdot = { .d_name.name = "..", .d_name.len = 2, };
34 34
35/* 35/*
36 * XFS encodes and decodes the fileid portion of NFS filehandles 36 * Note that we only accept fileids which are long enough rather than allow
37 * itself instead of letting the generic NFS code do it. This 37 * the parent generation number to default to zero. XFS considers zero a
38 * allows filesystems with 64 bit inode numbers to be exported. 38 * valid generation number not an invalid/wildcard value.
39 *
40 * Note that a side effect is that xfs_vget() won't be passed a
41 * zero inode/generation pair under normal circumstances. As
42 * however a malicious client could send us such data, the check
43 * remains in that code.
44 */ 39 */
45 40static int xfs_fileid_length(int fileid_type)
46STATIC struct dentry *
47xfs_fs_decode_fh(
48 struct super_block *sb,
49 __u32 *fh,
50 int fh_len,
51 int fileid_type,
52 int (*acceptable)(
53 void *context,
54 struct dentry *de),
55 void *context)
56{ 41{
57 xfs_fid_t ifid; 42 switch (fileid_type) {
58 xfs_fid_t pfid; 43 case FILEID_INO32_GEN:
59 void *parent = NULL; 44 return 2;
60 int is64 = 0; 45 case FILEID_INO32_GEN_PARENT:
61 __u32 *p = fh; 46 return 4;
62 47 case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG:
63#if XFS_BIG_INUMS 48 return 3;
64 is64 = (fileid_type & XFS_FILEID_TYPE_64FLAG); 49 case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
65 fileid_type &= ~XFS_FILEID_TYPE_64FLAG; 50 return 6;
66#endif
67
68 /*
69 * Note that we only accept fileids which are long enough
70 * rather than allow the parent generation number to default
71 * to zero. XFS considers zero a valid generation number not
72 * an invalid/wildcard value. There's little point printk'ing
73 * a warning here as we don't have the client information
74 * which would make such a warning useful.
75 */
76 if (fileid_type > 2 ||
77 fh_len < xfs_fileid_length((fileid_type == 2), is64))
78 return NULL;
79
80 p = xfs_fileid_decode_fid2(p, &ifid, is64);
81
82 if (fileid_type == 2) {
83 p = xfs_fileid_decode_fid2(p, &pfid, is64);
84 parent = &pfid;
85 } 51 }
86 52 return 255; /* invalid */
87 fh = (__u32 *)&ifid;
88 return sb->s_export_op->find_exported_dentry(sb, fh, parent, acceptable, context);
89} 53}
90 54
91
92STATIC int 55STATIC int
93xfs_fs_encode_fh( 56xfs_fs_encode_fh(
94 struct dentry *dentry, 57 struct dentry *dentry,
@@ -96,21 +59,21 @@ xfs_fs_encode_fh(
96 int *max_len, 59 int *max_len,
97 int connectable) 60 int connectable)
98{ 61{
62 struct fid *fid = (struct fid *)fh;
63 struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fh;
99 struct inode *inode = dentry->d_inode; 64 struct inode *inode = dentry->d_inode;
100 int type = 1; 65 int fileid_type;
101 __u32 *p = fh;
102 int len; 66 int len;
103 int is64 = 0;
104#if XFS_BIG_INUMS
105 if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS)) {
106 /* filesystem may contain 64bit inode numbers */
107 is64 = XFS_FILEID_TYPE_64FLAG;
108 }
109#endif
110 67
111 /* Directories don't need their parent encoded, they have ".." */ 68 /* Directories don't need their parent encoded, they have ".." */
112 if (S_ISDIR(inode->i_mode)) 69 if (S_ISDIR(inode->i_mode))
113 connectable = 0; 70 fileid_type = FILEID_INO32_GEN;
71 else
72 fileid_type = FILEID_INO32_GEN_PARENT;
73
74 /* filesystem may contain 64bit inode numbers */
75 if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS))
76 fileid_type |= XFS_FILEID_TYPE_64FLAG;
114 77
115 /* 78 /*
116 * Only encode if there is enough space given. In practice 79 * Only encode if there is enough space given. In practice
@@ -118,39 +81,118 @@ xfs_fs_encode_fh(
118 * over NFSv2 with the subtree_check export option; the other 81 * over NFSv2 with the subtree_check export option; the other
119 * seven combinations work. The real answer is "don't use v2". 82 * seven combinations work. The real answer is "don't use v2".
120 */ 83 */
121 len = xfs_fileid_length(connectable, is64); 84 len = xfs_fileid_length(fileid_type);
122 if (*max_len < len) 85 if (*max_len < len)
123 return 255; 86 return 255;
124 *max_len = len; 87 *max_len = len;
125 88
126 p = xfs_fileid_encode_inode(p, inode, is64); 89 switch (fileid_type) {
127 if (connectable) { 90 case FILEID_INO32_GEN_PARENT:
128 spin_lock(&dentry->d_lock); 91 spin_lock(&dentry->d_lock);
129 p = xfs_fileid_encode_inode(p, dentry->d_parent->d_inode, is64); 92 fid->i32.parent_ino = dentry->d_parent->d_inode->i_ino;
93 fid->i32.parent_gen = dentry->d_parent->d_inode->i_generation;
130 spin_unlock(&dentry->d_lock); 94 spin_unlock(&dentry->d_lock);
131 type = 2; 95 /*FALLTHRU*/
96 case FILEID_INO32_GEN:
97 fid->i32.ino = inode->i_ino;
98 fid->i32.gen = inode->i_generation;
99 break;
100 case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
101 spin_lock(&dentry->d_lock);
102 fid64->parent_ino = dentry->d_parent->d_inode->i_ino;
103 fid64->parent_gen = dentry->d_parent->d_inode->i_generation;
104 spin_unlock(&dentry->d_lock);
105 /*FALLTHRU*/
106 case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG:
107 fid64->ino = inode->i_ino;
108 fid64->gen = inode->i_generation;
109 break;
132 } 110 }
133 BUG_ON((p - fh) != len); 111
134 return type | is64; 112 return fileid_type;
135} 113}
136 114
137STATIC struct dentry * 115STATIC struct inode *
138xfs_fs_get_dentry( 116xfs_nfs_get_inode(
139 struct super_block *sb, 117 struct super_block *sb,
140 void *data) 118 u64 ino,
141{ 119 u32 generation)
120 {
121 xfs_fid_t xfid;
142 bhv_vnode_t *vp; 122 bhv_vnode_t *vp;
143 struct inode *inode;
144 struct dentry *result;
145 int error; 123 int error;
146 124
147 error = xfs_vget(XFS_M(sb), &vp, data); 125 xfid.fid_len = sizeof(xfs_fid_t) - sizeof(xfid.fid_len);
148 if (error || vp == NULL) 126 xfid.fid_pad = 0;
149 return ERR_PTR(-ESTALE) ; 127 xfid.fid_ino = ino;
128 xfid.fid_gen = generation;
150 129
151 inode = vn_to_inode(vp); 130 error = xfs_vget(XFS_M(sb), &vp, &xfid);
131 if (error)
132 return ERR_PTR(-error);
133
134 return vp ? vn_to_inode(vp) : NULL;
135}
136
137STATIC struct dentry *
138xfs_fs_fh_to_dentry(struct super_block *sb, struct fid *fid,
139 int fh_len, int fileid_type)
140{
141 struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fid;
142 struct inode *inode = NULL;
143 struct dentry *result;
144
145 if (fh_len < xfs_fileid_length(fileid_type))
146 return NULL;
147
148 switch (fileid_type) {
149 case FILEID_INO32_GEN_PARENT:
150 case FILEID_INO32_GEN:
151 inode = xfs_nfs_get_inode(sb, fid->i32.ino, fid->i32.gen);
152 break;
153 case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
154 case FILEID_INO32_GEN | XFS_FILEID_TYPE_64FLAG:
155 inode = xfs_nfs_get_inode(sb, fid64->ino, fid64->gen);
156 break;
157 }
158
159 if (!inode)
160 return NULL;
161 if (IS_ERR(inode))
162 return ERR_PTR(PTR_ERR(inode));
163 result = d_alloc_anon(inode);
164 if (!result) {
165 iput(inode);
166 return ERR_PTR(-ENOMEM);
167 }
168 return result;
169}
170
171STATIC struct dentry *
172xfs_fs_fh_to_parent(struct super_block *sb, struct fid *fid,
173 int fh_len, int fileid_type)
174{
175 struct xfs_fid64 *fid64 = (struct xfs_fid64 *)fid;
176 struct inode *inode = NULL;
177 struct dentry *result;
178
179 switch (fileid_type) {
180 case FILEID_INO32_GEN_PARENT:
181 inode = xfs_nfs_get_inode(sb, fid->i32.parent_ino,
182 fid->i32.parent_gen);
183 break;
184 case FILEID_INO32_GEN_PARENT | XFS_FILEID_TYPE_64FLAG:
185 inode = xfs_nfs_get_inode(sb, fid64->parent_ino,
186 fid64->parent_gen);
187 break;
188 }
189
190 if (!inode)
191 return NULL;
192 if (IS_ERR(inode))
193 return ERR_PTR(PTR_ERR(inode));
152 result = d_alloc_anon(inode); 194 result = d_alloc_anon(inode);
153 if (!result) { 195 if (!result) {
154 iput(inode); 196 iput(inode);
155 return ERR_PTR(-ENOMEM); 197 return ERR_PTR(-ENOMEM);
156 } 198 }
@@ -178,9 +220,9 @@ xfs_fs_get_parent(
178 return parent; 220 return parent;
179} 221}
180 222
181struct export_operations xfs_export_operations = { 223const struct export_operations xfs_export_operations = {
182 .decode_fh = xfs_fs_decode_fh,
183 .encode_fh = xfs_fs_encode_fh, 224 .encode_fh = xfs_fs_encode_fh,
225 .fh_to_dentry = xfs_fs_fh_to_dentry,
226 .fh_to_parent = xfs_fs_fh_to_parent,
184 .get_parent = xfs_fs_get_parent, 227 .get_parent = xfs_fs_get_parent,
185 .get_dentry = xfs_fs_get_dentry,
186}; 228};
diff --git a/fs/xfs/linux-2.6/xfs_export.h b/fs/xfs/linux-2.6/xfs_export.h
index 2f36071a86f7..3272b6ae7a35 100644
--- a/fs/xfs/linux-2.6/xfs_export.h
+++ b/fs/xfs/linux-2.6/xfs_export.h
@@ -59,50 +59,14 @@
59 * a subdirectory) or use the "fsid" export option. 59 * a subdirectory) or use the "fsid" export option.
60 */ 60 */
61 61
62struct xfs_fid64 {
63 u64 ino;
64 u32 gen;
65 u64 parent_ino;
66 u32 parent_gen;
67} __attribute__((packed));
68
62/* This flag goes on the wire. Don't play with it. */ 69/* This flag goes on the wire. Don't play with it. */
63#define XFS_FILEID_TYPE_64FLAG 0x80 /* NFS fileid has 64bit inodes */ 70#define XFS_FILEID_TYPE_64FLAG 0x80 /* NFS fileid has 64bit inodes */
64 71
65/* Calculate the length in u32 units of the fileid data */
66static inline int
67xfs_fileid_length(int hasparent, int is64)
68{
69 return hasparent ? (is64 ? 6 : 4) : (is64 ? 3 : 2);
70}
71
72/*
73 * Decode encoded inode information (either for the inode itself
74 * or the parent) into an xfs_fid_t structure. Advances and
75 * returns the new data pointer
76 */
77static inline __u32 *
78xfs_fileid_decode_fid2(__u32 *p, xfs_fid_t *fid, int is64)
79{
80 fid->fid_len = sizeof(xfs_fid_t) - sizeof(fid->fid_len);
81 fid->fid_pad = 0;
82 fid->fid_ino = *p++;
83#if XFS_BIG_INUMS
84 if (is64)
85 fid->fid_ino |= (((__u64)(*p++)) << 32);
86#endif
87 fid->fid_gen = *p++;
88 return p;
89}
90
91/*
92 * Encode inode information (either for the inode itself or the
93 * parent) into a fileid buffer. Advances and returns the new
94 * data pointer.
95 */
96static inline __u32 *
97xfs_fileid_encode_inode(__u32 *p, struct inode *inode, int is64)
98{
99 *p++ = (__u32)inode->i_ino;
100#if XFS_BIG_INUMS
101 if (is64)
102 *p++ = (__u32)(inode->i_ino >> 32);
103#endif
104 *p++ = inode->i_generation;
105 return p;
106}
107
108#endif /* __XFS_EXPORT_H__ */ 72#endif /* __XFS_EXPORT_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_super.h b/fs/xfs/linux-2.6/xfs_super.h
index c78c23310fe8..3efcf45b14ab 100644
--- a/fs/xfs/linux-2.6/xfs_super.h
+++ b/fs/xfs/linux-2.6/xfs_super.h
@@ -118,7 +118,7 @@ extern int xfs_blkdev_get(struct xfs_mount *, const char *,
118extern void xfs_blkdev_put(struct block_device *); 118extern void xfs_blkdev_put(struct block_device *);
119extern void xfs_blkdev_issue_flush(struct xfs_buftarg *); 119extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
120 120
121extern struct export_operations xfs_export_operations; 121extern const struct export_operations xfs_export_operations;
122 122
123#define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info)) 123#define XFS_M(sb) ((struct xfs_mount *)((sb)->s_fs_info))
124 124