aboutsummaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/afs/cell.c1
-rw-r--r--fs/afs/dir.c1
-rw-r--r--fs/afs/file.c1
-rw-r--r--fs/afs/inode.c1
-rw-r--r--fs/afs/main.c1
-rw-r--r--fs/afs/mntpt.c1
-rw-r--r--fs/afs/proc.c1
-rw-r--r--fs/binfmt_elf.c3
-rw-r--r--fs/coda/sysctl.c60
-rw-r--r--fs/dquot.c2
-rw-r--r--fs/ecryptfs/keystore.c1
-rw-r--r--fs/ext3/hash.c1
-rw-r--r--fs/ext3/resize.c1
-rw-r--r--fs/ext4/hash.c1
-rw-r--r--fs/ext4/resize.c1
-rw-r--r--fs/filesystems.c1
-rw-r--r--fs/gfs2/bmap.c1
-rw-r--r--fs/gfs2/dir.c1
-rw-r--r--fs/gfs2/eaops.c1
-rw-r--r--fs/gfs2/eattr.c1
-rw-r--r--fs/gfs2/glops.c1
-rw-r--r--fs/gfs2/lm.c1
-rw-r--r--fs/gfs2/main.c1
-rw-r--r--fs/gfs2/mount.c1
-rw-r--r--fs/gfs2/ondisk.c1
-rw-r--r--fs/gfs2/ops_dentry.c1
-rw-r--r--fs/gfs2/ops_export.c1
-rw-r--r--fs/gfs2/ops_file.c1
-rw-r--r--fs/gfs2/ops_inode.c1
-rw-r--r--fs/gfs2/ops_vm.c1
-rw-r--r--fs/gfs2/recovery.c1
-rw-r--r--fs/gfs2/rgrp.c1
-rw-r--r--fs/gfs2/util.c1
-rw-r--r--fs/hfsplus/catalog.c1
-rw-r--r--fs/hfsplus/dir.c1
-rw-r--r--fs/hfsplus/super.c1
-rw-r--r--fs/jffs2/compr_zlib.c1
-rw-r--r--fs/jffs2/dir.c1
-rw-r--r--fs/jffs2/summary.c1
-rw-r--r--fs/lockd/host.c1
-rw-r--r--fs/lockd/svc.c2
-rw-r--r--fs/nfs/nfs4renewd.c1
-rw-r--r--fs/nfs/sysctl.c2
-rw-r--r--fs/nfsd/export.c107
-rw-r--r--fs/nfsd/nfs3xdr.c31
-rw-r--r--fs/nfsd/nfs4idmap.c1
-rw-r--r--fs/nfsd/nfs4xdr.c10
-rw-r--r--fs/nfsd/nfsctl.c2
-rw-r--r--fs/nfsd/nfsfh.c145
-rw-r--r--fs/nfsd/nfsxdr.c19
-rw-r--r--fs/ntfs/sysctl.c34
-rw-r--r--fs/ocfs2/cluster/nodemanager.c6
-rw-r--r--fs/ocfs2/cluster/nodemanager.h3
-rw-r--r--fs/proc/Makefile2
-rw-r--r--fs/proc/generic.c2
-rw-r--r--fs/proc/inode.c1
-rw-r--r--fs/proc/internal.h2
-rw-r--r--fs/proc/proc_sysctl.c479
-rw-r--r--fs/proc/root.c14
-rw-r--r--fs/smbfs/symlink.c1
-rw-r--r--fs/ufs/balloc.c1
-rw-r--r--fs/ufs/dir.c1
-rw-r--r--fs/xattr_acl.c1
-rw-r--r--fs/xfs/linux-2.6/kmem.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_sysctl.c2
65 files changed, 752 insertions, 220 deletions
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index bfc1fd22d5b..1fc57837275 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -10,7 +10,6 @@
*/
#include <linux/module.h>
-#include <linux/sched.h>
#include <linux/slab.h>
#include <rxrpc/peer.h>
#include <rxrpc/connection.h>
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index 9908462bcad..b6dc2ebe47a 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
diff --git a/fs/afs/file.c b/fs/afs/file.c
index eeff14c3f74..b17634541f6 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
diff --git a/fs/afs/inode.c b/fs/afs/inode.c
index 6f37754906c..9d9bca6c28b 100644
--- a/fs/afs/inode.c
+++ b/fs/afs/inode.c
@@ -16,7 +16,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
diff --git a/fs/afs/main.c b/fs/afs/main.c
index 913c689bdb3..f2704ba5385 100644
--- a/fs/afs/main.c
+++ b/fs/afs/main.c
@@ -12,7 +12,6 @@
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
-#include <linux/sched.h>
#include <linux/completion.h>
#include <rxrpc/rxrpc.h>
#include <rxrpc/transport.h>
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index fdf23b2a211..68495f0de7b 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -12,7 +12,6 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
diff --git a/fs/afs/proc.c b/fs/afs/proc.c
index 86463ec9ccb..ae6b85b1e48 100644
--- a/fs/afs/proc.c
+++ b/fs/afs/proc.c
@@ -9,7 +9,6 @@
* 2 of the License, or (at your option) any later version.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 669dbe5b031..51db1182b27 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -76,7 +76,8 @@ static struct linux_binfmt elf_format = {
.load_binary = load_elf_binary,
.load_shlib = load_elf_library,
.core_dump = elf_core_dump,
- .min_coredump = ELF_EXEC_PAGESIZE
+ .min_coredump = ELF_EXEC_PAGESIZE,
+ .hasvdso = 1
};
#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)
diff --git a/fs/coda/sysctl.c b/fs/coda/sysctl.c
index db3b1a9c9a5..c57a1fa7cf2 100644
--- a/fs/coda/sysctl.c
+++ b/fs/coda/sysctl.c
@@ -33,8 +33,6 @@
static struct ctl_table_header *fs_table_header;
-#define FS_CODA 1 /* Coda file system */
-
#define CODA_TIMEOUT 3 /* timeout on upcalls to become intrble */
#define CODA_HARD 5 /* mount type "hard" or "soft" */
#define CODA_VFS 6 /* vfs statistics */
@@ -183,17 +181,57 @@ static const struct file_operations proc_cache_inv_stats_fops = {
};
static ctl_table coda_table[] = {
- {CODA_TIMEOUT, "timeout", &coda_timeout, sizeof(int), 0644, NULL, &proc_dointvec},
- {CODA_HARD, "hard", &coda_hard, sizeof(int), 0644, NULL, &proc_dointvec},
- {CODA_VFS, "vfs_stats", NULL, 0, 0644, NULL, &do_reset_coda_vfs_stats},
- {CODA_CACHE_INV, "cache_inv_stats", NULL, 0, 0644, NULL, &do_reset_coda_cache_inv_stats},
- {CODA_FAKE_STATFS, "fake_statfs", &coda_fake_statfs, sizeof(int), 0600, NULL, &proc_dointvec},
- { 0 }
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "timeout",
+ .data = &coda_timeout,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "hard",
+ .data = &coda_hard,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = &proc_dointvec
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "vfs_stats",
+ .data = NULL,
+ .maxlen = 0,
+ .mode = 0644,
+ .proc_handler = &do_reset_coda_vfs_stats
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "cache_inv_stats",
+ .data = NULL,
+ .maxlen = 0,
+ .mode = 0644,
+ .proc_handler = &do_reset_coda_cache_inv_stats
+ },
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "fake_statfs",
+ .data = &coda_fake_statfs,
+ .maxlen = sizeof(int),
+ .mode = 0600,
+ .proc_handler = &proc_dointvec
+ },
+ {}
};
static ctl_table fs_table[] = {
- {FS_CODA, "coda", NULL, 0, 0555, coda_table},
- {0}
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "coda",
+ .mode = 0555,
+ .child = coda_table
+ },
+ {}
};
@@ -233,7 +271,7 @@ void coda_sysctl_init(void)
#ifdef CONFIG_SYSCTL
if ( !fs_table_header )
- fs_table_header = register_sysctl_table(fs_table, 0);
+ fs_table_header = register_sysctl_table(fs_table);
#endif
}
diff --git a/fs/dquot.c b/fs/dquot.c
index 9eb166f9148..b16f991662c 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -1841,7 +1841,7 @@ static int __init dquot_init(void)
printk(KERN_NOTICE "VFS: Disk quotas %s\n", __DQUOT_VERSION__);
- register_sysctl_table(sys_table, 0);
+ register_sysctl_table(sys_table);
dquot_cachep = kmem_cache_create("dquot",
sizeof(struct dquot), sizeof(unsigned long) * 4,
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index c209f67e7a2..81156e95ef8 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -26,7 +26,6 @@
*/
#include <linux/string.h>
-#include <linux/sched.h>
#include <linux/syscalls.h>
#include <linux/pagemap.h>
#include <linux/key.h>
diff --git a/fs/ext3/hash.c b/fs/ext3/hash.c
index deeb27b5ba8..c30e149fbd2 100644
--- a/fs/ext3/hash.c
+++ b/fs/ext3/hash.c
@@ -11,7 +11,6 @@
#include <linux/fs.h>
#include <linux/jbd.h>
-#include <linux/sched.h>
#include <linux/ext3_fs.h>
#include <linux/cryptohash.h>
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index b73cba12f79..ecf89904c11 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -11,7 +11,6 @@
#define EXT3FS_DEBUG
-#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/ext3_jbd.h>
diff --git a/fs/ext4/hash.c b/fs/ext4/hash.c
index a67966385e0..1555024e3b3 100644
--- a/fs/ext4/hash.c
+++ b/fs/ext4/hash.c
@@ -11,7 +11,6 @@
#include <linux/fs.h>
#include <linux/jbd2.h>
-#include <linux/sched.h>
#include <linux/ext4_fs.h>
#include <linux/cryptohash.h>
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 4fe49c3661b..ea99f6c97f5 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -11,7 +11,6 @@
#define EXT4FS_DEBUG
-#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/ext4_jbd2.h>
diff --git a/fs/filesystems.c b/fs/filesystems.c
index e3fa77c6ed5..7a4f61aa05f 100644
--- a/fs/filesystems.c
+++ b/fs/filesystems.c
@@ -12,7 +12,6 @@
#include <linux/kmod.h>
#include <linux/init.h>
#include <linux/module.h>
-#include <linux/sched.h> /* for 'current' */
#include <asm/uaccess.h>
/*
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 113f6c9110c..c53a5d2d059 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index c93ca8f361b..82a1ac7895a 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -53,7 +53,6 @@
* but never before the maximum hash table size has been reached.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/buffer_head.h>
diff --git a/fs/gfs2/eaops.c b/fs/gfs2/eaops.c
index cd747c00f67..c1f44009853 100644
--- a/fs/gfs2/eaops.c
+++ b/fs/gfs2/eaops.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/gfs2/eattr.c b/fs/gfs2/eattr.c
index 0c83c7f4dda..5b83ca6acab 100644
--- a/fs/gfs2/eattr.c
+++ b/fs/gfs2/eattr.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index c4b0391b7aa..46af5535551 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/gfs2/lm.c b/fs/gfs2/lm.c
index e30673dd37e..cfcc39b86a5 100644
--- a/fs/gfs2/lm.c
+++ b/fs/gfs2/lm.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c
index 7c1a9e22a52..6e8a59809ab 100644
--- a/fs/gfs2/main.c
+++ b/fs/gfs2/main.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/gfs2/mount.c b/fs/gfs2/mount.c
index ef3092e2960..32caecd2030 100644
--- a/fs/gfs2/mount.c
+++ b/fs/gfs2/mount.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/gfs2/ondisk.c b/fs/gfs2/ondisk.c
index f2495f1e21a..d9ecfd23a49 100644
--- a/fs/gfs2/ondisk.c
+++ b/fs/gfs2/ondisk.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/gfs2/ops_dentry.c b/fs/gfs2/ops_dentry.c
index 9187eb174b4..c6bac6b6942 100644
--- a/fs/gfs2/ops_dentry.c
+++ b/fs/gfs2/ops_dentry.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
index 4855e8cca62..1de05b63d43 100644
--- a/fs/gfs2/ops_export.c
+++ b/fs/gfs2/ops_export.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index c996aa739a0..b50180e2277 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 60f47bf2e8e..d85f6e05cb9 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c
index 14b380fb060..aa0dbd2aac1 100644
--- a/fs/gfs2/ops_vm.c
+++ b/fs/gfs2/ops_vm.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c
index d0c806b85c8..8bc182c7e2e 100644
--- a/fs/gfs2/recovery.c
+++ b/fs/gfs2/recovery.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index ff0846528d5..8d9c08b5c4b 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/gfs2/util.c b/fs/gfs2/util.c
index e5707a9f78c..601eaa1b9ed 100644
--- a/fs/gfs2/util.c
+++ b/fs/gfs2/util.c
@@ -7,7 +7,6 @@
* of the GNU General Public License version 2.
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
diff --git a/fs/hfsplus/catalog.c b/fs/hfsplus/catalog.c
index f2d7c49ce75..ba117c445e7 100644
--- a/fs/hfsplus/catalog.c
+++ b/fs/hfsplus/catalog.c
@@ -8,7 +8,6 @@
* Handling of catalog records
*/
-#include <linux/sched.h>
#include "hfsplus_fs.h"
#include "hfsplus_raw.h"
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c
index 78137007ccc..80b5682a227 100644
--- a/fs/hfsplus/dir.c
+++ b/fs/hfsplus/dir.c
@@ -10,7 +10,6 @@
#include <linux/errno.h>
#include <linux/fs.h>
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/random.h>
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 5a282f64c63..1a97f929344 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -11,7 +11,6 @@
#include <linux/init.h>
#include <linux/pagemap.h>
#include <linux/fs.h>
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/vfs.h>
#include <linux/nls.h>
diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c
index 3681d0728ac..0c1fc6e20b4 100644
--- a/fs/jffs2/compr_zlib.c
+++ b/fs/jffs2/compr_zlib.c
@@ -16,7 +16,6 @@
#endif
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/zlib.h>
#include <linux/zutil.h>
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index cdbe2fe14e2..9fa2e27f064 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -13,7 +13,6 @@
#include <linux/kernel.h>
#include <linux/slab.h>
-#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/crc32.h>
#include <linux/jffs2.h>
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index 25265965bdc..30f888414ce 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -14,7 +14,6 @@
*/
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/mtd/mtd.h>
#include <linux/pagemap.h>
diff --git a/fs/lockd/host.c b/fs/lockd/host.c
index 22d40320897..ad21c0713ef 100644
--- a/fs/lockd/host.c
+++ b/fs/lockd/host.c
@@ -9,7 +9,6 @@
*/
#include <linux/types.h>
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/in.h>
#include <linux/sunrpc/clnt.h>
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index 80fcacc1acf..50cb8daba4e 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -512,7 +512,7 @@ module_param(nsm_use_hostnames, bool, 0644);
static int __init init_nlm(void)
{
- nlm_sysctl_table = register_sysctl_table(nlm_sysctl_root, 0);
+ nlm_sysctl_table = register_sysctl_table(nlm_sysctl_root);
return nlm_sysctl_table ? 0 : -ENOMEM;
}
diff --git a/fs/nfs/nfs4renewd.c b/fs/nfs/nfs4renewd.c
index 823298561c0..f5f4430fb2a 100644
--- a/fs/nfs/nfs4renewd.c
+++ b/fs/nfs/nfs4renewd.c
@@ -43,7 +43,6 @@
* child task framework of the RPC layer?
*/
-#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <linux/mm.h>
#include <linux/pagemap.h>
diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c
index 3ea50ac6482..fcdcafbb329 100644
--- a/fs/nfs/sysctl.c
+++ b/fs/nfs/sysctl.c
@@ -75,7 +75,7 @@ static ctl_table nfs_cb_sysctl_root[] = {
int nfs_register_sysctl(void)
{
- nfs_callback_sysctl_table = register_sysctl_table(nfs_cb_sysctl_root, 0);
+ nfs_callback_sysctl_table = register_sysctl_table(nfs_cb_sysctl_root);
if (nfs_callback_sysctl_table == NULL)
return -ENOMEM;
return 0;
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 49c310b8492..6f24768272a 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -16,7 +16,6 @@
#include <linux/unistd.h>
#include <linux/slab.h>
-#include <linux/sched.h>
#include <linux/stat.h>
#include <linux/in.h>
#include <linux/seq_file.h>
@@ -190,18 +189,17 @@ static int expkey_show(struct seq_file *m,
struct cache_head *h)
{
struct svc_expkey *ek ;
+ int i;
if (h ==NULL) {
seq_puts(m, "#domain fsidtype fsid [path]\n");
return 0;
}
ek = container_of(h, struct svc_expkey, h);
- seq_printf(m, "%s %d 0x%08x", ek->ek_client->name,
- ek->ek_fsidtype, ek->ek_fsid[0]);
- if (ek->ek_fsidtype != 1)
- seq_printf(m, "%08x", ek->ek_fsid[1]);
- if (ek->ek_fsidtype == 2)
- seq_printf(m, "%08x", ek->ek_fsid[2]);
+ seq_printf(m, "%s %d 0x", ek->ek_client->name,
+ ek->ek_fsidtype);
+ for (i=0; i < key_len(ek->ek_fsidtype)/4; i++)
+ seq_printf(m, "%08x", ek->ek_fsid[i]);
if (test_bit(CACHE_VALID, &h->flags) &&
!test_bit(CACHE_NEGATIVE, &h->flags)) {
seq_printf(m, " ");
@@ -232,9 +230,8 @@ static inline void expkey_init(struct cache_head *cnew,
kref_get(&item->ek_client->ref);
new->ek_client = item->ek_client;
new->ek_fsidtype = item->ek_fsidtype;
- new->ek_fsid[0] = item->ek_fsid[0];
- new->ek_fsid[1] = item->ek_fsid[1];
- new->ek_fsid[2] = item->ek_fsid[2];
+
+ memcpy(new->ek_fsid, item->ek_fsid, sizeof(new->ek_fsid));
}
static inline void expkey_update(struct cache_head *cnew,
@@ -363,7 +360,7 @@ static struct svc_export *svc_export_update(struct svc_export *new,
struct svc_export *old);
static struct svc_export *svc_export_lookup(struct svc_export *);
-static int check_export(struct inode *inode, int flags)
+static int check_export(struct inode *inode, int flags, unsigned char *uuid)
{
/* We currently export only dirs and regular files.
@@ -376,12 +373,13 @@ static int check_export(struct inode *inode, int flags)
/* There are two requirements on a filesystem to be exportable.
* 1: We must be able to identify the filesystem from a number.
* either a device number (so FS_REQUIRES_DEV needed)
- * or an FSID number (so NFSEXP_FSID needed).
+ * or an FSID number (so NFSEXP_FSID or ->uuid is needed).
* 2: We must be able to find an inode from a filehandle.
* This means that s_export_op must be set.
*/
if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) &&
- !(flags & NFSEXP_FSID)) {
+ !(flags & NFSEXP_FSID) &&
+ uuid == NULL) {
dprintk("exp_export: export of non-dev fs without fsid\n");
return -EINVAL;
}
@@ -406,10 +404,6 @@ fsloc_parse(char **mesg, char *buf, struct nfsd4_fs_locations *fsloc)
int len;
int migrated, i, err;
- len = qword_get(mesg, buf, PAGE_SIZE);
- if (len != 5 || memcmp(buf, "fsloc", 5))
- return 0;
-
/* listsize */
err = get_int(mesg, &fsloc->locations_count);
if (err)
@@ -520,6 +514,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
exp.ex_fslocs.locations_count = 0;
exp.ex_fslocs.migrated = 0;
+ exp.ex_uuid = NULL;
+
/* flags */
err = get_int(&mesg, &an_int);
if (err == -ENOENT)
@@ -543,12 +539,33 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
if (err) goto out;
exp.ex_fsid = an_int;
- err = check_export(nd.dentry->d_inode, exp.ex_flags);
- if (err) goto out;
+ while ((len = qword_get(&mesg, buf, PAGE_SIZE)) > 0) {
+ if (strcmp(buf, "fsloc") == 0)
+ err = fsloc_parse(&mesg, buf, &exp.ex_fslocs);
+ else if (strcmp(buf, "uuid") == 0) {
+ /* expect a 16 byte uuid encoded as \xXXXX... */
+ len = qword_get(&mesg, buf, PAGE_SIZE);
+ if (len != 16)
+ err = -EINVAL;
+ else {
+ exp.ex_uuid =
+ kmemdup(buf, 16, GFP_KERNEL);
+ if (exp.ex_uuid == NULL)
+ err = -ENOMEM;
+ }
+ } else
+ /* quietly ignore unknown words and anything
+ * following. Newer user-space can try to set
+ * new values, then see what the result was.
+ */
+ break;
+ if (err)
+ goto out;
+ }
- err = fsloc_parse(&mesg, buf, &exp.ex_fslocs);
- if (err)
- goto out;
+ err = check_export(nd.dentry->d_inode, exp.ex_flags,
+ exp.ex_uuid);
+ if (err) goto out;
}
expp = svc_export_lookup(&exp);
@@ -562,6 +579,8 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen)
else
exp_put(expp);
out:
+ nfsd4_fslocs_free(&exp.ex_fslocs);
+ kfree(exp.ex_uuid);
kfree(exp.ex_path);
if (nd.dentry)
path_release(&nd);
@@ -591,9 +610,19 @@ static int svc_export_show(struct seq_file *m,
seq_escape(m, exp->ex_client->name, " \t\n\\");
seq_putc(m, '(');
if (test_bit(CACHE_VALID, &h->flags) &&
- !test_bit(CACHE_NEGATIVE, &h->flags))
+ !test_bit(CACHE_NEGATIVE, &h->flags)) {
exp_flags(m, exp->ex_flags, exp->ex_fsid,
exp->ex_anon_uid, exp->ex_anon_gid, &exp->ex_fslocs);
+ if (exp->ex_uuid) {
+ int i;
+ seq_puts(m, ",uuid=");
+ for (i=0; i<16; i++) {
+ if ((i&3) == 0 && i)
+ seq_putc(m, ':');
+ seq_printf(m, "%02x", exp->ex_uuid[i]);
+ }
+ }
+ }
seq_puts(m, ")\n");
return 0;
}
@@ -630,6 +659,8 @@ static void export_update(struct cache_head *cnew, struct cache_head *citem)
new->ex_anon_uid = item->ex_anon_uid;
new->ex_anon_gid = item->ex_anon_gid;
new->ex_fsid = item->ex_fsid;
+ new->ex_uuid = item->ex_uuid;
+ item->ex_uuid = NULL;
new->ex_path = item->ex_path;
item->ex_path = NULL;
new->ex_fslocs.locations = item->ex_fslocs.locations;
@@ -752,11 +783,11 @@ exp_get_key(svc_client *clp, dev_t dev, ino_t ino)
u32 fsidv[3];
if (old_valid_dev(dev)) {
- mk_fsid_v0(fsidv, dev, ino);
- return exp_find_key(clp, 0, fsidv, NULL);
+ mk_fsid(FSID_DEV, fsidv, dev, ino, 0, NULL);
+ return exp_find_key(clp, FSID_DEV, fsidv, NULL);
}
- mk_fsid_v3(fsidv, dev, ino);
- return exp_find_key(clp, 3, fsidv, NULL);
+ mk_fsid(FSID_ENCODE_DEV, fsidv, dev, ino, 0, NULL);
+ return exp_find_key(clp, FSID_ENCODE_DEV, fsidv, NULL);
}
/*
@@ -767,9 +798,9 @@ exp_get_fsid_key(svc_client *clp, int fsid)
{
u32 fsidv[2];
- mk_fsid_v1(fsidv, fsid);
+ mk_fsid(FSID_NUM, fsidv, 0, 0, fsid, NULL);
- return exp_find_key(clp, 1, fsidv, NULL);
+ return exp_find_key(clp, FSID_NUM, fsidv, NULL);
}
svc_export *
@@ -883,8 +914,8 @@ static int exp_fsid_hash(svc_client *clp, struct svc_export *exp)
if ((exp->ex_flags & NFSEXP_FSID) == 0)
return 0;
- mk_fsid_v1(fsid, exp->ex_fsid);
- return exp_set_key(clp, 1, fsid, exp);
+ mk_fsid(FSID_NUM, fsid, 0, 0, exp->ex_fsid, NULL);
+ return exp_set_key(clp, FSID_NUM, fsid, exp);
}
static int exp_hash(struct auth_domain *clp, struct svc_export *exp)
@@ -894,11 +925,11 @@ static int exp_hash(struct auth_domain *clp, struct svc_export *exp)
dev_t dev = inode->i_sb->s_dev;
if (old_valid_dev(dev)) {
- mk_fsid_v0(fsid, dev, inode->i_ino);
- return exp_set_key(clp, 0, fsid, exp);
+ mk_fsid(FSID_DEV, fsid, dev, inode->i_ino, 0, NULL);
+ return exp_set_key(clp, FSID_DEV, fsid, exp);
}
- mk_fsid_v3(fsid, dev, inode->i_ino);
- return exp_set_key(clp, 3, fsid, exp);
+ mk_fsid(FSID_ENCODE_DEV, fsid, dev, inode->i_ino, 0, NULL);
+ return exp_set_key(clp, FSID_ENCODE_DEV, fsid, exp);
}
static void exp_unhash(struct svc_export *exp)
@@ -977,7 +1008,7 @@ exp_export(struct nfsctl_export *nxp)
goto finish;
}
- err = check_export(nd.dentry->d_inode, nxp->ex_flags);
+ err = check_export(nd.dentry->d_inode, nxp->ex_flags, NULL);
if (err) goto finish;
err = -ENOMEM;
@@ -1170,9 +1201,9 @@ exp_pseudoroot(struct auth_domain *clp, struct svc_fh *fhp,
__be32 rv;
u32 fsidv[2];
- mk_fsid_v1(fsidv, 0);
+ mk_fsid(FSID_NUM, fsidv, 0, 0, 0, NULL);
- exp = exp_find(clp, 1, fsidv, creq);
+ exp = exp_find(clp, FSID_NUM, fsidv, creq);
if (IS_ERR(exp))
return nfserrno(PTR_ERR(exp));
if (exp == NULL)
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index e695660921e..6f677988c71 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -149,6 +149,27 @@ decode_sattr3(__be32 *p, struct iattr *iap)
return p;
}
+static __be32 *encode_fsid(__be32 *p, struct svc_fh *fhp)
+{
+ u64 f;
+ switch(fsid_source(fhp)) {
+ default:
+ case FSIDSOURCE_DEV:
+ p = xdr_encode_hyper(p, (u64)huge_encode_dev
+ (fhp->fh_dentry->d_inode->i_sb->s_dev));
+ break;
+ case FSIDSOURCE_FSID:
+ p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
+ break;
+ case FSIDSOURCE_UUID:
+ f = ((u64*)fhp->fh_export->ex_uuid)[0];
+ f ^= ((u64*)fhp->fh_export->ex_uuid)[1];
+ p = xdr_encode_hyper(p, f);
+ break;
+ }
+ return p;
+}
+
static __be32 *
encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
struct kstat *stat)
@@ -169,10 +190,7 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
p = xdr_encode_hyper(p, ((u64)stat->blocks) << 9);
*p++ = htonl((u32) MAJOR(stat->rdev));
*p++ = htonl((u32) MINOR(stat->rdev));
- if (is_fsid(fhp, rqstp->rq_reffh))
- p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
- else
- p = xdr_encode_hyper(p, (u64) huge_encode_dev(stat->dev));
+ p = encode_fsid(p, fhp);
p = xdr_encode_hyper(p, (u64) stat->ino);
p = encode_time3(p, &stat->atime);
lease_get_mtime(dentry->d_inode, &time);
@@ -203,10 +221,7 @@ encode_saved_post_attr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp)
p = xdr_encode_hyper(p, ((u64)fhp->fh_post_blocks) << 9);
*p++ = fhp->fh_post_rdev[0];
*p++ = fhp->fh_post_rdev[1];
- if (is_fsid(fhp, rqstp->rq_reffh))
- p = xdr_encode_hyper(p, (u64) fhp->fh_export->ex_fsid);
- else
- p = xdr_encode_hyper(p, (u64)huge_encode_dev(inode->i_sb->s_dev));
+ p = encode_fsid(p, fhp);
p = xdr_encode_hyper(p, (u64) inode->i_ino);
p = encode_time3(p, &fhp->fh_post_atime);
p = encode_time3(p, &fhp->fh_post_mtime);
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index b1902ebaab4..e4a83d727af 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -50,7 +50,6 @@
#include <linux/sunrpc/cache.h>
#include <linux/nfsd_idmap.h>
#include <linux/list.h>
-#include <linux/sched.h>
#include <linux/time.h>
#include <linux/seq_file.h>
#include <linux/sunrpc/svcauth.h>
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 18aa9440df1..0efba557fb5 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1563,14 +1563,20 @@ nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp,
if (exp->ex_fslocs.migrated) {
WRITE64(NFS4_REFERRAL_FSID_MAJOR);
WRITE64(NFS4_REFERRAL_FSID_MINOR);
- } else if (is_fsid(fhp, rqstp->rq_reffh)) {
+ } else switch(fsid_source(fhp)) {
+ case FSIDSOURCE_FSID:
WRITE64((u64)exp->ex_fsid);
WRITE64((u64)0);
- } else {
+ break;
+ case FSIDSOURCE_DEV:
WRITE32(0);
WRITE32(MAJOR(stat.dev));
WRITE32(0);
WRITE32(MINOR(stat.dev));
+ break;
+ case FSIDSOURCE_UUID:
+ WRITEMEM(exp->ex_uuid, 16);
+ break;
}
}
if (bmval0 & FATTR4_WORD0_UNIQUE_HANDLES) {
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index eedf2e3990a..71c686dc725 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -123,7 +123,7 @@ static ssize_t nfsctl_transaction_write(struct file *file, const char __user *bu
return PTR_ERR(data);
rv = write_op[ino](file, data, size);
- if (rv>0) {
+ if (rv >= 0) {
simple_transaction_set(file, rv);
rv = size;
}
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index a0b4282cb28..c2660cbfcd9 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -9,7 +9,6 @@
* ... and again Southern-Winter 2001 to support export_operations
*/
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/fs.h>
@@ -119,9 +118,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));
- /* keep this filehandle for possible reference when encoding attributes */
- rqstp->rq_reffh = fh;
-
if (!fhp->fh_dentry) {
__u32 *datap=NULL;
__u32 tfh[3]; /* filehandle fragment for oldstyle filehandles */
@@ -146,10 +142,10 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
}
len = key_len(fh->fh_fsid_type) / 4;
if (len == 0) goto out;
- if (fh->fh_fsid_type == 2) {
+ if (fh->fh_fsid_type == FSID_MAJOR_MINOR) {
/* deprecated, convert to type 3 */
- len = 3;
- fh->fh_fsid_type = 3;
+ len = key_len(FSID_ENCODE_DEV)/4;
+ fh->fh_fsid_type = FSID_ENCODE_DEV;
fh->fh_fsid[0] = new_encode_dev(MKDEV(ntohl(fh->fh_fsid[0]), ntohl(fh->fh_fsid[1])));
fh->fh_fsid[1] = fh->fh_fsid[2];
}
@@ -164,8 +160,9 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
/* assume old filehandle format */
xdev = old_decode_dev(fh->ofh_xdev);
xino = u32_to_ino_t(fh->ofh_xino);
- mk_fsid_v0(tfh, xdev, xino);
- exp = exp_find(rqstp->rq_client, 0, tfh, &rqstp->rq_chandle);
+ mk_fsid(FSID_DEV, tfh, xdev, xino, 0, NULL);
+ exp = exp_find(rqstp->rq_client, FSID_DEV, tfh,
+ &rqstp->rq_chandle);
}
if (IS_ERR(exp) && (PTR_ERR(exp) == -EAGAIN
@@ -212,7 +209,7 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
fileid_type = 2;
} else
fileid_type = fh->fh_fileid_type;
-
+
if (fileid_type == 0)
dentry = dget(exp->ex_dentry);
else {
@@ -292,7 +289,7 @@ static inline int _fh_update(struct dentry *dentry, struct svc_export *exp,
__u32 *datap, int *maxsize)
{
struct export_operations *nop = exp->ex_mnt->mnt_sb->s_export_op;
-
+
if (dentry == exp->ex_dentry) {
*maxsize = 0;
return 0;
@@ -317,7 +314,8 @@ static inline void _fh_update_old(struct dentry *dentry,
}
__be32
-fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct svc_fh *ref_fh)
+fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry,
+ struct svc_fh *ref_fh)
{
/* ref_fh is a reference file handle.
* if it is non-null and for the same filesystem, then we should compose
@@ -327,12 +325,13 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
*
*/
- u8 ref_fh_version = 0;
- u8 ref_fh_fsid_type = 0;
+ u8 version = 1;
+ u8 fsid_type = 0;
struct inode * inode = dentry->d_inode;
struct dentry *parent = dentry->d_parent;
__u32 *datap;
dev_t ex_dev = exp->ex_dentry->d_inode->i_sb->s_dev;
+ int root_export = (exp->ex_dentry == exp->ex_dentry->d_sb->s_root);
dprintk("nfsd: fh_compose(exp %02x:%02x/%ld %s/%s, ino=%ld)\n",
MAJOR(ex_dev), MINOR(ex_dev),
@@ -340,57 +339,64 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
parent->d_name.name, dentry->d_name.name,
(inode ? inode->i_ino : 0));
+ /* Choose filehandle version and fsid type based on
+ * the reference filehandle (if it is in the same export)
+ * or the export options.
+ */
if (ref_fh && ref_fh->fh_export == exp) {
- ref_fh_version = ref_fh->fh_handle.fh_version;
- if (ref_fh_version == 0xca)
- ref_fh_fsid_type = 0;
+ version = ref_fh->fh_handle.fh_version;
+ if (version == 0xca)
+ fsid_type = FSID_DEV;
else
- ref_fh_fsid_type = ref_fh->fh_handle.fh_fsid_type;
- if (ref_fh_fsid_type > 3)
- ref_fh_fsid_type = 0;
-
- /* make sure ref_fh type works for given export */
- if (ref_fh_fsid_type == 1 &&
- !(exp->ex_flags & NFSEXP_FSID)) {
- /* if we don't have an fsid, we cannot provide one... */
- ref_fh_fsid_type = 0;
+ fsid_type = ref_fh->fh_handle.fh_fsid_type;
+ /* We know this version/type works for this export
+ * so there is no need for further checks.
+ */
+ } else if (exp->ex_uuid) {
+ if (fhp->fh_maxsize >= 64) {
+ if (root_export)
+ fsid_type = FSID_UUID16;
+ else
+ fsid_type = FSID_UUID16_INUM;
+ } else {
+ if (root_export)
+ fsid_type = FSID_UUID8;
+ else
+ fsid_type = FSID_UUID4_INUM;
}
} else if (exp->ex_flags & NFSEXP_FSID)
- ref_fh_fsid_type = 1;
-
- if (!old_valid_dev(ex_dev) && ref_fh_fsid_type == 0) {
+ fsid_type = FSID_NUM;
+ else if (!old_valid_dev(ex_dev))
/* for newer device numbers, we must use a newer fsid format */
- ref_fh_version = 1;
- ref_fh_fsid_type = 3;
- }
- if (old_valid_dev(ex_dev) &&
- (ref_fh_fsid_type == 2 || ref_fh_fsid_type == 3))
- /* must use type1 for smaller device numbers */
- ref_fh_fsid_type = 0;
+ fsid_type = FSID_ENCODE_DEV;
+ else
+ fsid_type = FSID_DEV;
if (ref_fh == fhp)
fh_put(ref_fh);
if (fhp->fh_locked || fhp->fh_dentry) {
printk(KERN_ERR "fh_compose: fh %s/%s not initialized!\n",
- parent->d_name.name, dentry->d_name.name);
+ parent->d_name.name, dentry->d_name.name);
}
if (fhp->fh_maxsize < NFS_FHSIZE)
printk(KERN_ERR "fh_compose: called with maxsize %d! %s/%s\n",
- fhp->fh_maxsize, parent->d_name.name, dentry->d_name.name);
+ fhp->fh_maxsize,
+ parent->d_name.name, dentry->d_name.name);
fhp->fh_dentry = dget(dentry); /* our internal copy */
fhp->fh_export = exp;
cache_get(&exp->h);
- if (ref_fh_version == 0xca) {
+ if (version == 0xca) {
/* old style filehandle please */
memset(&fhp->fh_handle.fh_base, 0, NFS_FHSIZE);
fhp->fh_handle.fh_size = NFS_FHSIZE;
fhp->fh_handle.ofh_dcookie = 0xfeebbaca;
fhp->fh_handle.ofh_dev = old_encode_dev(ex_dev);
fhp->fh_handle.ofh_xdev = fhp->fh_handle.ofh_dev;
- fhp->fh_handle.ofh_xino = ino_t_to_u32(exp->ex_dentry->d_inode->i_ino);
+ fhp->fh_handle.ofh_xino =
+ ino_t_to_u32(exp->ex_dentry->d_inode->i_ino);
fhp->fh_handle.ofh_dirino = ino_t_to_u32(parent_ino(dentry));
if (inode)
_fh_update_old(dentry, exp, &fhp->fh_handle);
@@ -399,38 +405,12 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
fhp->fh_handle.fh_version = 1;
fhp->fh_handle.fh_auth_type = 0;
datap = fhp->fh_handle.fh_auth+0;
- fhp->fh_handle.fh_fsid_type = ref_fh_fsid_type;
- switch (ref_fh_fsid_type) {
- case 0:
- /*
- * fsid_type 0:
- * 2byte major, 2byte minor, 4byte inode
- */
- mk_fsid_v0(datap, ex_dev,
- exp->ex_dentry->d_inode->i_ino);
- break;
- case 1:
- /* fsid_type 1 == 4 bytes filesystem id */
- mk_fsid_v1(datap, exp->ex_fsid);
- break;
- case 2:
- /*
- * fsid_type 2:
- * 4byte major, 4byte minor, 4byte inode
- */
- mk_fsid_v2(datap, ex_dev,
- exp->ex_dentry->d_inode->i_ino);
- break;
- case 3:
- /*
- * fsid_type 3:
- * 4byte devicenumber, 4byte inode
- */
- mk_fsid_v3(datap, ex_dev,
- exp->ex_dentry->d_inode->i_ino);
- break;
- }
- len = key_len(ref_fh_fsid_type);
+ fhp->fh_handle.fh_fsid_type = fsid_type;
+ mk_fsid(fsid_type, datap, ex_dev,
+ exp->ex_dentry->d_inode->i_ino,
+ exp->ex_fsid, exp->ex_uuid);
+
+ len = key_len(fsid_type);
datap += len/4;
fhp->fh_handle.fh_size = 4 + len;
@@ -457,7 +437,7 @@ fh_update(struct svc_fh *fhp)
{
struct dentry *dentry;
__u32 *datap;
-
+
if (!fhp->fh_dentry)
goto out_bad;
@@ -534,3 +514,22 @@ char * SVCFH_fmt(struct svc_fh *fhp)
fh->fh_base.fh_pad[5]);
return buf;
}
+
+enum fsid_source fsid_source(struct svc_fh *fhp)
+{
+ if (fhp->fh_handle.fh_version != 1)
+ return FSIDSOURCE_DEV;
+ switch(fhp->fh_handle.fh_fsid_type) {
+ case FSID_DEV:
+ case FSID_ENCODE_DEV:
+ case FSID_MAJOR_MINOR:
+ return FSIDSOURCE_DEV;
+ case FSID_NUM:
+ return FSIDSOURCE_FSID;
+ default:
+ if (fhp->fh_export->ex_flags & NFSEXP_FSID)
+ return FSIDSOURCE_FSID;
+ else
+ return FSIDSOURCE_UUID;
+ }
+}
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 6555c50d900..0c24b9e24fe 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -153,6 +153,7 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
struct dentry *dentry = fhp->fh_dentry;
int type;
struct timespec time;
+ u32 f;
type = (stat->mode & S_IFMT);
@@ -173,10 +174,22 @@ encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
else
*p++ = htonl(0xffffffff);
*p++ = htonl((u32) stat->blocks);
- if (is_fsid(fhp, rqstp->rq_reffh))
- *p++ = htonl((u32) fhp->fh_export->ex_fsid);
- else
+ switch (fsid_source(fhp)) {
+ default:
+ case FSIDSOURCE_DEV:
*p++ = htonl(new_encode_dev(stat->dev));
+ break;
+ case FSIDSOURCE_FSID:
+ *p++ = htonl((u32) fhp->fh_export->ex_fsid);
+ break;
+ case FSIDSOURCE_UUID:
+ f = ((u32*)fhp->fh_export->ex_uuid)[0];
+ f ^= ((u32*)fhp->fh_export->ex_uuid)[1];
+ f ^= ((u32*)fhp->fh_export->ex_uuid)[2];
+ f ^= ((u32*)fhp->fh_export->ex_uuid)[3];
+ *p++ = htonl(f);
+ break;
+ }
*p++ = htonl((u32) stat->ino);
*p++ = htonl((u32) stat->atime.tv_sec);
*p++ = htonl(stat->atime.tv_nsec ? stat->atime.tv_nsec / 1000 : 0);
diff --git a/fs/ntfs/sysctl.c b/fs/ntfs/sysctl.c
index 1c23138d00b..4847fbfb010 100644
--- a/fs/ntfs/sysctl.c
+++ b/fs/ntfs/sysctl.c
@@ -33,20 +33,28 @@
#include "sysctl.h"
#include "debug.h"
-#define FS_NTFS 1
-
/* Definition of the ntfs sysctl. */
static ctl_table ntfs_sysctls[] = {
- { FS_NTFS, "ntfs-debug", /* Binary and text IDs. */
- &debug_msgs,sizeof(debug_msgs), /* Data pointer and size. */
- 0644, NULL, &proc_dointvec }, /* Mode, child, proc handler. */
- { 0 }
+ {
+ .ctl_name = CTL_UNNUMBERED, /* Binary and text IDs. */
+ .procname = "ntfs-debug",
+ .data = &debug_msgs, /* Data pointer and size. */
+ .maxlen = sizeof(debug_msgs),
+ .mode = 0644, /* Mode, proc handler. */
+ .proc_handler = &proc_dointvec
+ },
+ {}
};
/* Define the parent directory /proc/sys/fs. */
static ctl_table sysctls_root[] = {
- { CTL_FS, "fs", NULL, 0, 0555, ntfs_sysctls },
- { 0 }
+ {
+ .ctl_name = CTL_FS,
+ .procname = "fs",
+ .mode = 0555,
+ .child = ntfs_sysctls
+ },
+ {}
};
/* Storage for the sysctls header. */
@@ -62,17 +70,9 @@ int ntfs_sysctl(int add)
{
if (add) {
BUG_ON(sysctls_root_table);
- sysctls_root_table = register_sysctl_table(sysctls_root, 0);
+ sysctls_root_table = register_sysctl_table(sysctls_root);
if (!sysctls_root_table)
return -ENOMEM;
-#ifdef CONFIG_PROC_FS
- /*
- * If the proc filesystem is in use and we are a module, need
- * to set the owner of our proc entry to our module. In the
- * non-modular case, THIS_MODULE is NULL, so this is ok.
- */
- ntfs_sysctls[0].de->owner = THIS_MODULE;
-#endif
} else {
BUG_ON(!sysctls_root_table);
unregister_sysctl_table(sysctls_root_table);
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c
index b17333a0606..9f5ad0f01ce 100644
--- a/fs/ocfs2/cluster/nodemanager.c
+++ b/fs/ocfs2/cluster/nodemanager.c
@@ -55,7 +55,7 @@ static ctl_table ocfs2_nm_table[] = {
static ctl_table ocfs2_mod_table[] = {
{
- .ctl_name = KERN_OCFS2_NM,
+ .ctl_name = FS_OCFS2_NM,
.procname = "nm",
.data = NULL,
.maxlen = 0,
@@ -67,7 +67,7 @@ static ctl_table ocfs2_mod_table[] = {
static ctl_table ocfs2_kern_table[] = {
{
- .ctl_name = KERN_OCFS2,
+ .ctl_name = FS_OCFS2,
.procname = "ocfs2",
.data = NULL,
.maxlen = 0,
@@ -922,7 +922,7 @@ static int __init init_o2nm(void)
o2hb_init();
o2net_init();
- ocfs2_table_header = register_sysctl_table(ocfs2_root_table, 0);
+ ocfs2_table_header = register_sysctl_table(ocfs2_root_table);
if (!ocfs2_table_header) {
printk(KERN_ERR "nodemanager: unable to register sysctl\n");
ret = -ENOMEM; /* or something. */
diff --git a/fs/ocfs2/cluster/nodemanager.h b/fs/ocfs2/cluster/nodemanager.h
index 8fb23cacc2f..070522138ae 100644
--- a/fs/ocfs2/cluster/nodemanager.h
+++ b/fs/ocfs2/cluster/nodemanager.h
@@ -33,8 +33,7 @@
#include <linux/configfs.h>
#include <linux/rbtree.h>
-#define KERN_OCFS2 988
-#define KERN_OCFS2_NM 1
+#define FS_OCFS2_NM 1
const char *o2nm_get_hb_ctl_path(void);
diff --git a/fs/proc/Makefile b/fs/proc/Makefile
index f6c77627257..a6b3a8f878f 100644
--- a/fs/proc/Makefile
+++ b/fs/proc/Makefile
@@ -8,7 +8,7 @@ proc-y := nommu.o task_nommu.o
proc-$(CONFIG_MMU) := mmu.o task_mmu.o
proc-y += inode.o root.o base.o generic.o array.o \
- proc_tty.o proc_misc.o
+ proc_tty.o proc_misc.o proc_sysctl.o
proc-$(CONFIG_PROC_KCORE) += kcore.o
proc-$(CONFIG_PROC_VMCORE) += vmcore.o
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index 0cdc00d9d97..775fb21294d 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -32,7 +32,7 @@ static loff_t proc_file_lseek(struct file *, loff_t, int);
DEFINE_SPINLOCK(proc_subdir_lock);
-int proc_match(int len, const char *name, struct proc_dir_entry *de)
+static int proc_match(int len, const char *name, struct proc_dir_entry *de)
{
if (de->namelen != len)
return 0;
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index f6722be37dd..c372eb151a3 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -161,6 +161,7 @@ struct inode *proc_get_inode(struct super_block *sb, unsigned int ino,
if (!inode)
goto out_ino;
+ PROC_I(inode)->fd = 0;
PROC_I(inode)->pde = de;
if (de) {
if (de->mode) {
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 277dcd66ebe..c932aa65e19 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -11,6 +11,8 @@
#include <linux/proc_fs.h>
+extern int proc_sys_init(void);
+
struct vmalloc_info {
unsigned long used;
unsigned long largest_chunk;
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
new file mode 100644
index 00000000000..20e8cbb3436
--- /dev/null
+++ b/fs/proc/proc_sysctl.c
@@ -0,0 +1,479 @@
+/*
+ * /proc/sys support
+ */
+
+#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
+#include <linux/security.h>
+#include "internal.h"
+
+static struct dentry_operations proc_sys_dentry_operations;
+static const struct file_operations proc_sys_file_operations;
+static struct inode_operations proc_sys_inode_operations;
+
+static void proc_sys_refresh_inode(struct inode *inode, struct ctl_table *table)
+{
+ /* Refresh the cached information bits in the inode */
+ if (table) {
+ inode->i_uid = 0;
+ inode->i_gid = 0;
+ inode->i_mode = table->mode;
+ if (table->proc_handler) {
+ inode->i_mode |= S_IFREG;
+ inode->i_nlink = 1;
+ } else {
+ inode->i_mode |= S_IFDIR;
+ inode->i_nlink = 0; /* It is too hard to figure out */
+ }
+ }
+}
+
+static struct inode *proc_sys_make_inode(struct inode *dir, struct ctl_table *table)
+{
+ struct inode *inode;
+ struct proc_inode *dir_ei, *ei;
+ int depth;
+
+ inode = new_inode(dir->i_sb);
+ if (!inode)
+ goto out;
+
+ /* A directory is always one deeper than it's parent */
+ dir_ei = PROC_I(dir);
+ depth = dir_ei->fd + 1;
+
+ ei = PROC_I(inode);
+ ei->fd = depth;
+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+ inode->i_op = &proc_sys_inode_operations;
+ inode->i_fop = &proc_sys_file_operations;
+ inode->i_flags |= S_PRIVATE; /* tell selinux to ignore this inode */
+ proc_sys_refresh_inode(inode, table);
+out:
+ return inode;
+}
+
+static struct dentry *proc_sys_ancestor(struct dentry *dentry, int depth)
+{
+ for (;;) {
+ struct proc_inode *ei;
+
+ ei = PROC_I(dentry->d_inode);
+ if (ei->fd == depth)
+ break; /* found */
+
+ dentry = dentry->d_parent;
+ }
+ return dentry;
+}
+
+static struct ctl_table *proc_sys_lookup_table_one(struct ctl_table *table,
+ struct qstr *name)
+{
+ int len;
+ for ( ; table->ctl_name || table->procname; table++) {
+
+ if (!table->procname)
+ continue;
+
+ len = strlen(table->procname);
+ if (len != name->len)
+ continue;
+
+ if (memcmp(table->procname, name->name, len) != 0)
+ continue;
+
+ /* I have a match */
+ return table;
+ }
+ return NULL;
+}
+
+static struct ctl_table *proc_sys_lookup_table(struct dentry *dentry,
+ struct ctl_table *table)
+{
+ struct dentry *ancestor;
+ struct proc_inode *ei;
+ int depth, i;
+
+ ei = PROC_I(dentry->d_inode);
+ depth = ei->fd;
+
+ if (depth == 0)
+ return table;
+
+ for (i = 1; table && (i <= depth); i++) {
+ ancestor = proc_sys_ancestor(dentry, i);
+ table = proc_sys_lookup_table_one(table, &ancestor->d_name);
+ if (table)
+ table = table->child;
+ }
+ return table;
+
+}
+static struct ctl_table *proc_sys_lookup_entry(struct dentry *dparent,
+ struct qstr *name,
+ struct ctl_table *table)
+{
+ table = proc_sys_lookup_table(dparent, table);
+ if (table)
+ table = proc_sys_lookup_table_one(table, name);
+ return table;
+}
+
+static struct ctl_table *do_proc_sys_lookup(struct dentry *parent,
+ struct qstr *name,
+ struct ctl_table_header **ptr)
+{
+ struct ctl_table_header *head;
+ struct ctl_table *table = NULL;
+
+ for (head = sysctl_head_next(NULL); head;
+ head = sysctl_head_next(head)) {
+ table = proc_sys_lookup_entry(parent, name, head->ctl_table);
+ if (table)
+ break;
+ }
+ *ptr = head;
+ return table;
+}
+
+static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry,
+ struct nameidata *nd)
+{
+ struct ctl_table_header *head;
+ struct inode *inode;
+ struct dentry *err;
+ struct ctl_table *table;
+
+ err = ERR_PTR(-ENOENT);
+ table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
+ if (!table)
+ goto out;
+
+ err = ERR_PTR(-ENOMEM);
+ inode = proc_sys_make_inode(dir, table);
+ if (!inode)
+ goto out;
+
+ err = NULL;
+ dentry->d_op = &proc_sys_dentry_operations;
+ d_add(dentry, inode);
+
+out:
+ sysctl_head_finish(head);
+ return err;
+}
+
+static ssize_t proc_sys_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct dentry *dentry = filp->f_dentry;
+ struct ctl_table_header *head;
+ struct ctl_table *table;
+ ssize_t error, res;
+
+ table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
+ /* Has the sysctl entry disappeared on us? */
+ error = -ENOENT;
+ if (!table)
+ goto out;
+
+ /* Has the sysctl entry been replaced by a directory? */
+ error = -EISDIR;
+ if (!table->proc_handler)
+ goto out;
+
+ /*
+ * At this point we know that the sysctl was not unregistered
+ * and won't be until we finish.
+ */
+ error = -EPERM;
+ if (sysctl_perm(table, MAY_READ))
+ goto out;
+
+ /* careful: calling conventions are nasty here */
+ res = count;
+ error = table->proc_handler(table, 0, filp, buf, &res, ppos);
+ if (!error)
+ error = res;
+out:
+ sysctl_head_finish(head);
+
+ return error;
+}
+
+static ssize_t proc_sys_write(struct file *filp, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ struct dentry *dentry = filp->f_dentry;
+ struct ctl_table_header *head;
+ struct ctl_table *table;
+ ssize_t error, res;
+
+ table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
+ /* Has the sysctl entry disappeared on us? */
+ error = -ENOENT;
+ if (!table)
+ goto out;
+
+ /* Has the sysctl entry been replaced by a directory? */
+ error = -EISDIR;
+ if (!table->proc_handler)
+ goto out;
+
+ /*
+ * At this point we know that the sysctl was not unregistered
+ * and won't be until we finish.
+ */
+ error = -EPERM;
+ if (sysctl_perm(table, MAY_WRITE))
+ goto out;
+
+ /* careful: calling conventions are nasty here */
+ res = count;
+ error = table->proc_handler(table, 1, filp, (char __user *)buf,
+ &res, ppos);
+ if (!error)
+ error = res;
+out:
+ sysctl_head_finish(head);
+
+ return error;
+}
+
+
+static int proc_sys_fill_cache(struct file *filp, void *dirent,
+ filldir_t filldir, struct ctl_table *table)
+{
+ struct ctl_table_header *head;
+ struct ctl_table *child_table = NULL;
+ struct dentry *child, *dir = filp->f_path.dentry;
+ struct inode *inode;
+ struct qstr qname;
+ ino_t ino = 0;
+ unsigned type = DT_UNKNOWN;
+ int ret;
+
+ qname.name = table->procname;
+ qname.len = strlen(table->procname);
+ qname.hash = full_name_hash(qname.name, qname.len);
+
+ /* Suppress duplicates.
+ * Only fill a directory entry if it is the value that
+ * an ordinary lookup of that name returns. Hide all
+ * others.
+ *
+ * If we ever cache this translation in the dcache
+ * I should do a dcache lookup first. But for now
+ * it is just simpler not to.
+ */
+ ret = 0;
+ child_table = do_proc_sys_lookup(dir, &qname, &head);
+ sysctl_head_finish(head);
+ if (child_table != table)
+ return 0;
+
+ child = d_lookup(dir, &qname);
+ if (!child) {
+ struct dentry *new;
+ new = d_alloc(dir, &qname);
+ if (new) {
+ inode = proc_sys_make_inode(dir->d_inode, table);
+ if (!inode)
+ child = ERR_PTR(-ENOMEM);
+ else {
+ new->d_op = &proc_sys_dentry_operations;
+ d_add(new, inode);
+ }
+ if (child)
+ dput(new);
+ else
+ child = new;
+ }
+ }
+ if (!child || IS_ERR(child) || !child->d_inode)
+ goto end_instantiate;
+ inode = child->d_inode;
+ if (inode) {
+ ino = inode->i_ino;
+ type = inode->i_mode >> 12;
+ }
+ dput(child);
+end_instantiate:
+ if (!ino)
+ ino= find_inode_number(dir, &qname);
+ if (!ino)
+ ino = 1;
+ return filldir(dirent, qname.name, qname.len, filp->f_pos, ino, type);
+}
+
+static int proc_sys_readdir(struct file *filp, void *dirent, filldir_t filldir)
+{
+ struct dentry *dentry = filp->f_dentry;
+ struct inode *inode = dentry->d_inode;
+ struct ctl_table_header *head = NULL;
+ struct ctl_table *table;
+ unsigned long pos;
+ int ret;
+
+ ret = -ENOTDIR;
+ if (!S_ISDIR(inode->i_mode))
+ goto out;
+
+ ret = 0;
+ /* Avoid a switch here: arm builds fail with missing __cmpdi2 */
+ if (filp->f_pos == 0) {
+ if (filldir(dirent, ".", 1, filp->f_pos,
+ inode->i_ino, DT_DIR) < 0)
+ goto out;
+ filp->f_pos++;
+ }
+ if (filp->f_pos == 1) {
+ if (filldir(dirent, "..", 2, filp->f_pos,
+ parent_ino(dentry), DT_DIR) < 0)
+ goto out;
+ filp->f_pos++;
+ }
+ pos = 2;
+
+ /* - Find each instance of the directory
+ * - Read all entries in each instance
+ * - Before returning an entry to user space lookup the entry
+ * by name and if I find a different entry don't return
+ * this one because it means it is a buried dup.
+ * For sysctl this should only happen for directory entries.
+ */
+ for (head = sysctl_head_next(NULL); head; head = sysctl_head_next(head)) {
+ table = proc_sys_lookup_table(dentry, head->ctl_table);
+
+ if (!table)
+ continue;
+
+ for (; table->ctl_name || table->procname; table++, pos++) {
+ /* Can't do anything without a proc name */
+ if (!table->procname)
+ continue;
+
+ if (pos < filp->f_pos)
+ continue;
+
+ if (proc_sys_fill_cache(filp, dirent, filldir, table) < 0)
+ goto out;
+ filp->f_pos = pos + 1;
+ }
+ }
+ ret = 1;
+out:
+ sysctl_head_finish(head);
+ return ret;
+}
+
+static int proc_sys_permission(struct inode *inode, int mask, struct nameidata *nd)
+{
+ /*
+ * sysctl entries that are not writeable,
+ * are _NOT_ writeable, capabilities or not.
+ */
+ struct ctl_table_header *head;
+ struct ctl_table *table;
+ struct dentry *dentry;
+ int mode;
+ int depth;
+ int error;
+
+ head = NULL;
+ depth = PROC_I(inode)->fd;
+
+ /* First check the cached permissions, in case we don't have
+ * enough information to lookup the sysctl table entry.
+ */
+ error = -EACCES;
+ mode = inode->i_mode;
+
+ if (current->euid == 0)
+ mode >>= 6;
+ else if (in_group_p(0))
+ mode >>= 3;
+
+ if ((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask)
+ error = 0;
+
+ /* If we can't get a sysctl table entry the permission
+ * checks on the cached mode will have to be enough.
+ */
+ if (!nd || !depth)
+ goto out;
+
+ dentry = nd->dentry;
+ table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
+
+ /* If the entry does not exist deny permission */
+ error = -EACCES;
+ if (!table)
+ goto out;
+
+ /* Use the permissions on the sysctl table entry */
+ error = sysctl_perm(table, mask);
+out:
+ sysctl_head_finish(head);
+ return error;
+}
+
+static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
+{
+ struct inode *inode = dentry->d_inode;
+ int error;
+
+ if (attr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
+ return -EPERM;
+
+ error = inode_change_ok(inode, attr);
+ if (!error) {
+ error = security_inode_setattr(dentry, attr);
+ if (!error)
+ error = inode_setattr(inode, attr);
+ }
+
+ return error;
+}
+
+/* I'm lazy and don't distinguish between files and directories,
+ * until access time.
+ */
+static const struct file_operations proc_sys_file_operations = {
+ .read = proc_sys_read,
+ .write = proc_sys_write,
+ .readdir = proc_sys_readdir,
+};
+
+static struct inode_operations proc_sys_inode_operations = {
+ .lookup = proc_sys_lookup,
+ .permission = proc_sys_permission,
+ .setattr = proc_sys_setattr,
+};
+
+static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd)
+{
+ struct ctl_table_header *head;
+ struct ctl_table *table;
+ table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
+ proc_sys_refresh_inode(dentry->d_inode, table);
+ sysctl_head_finish(head);
+ return !!table;
+}
+
+static struct dentry_operations proc_sys_dentry_operations = {
+ .d_revalidate = proc_sys_revalidate,
+};
+
+static struct proc_dir_entry *proc_sys_root;
+
+int proc_sys_init(void)
+{
+ proc_sys_root = proc_mkdir("sys", NULL);
+ proc_sys_root->proc_iops = &proc_sys_inode_operations;
+ proc_sys_root->proc_fops = &proc_sys_file_operations;
+ proc_sys_root->nlink = 0;
+ return 0;
+}
diff --git a/fs/proc/root.c b/fs/proc/root.c
index af154458b54..5834a744c2a 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -23,10 +23,6 @@
struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver;
-#ifdef CONFIG_SYSCTL
-struct proc_dir_entry *proc_sys_root;
-#endif
-
static int proc_get_sb(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data, struct vfsmount *mnt)
{
@@ -71,13 +67,6 @@ void __init proc_root_init(void)
#ifdef CONFIG_SYSVIPC
proc_mkdir("sysvipc", NULL);
#endif
-#ifdef CONFIG_SYSCTL
- proc_sys_root = proc_mkdir("sys", NULL);
-#endif
-#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
- proc_mkdir("sys/fs", NULL);
- proc_mkdir("sys/fs/binfmt_misc", NULL);
-#endif
proc_root_fs = proc_mkdir("fs", NULL);
proc_root_driver = proc_mkdir("driver", NULL);
proc_mkdir("fs/nfsd", NULL); /* somewhere for the nfsd filesystem to be mounted */
@@ -90,6 +79,9 @@ void __init proc_root_init(void)
proc_device_tree_init();
#endif
proc_bus = proc_mkdir("bus", NULL);
+#ifdef CONFIG_SYSCTL
+ proc_sys_init();
+#endif
}
static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat
diff --git a/fs/smbfs/symlink.c b/fs/smbfs/symlink.c
index e4bf3456d07..fea20ceb8a5 100644
--- a/fs/smbfs/symlink.c
+++ b/fs/smbfs/symlink.c
@@ -6,7 +6,6 @@
* Please add a note about your changes to smbfs in the ChangeLog file.
*/
-#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/fcntl.h>
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 0e97a4f79c3..bcc44084e00 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -16,7 +16,6 @@
#include <linux/quotaops.h>
#include <linux/buffer_head.h>
#include <linux/capability.h>
-#include <linux/sched.h>
#include <linux/bitops.h>
#include <asm/byteorder.h>
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index a6c0ca9f48b..4890ddf1518 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -20,7 +20,6 @@
#include <linux/fs.h>
#include <linux/ufs_fs.h>
#include <linux/smp_lock.h>
-#include <linux/sched.h>
#include "swab.h"
#include "util.h"
diff --git a/fs/xattr_acl.c b/fs/xattr_acl.c
index 789a2559bd5..c6ad7c7e3ee 100644
--- a/fs/xattr_acl.c
+++ b/fs/xattr_acl.c
@@ -6,7 +6,6 @@
*/
#include <linux/module.h>
-#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/posix_acl_xattr.h>
diff --git a/fs/xfs/linux-2.6/kmem.c b/fs/xfs/linux-2.6/kmem.c
index 004baf60061..ed2b16dff91 100644
--- a/fs/xfs/linux-2.6/kmem.c
+++ b/fs/xfs/linux-2.6/kmem.c
@@ -15,7 +15,6 @@
* along with this program; if not, write the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <linux/sched.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>
#include <linux/highmem.h>
diff --git a/fs/xfs/linux-2.6/xfs_sysctl.c b/fs/xfs/linux-2.6/xfs_sysctl.c
index 5c46c35a97a..cd6eaa44aa2 100644
--- a/fs/xfs/linux-2.6/xfs_sysctl.c
+++ b/fs/xfs/linux-2.6/xfs_sysctl.c
@@ -251,7 +251,7 @@ static ctl_table xfs_root_table[] = {
void
xfs_sysctl_register(void)
{
- xfs_table_header = register_sysctl_table(xfs_root_table, 0);
+ xfs_table_header = register_sysctl_table(xfs_root_table);
}
void