aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-26 23:23:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-26 23:23:44 -0400
commit4836e3007882984279ca63d3c42bf0b14616eb78 (patch)
tree28bf22726964e068b825491d71a141eefedbe5f8
parent5c7c204aeca51ccfad63caab4fcdc5d8026c0fd8 (diff)
parent4e1e018ecc6f7bfd10fc75b3ff9715cc8164e0a2 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (39 commits) [PATCH] fix RLIM_NOFILE handling [PATCH] get rid of corner case in dup3() entirely [PATCH] remove remaining namei_{32,64}.h crap [PATCH] get rid of indirect users of namei.h [PATCH] get rid of __user_path_lookup_open [PATCH] f_count may wrap around [PATCH] dup3 fix [PATCH] don't pass nameidata to __ncp_lookup_validate() [PATCH] don't pass nameidata to gfs2_lookupi() [PATCH] new (local) helper: user_path_parent() [PATCH] sanitize __user_walk_fd() et.al. [PATCH] preparation to __user_walk_fd cleanup [PATCH] kill nameidata passing to permission(), rename to inode_permission() [PATCH] take noexec checks to very few callers that care Re: [PATCH 3/6] vfs: open_exec cleanup [patch 4/4] vfs: immutable inode checking cleanup [patch 3/4] fat: dont call notify_change [patch 2/4] vfs: utimes cleanup [patch 1/4] vfs: utimes: move owner check into inode_change_ok() [PATCH] vfs: use kstrdup() and check failing allocation ...
-rw-r--r--arch/alpha/kernel/osf_sys.c10
-rw-r--r--arch/parisc/hpux/sys_hpux.c10
-rw-r--r--drivers/net/ppp_generic.c6
-rw-r--r--fs/affs/file.c4
-rw-r--r--fs/afs/internal.h4
-rw-r--r--fs/afs/security.c2
-rw-r--r--fs/aio.c6
-rw-r--r--fs/attr.c7
-rw-r--r--fs/bad_inode.c3
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/coda/dir.c4
-rw-r--r--fs/coda/pioctl.c20
-rw-r--r--fs/compat.c20
-rw-r--r--fs/ecryptfs/inode.c21
-rw-r--r--fs/exec.c81
-rw-r--r--fs/ext2/acl.c2
-rw-r--r--fs/ext2/acl.h2
-rw-r--r--fs/ext3/acl.c2
-rw-r--r--fs/ext3/acl.h2
-rw-r--r--fs/ext4/acl.c2
-rw-r--r--fs/ext4/acl.h2
-rw-r--r--fs/fat/file.c15
-rw-r--r--fs/fcntl.c33
-rw-r--r--fs/fifo.c8
-rw-r--r--fs/file.c9
-rw-r--r--fs/file_table.c10
-rw-r--r--fs/fuse/dir.c6
-rw-r--r--fs/fuse/file.c2
-rw-r--r--fs/gfs2/inode.c6
-rw-r--r--fs/gfs2/inode.h2
-rw-r--r--fs/gfs2/ops_export.c2
-rw-r--r--fs/gfs2/ops_inode.c16
-rw-r--r--fs/gfs2/super.c2
-rw-r--r--fs/hfs/inode.c7
-rw-r--r--fs/hfsplus/inode.c6
-rw-r--r--fs/hostfs/hostfs_kern.c2
-rw-r--r--fs/hpfs/namei.c2
-rw-r--r--fs/hppfs/hppfs.c7
-rw-r--r--fs/inotify_user.c22
-rw-r--r--fs/jffs2/acl.c2
-rw-r--r--fs/jffs2/acl.h2
-rw-r--r--fs/jfs/acl.c2
-rw-r--r--fs/jfs/jfs_acl.h2
-rw-r--r--fs/namei.c354
-rw-r--r--fs/namespace.c106
-rw-r--r--fs/ncpfs/dir.c4
-rw-r--r--fs/nfs/dir.c11
-rw-r--r--fs/nfsd/nfsctl.c1
-rw-r--r--fs/nfsd/nfsfh.c2
-rw-r--r--fs/nfsd/vfs.c14
-rw-r--r--fs/ntfs/file.c2
-rw-r--r--fs/ocfs2/file.c2
-rw-r--r--fs/ocfs2/file.h3
-rw-r--r--fs/open.c179
-rw-r--r--fs/pipe.c51
-rw-r--r--fs/proc/base.c3
-rw-r--r--fs/proc/inode.c5
-rw-r--r--fs/proc/proc_sysctl.c429
-rw-r--r--fs/reiserfs/xattr.c2
-rw-r--r--fs/smbfs/file.c4
-rw-r--r--fs/splice.c4
-rw-r--r--fs/stat.c32
-rw-r--r--fs/ubifs/file.c1
-rw-r--r--fs/utimes.c139
-rw-r--r--fs/xattr.c98
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c14
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c3
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c2
-rw-r--r--include/asm-alpha/namei.h17
-rw-r--r--include/asm-arm/namei.h25
-rw-r--r--include/asm-avr32/namei.h7
-rw-r--r--include/asm-blackfin/namei.h19
-rw-r--r--include/asm-cris/namei.h17
-rw-r--r--include/asm-frv/namei.h18
-rw-r--r--include/asm-h8300/namei.h17
-rw-r--r--include/asm-ia64/namei.h25
-rw-r--r--include/asm-m32r/namei.h17
-rw-r--r--include/asm-m68k/namei.h17
-rw-r--r--include/asm-m68knommu/namei.h1
-rw-r--r--include/asm-mips/namei.h11
-rw-r--r--include/asm-mn10300/namei.h22
-rw-r--r--include/asm-parisc/namei.h17
-rw-r--r--include/asm-powerpc/namei.h20
-rw-r--r--include/asm-s390/namei.h21
-rw-r--r--include/asm-sh/namei.h17
-rw-r--r--include/asm-sparc/namei.h8
-rw-r--r--include/asm-sparc/namei_32.h13
-rw-r--r--include/asm-sparc/namei_64.h13
-rw-r--r--include/asm-sparc64/namei.h1
-rw-r--r--include/asm-um/namei.h6
-rw-r--r--include/asm-v850/namei.h17
-rw-r--r--include/asm-x86/namei.h11
-rw-r--r--include/asm-xtensa/namei.h26
-rw-r--r--include/linux/coda_linux.h2
-rw-r--r--include/linux/fs.h57
-rw-r--r--include/linux/fs_struct.h3
-rw-r--r--include/linux/mount.h2
-rw-r--r--include/linux/namei.h19
-rw-r--r--include/linux/nfs_fs.h3
-rw-r--r--include/linux/proc_fs.h5
-rw-r--r--include/linux/reiserfs_xattr.h2
-rw-r--r--include/linux/security.h7
-rw-r--r--include/linux/shmem_fs.h2
-rw-r--r--include/linux/sysctl.h25
-rw-r--r--include/net/af_unix.h2
-rw-r--r--include/net/ip.h2
-rw-r--r--include/net/net_namespace.h4
-rw-r--r--ipc/mqueue.c2
-rw-r--r--kernel/cgroup.c1
-rw-r--r--kernel/exec_domain.c1
-rw-r--r--kernel/exit.c2
-rw-r--r--kernel/fork.c7
-rw-r--r--kernel/sysctl.c166
-rw-r--r--mm/filemap.c7
-rw-r--r--mm/filemap_xip.c2
-rw-r--r--mm/shmem_acl.c2
-rw-r--r--net/ipv4/af_inet.c4
-rw-r--r--net/ipv4/sysctl_net_ipv4.c7
-rw-r--r--net/sched/sch_atm.c4
-rw-r--r--net/sysctl_net.c22
-rw-r--r--net/unix/af_unix.c2
-rw-r--r--net/unix/garbage.c18
-rw-r--r--security/capability.c3
-rw-r--r--security/security.c5
-rw-r--r--security/selinux/hooks.c5
-rw-r--r--security/smack/smack_lsm.c3
126 files changed, 1088 insertions, 1535 deletions
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c
index 32ca1b927307..6e943135f0e0 100644
--- a/arch/alpha/kernel/osf_sys.c
+++ b/arch/alpha/kernel/osf_sys.c
@@ -253,15 +253,15 @@ do_osf_statfs(struct dentry * dentry, struct osf_statfs __user *buffer,
253} 253}
254 254
255asmlinkage int 255asmlinkage int
256osf_statfs(char __user *path, struct osf_statfs __user *buffer, unsigned long bufsiz) 256osf_statfs(char __user *pathname, struct osf_statfs __user *buffer, unsigned long bufsiz)
257{ 257{
258 struct nameidata nd; 258 struct path path;
259 int retval; 259 int retval;
260 260
261 retval = user_path_walk(path, &nd); 261 retval = user_path(pathname, &path);
262 if (!retval) { 262 if (!retval) {
263 retval = do_osf_statfs(nd.path.dentry, buffer, bufsiz); 263 retval = do_osf_statfs(path.dentry, buffer, bufsiz);
264 path_put(&nd.path); 264 path_put(&path);
265 } 265 }
266 return retval; 266 return retval;
267} 267}
diff --git a/arch/parisc/hpux/sys_hpux.c b/arch/parisc/hpux/sys_hpux.c
index be255ebb609c..18072e03a019 100644
--- a/arch/parisc/hpux/sys_hpux.c
+++ b/arch/parisc/hpux/sys_hpux.c
@@ -210,19 +210,19 @@ static int vfs_statfs_hpux(struct dentry *dentry, struct hpux_statfs *buf)
210} 210}
211 211
212/* hpux statfs */ 212/* hpux statfs */
213asmlinkage long hpux_statfs(const char __user *path, 213asmlinkage long hpux_statfs(const char __user *pathname,
214 struct hpux_statfs __user *buf) 214 struct hpux_statfs __user *buf)
215{ 215{
216 struct nameidata nd; 216 struct path path;
217 int error; 217 int error;
218 218
219 error = user_path_walk(path, &nd); 219 error = user_path(pathname, &path);
220 if (!error) { 220 if (!error) {
221 struct hpux_statfs tmp; 221 struct hpux_statfs tmp;
222 error = vfs_statfs_hpux(nd.path.dentry, &tmp); 222 error = vfs_statfs_hpux(path.dentry, &tmp);
223 if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) 223 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
224 error = -EFAULT; 224 error = -EFAULT;
225 path_put(&nd.path); 225 path_put(&path);
226 } 226 }
227 return error; 227 return error;
228} 228}
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 739b3ab7bccc..ddccc074a76a 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -581,12 +581,12 @@ static long ppp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
581 if (file == ppp->owner) 581 if (file == ppp->owner)
582 ppp_shutdown_interface(ppp); 582 ppp_shutdown_interface(ppp);
583 } 583 }
584 if (atomic_read(&file->f_count) <= 2) { 584 if (atomic_long_read(&file->f_count) <= 2) {
585 ppp_release(NULL, file); 585 ppp_release(NULL, file);
586 err = 0; 586 err = 0;
587 } else 587 } else
588 printk(KERN_DEBUG "PPPIOCDETACH file->f_count=%d\n", 588 printk(KERN_DEBUG "PPPIOCDETACH file->f_count=%ld\n",
589 atomic_read(&file->f_count)); 589 atomic_long_read(&file->f_count));
590 unlock_kernel(); 590 unlock_kernel();
591 return err; 591 return err;
592 } 592 }
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 6eac7bdeec94..1377b1240b6e 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -46,8 +46,6 @@ const struct inode_operations affs_file_inode_operations = {
46static int 46static int
47affs_file_open(struct inode *inode, struct file *filp) 47affs_file_open(struct inode *inode, struct file *filp)
48{ 48{
49 if (atomic_read(&filp->f_count) != 1)
50 return 0;
51 pr_debug("AFFS: open(%lu,%d)\n", 49 pr_debug("AFFS: open(%lu,%d)\n",
52 inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt)); 50 inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
53 atomic_inc(&AFFS_I(inode)->i_opencnt); 51 atomic_inc(&AFFS_I(inode)->i_opencnt);
@@ -57,8 +55,6 @@ affs_file_open(struct inode *inode, struct file *filp)
57static int 55static int
58affs_file_release(struct inode *inode, struct file *filp) 56affs_file_release(struct inode *inode, struct file *filp)
59{ 57{
60 if (atomic_read(&filp->f_count) != 0)
61 return 0;
62 pr_debug("AFFS: release(%lu, %d)\n", 58 pr_debug("AFFS: release(%lu, %d)\n",
63 inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt)); 59 inode->i_ino, atomic_read(&AFFS_I(inode)->i_opencnt));
64 60
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 7102824ba847..3cb6920ff30b 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -469,8 +469,6 @@ extern bool afs_cm_incoming_call(struct afs_call *);
469extern const struct inode_operations afs_dir_inode_operations; 469extern const struct inode_operations afs_dir_inode_operations;
470extern const struct file_operations afs_dir_file_operations; 470extern const struct file_operations afs_dir_file_operations;
471 471
472extern int afs_permission(struct inode *, int, struct nameidata *);
473
474/* 472/*
475 * file.c 473 * file.c
476 */ 474 */
@@ -605,7 +603,7 @@ extern void afs_clear_permits(struct afs_vnode *);
605extern void afs_cache_permit(struct afs_vnode *, struct key *, long); 603extern void afs_cache_permit(struct afs_vnode *, struct key *, long);
606extern void afs_zap_permits(struct rcu_head *); 604extern void afs_zap_permits(struct rcu_head *);
607extern struct key *afs_request_key(struct afs_cell *); 605extern struct key *afs_request_key(struct afs_cell *);
608extern int afs_permission(struct inode *, int, struct nameidata *); 606extern int afs_permission(struct inode *, int);
609 607
610/* 608/*
611 * server.c 609 * server.c
diff --git a/fs/afs/security.c b/fs/afs/security.c
index 3bcbeceba1bb..3ef504370034 100644
--- a/fs/afs/security.c
+++ b/fs/afs/security.c
@@ -284,7 +284,7 @@ static int afs_check_permit(struct afs_vnode *vnode, struct key *key,
284 * - AFS ACLs are attached to directories only, and a file is controlled by its 284 * - AFS ACLs are attached to directories only, and a file is controlled by its
285 * parent directory's ACL 285 * parent directory's ACL
286 */ 286 */
287int afs_permission(struct inode *inode, int mask, struct nameidata *nd) 287int afs_permission(struct inode *inode, int mask)
288{ 288{
289 struct afs_vnode *vnode = AFS_FS_I(inode); 289 struct afs_vnode *vnode = AFS_FS_I(inode);
290 afs_access_t uninitialized_var(access); 290 afs_access_t uninitialized_var(access);
diff --git a/fs/aio.c b/fs/aio.c
index 0051fd94b44e..f658441d5666 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -512,8 +512,8 @@ static void aio_fput_routine(struct work_struct *data)
512 */ 512 */
513static int __aio_put_req(struct kioctx *ctx, struct kiocb *req) 513static int __aio_put_req(struct kioctx *ctx, struct kiocb *req)
514{ 514{
515 dprintk(KERN_DEBUG "aio_put(%p): f_count=%d\n", 515 dprintk(KERN_DEBUG "aio_put(%p): f_count=%ld\n",
516 req, atomic_read(&req->ki_filp->f_count)); 516 req, atomic_long_read(&req->ki_filp->f_count));
517 517
518 assert_spin_locked(&ctx->ctx_lock); 518 assert_spin_locked(&ctx->ctx_lock);
519 519
@@ -528,7 +528,7 @@ static int __aio_put_req(struct kioctx *ctx, struct kiocb *req)
528 /* Must be done under the lock to serialise against cancellation. 528 /* Must be done under the lock to serialise against cancellation.
529 * Call this aio_fput as it duplicates fput via the fput_work. 529 * Call this aio_fput as it duplicates fput via the fput_work.
530 */ 530 */
531 if (unlikely(atomic_dec_and_test(&req->ki_filp->f_count))) { 531 if (unlikely(atomic_long_dec_and_test(&req->ki_filp->f_count))) {
532 get_ioctx(ctx); 532 get_ioctx(ctx);
533 spin_lock(&fput_lock); 533 spin_lock(&fput_lock);
534 list_add(&req->ki_list, &fput_head); 534 list_add(&req->ki_list, &fput_head);
diff --git a/fs/attr.c b/fs/attr.c
index 966b73e25f82..26c71ba1eed4 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -51,7 +51,7 @@ int inode_change_ok(struct inode *inode, struct iattr *attr)
51 } 51 }
52 52
53 /* Check for setting the inode time. */ 53 /* Check for setting the inode time. */
54 if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET)) { 54 if (ia_valid & (ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)) {
55 if (!is_owner_or_cap(inode)) 55 if (!is_owner_or_cap(inode))
56 goto error; 56 goto error;
57 } 57 }
@@ -108,6 +108,11 @@ int notify_change(struct dentry * dentry, struct iattr * attr)
108 struct timespec now; 108 struct timespec now;
109 unsigned int ia_valid = attr->ia_valid; 109 unsigned int ia_valid = attr->ia_valid;
110 110
111 if (ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID | ATTR_TIMES_SET)) {
112 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
113 return -EPERM;
114 }
115
111 now = current_fs_time(inode->i_sb); 116 now = current_fs_time(inode->i_sb);
112 117
113 attr->ia_ctime = now; 118 attr->ia_ctime = now;
diff --git a/fs/bad_inode.c b/fs/bad_inode.c
index f1c2ea8342f5..5f1538c03b1b 100644
--- a/fs/bad_inode.c
+++ b/fs/bad_inode.c
@@ -243,8 +243,7 @@ static int bad_inode_readlink(struct dentry *dentry, char __user *buffer,
243 return -EIO; 243 return -EIO;
244} 244}
245 245
246static int bad_inode_permission(struct inode *inode, int mask, 246static int bad_inode_permission(struct inode *inode, int mask)
247 struct nameidata *nd)
248{ 247{
249 return -EIO; 248 return -EIO;
250} 249}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index fe5f6809cba6..1ec7076f7b24 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -267,7 +267,7 @@ cifs_statfs(struct dentry *dentry, struct kstatfs *buf)
267 return 0; 267 return 0;
268} 268}
269 269
270static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd) 270static int cifs_permission(struct inode *inode, int mask)
271{ 271{
272 struct cifs_sb_info *cifs_sb; 272 struct cifs_sb_info *cifs_sb;
273 273
diff --git a/fs/coda/dir.c b/fs/coda/dir.c
index 3d2580e00a3e..c5916228243c 100644
--- a/fs/coda/dir.c
+++ b/fs/coda/dir.c
@@ -137,9 +137,11 @@ exit:
137} 137}
138 138
139 139
140int coda_permission(struct inode *inode, int mask, struct nameidata *nd) 140int coda_permission(struct inode *inode, int mask)
141{ 141{
142 int error = 0; 142 int error = 0;
143
144 mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
143 145
144 if (!mask) 146 if (!mask)
145 return 0; 147 return 0;
diff --git a/fs/coda/pioctl.c b/fs/coda/pioctl.c
index c21a1f552a63..c51365422aa8 100644
--- a/fs/coda/pioctl.c
+++ b/fs/coda/pioctl.c
@@ -24,8 +24,7 @@
24#include <linux/coda_psdev.h> 24#include <linux/coda_psdev.h>
25 25
26/* pioctl ops */ 26/* pioctl ops */
27static int coda_ioctl_permission(struct inode *inode, int mask, 27static int coda_ioctl_permission(struct inode *inode, int mask);
28 struct nameidata *nd);
29static int coda_pioctl(struct inode * inode, struct file * filp, 28static int coda_pioctl(struct inode * inode, struct file * filp,
30 unsigned int cmd, unsigned long user_data); 29 unsigned int cmd, unsigned long user_data);
31 30
@@ -42,8 +41,7 @@ const struct file_operations coda_ioctl_operations = {
42}; 41};
43 42
44/* the coda pioctl inode ops */ 43/* the coda pioctl inode ops */
45static int coda_ioctl_permission(struct inode *inode, int mask, 44static int coda_ioctl_permission(struct inode *inode, int mask)
46 struct nameidata *nd)
47{ 45{
48 return 0; 46 return 0;
49} 47}
@@ -51,7 +49,7 @@ static int coda_ioctl_permission(struct inode *inode, int mask,
51static int coda_pioctl(struct inode * inode, struct file * filp, 49static int coda_pioctl(struct inode * inode, struct file * filp,
52 unsigned int cmd, unsigned long user_data) 50 unsigned int cmd, unsigned long user_data)
53{ 51{
54 struct nameidata nd; 52 struct path path;
55 int error; 53 int error;
56 struct PioctlData data; 54 struct PioctlData data;
57 struct inode *target_inode = NULL; 55 struct inode *target_inode = NULL;
@@ -66,21 +64,21 @@ static int coda_pioctl(struct inode * inode, struct file * filp,
66 * Look up the pathname. Note that the pathname is in 64 * Look up the pathname. Note that the pathname is in
67 * user memory, and namei takes care of this 65 * user memory, and namei takes care of this
68 */ 66 */
69 if ( data.follow ) { 67 if (data.follow) {
70 error = user_path_walk(data.path, &nd); 68 error = user_path(data.path, &path);
71 } else { 69 } else {
72 error = user_path_walk_link(data.path, &nd); 70 error = user_lpath(data.path, &path);
73 } 71 }
74 72
75 if ( error ) { 73 if ( error ) {
76 return error; 74 return error;
77 } else { 75 } else {
78 target_inode = nd.path.dentry->d_inode; 76 target_inode = path.dentry->d_inode;
79 } 77 }
80 78
81 /* return if it is not a Coda inode */ 79 /* return if it is not a Coda inode */
82 if ( target_inode->i_sb != inode->i_sb ) { 80 if ( target_inode->i_sb != inode->i_sb ) {
83 path_put(&nd.path); 81 path_put(&path);
84 return -EINVAL; 82 return -EINVAL;
85 } 83 }
86 84
@@ -89,7 +87,7 @@ static int coda_pioctl(struct inode * inode, struct file * filp,
89 87
90 error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data); 88 error = venus_pioctl(inode->i_sb, &(cnp->c_fid), cmd, &data);
91 89
92 path_put(&nd.path); 90 path_put(&path);
93 return error; 91 return error;
94} 92}
95 93
diff --git a/fs/compat.c b/fs/compat.c
index 106eba28ec5a..c9d1472e65c5 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -234,18 +234,18 @@ static int put_compat_statfs(struct compat_statfs __user *ubuf, struct kstatfs *
234 * The following statfs calls are copies of code from fs/open.c and 234 * The following statfs calls are copies of code from fs/open.c and
235 * should be checked against those from time to time 235 * should be checked against those from time to time
236 */ 236 */
237asmlinkage long compat_sys_statfs(const char __user *path, struct compat_statfs __user *buf) 237asmlinkage long compat_sys_statfs(const char __user *pathname, struct compat_statfs __user *buf)
238{ 238{
239 struct nameidata nd; 239 struct path path;
240 int error; 240 int error;
241 241
242 error = user_path_walk(path, &nd); 242 error = user_path(pathname, &path);
243 if (!error) { 243 if (!error) {
244 struct kstatfs tmp; 244 struct kstatfs tmp;
245 error = vfs_statfs(nd.path.dentry, &tmp); 245 error = vfs_statfs(path.dentry, &tmp);
246 if (!error) 246 if (!error)
247 error = put_compat_statfs(buf, &tmp); 247 error = put_compat_statfs(buf, &tmp);
248 path_put(&nd.path); 248 path_put(&path);
249 } 249 }
250 return error; 250 return error;
251} 251}
@@ -299,21 +299,21 @@ static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstat
299 return 0; 299 return 0;
300} 300}
301 301
302asmlinkage long compat_sys_statfs64(const char __user *path, compat_size_t sz, struct compat_statfs64 __user *buf) 302asmlinkage long compat_sys_statfs64(const char __user *pathname, compat_size_t sz, struct compat_statfs64 __user *buf)
303{ 303{
304 struct nameidata nd; 304 struct path path;
305 int error; 305 int error;
306 306
307 if (sz != sizeof(*buf)) 307 if (sz != sizeof(*buf))
308 return -EINVAL; 308 return -EINVAL;
309 309
310 error = user_path_walk(path, &nd); 310 error = user_path(pathname, &path);
311 if (!error) { 311 if (!error) {
312 struct kstatfs tmp; 312 struct kstatfs tmp;
313 error = vfs_statfs(nd.path.dentry, &tmp); 313 error = vfs_statfs(path.dentry, &tmp);
314 if (!error) 314 if (!error)
315 error = put_compat_statfs64(buf, &tmp); 315 error = put_compat_statfs64(buf, &tmp);
316 path_put(&nd.path); 316 path_put(&path);
317 } 317 }
318 return error; 318 return error;
319} 319}
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index d755455e3bff..89209f00f9c7 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -465,7 +465,6 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry,
465 int rc; 465 int rc;
466 struct dentry *lower_dentry; 466 struct dentry *lower_dentry;
467 struct dentry *lower_dir_dentry; 467 struct dentry *lower_dir_dentry;
468 umode_t mode;
469 char *encoded_symname; 468 char *encoded_symname;
470 int encoded_symlen; 469 int encoded_symlen;
471 struct ecryptfs_crypt_stat *crypt_stat = NULL; 470 struct ecryptfs_crypt_stat *crypt_stat = NULL;
@@ -473,7 +472,6 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry,
473 lower_dentry = ecryptfs_dentry_to_lower(dentry); 472 lower_dentry = ecryptfs_dentry_to_lower(dentry);
474 dget(lower_dentry); 473 dget(lower_dentry);
475 lower_dir_dentry = lock_parent(lower_dentry); 474 lower_dir_dentry = lock_parent(lower_dentry);
476 mode = S_IALLUGO;
477 encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname, 475 encoded_symlen = ecryptfs_encode_filename(crypt_stat, symname,
478 strlen(symname), 476 strlen(symname),
479 &encoded_symname); 477 &encoded_symname);
@@ -482,7 +480,7 @@ static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry,
482 goto out_lock; 480 goto out_lock;
483 } 481 }
484 rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry, 482 rc = vfs_symlink(lower_dir_dentry->d_inode, lower_dentry,
485 encoded_symname, mode); 483 encoded_symname);
486 kfree(encoded_symname); 484 kfree(encoded_symname);
487 if (rc || !lower_dentry->d_inode) 485 if (rc || !lower_dentry->d_inode)
488 goto out_lock; 486 goto out_lock;
@@ -830,22 +828,9 @@ out:
830} 828}
831 829
832static int 830static int
833ecryptfs_permission(struct inode *inode, int mask, struct nameidata *nd) 831ecryptfs_permission(struct inode *inode, int mask)
834{ 832{
835 int rc; 833 return inode_permission(ecryptfs_inode_to_lower(inode), mask);
836
837 if (nd) {
838 struct vfsmount *vfsmnt_save = nd->path.mnt;
839 struct dentry *dentry_save = nd->path.dentry;
840
841 nd->path.mnt = ecryptfs_dentry_to_lower_mnt(nd->path.dentry);
842 nd->path.dentry = ecryptfs_dentry_to_lower(nd->path.dentry);
843 rc = permission(ecryptfs_inode_to_lower(inode), mask, nd);
844 nd->path.mnt = vfsmnt_save;
845 nd->path.dentry = dentry_save;
846 } else
847 rc = permission(ecryptfs_inode_to_lower(inode), mask, NULL);
848 return rc;
849} 834}
850 835
851/** 836/**
diff --git a/fs/exec.c b/fs/exec.c
index b8792a131533..9696bbf0f0b1 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -106,11 +106,17 @@ static inline void put_binfmt(struct linux_binfmt * fmt)
106 */ 106 */
107asmlinkage long sys_uselib(const char __user * library) 107asmlinkage long sys_uselib(const char __user * library)
108{ 108{
109 struct file * file; 109 struct file *file;
110 struct nameidata nd; 110 struct nameidata nd;
111 int error; 111 char *tmp = getname(library);
112 112 int error = PTR_ERR(tmp);
113 error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC); 113
114 if (!IS_ERR(tmp)) {
115 error = path_lookup_open(AT_FDCWD, tmp,
116 LOOKUP_FOLLOW, &nd,
117 FMODE_READ|FMODE_EXEC);
118 putname(tmp);
119 }
114 if (error) 120 if (error)
115 goto out; 121 goto out;
116 122
@@ -118,7 +124,11 @@ asmlinkage long sys_uselib(const char __user * library)
118 if (!S_ISREG(nd.path.dentry->d_inode->i_mode)) 124 if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
119 goto exit; 125 goto exit;
120 126
121 error = vfs_permission(&nd, MAY_READ | MAY_EXEC); 127 error = -EACCES;
128 if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
129 goto exit;
130
131 error = vfs_permission(&nd, MAY_READ | MAY_EXEC | MAY_OPEN);
122 if (error) 132 if (error)
123 goto exit; 133 goto exit;
124 134
@@ -656,38 +666,43 @@ EXPORT_SYMBOL(setup_arg_pages);
656struct file *open_exec(const char *name) 666struct file *open_exec(const char *name)
657{ 667{
658 struct nameidata nd; 668 struct nameidata nd;
659 int err;
660 struct file *file; 669 struct file *file;
670 int err;
661 671
662 err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC); 672 err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd,
663 file = ERR_PTR(err); 673 FMODE_READ|FMODE_EXEC);
664 674 if (err)
665 if (!err) { 675 goto out;
666 struct inode *inode = nd.path.dentry->d_inode; 676
667 file = ERR_PTR(-EACCES); 677 err = -EACCES;
668 if (S_ISREG(inode->i_mode)) { 678 if (!S_ISREG(nd.path.dentry->d_inode->i_mode))
669 int err = vfs_permission(&nd, MAY_EXEC); 679 goto out_path_put;
670 file = ERR_PTR(err); 680
671 if (!err) { 681 if (nd.path.mnt->mnt_flags & MNT_NOEXEC)
672 file = nameidata_to_filp(&nd, 682 goto out_path_put;
673 O_RDONLY|O_LARGEFILE); 683
674 if (!IS_ERR(file)) { 684 err = vfs_permission(&nd, MAY_EXEC | MAY_OPEN);
675 err = deny_write_access(file); 685 if (err)
676 if (err) { 686 goto out_path_put;
677 fput(file); 687
678 file = ERR_PTR(err); 688 file = nameidata_to_filp(&nd, O_RDONLY|O_LARGEFILE);
679 } 689 if (IS_ERR(file))
680 } 690 return file;
681out: 691
682 return file; 692 err = deny_write_access(file);
683 } 693 if (err) {
684 } 694 fput(file);
685 release_open_intent(&nd); 695 goto out;
686 path_put(&nd.path);
687 } 696 }
688 goto out;
689}
690 697
698 return file;
699
700 out_path_put:
701 release_open_intent(&nd);
702 path_put(&nd.path);
703 out:
704 return ERR_PTR(err);
705}
691EXPORT_SYMBOL(open_exec); 706EXPORT_SYMBOL(open_exec);
692 707
693int kernel_read(struct file *file, unsigned long offset, 708int kernel_read(struct file *file, unsigned long offset,
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index e58669e1b87c..ae8c4f850b27 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -294,7 +294,7 @@ ext2_check_acl(struct inode *inode, int mask)
294} 294}
295 295
296int 296int
297ext2_permission(struct inode *inode, int mask, struct nameidata *nd) 297ext2_permission(struct inode *inode, int mask)
298{ 298{
299 return generic_permission(inode, mask, ext2_check_acl); 299 return generic_permission(inode, mask, ext2_check_acl);
300} 300}
diff --git a/fs/ext2/acl.h b/fs/ext2/acl.h
index 0bde85bafe38..b42cf578554b 100644
--- a/fs/ext2/acl.h
+++ b/fs/ext2/acl.h
@@ -58,7 +58,7 @@ static inline int ext2_acl_count(size_t size)
58#define EXT2_ACL_NOT_CACHED ((void *)-1) 58#define EXT2_ACL_NOT_CACHED ((void *)-1)
59 59
60/* acl.c */ 60/* acl.c */
61extern int ext2_permission (struct inode *, int, struct nameidata *); 61extern int ext2_permission (struct inode *, int);
62extern int ext2_acl_chmod (struct inode *); 62extern int ext2_acl_chmod (struct inode *);
63extern int ext2_init_acl (struct inode *, struct inode *); 63extern int ext2_init_acl (struct inode *, struct inode *);
64 64
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index a754d1848173..b60bb241880c 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -299,7 +299,7 @@ ext3_check_acl(struct inode *inode, int mask)
299} 299}
300 300
301int 301int
302ext3_permission(struct inode *inode, int mask, struct nameidata *nd) 302ext3_permission(struct inode *inode, int mask)
303{ 303{
304 return generic_permission(inode, mask, ext3_check_acl); 304 return generic_permission(inode, mask, ext3_check_acl);
305} 305}
diff --git a/fs/ext3/acl.h b/fs/ext3/acl.h
index 0d1e6279cbfd..42da16b8cac0 100644
--- a/fs/ext3/acl.h
+++ b/fs/ext3/acl.h
@@ -58,7 +58,7 @@ static inline int ext3_acl_count(size_t size)
58#define EXT3_ACL_NOT_CACHED ((void *)-1) 58#define EXT3_ACL_NOT_CACHED ((void *)-1)
59 59
60/* acl.c */ 60/* acl.c */
61extern int ext3_permission (struct inode *, int, struct nameidata *); 61extern int ext3_permission (struct inode *, int);
62extern int ext3_acl_chmod (struct inode *); 62extern int ext3_acl_chmod (struct inode *);
63extern int ext3_init_acl (handle_t *, struct inode *, struct inode *); 63extern int ext3_init_acl (handle_t *, struct inode *, struct inode *);
64 64
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index 3c8dab880d91..c7d04e165446 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -299,7 +299,7 @@ ext4_check_acl(struct inode *inode, int mask)
299} 299}
300 300
301int 301int
302ext4_permission(struct inode *inode, int mask, struct nameidata *nd) 302ext4_permission(struct inode *inode, int mask)
303{ 303{
304 return generic_permission(inode, mask, ext4_check_acl); 304 return generic_permission(inode, mask, ext4_check_acl);
305} 305}
diff --git a/fs/ext4/acl.h b/fs/ext4/acl.h
index 26a5c1abf147..cd2b855a07d6 100644
--- a/fs/ext4/acl.h
+++ b/fs/ext4/acl.h
@@ -58,7 +58,7 @@ static inline int ext4_acl_count(size_t size)
58#define EXT4_ACL_NOT_CACHED ((void *)-1) 58#define EXT4_ACL_NOT_CACHED ((void *)-1)
59 59
60/* acl.c */ 60/* acl.c */
61extern int ext4_permission (struct inode *, int, struct nameidata *); 61extern int ext4_permission (struct inode *, int);
62extern int ext4_acl_chmod (struct inode *); 62extern int ext4_acl_chmod (struct inode *);
63extern int ext4_init_acl (handle_t *, struct inode *, struct inode *); 63extern int ext4_init_acl (handle_t *, struct inode *, struct inode *);
64 64
diff --git a/fs/fat/file.c b/fs/fat/file.c
index c672df4036e9..8707a8cfa02c 100644
--- a/fs/fat/file.c
+++ b/fs/fat/file.c
@@ -15,6 +15,8 @@
15#include <linux/writeback.h> 15#include <linux/writeback.h>
16#include <linux/backing-dev.h> 16#include <linux/backing-dev.h>
17#include <linux/blkdev.h> 17#include <linux/blkdev.h>
18#include <linux/fsnotify.h>
19#include <linux/security.h>
18 20
19int fat_generic_ioctl(struct inode *inode, struct file *filp, 21int fat_generic_ioctl(struct inode *inode, struct file *filp,
20 unsigned int cmd, unsigned long arg) 22 unsigned int cmd, unsigned long arg)
@@ -64,6 +66,7 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp,
64 66
65 /* Equivalent to a chmod() */ 67 /* Equivalent to a chmod() */
66 ia.ia_valid = ATTR_MODE | ATTR_CTIME; 68 ia.ia_valid = ATTR_MODE | ATTR_CTIME;
69 ia.ia_ctime = current_fs_time(inode->i_sb);
67 if (is_dir) { 70 if (is_dir) {
68 ia.ia_mode = MSDOS_MKMODE(attr, 71 ia.ia_mode = MSDOS_MKMODE(attr,
69 S_IRWXUGO & ~sbi->options.fs_dmask) 72 S_IRWXUGO & ~sbi->options.fs_dmask)
@@ -90,11 +93,21 @@ int fat_generic_ioctl(struct inode *inode, struct file *filp,
90 } 93 }
91 } 94 }
92 95
96 /*
97 * The security check is questionable... We single
98 * out the RO attribute for checking by the security
99 * module, just because it maps to a file mode.
100 */
101 err = security_inode_setattr(filp->f_path.dentry, &ia);
102 if (err)
103 goto up;
104
93 /* This MUST be done before doing anything irreversible... */ 105 /* This MUST be done before doing anything irreversible... */
94 err = notify_change(filp->f_path.dentry, &ia); 106 err = fat_setattr(filp->f_path.dentry, &ia);
95 if (err) 107 if (err)
96 goto up; 108 goto up;
97 109
110 fsnotify_change(filp->f_path.dentry, ia.ia_valid);
98 if (sbi->options.sys_immutable) { 111 if (sbi->options.sys_immutable) {
99 if (attr & ATTR_SYS) 112 if (attr & ATTR_SYS)
100 inode->i_flags |= S_IMMUTABLE; 113 inode->i_flags |= S_IMMUTABLE;
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 9679fcbdeaa0..61d625136813 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -64,11 +64,6 @@ static int locate_fd(unsigned int orig_start, int cloexec)
64 struct fdtable *fdt; 64 struct fdtable *fdt;
65 65
66 spin_lock(&files->file_lock); 66 spin_lock(&files->file_lock);
67
68 error = -EINVAL;
69 if (orig_start >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
70 goto out;
71
72repeat: 67repeat:
73 fdt = files_fdtable(files); 68 fdt = files_fdtable(files);
74 /* 69 /*
@@ -83,10 +78,6 @@ repeat:
83 if (start < fdt->max_fds) 78 if (start < fdt->max_fds)
84 newfd = find_next_zero_bit(fdt->open_fds->fds_bits, 79 newfd = find_next_zero_bit(fdt->open_fds->fds_bits,
85 fdt->max_fds, start); 80 fdt->max_fds, start);
86
87 error = -EMFILE;
88 if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
89 goto out;
90 81
91 error = expand_files(files, newfd); 82 error = expand_files(files, newfd);
92 if (error < 0) 83 if (error < 0)
@@ -135,20 +126,20 @@ asmlinkage long sys_dup3(unsigned int oldfd, unsigned int newfd, int flags)
135 if ((flags & ~O_CLOEXEC) != 0) 126 if ((flags & ~O_CLOEXEC) != 0)
136 return -EINVAL; 127 return -EINVAL;
137 128
129 if (unlikely(oldfd == newfd))
130 return -EINVAL;
131
138 spin_lock(&files->file_lock); 132 spin_lock(&files->file_lock);
139 if (!(file = fcheck(oldfd))) 133 if (!(file = fcheck(oldfd)))
140 goto out_unlock; 134 goto out_unlock;
141 err = newfd;
142 if (newfd == oldfd)
143 goto out_unlock;
144 err = -EBADF;
145 if (newfd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
146 goto out_unlock;
147 get_file(file); /* We are now finished with oldfd */ 135 get_file(file); /* We are now finished with oldfd */
148 136
149 err = expand_files(files, newfd); 137 err = expand_files(files, newfd);
150 if (err < 0) 138 if (unlikely(err < 0)) {
139 if (err == -EMFILE)
140 err = -EBADF;
151 goto out_fput; 141 goto out_fput;
142 }
152 143
153 /* To avoid races with open() and dup(), we will mark the fd as 144 /* To avoid races with open() and dup(), we will mark the fd as
154 * in-use in the open-file bitmap throughout the entire dup2() 145 * in-use in the open-file bitmap throughout the entire dup2()
@@ -189,6 +180,14 @@ out_fput:
189 180
190asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd) 181asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
191{ 182{
183 if (unlikely(newfd == oldfd)) { /* corner case */
184 struct files_struct *files = current->files;
185 rcu_read_lock();
186 if (!fcheck_files(files, oldfd))
187 oldfd = -EBADF;
188 rcu_read_unlock();
189 return oldfd;
190 }
192 return sys_dup3(oldfd, newfd, 0); 191 return sys_dup3(oldfd, newfd, 0);
193} 192}
194 193
@@ -321,6 +320,8 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
321 switch (cmd) { 320 switch (cmd) {
322 case F_DUPFD: 321 case F_DUPFD:
323 case F_DUPFD_CLOEXEC: 322 case F_DUPFD_CLOEXEC:
323 if (arg >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
324 break;
324 get_file(filp); 325 get_file(filp);
325 err = dupfd(filp, arg, cmd == F_DUPFD_CLOEXEC); 326 err = dupfd(filp, arg, cmd == F_DUPFD_CLOEXEC);
326 break; 327 break;
diff --git a/fs/fifo.c b/fs/fifo.c
index 9785e36f81e7..987bf9411495 100644
--- a/fs/fifo.c
+++ b/fs/fifo.c
@@ -57,7 +57,7 @@ static int fifo_open(struct inode *inode, struct file *filp)
57 * POSIX.1 says that O_NONBLOCK means return with the FIFO 57 * POSIX.1 says that O_NONBLOCK means return with the FIFO
58 * opened, even when there is no process writing the FIFO. 58 * opened, even when there is no process writing the FIFO.
59 */ 59 */
60 filp->f_op = &read_fifo_fops; 60 filp->f_op = &read_pipefifo_fops;
61 pipe->r_counter++; 61 pipe->r_counter++;
62 if (pipe->readers++ == 0) 62 if (pipe->readers++ == 0)
63 wake_up_partner(inode); 63 wake_up_partner(inode);
@@ -86,7 +86,7 @@ static int fifo_open(struct inode *inode, struct file *filp)
86 if ((filp->f_flags & O_NONBLOCK) && !pipe->readers) 86 if ((filp->f_flags & O_NONBLOCK) && !pipe->readers)
87 goto err; 87 goto err;
88 88
89 filp->f_op = &write_fifo_fops; 89 filp->f_op = &write_pipefifo_fops;
90 pipe->w_counter++; 90 pipe->w_counter++;
91 if (!pipe->writers++) 91 if (!pipe->writers++)
92 wake_up_partner(inode); 92 wake_up_partner(inode);
@@ -105,7 +105,7 @@ static int fifo_open(struct inode *inode, struct file *filp)
105 * This implementation will NEVER block on a O_RDWR open, since 105 * This implementation will NEVER block on a O_RDWR open, since
106 * the process can at least talk to itself. 106 * the process can at least talk to itself.
107 */ 107 */
108 filp->f_op = &rdwr_fifo_fops; 108 filp->f_op = &rdwr_pipefifo_fops;
109 109
110 pipe->readers++; 110 pipe->readers++;
111 pipe->writers++; 111 pipe->writers++;
@@ -151,5 +151,5 @@ err_nocleanup:
151 * depending on the access mode of the file... 151 * depending on the access mode of the file...
152 */ 152 */
153const struct file_operations def_fifo_fops = { 153const struct file_operations def_fifo_fops = {
154 .open = fifo_open, /* will set read or write pipe_fops */ 154 .open = fifo_open, /* will set read_ or write_pipefifo_fops */
155}; 155};
diff --git a/fs/file.c b/fs/file.c
index 7b3887e054d0..d8773b19fe47 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -250,9 +250,18 @@ int expand_files(struct files_struct *files, int nr)
250 struct fdtable *fdt; 250 struct fdtable *fdt;
251 251
252 fdt = files_fdtable(files); 252 fdt = files_fdtable(files);
253
254 /*
255 * N.B. For clone tasks sharing a files structure, this test
256 * will limit the total number of files that can be opened.
257 */
258 if (nr >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
259 return -EMFILE;
260
253 /* Do we need to expand? */ 261 /* Do we need to expand? */
254 if (nr < fdt->max_fds) 262 if (nr < fdt->max_fds)
255 return 0; 263 return 0;
264
256 /* Can we expand? */ 265 /* Can we expand? */
257 if (nr >= sysctl_nr_open) 266 if (nr >= sysctl_nr_open)
258 return -EMFILE; 267 return -EMFILE;
diff --git a/fs/file_table.c b/fs/file_table.c
index 83084225b4c3..f45a4493f9e7 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -120,7 +120,7 @@ struct file *get_empty_filp(void)
120 120
121 tsk = current; 121 tsk = current;
122 INIT_LIST_HEAD(&f->f_u.fu_list); 122 INIT_LIST_HEAD(&f->f_u.fu_list);
123 atomic_set(&f->f_count, 1); 123 atomic_long_set(&f->f_count, 1);
124 rwlock_init(&f->f_owner.lock); 124 rwlock_init(&f->f_owner.lock);
125 f->f_uid = tsk->fsuid; 125 f->f_uid = tsk->fsuid;
126 f->f_gid = tsk->fsgid; 126 f->f_gid = tsk->fsgid;
@@ -219,7 +219,7 @@ EXPORT_SYMBOL(init_file);
219 219
220void fput(struct file *file) 220void fput(struct file *file)
221{ 221{
222 if (atomic_dec_and_test(&file->f_count)) 222 if (atomic_long_dec_and_test(&file->f_count))
223 __fput(file); 223 __fput(file);
224} 224}
225 225
@@ -294,7 +294,7 @@ struct file *fget(unsigned int fd)
294 rcu_read_lock(); 294 rcu_read_lock();
295 file = fcheck_files(files, fd); 295 file = fcheck_files(files, fd);
296 if (file) { 296 if (file) {
297 if (!atomic_inc_not_zero(&file->f_count)) { 297 if (!atomic_long_inc_not_zero(&file->f_count)) {
298 /* File object ref couldn't be taken */ 298 /* File object ref couldn't be taken */
299 rcu_read_unlock(); 299 rcu_read_unlock();
300 return NULL; 300 return NULL;
@@ -326,7 +326,7 @@ struct file *fget_light(unsigned int fd, int *fput_needed)
326 rcu_read_lock(); 326 rcu_read_lock();
327 file = fcheck_files(files, fd); 327 file = fcheck_files(files, fd);
328 if (file) { 328 if (file) {
329 if (atomic_inc_not_zero(&file->f_count)) 329 if (atomic_long_inc_not_zero(&file->f_count))
330 *fput_needed = 1; 330 *fput_needed = 1;
331 else 331 else
332 /* Didn't get the reference, someone's freed */ 332 /* Didn't get the reference, someone's freed */
@@ -341,7 +341,7 @@ struct file *fget_light(unsigned int fd, int *fput_needed)
341 341
342void put_filp(struct file *file) 342void put_filp(struct file *file)
343{ 343{
344 if (atomic_dec_and_test(&file->f_count)) { 344 if (atomic_long_dec_and_test(&file->f_count)) {
345 security_file_free(file); 345 security_file_free(file);
346 file_kill(file); 346 file_kill(file);
347 file_free(file); 347 file_free(file);
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 51d0035ff07e..fd03330cadeb 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -898,7 +898,7 @@ static int fuse_access(struct inode *inode, int mask)
898 return PTR_ERR(req); 898 return PTR_ERR(req);
899 899
900 memset(&inarg, 0, sizeof(inarg)); 900 memset(&inarg, 0, sizeof(inarg));
901 inarg.mask = mask; 901 inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
902 req->in.h.opcode = FUSE_ACCESS; 902 req->in.h.opcode = FUSE_ACCESS;
903 req->in.h.nodeid = get_node_id(inode); 903 req->in.h.nodeid = get_node_id(inode);
904 req->in.numargs = 1; 904 req->in.numargs = 1;
@@ -927,7 +927,7 @@ static int fuse_access(struct inode *inode, int mask)
927 * access request is sent. Execute permission is still checked 927 * access request is sent. Execute permission is still checked
928 * locally based on file mode. 928 * locally based on file mode.
929 */ 929 */
930static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd) 930static int fuse_permission(struct inode *inode, int mask)
931{ 931{
932 struct fuse_conn *fc = get_fuse_conn(inode); 932 struct fuse_conn *fc = get_fuse_conn(inode);
933 bool refreshed = false; 933 bool refreshed = false;
@@ -962,7 +962,7 @@ static int fuse_permission(struct inode *inode, int mask, struct nameidata *nd)
962 exist. So if permissions are revoked this won't be 962 exist. So if permissions are revoked this won't be
963 noticed immediately, only after the attribute 963 noticed immediately, only after the attribute
964 timeout has expired */ 964 timeout has expired */
965 } else if (nd && (nd->flags & (LOOKUP_ACCESS | LOOKUP_CHDIR))) { 965 } else if (mask & MAY_ACCESS) {
966 err = fuse_access(inode, mask); 966 err = fuse_access(inode, mask);
967 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) { 967 } else if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
968 if (!(inode->i_mode & S_IXUGO)) { 968 if (!(inode->i_mode & S_IXUGO)) {
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 67ff2c6a8f63..2bada6bbc317 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -893,7 +893,7 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
893 if (count == 0) 893 if (count == 0)
894 goto out; 894 goto out;
895 895
896 err = remove_suid(file->f_path.dentry); 896 err = file_remove_suid(file);
897 if (err) 897 if (err)
898 goto out; 898 goto out;
899 899
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 6da0ab355b8a..8b0806a32948 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -448,7 +448,7 @@ struct inode *gfs2_lookup_simple(struct inode *dip, const char *name)
448 struct qstr qstr; 448 struct qstr qstr;
449 struct inode *inode; 449 struct inode *inode;
450 gfs2_str2qstr(&qstr, name); 450 gfs2_str2qstr(&qstr, name);
451 inode = gfs2_lookupi(dip, &qstr, 1, NULL); 451 inode = gfs2_lookupi(dip, &qstr, 1);
452 /* gfs2_lookupi has inconsistent callers: vfs 452 /* gfs2_lookupi has inconsistent callers: vfs
453 * related routines expect NULL for no entry found, 453 * related routines expect NULL for no entry found,
454 * gfs2_lookup_simple callers expect ENOENT 454 * gfs2_lookup_simple callers expect ENOENT
@@ -477,7 +477,7 @@ struct inode *gfs2_lookup_simple(struct inode *dip, const char *name)
477 */ 477 */
478 478
479struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, 479struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
480 int is_root, struct nameidata *nd) 480 int is_root)
481{ 481{
482 struct super_block *sb = dir->i_sb; 482 struct super_block *sb = dir->i_sb;
483 struct gfs2_inode *dip = GFS2_I(dir); 483 struct gfs2_inode *dip = GFS2_I(dir);
@@ -1173,7 +1173,7 @@ int gfs2_ok_to_move(struct gfs2_inode *this, struct gfs2_inode *to)
1173 break; 1173 break;
1174 } 1174 }
1175 1175
1176 tmp = gfs2_lookupi(dir, &dotdot, 1, NULL); 1176 tmp = gfs2_lookupi(dir, &dotdot, 1);
1177 if (IS_ERR(tmp)) { 1177 if (IS_ERR(tmp)) {
1178 error = PTR_ERR(tmp); 1178 error = PTR_ERR(tmp);
1179 break; 1179 break;
diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h
index 6074c2506f75..58f9607d6a86 100644
--- a/fs/gfs2/inode.h
+++ b/fs/gfs2/inode.h
@@ -83,7 +83,7 @@ int gfs2_inode_refresh(struct gfs2_inode *ip);
83int gfs2_dinode_dealloc(struct gfs2_inode *inode); 83int gfs2_dinode_dealloc(struct gfs2_inode *inode);
84int gfs2_change_nlink(struct gfs2_inode *ip, int diff); 84int gfs2_change_nlink(struct gfs2_inode *ip, int diff);
85struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name, 85struct inode *gfs2_lookupi(struct inode *dir, const struct qstr *name,
86 int is_root, struct nameidata *nd); 86 int is_root);
87struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name, 87struct inode *gfs2_createi(struct gfs2_holder *ghs, const struct qstr *name,
88 unsigned int mode, dev_t dev); 88 unsigned int mode, dev_t dev);
89int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name, 89int gfs2_rmdiri(struct gfs2_inode *dip, const struct qstr *name,
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c
index 990d9f4bc463..9cda8536530c 100644
--- a/fs/gfs2/ops_export.c
+++ b/fs/gfs2/ops_export.c
@@ -134,7 +134,7 @@ static struct dentry *gfs2_get_parent(struct dentry *child)
134 struct dentry *dentry; 134 struct dentry *dentry;
135 135
136 gfs2_str2qstr(&dotdot, ".."); 136 gfs2_str2qstr(&dotdot, "..");
137 inode = gfs2_lookupi(child->d_inode, &dotdot, 1, NULL); 137 inode = gfs2_lookupi(child->d_inode, &dotdot, 1);
138 138
139 if (!inode) 139 if (!inode)
140 return ERR_PTR(-ENOENT); 140 return ERR_PTR(-ENOENT);
diff --git a/fs/gfs2/ops_inode.c b/fs/gfs2/ops_inode.c
index 1e252dfc5294..e2c62f73a778 100644
--- a/fs/gfs2/ops_inode.c
+++ b/fs/gfs2/ops_inode.c
@@ -74,7 +74,7 @@ static int gfs2_create(struct inode *dir, struct dentry *dentry,
74 return PTR_ERR(inode); 74 return PTR_ERR(inode);
75 } 75 }
76 76
77 inode = gfs2_lookupi(dir, &dentry->d_name, 0, nd); 77 inode = gfs2_lookupi(dir, &dentry->d_name, 0);
78 if (inode) { 78 if (inode) {
79 if (!IS_ERR(inode)) { 79 if (!IS_ERR(inode)) {
80 gfs2_holder_uninit(ghs); 80 gfs2_holder_uninit(ghs);
@@ -109,7 +109,7 @@ static struct dentry *gfs2_lookup(struct inode *dir, struct dentry *dentry,
109 109
110 dentry->d_op = &gfs2_dops; 110 dentry->d_op = &gfs2_dops;
111 111
112 inode = gfs2_lookupi(dir, &dentry->d_name, 0, nd); 112 inode = gfs2_lookupi(dir, &dentry->d_name, 0);
113 if (inode && IS_ERR(inode)) 113 if (inode && IS_ERR(inode))
114 return ERR_CAST(inode); 114 return ERR_CAST(inode);
115 115
@@ -915,12 +915,6 @@ int gfs2_permission(struct inode *inode, int mask)
915 return error; 915 return error;
916} 916}
917 917
918static int gfs2_iop_permission(struct inode *inode, int mask,
919 struct nameidata *nd)
920{
921 return gfs2_permission(inode, mask);
922}
923
924static int setattr_size(struct inode *inode, struct iattr *attr) 918static int setattr_size(struct inode *inode, struct iattr *attr)
925{ 919{
926 struct gfs2_inode *ip = GFS2_I(inode); 920 struct gfs2_inode *ip = GFS2_I(inode);
@@ -1150,7 +1144,7 @@ static int gfs2_removexattr(struct dentry *dentry, const char *name)
1150} 1144}
1151 1145
1152const struct inode_operations gfs2_file_iops = { 1146const struct inode_operations gfs2_file_iops = {
1153 .permission = gfs2_iop_permission, 1147 .permission = gfs2_permission,
1154 .setattr = gfs2_setattr, 1148 .setattr = gfs2_setattr,
1155 .getattr = gfs2_getattr, 1149 .getattr = gfs2_getattr,
1156 .setxattr = gfs2_setxattr, 1150 .setxattr = gfs2_setxattr,
@@ -1169,7 +1163,7 @@ const struct inode_operations gfs2_dir_iops = {
1169 .rmdir = gfs2_rmdir, 1163 .rmdir = gfs2_rmdir,
1170 .mknod = gfs2_mknod, 1164 .mknod = gfs2_mknod,
1171 .rename = gfs2_rename, 1165 .rename = gfs2_rename,
1172 .permission = gfs2_iop_permission, 1166 .permission = gfs2_permission,
1173 .setattr = gfs2_setattr, 1167 .setattr = gfs2_setattr,
1174 .getattr = gfs2_getattr, 1168 .getattr = gfs2_getattr,
1175 .setxattr = gfs2_setxattr, 1169 .setxattr = gfs2_setxattr,
@@ -1181,7 +1175,7 @@ const struct inode_operations gfs2_dir_iops = {
1181const struct inode_operations gfs2_symlink_iops = { 1175const struct inode_operations gfs2_symlink_iops = {
1182 .readlink = gfs2_readlink, 1176 .readlink = gfs2_readlink,
1183 .follow_link = gfs2_follow_link, 1177 .follow_link = gfs2_follow_link,
1184 .permission = gfs2_iop_permission, 1178 .permission = gfs2_permission,
1185 .setattr = gfs2_setattr, 1179 .setattr = gfs2_setattr,
1186 .getattr = gfs2_getattr, 1180 .getattr = gfs2_getattr,
1187 .setxattr = gfs2_setxattr, 1181 .setxattr = gfs2_setxattr,
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c
index 63a8a902d9db..ca831991cbc2 100644
--- a/fs/gfs2/super.c
+++ b/fs/gfs2/super.c
@@ -389,7 +389,7 @@ int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
389 break; 389 break;
390 390
391 INIT_LIST_HEAD(&jd->extent_list); 391 INIT_LIST_HEAD(&jd->extent_list);
392 jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1, NULL); 392 jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1);
393 if (!jd->jd_inode || IS_ERR(jd->jd_inode)) { 393 if (!jd->jd_inode || IS_ERR(jd->jd_inode)) {
394 if (!jd->jd_inode) 394 if (!jd->jd_inode)
395 error = -ENOENT; 395 error = -ENOENT;
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index dc4ec640e875..7e19835efa2e 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -511,8 +511,7 @@ void hfs_clear_inode(struct inode *inode)
511 } 511 }
512} 512}
513 513
514static int hfs_permission(struct inode *inode, int mask, 514static int hfs_permission(struct inode *inode, int mask)
515 struct nameidata *nd)
516{ 515{
517 if (S_ISREG(inode->i_mode) && mask & MAY_EXEC) 516 if (S_ISREG(inode->i_mode) && mask & MAY_EXEC)
518 return 0; 517 return 0;
@@ -523,8 +522,6 @@ static int hfs_file_open(struct inode *inode, struct file *file)
523{ 522{
524 if (HFS_IS_RSRC(inode)) 523 if (HFS_IS_RSRC(inode))
525 inode = HFS_I(inode)->rsrc_inode; 524 inode = HFS_I(inode)->rsrc_inode;
526 if (atomic_read(&file->f_count) != 1)
527 return 0;
528 atomic_inc(&HFS_I(inode)->opencnt); 525 atomic_inc(&HFS_I(inode)->opencnt);
529 return 0; 526 return 0;
530} 527}
@@ -535,8 +532,6 @@ static int hfs_file_release(struct inode *inode, struct file *file)
535 532
536 if (HFS_IS_RSRC(inode)) 533 if (HFS_IS_RSRC(inode))
537 inode = HFS_I(inode)->rsrc_inode; 534 inode = HFS_I(inode)->rsrc_inode;
538 if (atomic_read(&file->f_count) != 0)
539 return 0;
540 if (atomic_dec_and_test(&HFS_I(inode)->opencnt)) { 535 if (atomic_dec_and_test(&HFS_I(inode)->opencnt)) {
541 mutex_lock(&inode->i_mutex); 536 mutex_lock(&inode->i_mutex);
542 hfs_file_truncate(inode); 537 hfs_file_truncate(inode);
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index cc3b5e24339b..b085d64a2b67 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -238,7 +238,7 @@ static void hfsplus_set_perms(struct inode *inode, struct hfsplus_perm *perms)
238 perms->dev = cpu_to_be32(HFSPLUS_I(inode).dev); 238 perms->dev = cpu_to_be32(HFSPLUS_I(inode).dev);
239} 239}
240 240
241static int hfsplus_permission(struct inode *inode, int mask, struct nameidata *nd) 241static int hfsplus_permission(struct inode *inode, int mask)
242{ 242{
243 /* MAY_EXEC is also used for lookup, if no x bit is set allow lookup, 243 /* MAY_EXEC is also used for lookup, if no x bit is set allow lookup,
244 * open_exec has the same test, so it's still not executable, if a x bit 244 * open_exec has the same test, so it's still not executable, if a x bit
@@ -254,8 +254,6 @@ static int hfsplus_file_open(struct inode *inode, struct file *file)
254{ 254{
255 if (HFSPLUS_IS_RSRC(inode)) 255 if (HFSPLUS_IS_RSRC(inode))
256 inode = HFSPLUS_I(inode).rsrc_inode; 256 inode = HFSPLUS_I(inode).rsrc_inode;
257 if (atomic_read(&file->f_count) != 1)
258 return 0;
259 atomic_inc(&HFSPLUS_I(inode).opencnt); 257 atomic_inc(&HFSPLUS_I(inode).opencnt);
260 return 0; 258 return 0;
261} 259}
@@ -266,8 +264,6 @@ static int hfsplus_file_release(struct inode *inode, struct file *file)
266 264
267 if (HFSPLUS_IS_RSRC(inode)) 265 if (HFSPLUS_IS_RSRC(inode))
268 inode = HFSPLUS_I(inode).rsrc_inode; 266 inode = HFSPLUS_I(inode).rsrc_inode;
269 if (atomic_read(&file->f_count) != 0)
270 return 0;
271 if (atomic_dec_and_test(&HFSPLUS_I(inode).opencnt)) { 267 if (atomic_dec_and_test(&HFSPLUS_I(inode).opencnt)) {
272 mutex_lock(&inode->i_mutex); 268 mutex_lock(&inode->i_mutex);
273 hfsplus_file_truncate(inode); 269 hfsplus_file_truncate(inode);
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 5222345ddccf..d6ecabf4d231 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -822,7 +822,7 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from,
822 return err; 822 return err;
823} 823}
824 824
825int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd) 825int hostfs_permission(struct inode *ino, int desired)
826{ 826{
827 char *name; 827 char *name;
828 int r = 0, w = 0, x = 0, err; 828 int r = 0, w = 0, x = 0, err;
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c
index d256559b4104..d9c59a775449 100644
--- a/fs/hpfs/namei.c
+++ b/fs/hpfs/namei.c
@@ -415,7 +415,7 @@ again:
415 d_drop(dentry); 415 d_drop(dentry);
416 spin_lock(&dentry->d_lock); 416 spin_lock(&dentry->d_lock);
417 if (atomic_read(&dentry->d_count) > 1 || 417 if (atomic_read(&dentry->d_count) > 1 ||
418 permission(inode, MAY_WRITE, NULL) || 418 generic_permission(inode, MAY_WRITE, NULL) ||
419 !S_ISREG(inode->i_mode) || 419 !S_ISREG(inode->i_mode) ||
420 get_write_access(inode)) { 420 get_write_access(inode)) {
421 spin_unlock(&dentry->d_lock); 421 spin_unlock(&dentry->d_lock);
diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c
index 65077aa90f0a..2b3d1828db99 100644
--- a/fs/hppfs/hppfs.c
+++ b/fs/hppfs/hppfs.c
@@ -655,20 +655,13 @@ static void *hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
655 return proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd); 655 return proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd);
656} 656}
657 657
658int hppfs_permission(struct inode *inode, int mask, struct nameidata *nd)
659{
660 return generic_permission(inode, mask, NULL);
661}
662
663static const struct inode_operations hppfs_dir_iops = { 658static const struct inode_operations hppfs_dir_iops = {
664 .lookup = hppfs_lookup, 659 .lookup = hppfs_lookup,
665 .permission = hppfs_permission,
666}; 660};
667 661
668static const struct inode_operations hppfs_link_iops = { 662static const struct inode_operations hppfs_link_iops = {
669 .readlink = hppfs_readlink, 663 .readlink = hppfs_readlink,
670 .follow_link = hppfs_follow_link, 664 .follow_link = hppfs_follow_link,
671 .permission = hppfs_permission,
672}; 665};
673 666
674static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) 667static struct inode *get_inode(struct super_block *sb, struct dentry *dentry)
diff --git a/fs/inotify_user.c b/fs/inotify_user.c
index fe79c25d95dc..60249429a253 100644
--- a/fs/inotify_user.c
+++ b/fs/inotify_user.c
@@ -354,20 +354,20 @@ static void inotify_dev_event_dequeue(struct inotify_device *dev)
354} 354}
355 355
356/* 356/*
357 * find_inode - resolve a user-given path to a specific inode and return a nd 357 * find_inode - resolve a user-given path to a specific inode
358 */ 358 */
359static int find_inode(const char __user *dirname, struct nameidata *nd, 359static int find_inode(const char __user *dirname, struct path *path,
360 unsigned flags) 360 unsigned flags)
361{ 361{
362 int error; 362 int error;
363 363
364 error = __user_walk(dirname, flags, nd); 364 error = user_path_at(AT_FDCWD, dirname, flags, path);
365 if (error) 365 if (error)
366 return error; 366 return error;
367 /* you can only watch an inode if you have read permissions on it */ 367 /* you can only watch an inode if you have read permissions on it */
368 error = vfs_permission(nd, MAY_READ); 368 error = inode_permission(path->dentry->d_inode, MAY_READ);
369 if (error) 369 if (error)
370 path_put(&nd->path); 370 path_put(path);
371 return error; 371 return error;
372} 372}
373 373
@@ -650,11 +650,11 @@ asmlinkage long sys_inotify_init(void)
650 return sys_inotify_init1(0); 650 return sys_inotify_init1(0);
651} 651}
652 652
653asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask) 653asmlinkage long sys_inotify_add_watch(int fd, const char __user *pathname, u32 mask)
654{ 654{
655 struct inode *inode; 655 struct inode *inode;
656 struct inotify_device *dev; 656 struct inotify_device *dev;
657 struct nameidata nd; 657 struct path path;
658 struct file *filp; 658 struct file *filp;
659 int ret, fput_needed; 659 int ret, fput_needed;
660 unsigned flags = 0; 660 unsigned flags = 0;
@@ -674,12 +674,12 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
674 if (mask & IN_ONLYDIR) 674 if (mask & IN_ONLYDIR)
675 flags |= LOOKUP_DIRECTORY; 675 flags |= LOOKUP_DIRECTORY;
676 676
677 ret = find_inode(path, &nd, flags); 677 ret = find_inode(pathname, &path, flags);
678 if (unlikely(ret)) 678 if (unlikely(ret))
679 goto fput_and_out; 679 goto fput_and_out;
680 680
681 /* inode held in place by reference to nd; dev by fget on fd */ 681 /* inode held in place by reference to path; dev by fget on fd */
682 inode = nd.path.dentry->d_inode; 682 inode = path.dentry->d_inode;
683 dev = filp->private_data; 683 dev = filp->private_data;
684 684
685 mutex_lock(&dev->up_mutex); 685 mutex_lock(&dev->up_mutex);
@@ -688,7 +688,7 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
688 ret = create_watch(dev, inode, mask); 688 ret = create_watch(dev, inode, mask);
689 mutex_unlock(&dev->up_mutex); 689 mutex_unlock(&dev->up_mutex);
690 690
691 path_put(&nd.path); 691 path_put(&path);
692fput_and_out: 692fput_and_out:
693 fput_light(filp, fput_needed); 693 fput_light(filp, fput_needed);
694 return ret; 694 return ret;
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
index 4c80404a9aba..d98713777a1b 100644
--- a/fs/jffs2/acl.c
+++ b/fs/jffs2/acl.c
@@ -314,7 +314,7 @@ static int jffs2_check_acl(struct inode *inode, int mask)
314 return -EAGAIN; 314 return -EAGAIN;
315} 315}
316 316
317int jffs2_permission(struct inode *inode, int mask, struct nameidata *nd) 317int jffs2_permission(struct inode *inode, int mask)
318{ 318{
319 return generic_permission(inode, mask, jffs2_check_acl); 319 return generic_permission(inode, mask, jffs2_check_acl);
320} 320}
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h
index 0bb7f003fd80..8ca058aed384 100644
--- a/fs/jffs2/acl.h
+++ b/fs/jffs2/acl.h
@@ -28,7 +28,7 @@ struct jffs2_acl_header {
28 28
29#define JFFS2_ACL_NOT_CACHED ((void *)-1) 29#define JFFS2_ACL_NOT_CACHED ((void *)-1)
30 30
31extern int jffs2_permission(struct inode *, int, struct nameidata *); 31extern int jffs2_permission(struct inode *, int);
32extern int jffs2_acl_chmod(struct inode *); 32extern int jffs2_acl_chmod(struct inode *);
33extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *); 33extern int jffs2_init_acl_pre(struct inode *, struct inode *, int *);
34extern int jffs2_init_acl_post(struct inode *); 34extern int jffs2_init_acl_post(struct inode *);
diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
index 4d84bdc88299..d3e5c33665de 100644
--- a/fs/jfs/acl.c
+++ b/fs/jfs/acl.c
@@ -140,7 +140,7 @@ static int jfs_check_acl(struct inode *inode, int mask)
140 return -EAGAIN; 140 return -EAGAIN;
141} 141}
142 142
143int jfs_permission(struct inode *inode, int mask, struct nameidata *nd) 143int jfs_permission(struct inode *inode, int mask)
144{ 144{
145 return generic_permission(inode, mask, jfs_check_acl); 145 return generic_permission(inode, mask, jfs_check_acl);
146} 146}
diff --git a/fs/jfs/jfs_acl.h b/fs/jfs/jfs_acl.h
index 455fa4292045..88475f10a389 100644
--- a/fs/jfs/jfs_acl.h
+++ b/fs/jfs/jfs_acl.h
@@ -20,7 +20,7 @@
20 20
21#ifdef CONFIG_JFS_POSIX_ACL 21#ifdef CONFIG_JFS_POSIX_ACL
22 22
23int jfs_permission(struct inode *, int, struct nameidata *); 23int jfs_permission(struct inode *, int);
24int jfs_init_acl(tid_t, struct inode *, struct inode *); 24int jfs_init_acl(tid_t, struct inode *, struct inode *);
25int jfs_setattr(struct dentry *, struct iattr *); 25int jfs_setattr(struct dentry *, struct iattr *);
26 26
diff --git a/fs/namei.c b/fs/namei.c
index 01e67dddcc3d..a7b0a0b80128 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -31,7 +31,6 @@
31#include <linux/file.h> 31#include <linux/file.h>
32#include <linux/fcntl.h> 32#include <linux/fcntl.h>
33#include <linux/device_cgroup.h> 33#include <linux/device_cgroup.h>
34#include <asm/namei.h>
35#include <asm/uaccess.h> 34#include <asm/uaccess.h>
36 35
37#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE]) 36#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
@@ -185,6 +184,8 @@ int generic_permission(struct inode *inode, int mask,
185{ 184{
186 umode_t mode = inode->i_mode; 185 umode_t mode = inode->i_mode;
187 186
187 mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
188
188 if (current->fsuid == inode->i_uid) 189 if (current->fsuid == inode->i_uid)
189 mode >>= 6; 190 mode >>= 6;
190 else { 191 else {
@@ -203,7 +204,7 @@ int generic_permission(struct inode *inode, int mask,
203 /* 204 /*
204 * If the DACs are ok we don't need any capability check. 205 * If the DACs are ok we don't need any capability check.
205 */ 206 */
206 if (((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask)) 207 if ((mask & ~mode) == 0)
207 return 0; 208 return 0;
208 209
209 check_capabilities: 210 check_capabilities:
@@ -226,13 +227,9 @@ int generic_permission(struct inode *inode, int mask,
226 return -EACCES; 227 return -EACCES;
227} 228}
228 229
229int permission(struct inode *inode, int mask, struct nameidata *nd) 230int inode_permission(struct inode *inode, int mask)
230{ 231{
231 int retval, submask; 232 int retval;
232 struct vfsmount *mnt = NULL;
233
234 if (nd)
235 mnt = nd->path.mnt;
236 233
237 if (mask & MAY_WRITE) { 234 if (mask & MAY_WRITE) {
238 umode_t mode = inode->i_mode; 235 umode_t mode = inode->i_mode;
@@ -251,19 +248,9 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
251 return -EACCES; 248 return -EACCES;
252 } 249 }
253 250
254 if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode)) {
255 /*
256 * MAY_EXEC on regular files is denied if the fs is mounted
257 * with the "noexec" flag.
258 */
259 if (mnt && (mnt->mnt_flags & MNT_NOEXEC))
260 return -EACCES;
261 }
262
263 /* Ordinary permission routines do not understand MAY_APPEND. */ 251 /* Ordinary permission routines do not understand MAY_APPEND. */
264 submask = mask & ~MAY_APPEND;
265 if (inode->i_op && inode->i_op->permission) { 252 if (inode->i_op && inode->i_op->permission) {
266 retval = inode->i_op->permission(inode, submask, nd); 253 retval = inode->i_op->permission(inode, mask);
267 if (!retval) { 254 if (!retval) {
268 /* 255 /*
269 * Exec permission on a regular file is denied if none 256 * Exec permission on a regular file is denied if none
@@ -277,7 +264,7 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
277 return -EACCES; 264 return -EACCES;
278 } 265 }
279 } else { 266 } else {
280 retval = generic_permission(inode, submask, NULL); 267 retval = generic_permission(inode, mask, NULL);
281 } 268 }
282 if (retval) 269 if (retval)
283 return retval; 270 return retval;
@@ -286,7 +273,8 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
286 if (retval) 273 if (retval)
287 return retval; 274 return retval;
288 275
289 return security_inode_permission(inode, mask, nd); 276 return security_inode_permission(inode,
277 mask & (MAY_READ|MAY_WRITE|MAY_EXEC));
290} 278}
291 279
292/** 280/**
@@ -301,7 +289,7 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
301 */ 289 */
302int vfs_permission(struct nameidata *nd, int mask) 290int vfs_permission(struct nameidata *nd, int mask)
303{ 291{
304 return permission(nd->path.dentry->d_inode, mask, nd); 292 return inode_permission(nd->path.dentry->d_inode, mask);
305} 293}
306 294
307/** 295/**
@@ -318,7 +306,7 @@ int vfs_permission(struct nameidata *nd, int mask)
318 */ 306 */
319int file_permission(struct file *file, int mask) 307int file_permission(struct file *file, int mask)
320{ 308{
321 return permission(file->f_path.dentry->d_inode, mask, NULL); 309 return inode_permission(file->f_path.dentry->d_inode, mask);
322} 310}
323 311
324/* 312/*
@@ -459,8 +447,7 @@ static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name,
459 * short-cut DAC fails, then call permission() to do more 447 * short-cut DAC fails, then call permission() to do more
460 * complete permission check. 448 * complete permission check.
461 */ 449 */
462static int exec_permission_lite(struct inode *inode, 450static int exec_permission_lite(struct inode *inode)
463 struct nameidata *nd)
464{ 451{
465 umode_t mode = inode->i_mode; 452 umode_t mode = inode->i_mode;
466 453
@@ -486,7 +473,7 @@ static int exec_permission_lite(struct inode *inode,
486 473
487 return -EACCES; 474 return -EACCES;
488ok: 475ok:
489 return security_inode_permission(inode, MAY_EXEC, nd); 476 return security_inode_permission(inode, MAY_EXEC);
490} 477}
491 478
492/* 479/*
@@ -519,7 +506,14 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s
519 */ 506 */
520 result = d_lookup(parent, name); 507 result = d_lookup(parent, name);
521 if (!result) { 508 if (!result) {
522 struct dentry * dentry = d_alloc(parent, name); 509 struct dentry *dentry;
510
511 /* Don't create child dentry for a dead directory. */
512 result = ERR_PTR(-ENOENT);
513 if (IS_DEADDIR(dir))
514 goto out_unlock;
515
516 dentry = d_alloc(parent, name);
523 result = ERR_PTR(-ENOMEM); 517 result = ERR_PTR(-ENOMEM);
524 if (dentry) { 518 if (dentry) {
525 result = dir->i_op->lookup(dir, dentry, nd); 519 result = dir->i_op->lookup(dir, dentry, nd);
@@ -528,6 +522,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s
528 else 522 else
529 result = dentry; 523 result = dentry;
530 } 524 }
525out_unlock:
531 mutex_unlock(&dir->i_mutex); 526 mutex_unlock(&dir->i_mutex);
532 return result; 527 return result;
533 } 528 }
@@ -545,27 +540,16 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s
545 return result; 540 return result;
546} 541}
547 542
548static int __emul_lookup_dentry(const char *, struct nameidata *);
549
550/* SMP-safe */ 543/* SMP-safe */
551static __always_inline int 544static __always_inline void
552walk_init_root(const char *name, struct nameidata *nd) 545walk_init_root(const char *name, struct nameidata *nd)
553{ 546{
554 struct fs_struct *fs = current->fs; 547 struct fs_struct *fs = current->fs;
555 548
556 read_lock(&fs->lock); 549 read_lock(&fs->lock);
557 if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) {
558 nd->path = fs->altroot;
559 path_get(&fs->altroot);
560 read_unlock(&fs->lock);
561 if (__emul_lookup_dentry(name,nd))
562 return 0;
563 read_lock(&fs->lock);
564 }
565 nd->path = fs->root; 550 nd->path = fs->root;
566 path_get(&fs->root); 551 path_get(&fs->root);
567 read_unlock(&fs->lock); 552 read_unlock(&fs->lock);
568 return 1;
569} 553}
570 554
571/* 555/*
@@ -606,12 +590,9 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l
606 590
607 if (*link == '/') { 591 if (*link == '/') {
608 path_put(&nd->path); 592 path_put(&nd->path);
609 if (!walk_init_root(link, nd)) 593 walk_init_root(link, nd);
610 /* weird __emul_prefix() stuff did it */
611 goto out;
612 } 594 }
613 res = link_path_walk(link, nd); 595 res = link_path_walk(link, nd);
614out:
615 if (nd->depth || res || nd->last_type!=LAST_NORM) 596 if (nd->depth || res || nd->last_type!=LAST_NORM)
616 return res; 597 return res;
617 /* 598 /*
@@ -889,7 +870,7 @@ static int __link_path_walk(const char *name, struct nameidata *nd)
889 unsigned int c; 870 unsigned int c;
890 871
891 nd->flags |= LOOKUP_CONTINUE; 872 nd->flags |= LOOKUP_CONTINUE;
892 err = exec_permission_lite(inode, nd); 873 err = exec_permission_lite(inode);
893 if (err == -EAGAIN) 874 if (err == -EAGAIN)
894 err = vfs_permission(nd, MAY_EXEC); 875 err = vfs_permission(nd, MAY_EXEC);
895 if (err) 876 if (err)
@@ -1060,67 +1041,6 @@ static int path_walk(const char *name, struct nameidata *nd)
1060 return link_path_walk(name, nd); 1041 return link_path_walk(name, nd);
1061} 1042}
1062 1043
1063/*
1064 * SMP-safe: Returns 1 and nd will have valid dentry and mnt, if
1065 * everything is done. Returns 0 and drops input nd, if lookup failed;
1066 */
1067static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
1068{
1069 if (path_walk(name, nd))
1070 return 0; /* something went wrong... */
1071
1072 if (!nd->path.dentry->d_inode ||
1073 S_ISDIR(nd->path.dentry->d_inode->i_mode)) {
1074 struct path old_path = nd->path;
1075 struct qstr last = nd->last;
1076 int last_type = nd->last_type;
1077 struct fs_struct *fs = current->fs;
1078
1079 /*
1080 * NAME was not found in alternate root or it's a directory.
1081 * Try to find it in the normal root:
1082 */
1083 nd->last_type = LAST_ROOT;
1084 read_lock(&fs->lock);
1085 nd->path = fs->root;
1086 path_get(&fs->root);
1087 read_unlock(&fs->lock);
1088 if (path_walk(name, nd) == 0) {
1089 if (nd->path.dentry->d_inode) {
1090 path_put(&old_path);
1091 return 1;
1092 }
1093 path_put(&nd->path);
1094 }
1095 nd->path = old_path;
1096 nd->last = last;
1097 nd->last_type = last_type;
1098 }
1099 return 1;
1100}
1101
1102void set_fs_altroot(void)
1103{
1104 char *emul = __emul_prefix();
1105 struct nameidata nd;
1106 struct path path = {}, old_path;
1107 int err;
1108 struct fs_struct *fs = current->fs;
1109
1110 if (!emul)
1111 goto set_it;
1112 err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd);
1113 if (!err)
1114 path = nd.path;
1115set_it:
1116 write_lock(&fs->lock);
1117 old_path = fs->altroot;
1118 fs->altroot = path;
1119 write_unlock(&fs->lock);
1120 if (old_path.dentry)
1121 path_put(&old_path);
1122}
1123
1124/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ 1044/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
1125static int do_path_lookup(int dfd, const char *name, 1045static int do_path_lookup(int dfd, const char *name,
1126 unsigned int flags, struct nameidata *nd) 1046 unsigned int flags, struct nameidata *nd)
@@ -1136,14 +1056,6 @@ static int do_path_lookup(int dfd, const char *name,
1136 1056
1137 if (*name=='/') { 1057 if (*name=='/') {
1138 read_lock(&fs->lock); 1058 read_lock(&fs->lock);
1139 if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) {
1140 nd->path = fs->altroot;
1141 path_get(&fs->altroot);
1142 read_unlock(&fs->lock);
1143 if (__emul_lookup_dentry(name,nd))
1144 goto out; /* found in altroot */
1145 read_lock(&fs->lock);
1146 }
1147 nd->path = fs->root; 1059 nd->path = fs->root;
1148 path_get(&fs->root); 1060 path_get(&fs->root);
1149 read_unlock(&fs->lock); 1061 read_unlock(&fs->lock);
@@ -1177,7 +1089,6 @@ static int do_path_lookup(int dfd, const char *name,
1177 } 1089 }
1178 1090
1179 retval = path_walk(name, nd); 1091 retval = path_walk(name, nd);
1180out:
1181 if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry && 1092 if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
1182 nd->path.dentry->d_inode)) 1093 nd->path.dentry->d_inode))
1183 audit_inode(name, nd->path.dentry); 1094 audit_inode(name, nd->path.dentry);
@@ -1282,19 +1193,6 @@ static int path_lookup_create(int dfd, const char *name,
1282 nd, open_flags, create_mode); 1193 nd, open_flags, create_mode);
1283} 1194}
1284 1195
1285int __user_path_lookup_open(const char __user *name, unsigned int lookup_flags,
1286 struct nameidata *nd, int open_flags)
1287{
1288 char *tmp = getname(name);
1289 int err = PTR_ERR(tmp);
1290
1291 if (!IS_ERR(tmp)) {
1292 err = __path_lookup_intent_open(AT_FDCWD, tmp, lookup_flags, nd, open_flags, 0);
1293 putname(tmp);
1294 }
1295 return err;
1296}
1297
1298static struct dentry *__lookup_hash(struct qstr *name, 1196static struct dentry *__lookup_hash(struct qstr *name,
1299 struct dentry *base, struct nameidata *nd) 1197 struct dentry *base, struct nameidata *nd)
1300{ 1198{
@@ -1317,7 +1215,14 @@ static struct dentry *__lookup_hash(struct qstr *name,
1317 1215
1318 dentry = cached_lookup(base, name, nd); 1216 dentry = cached_lookup(base, name, nd);
1319 if (!dentry) { 1217 if (!dentry) {
1320 struct dentry *new = d_alloc(base, name); 1218 struct dentry *new;
1219
1220 /* Don't create child dentry for a dead directory. */
1221 dentry = ERR_PTR(-ENOENT);
1222 if (IS_DEADDIR(inode))
1223 goto out;
1224
1225 new = d_alloc(base, name);
1321 dentry = ERR_PTR(-ENOMEM); 1226 dentry = ERR_PTR(-ENOMEM);
1322 if (!new) 1227 if (!new)
1323 goto out; 1228 goto out;
@@ -1340,7 +1245,7 @@ static struct dentry *lookup_hash(struct nameidata *nd)
1340{ 1245{
1341 int err; 1246 int err;
1342 1247
1343 err = permission(nd->path.dentry->d_inode, MAY_EXEC, nd); 1248 err = inode_permission(nd->path.dentry->d_inode, MAY_EXEC);
1344 if (err) 1249 if (err)
1345 return ERR_PTR(err); 1250 return ERR_PTR(err);
1346 return __lookup_hash(&nd->last, nd->path.dentry, nd); 1251 return __lookup_hash(&nd->last, nd->path.dentry, nd);
@@ -1388,7 +1293,7 @@ struct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
1388 if (err) 1293 if (err)
1389 return ERR_PTR(err); 1294 return ERR_PTR(err);
1390 1295
1391 err = permission(base->d_inode, MAY_EXEC, NULL); 1296 err = inode_permission(base->d_inode, MAY_EXEC);
1392 if (err) 1297 if (err)
1393 return ERR_PTR(err); 1298 return ERR_PTR(err);
1394 return __lookup_hash(&this, base, NULL); 1299 return __lookup_hash(&this, base, NULL);
@@ -1416,22 +1321,40 @@ struct dentry *lookup_one_noperm(const char *name, struct dentry *base)
1416 return __lookup_hash(&this, base, NULL); 1321 return __lookup_hash(&this, base, NULL);
1417} 1322}
1418 1323
1419int __user_walk_fd(int dfd, const char __user *name, unsigned flags, 1324int user_path_at(int dfd, const char __user *name, unsigned flags,
1420 struct nameidata *nd) 1325 struct path *path)
1421{ 1326{
1327 struct nameidata nd;
1422 char *tmp = getname(name); 1328 char *tmp = getname(name);
1423 int err = PTR_ERR(tmp); 1329 int err = PTR_ERR(tmp);
1424
1425 if (!IS_ERR(tmp)) { 1330 if (!IS_ERR(tmp)) {
1426 err = do_path_lookup(dfd, tmp, flags, nd); 1331
1332 BUG_ON(flags & LOOKUP_PARENT);
1333
1334 err = do_path_lookup(dfd, tmp, flags, &nd);
1427 putname(tmp); 1335 putname(tmp);
1336 if (!err)
1337 *path = nd.path;
1428 } 1338 }
1429 return err; 1339 return err;
1430} 1340}
1431 1341
1432int __user_walk(const char __user *name, unsigned flags, struct nameidata *nd) 1342static int user_path_parent(int dfd, const char __user *path,
1343 struct nameidata *nd, char **name)
1433{ 1344{
1434 return __user_walk_fd(AT_FDCWD, name, flags, nd); 1345 char *s = getname(path);
1346 int error;
1347
1348 if (IS_ERR(s))
1349 return PTR_ERR(s);
1350
1351 error = do_path_lookup(dfd, s, LOOKUP_PARENT, nd);
1352 if (error)
1353 putname(s);
1354 else
1355 *name = s;
1356
1357 return error;
1435} 1358}
1436 1359
1437/* 1360/*
@@ -1478,7 +1401,7 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
1478 BUG_ON(victim->d_parent->d_inode != dir); 1401 BUG_ON(victim->d_parent->d_inode != dir);
1479 audit_inode_child(victim->d_name.name, victim, dir); 1402 audit_inode_child(victim->d_name.name, victim, dir);
1480 1403
1481 error = permission(dir,MAY_WRITE | MAY_EXEC, NULL); 1404 error = inode_permission(dir, MAY_WRITE | MAY_EXEC);
1482 if (error) 1405 if (error)
1483 return error; 1406 return error;
1484 if (IS_APPEND(dir)) 1407 if (IS_APPEND(dir))
@@ -1515,7 +1438,7 @@ static inline int may_create(struct inode *dir, struct dentry *child,
1515 return -EEXIST; 1438 return -EEXIST;
1516 if (IS_DEADDIR(dir)) 1439 if (IS_DEADDIR(dir))
1517 return -ENOENT; 1440 return -ENOENT;
1518 return permission(dir,MAY_WRITE | MAY_EXEC, nd); 1441 return inode_permission(dir, MAY_WRITE | MAY_EXEC);
1519} 1442}
1520 1443
1521/* 1444/*
@@ -1755,7 +1678,7 @@ struct file *do_filp_open(int dfd, const char *pathname,
1755 int will_write; 1678 int will_write;
1756 int flag = open_to_namei_flags(open_flag); 1679 int flag = open_to_namei_flags(open_flag);
1757 1680
1758 acc_mode = ACC_MODE(flag); 1681 acc_mode = MAY_OPEN | ACC_MODE(flag);
1759 1682
1760 /* O_TRUNC implies we need access checks for write permissions */ 1683 /* O_TRUNC implies we need access checks for write permissions */
1761 if (flag & O_TRUNC) 1684 if (flag & O_TRUNC)
@@ -2071,20 +1994,18 @@ static int may_mknod(mode_t mode)
2071asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode, 1994asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode,
2072 unsigned dev) 1995 unsigned dev)
2073{ 1996{
2074 int error = 0; 1997 int error;
2075 char * tmp; 1998 char *tmp;
2076 struct dentry * dentry; 1999 struct dentry *dentry;
2077 struct nameidata nd; 2000 struct nameidata nd;
2078 2001
2079 if (S_ISDIR(mode)) 2002 if (S_ISDIR(mode))
2080 return -EPERM; 2003 return -EPERM;
2081 tmp = getname(filename);
2082 if (IS_ERR(tmp))
2083 return PTR_ERR(tmp);
2084 2004
2085 error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd); 2005 error = user_path_parent(dfd, filename, &nd, &tmp);
2086 if (error) 2006 if (error)
2087 goto out; 2007 return error;
2008
2088 dentry = lookup_create(&nd, 0); 2009 dentry = lookup_create(&nd, 0);
2089 if (IS_ERR(dentry)) { 2010 if (IS_ERR(dentry)) {
2090 error = PTR_ERR(dentry); 2011 error = PTR_ERR(dentry);
@@ -2116,7 +2037,6 @@ out_dput:
2116out_unlock: 2037out_unlock:
2117 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2038 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
2118 path_put(&nd.path); 2039 path_put(&nd.path);
2119out:
2120 putname(tmp); 2040 putname(tmp);
2121 2041
2122 return error; 2042 return error;
@@ -2156,14 +2076,10 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode)
2156 struct dentry *dentry; 2076 struct dentry *dentry;
2157 struct nameidata nd; 2077 struct nameidata nd;
2158 2078
2159 tmp = getname(pathname); 2079 error = user_path_parent(dfd, pathname, &nd, &tmp);
2160 error = PTR_ERR(tmp); 2080 if (error)
2161 if (IS_ERR(tmp))
2162 goto out_err; 2081 goto out_err;
2163 2082
2164 error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd);
2165 if (error)
2166 goto out;
2167 dentry = lookup_create(&nd, 1); 2083 dentry = lookup_create(&nd, 1);
2168 error = PTR_ERR(dentry); 2084 error = PTR_ERR(dentry);
2169 if (IS_ERR(dentry)) 2085 if (IS_ERR(dentry))
@@ -2181,7 +2097,6 @@ out_dput:
2181out_unlock: 2097out_unlock:
2182 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2098 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
2183 path_put(&nd.path); 2099 path_put(&nd.path);
2184out:
2185 putname(tmp); 2100 putname(tmp);
2186out_err: 2101out_err:
2187 return error; 2102 return error;
@@ -2259,13 +2174,9 @@ static long do_rmdir(int dfd, const char __user *pathname)
2259 struct dentry *dentry; 2174 struct dentry *dentry;
2260 struct nameidata nd; 2175 struct nameidata nd;
2261 2176
2262 name = getname(pathname); 2177 error = user_path_parent(dfd, pathname, &nd, &name);
2263 if(IS_ERR(name))
2264 return PTR_ERR(name);
2265
2266 error = do_path_lookup(dfd, name, LOOKUP_PARENT, &nd);
2267 if (error) 2178 if (error)
2268 goto exit; 2179 return error;
2269 2180
2270 switch(nd.last_type) { 2181 switch(nd.last_type) {
2271 case LAST_DOTDOT: 2182 case LAST_DOTDOT:
@@ -2294,7 +2205,6 @@ exit2:
2294 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2205 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
2295exit1: 2206exit1:
2296 path_put(&nd.path); 2207 path_put(&nd.path);
2297exit:
2298 putname(name); 2208 putname(name);
2299 return error; 2209 return error;
2300} 2210}
@@ -2343,19 +2253,16 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
2343 */ 2253 */
2344static long do_unlinkat(int dfd, const char __user *pathname) 2254static long do_unlinkat(int dfd, const char __user *pathname)
2345{ 2255{
2346 int error = 0; 2256 int error;
2347 char * name; 2257 char *name;
2348 struct dentry *dentry; 2258 struct dentry *dentry;
2349 struct nameidata nd; 2259 struct nameidata nd;
2350 struct inode *inode = NULL; 2260 struct inode *inode = NULL;
2351 2261
2352 name = getname(pathname); 2262 error = user_path_parent(dfd, pathname, &nd, &name);
2353 if(IS_ERR(name))
2354 return PTR_ERR(name);
2355
2356 error = do_path_lookup(dfd, name, LOOKUP_PARENT, &nd);
2357 if (error) 2263 if (error)
2358 goto exit; 2264 return error;
2265
2359 error = -EISDIR; 2266 error = -EISDIR;
2360 if (nd.last_type != LAST_NORM) 2267 if (nd.last_type != LAST_NORM)
2361 goto exit1; 2268 goto exit1;
@@ -2382,7 +2289,6 @@ static long do_unlinkat(int dfd, const char __user *pathname)
2382 iput(inode); /* truncate the inode here */ 2289 iput(inode); /* truncate the inode here */
2383exit1: 2290exit1:
2384 path_put(&nd.path); 2291 path_put(&nd.path);
2385exit:
2386 putname(name); 2292 putname(name);
2387 return error; 2293 return error;
2388 2294
@@ -2408,7 +2314,7 @@ asmlinkage long sys_unlink(const char __user *pathname)
2408 return do_unlinkat(AT_FDCWD, pathname); 2314 return do_unlinkat(AT_FDCWD, pathname);
2409} 2315}
2410 2316
2411int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode) 2317int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname)
2412{ 2318{
2413 int error = may_create(dir, dentry, NULL); 2319 int error = may_create(dir, dentry, NULL);
2414 2320
@@ -2432,23 +2338,20 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, i
2432asmlinkage long sys_symlinkat(const char __user *oldname, 2338asmlinkage long sys_symlinkat(const char __user *oldname,
2433 int newdfd, const char __user *newname) 2339 int newdfd, const char __user *newname)
2434{ 2340{
2435 int error = 0; 2341 int error;
2436 char * from; 2342 char *from;
2437 char * to; 2343 char *to;
2438 struct dentry *dentry; 2344 struct dentry *dentry;
2439 struct nameidata nd; 2345 struct nameidata nd;
2440 2346
2441 from = getname(oldname); 2347 from = getname(oldname);
2442 if(IS_ERR(from)) 2348 if (IS_ERR(from))
2443 return PTR_ERR(from); 2349 return PTR_ERR(from);
2444 to = getname(newname);
2445 error = PTR_ERR(to);
2446 if (IS_ERR(to))
2447 goto out_putname;
2448 2350
2449 error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd); 2351 error = user_path_parent(newdfd, newname, &nd, &to);
2450 if (error) 2352 if (error)
2451 goto out; 2353 goto out_putname;
2354
2452 dentry = lookup_create(&nd, 0); 2355 dentry = lookup_create(&nd, 0);
2453 error = PTR_ERR(dentry); 2356 error = PTR_ERR(dentry);
2454 if (IS_ERR(dentry)) 2357 if (IS_ERR(dentry))
@@ -2457,14 +2360,13 @@ asmlinkage long sys_symlinkat(const char __user *oldname,
2457 error = mnt_want_write(nd.path.mnt); 2360 error = mnt_want_write(nd.path.mnt);
2458 if (error) 2361 if (error)
2459 goto out_dput; 2362 goto out_dput;
2460 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from, S_IALLUGO); 2363 error = vfs_symlink(nd.path.dentry->d_inode, dentry, from);
2461 mnt_drop_write(nd.path.mnt); 2364 mnt_drop_write(nd.path.mnt);
2462out_dput: 2365out_dput:
2463 dput(dentry); 2366 dput(dentry);
2464out_unlock: 2367out_unlock:
2465 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2368 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
2466 path_put(&nd.path); 2369 path_put(&nd.path);
2467out:
2468 putname(to); 2370 putname(to);
2469out_putname: 2371out_putname:
2470 putname(from); 2372 putname(from);
@@ -2498,19 +2400,19 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
2498 return -EPERM; 2400 return -EPERM;
2499 if (!dir->i_op || !dir->i_op->link) 2401 if (!dir->i_op || !dir->i_op->link)
2500 return -EPERM; 2402 return -EPERM;
2501 if (S_ISDIR(old_dentry->d_inode->i_mode)) 2403 if (S_ISDIR(inode->i_mode))
2502 return -EPERM; 2404 return -EPERM;
2503 2405
2504 error = security_inode_link(old_dentry, dir, new_dentry); 2406 error = security_inode_link(old_dentry, dir, new_dentry);
2505 if (error) 2407 if (error)
2506 return error; 2408 return error;
2507 2409
2508 mutex_lock(&old_dentry->d_inode->i_mutex); 2410 mutex_lock(&inode->i_mutex);
2509 DQUOT_INIT(dir); 2411 DQUOT_INIT(dir);
2510 error = dir->i_op->link(old_dentry, dir, new_dentry); 2412 error = dir->i_op->link(old_dentry, dir, new_dentry);
2511 mutex_unlock(&old_dentry->d_inode->i_mutex); 2413 mutex_unlock(&inode->i_mutex);
2512 if (!error) 2414 if (!error)
2513 fsnotify_link(dir, old_dentry->d_inode, new_dentry); 2415 fsnotify_link(dir, inode, new_dentry);
2514 return error; 2416 return error;
2515} 2417}
2516 2418
@@ -2528,27 +2430,25 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
2528 int flags) 2430 int flags)
2529{ 2431{
2530 struct dentry *new_dentry; 2432 struct dentry *new_dentry;
2531 struct nameidata nd, old_nd; 2433 struct nameidata nd;
2434 struct path old_path;
2532 int error; 2435 int error;
2533 char * to; 2436 char *to;
2534 2437
2535 if ((flags & ~AT_SYMLINK_FOLLOW) != 0) 2438 if ((flags & ~AT_SYMLINK_FOLLOW) != 0)
2536 return -EINVAL; 2439 return -EINVAL;
2537 2440
2538 to = getname(newname); 2441 error = user_path_at(olddfd, oldname,
2539 if (IS_ERR(to)) 2442 flags & AT_SYMLINK_FOLLOW ? LOOKUP_FOLLOW : 0,
2540 return PTR_ERR(to); 2443 &old_path);
2541
2542 error = __user_walk_fd(olddfd, oldname,
2543 flags & AT_SYMLINK_FOLLOW ? LOOKUP_FOLLOW : 0,
2544 &old_nd);
2545 if (error) 2444 if (error)
2546 goto exit; 2445 return error;
2547 error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd); 2446
2447 error = user_path_parent(newdfd, newname, &nd, &to);
2548 if (error) 2448 if (error)
2549 goto out; 2449 goto out;
2550 error = -EXDEV; 2450 error = -EXDEV;
2551 if (old_nd.path.mnt != nd.path.mnt) 2451 if (old_path.mnt != nd.path.mnt)
2552 goto out_release; 2452 goto out_release;
2553 new_dentry = lookup_create(&nd, 0); 2453 new_dentry = lookup_create(&nd, 0);
2554 error = PTR_ERR(new_dentry); 2454 error = PTR_ERR(new_dentry);
@@ -2557,7 +2457,7 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
2557 error = mnt_want_write(nd.path.mnt); 2457 error = mnt_want_write(nd.path.mnt);
2558 if (error) 2458 if (error)
2559 goto out_dput; 2459 goto out_dput;
2560 error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry); 2460 error = vfs_link(old_path.dentry, nd.path.dentry->d_inode, new_dentry);
2561 mnt_drop_write(nd.path.mnt); 2461 mnt_drop_write(nd.path.mnt);
2562out_dput: 2462out_dput:
2563 dput(new_dentry); 2463 dput(new_dentry);
@@ -2565,10 +2465,9 @@ out_unlock:
2565 mutex_unlock(&nd.path.dentry->d_inode->i_mutex); 2465 mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
2566out_release: 2466out_release:
2567 path_put(&nd.path); 2467 path_put(&nd.path);
2568out:
2569 path_put(&old_nd.path);
2570exit:
2571 putname(to); 2468 putname(to);
2469out:
2470 path_put(&old_path);
2572 2471
2573 return error; 2472 return error;
2574} 2473}
@@ -2621,7 +2520,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
2621 * we'll need to flip '..'. 2520 * we'll need to flip '..'.
2622 */ 2521 */
2623 if (new_dir != old_dir) { 2522 if (new_dir != old_dir) {
2624 error = permission(old_dentry->d_inode, MAY_WRITE, NULL); 2523 error = inode_permission(old_dentry->d_inode, MAY_WRITE);
2625 if (error) 2524 if (error)
2626 return error; 2525 return error;
2627 } 2526 }
@@ -2724,20 +2623,22 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
2724 return error; 2623 return error;
2725} 2624}
2726 2625
2727static int do_rename(int olddfd, const char *oldname, 2626asmlinkage long sys_renameat(int olddfd, const char __user *oldname,
2728 int newdfd, const char *newname) 2627 int newdfd, const char __user *newname)
2729{ 2628{
2730 int error = 0; 2629 struct dentry *old_dir, *new_dir;
2731 struct dentry * old_dir, * new_dir; 2630 struct dentry *old_dentry, *new_dentry;
2732 struct dentry * old_dentry, *new_dentry; 2631 struct dentry *trap;
2733 struct dentry * trap;
2734 struct nameidata oldnd, newnd; 2632 struct nameidata oldnd, newnd;
2633 char *from;
2634 char *to;
2635 int error;
2735 2636
2736 error = do_path_lookup(olddfd, oldname, LOOKUP_PARENT, &oldnd); 2637 error = user_path_parent(olddfd, oldname, &oldnd, &from);
2737 if (error) 2638 if (error)
2738 goto exit; 2639 goto exit;
2739 2640
2740 error = do_path_lookup(newdfd, newname, LOOKUP_PARENT, &newnd); 2641 error = user_path_parent(newdfd, newname, &newnd, &to);
2741 if (error) 2642 if (error)
2742 goto exit1; 2643 goto exit1;
2743 2644
@@ -2799,29 +2700,11 @@ exit3:
2799 unlock_rename(new_dir, old_dir); 2700 unlock_rename(new_dir, old_dir);
2800exit2: 2701exit2:
2801 path_put(&newnd.path); 2702 path_put(&newnd.path);
2703 putname(to);
2802exit1: 2704exit1:
2803 path_put(&oldnd.path); 2705 path_put(&oldnd.path);
2804exit:
2805 return error;
2806}
2807
2808asmlinkage long sys_renameat(int olddfd, const char __user *oldname,
2809 int newdfd, const char __user *newname)
2810{
2811 int error;
2812 char * from;
2813 char * to;
2814
2815 from = getname(oldname);
2816 if(IS_ERR(from))
2817 return PTR_ERR(from);
2818 to = getname(newname);
2819 error = PTR_ERR(to);
2820 if (!IS_ERR(to)) {
2821 error = do_rename(olddfd, from, newdfd, to);
2822 putname(to);
2823 }
2824 putname(from); 2706 putname(from);
2707exit:
2825 return error; 2708 return error;
2826} 2709}
2827 2710
@@ -2959,8 +2842,7 @@ const struct inode_operations page_symlink_inode_operations = {
2959 .put_link = page_put_link, 2842 .put_link = page_put_link,
2960}; 2843};
2961 2844
2962EXPORT_SYMBOL(__user_walk); 2845EXPORT_SYMBOL(user_path_at);
2963EXPORT_SYMBOL(__user_walk_fd);
2964EXPORT_SYMBOL(follow_down); 2846EXPORT_SYMBOL(follow_down);
2965EXPORT_SYMBOL(follow_up); 2847EXPORT_SYMBOL(follow_up);
2966EXPORT_SYMBOL(get_write_access); /* binfmt_aout */ 2848EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
@@ -2975,7 +2857,7 @@ EXPORT_SYMBOL(page_symlink);
2975EXPORT_SYMBOL(page_symlink_inode_operations); 2857EXPORT_SYMBOL(page_symlink_inode_operations);
2976EXPORT_SYMBOL(path_lookup); 2858EXPORT_SYMBOL(path_lookup);
2977EXPORT_SYMBOL(vfs_path_lookup); 2859EXPORT_SYMBOL(vfs_path_lookup);
2978EXPORT_SYMBOL(permission); 2860EXPORT_SYMBOL(inode_permission);
2979EXPORT_SYMBOL(vfs_permission); 2861EXPORT_SYMBOL(vfs_permission);
2980EXPORT_SYMBOL(file_permission); 2862EXPORT_SYMBOL(file_permission);
2981EXPORT_SYMBOL(unlock_rename); 2863EXPORT_SYMBOL(unlock_rename);
diff --git a/fs/namespace.c b/fs/namespace.c
index f30b11e2240e..411728c0c8bb 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -112,9 +112,13 @@ struct vfsmount *alloc_vfsmnt(const char *name)
112 int err; 112 int err;
113 113
114 err = mnt_alloc_id(mnt); 114 err = mnt_alloc_id(mnt);
115 if (err) { 115 if (err)
116 kmem_cache_free(mnt_cache, mnt); 116 goto out_free_cache;
117 return NULL; 117
118 if (name) {
119 mnt->mnt_devname = kstrdup(name, GFP_KERNEL);
120 if (!mnt->mnt_devname)
121 goto out_free_id;
118 } 122 }
119 123
120 atomic_set(&mnt->mnt_count, 1); 124 atomic_set(&mnt->mnt_count, 1);
@@ -127,16 +131,14 @@ struct vfsmount *alloc_vfsmnt(const char *name)
127 INIT_LIST_HEAD(&mnt->mnt_slave_list); 131 INIT_LIST_HEAD(&mnt->mnt_slave_list);
128 INIT_LIST_HEAD(&mnt->mnt_slave); 132 INIT_LIST_HEAD(&mnt->mnt_slave);
129 atomic_set(&mnt->__mnt_writers, 0); 133 atomic_set(&mnt->__mnt_writers, 0);
130 if (name) {
131 int size = strlen(name) + 1;
132 char *newname = kmalloc(size, GFP_KERNEL);
133 if (newname) {
134 memcpy(newname, name, size);
135 mnt->mnt_devname = newname;
136 }
137 }
138 } 134 }
139 return mnt; 135 return mnt;
136
137out_free_id:
138 mnt_free_id(mnt);
139out_free_cache:
140 kmem_cache_free(mnt_cache, mnt);
141 return NULL;
140} 142}
141 143
142/* 144/*
@@ -1128,27 +1130,27 @@ static int do_umount(struct vfsmount *mnt, int flags)
1128 1130
1129asmlinkage long sys_umount(char __user * name, int flags) 1131asmlinkage long sys_umount(char __user * name, int flags)
1130{ 1132{
1131 struct nameidata nd; 1133 struct path path;
1132 int retval; 1134 int retval;
1133 1135
1134 retval = __user_walk(name, LOOKUP_FOLLOW, &nd); 1136 retval = user_path(name, &path);
1135 if (retval) 1137 if (retval)
1136 goto out; 1138 goto out;
1137 retval = -EINVAL; 1139 retval = -EINVAL;
1138 if (nd.path.dentry != nd.path.mnt->mnt_root) 1140 if (path.dentry != path.mnt->mnt_root)
1139 goto dput_and_out; 1141 goto dput_and_out;
1140 if (!check_mnt(nd.path.mnt)) 1142 if (!check_mnt(path.mnt))
1141 goto dput_and_out; 1143 goto dput_and_out;
1142 1144
1143 retval = -EPERM; 1145 retval = -EPERM;
1144 if (!capable(CAP_SYS_ADMIN)) 1146 if (!capable(CAP_SYS_ADMIN))
1145 goto dput_and_out; 1147 goto dput_and_out;
1146 1148
1147 retval = do_umount(nd.path.mnt, flags); 1149 retval = do_umount(path.mnt, flags);
1148dput_and_out: 1150dput_and_out:
1149 /* we mustn't call path_put() as that would clear mnt_expiry_mark */ 1151 /* we mustn't call path_put() as that would clear mnt_expiry_mark */
1150 dput(nd.path.dentry); 1152 dput(path.dentry);
1151 mntput_no_expire(nd.path.mnt); 1153 mntput_no_expire(path.mnt);
1152out: 1154out:
1153 return retval; 1155 return retval;
1154} 1156}
@@ -1972,7 +1974,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
1972 struct fs_struct *fs) 1974 struct fs_struct *fs)
1973{ 1975{
1974 struct mnt_namespace *new_ns; 1976 struct mnt_namespace *new_ns;
1975 struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; 1977 struct vfsmount *rootmnt = NULL, *pwdmnt = NULL;
1976 struct vfsmount *p, *q; 1978 struct vfsmount *p, *q;
1977 1979
1978 new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL); 1980 new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
@@ -2015,10 +2017,6 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2015 pwdmnt = p; 2017 pwdmnt = p;
2016 fs->pwd.mnt = mntget(q); 2018 fs->pwd.mnt = mntget(q);
2017 } 2019 }
2018 if (p == fs->altroot.mnt) {
2019 altrootmnt = p;
2020 fs->altroot.mnt = mntget(q);
2021 }
2022 } 2020 }
2023 p = next_mnt(p, mnt_ns->root); 2021 p = next_mnt(p, mnt_ns->root);
2024 q = next_mnt(q, new_ns->root); 2022 q = next_mnt(q, new_ns->root);
@@ -2029,8 +2027,6 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2029 mntput(rootmnt); 2027 mntput(rootmnt);
2030 if (pwdmnt) 2028 if (pwdmnt)
2031 mntput(pwdmnt); 2029 mntput(pwdmnt);
2032 if (altrootmnt)
2033 mntput(altrootmnt);
2034 2030
2035 return new_ns; 2031 return new_ns;
2036} 2032}
@@ -2183,28 +2179,26 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
2183 const char __user * put_old) 2179 const char __user * put_old)
2184{ 2180{
2185 struct vfsmount *tmp; 2181 struct vfsmount *tmp;
2186 struct nameidata new_nd, old_nd; 2182 struct path new, old, parent_path, root_parent, root;
2187 struct path parent_path, root_parent, root;
2188 int error; 2183 int error;
2189 2184
2190 if (!capable(CAP_SYS_ADMIN)) 2185 if (!capable(CAP_SYS_ADMIN))
2191 return -EPERM; 2186 return -EPERM;
2192 2187
2193 error = __user_walk(new_root, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, 2188 error = user_path_dir(new_root, &new);
2194 &new_nd);
2195 if (error) 2189 if (error)
2196 goto out0; 2190 goto out0;
2197 error = -EINVAL; 2191 error = -EINVAL;
2198 if (!check_mnt(new_nd.path.mnt)) 2192 if (!check_mnt(new.mnt))
2199 goto out1; 2193 goto out1;
2200 2194
2201 error = __user_walk(put_old, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old_nd); 2195 error = user_path_dir(put_old, &old);
2202 if (error) 2196 if (error)
2203 goto out1; 2197 goto out1;
2204 2198
2205 error = security_sb_pivotroot(&old_nd.path, &new_nd.path); 2199 error = security_sb_pivotroot(&old, &new);
2206 if (error) { 2200 if (error) {
2207 path_put(&old_nd.path); 2201 path_put(&old);
2208 goto out1; 2202 goto out1;
2209 } 2203 }
2210 2204
@@ -2213,69 +2207,69 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
2213 path_get(&current->fs->root); 2207 path_get(&current->fs->root);
2214 read_unlock(&current->fs->lock); 2208 read_unlock(&current->fs->lock);
2215 down_write(&namespace_sem); 2209 down_write(&namespace_sem);
2216 mutex_lock(&old_nd.path.dentry->d_inode->i_mutex); 2210 mutex_lock(&old.dentry->d_inode->i_mutex);
2217 error = -EINVAL; 2211 error = -EINVAL;
2218 if (IS_MNT_SHARED(old_nd.path.mnt) || 2212 if (IS_MNT_SHARED(old.mnt) ||
2219 IS_MNT_SHARED(new_nd.path.mnt->mnt_parent) || 2213 IS_MNT_SHARED(new.mnt->mnt_parent) ||
2220 IS_MNT_SHARED(root.mnt->mnt_parent)) 2214 IS_MNT_SHARED(root.mnt->mnt_parent))
2221 goto out2; 2215 goto out2;
2222 if (!check_mnt(root.mnt)) 2216 if (!check_mnt(root.mnt))
2223 goto out2; 2217 goto out2;
2224 error = -ENOENT; 2218 error = -ENOENT;
2225 if (IS_DEADDIR(new_nd.path.dentry->d_inode)) 2219 if (IS_DEADDIR(new.dentry->d_inode))
2226 goto out2; 2220 goto out2;
2227 if (d_unhashed(new_nd.path.dentry) && !IS_ROOT(new_nd.path.dentry)) 2221 if (d_unhashed(new.dentry) && !IS_ROOT(new.dentry))
2228 goto out2; 2222 goto out2;
2229 if (d_unhashed(old_nd.path.dentry) && !IS_ROOT(old_nd.path.dentry)) 2223 if (d_unhashed(old.dentry) && !IS_ROOT(old.dentry))
2230 goto out2; 2224 goto out2;
2231 error = -EBUSY; 2225 error = -EBUSY;
2232 if (new_nd.path.mnt == root.mnt || 2226 if (new.mnt == root.mnt ||
2233 old_nd.path.mnt == root.mnt) 2227 old.mnt == root.mnt)
2234 goto out2; /* loop, on the same file system */ 2228 goto out2; /* loop, on the same file system */
2235 error = -EINVAL; 2229 error = -EINVAL;
2236 if (root.mnt->mnt_root != root.dentry) 2230 if (root.mnt->mnt_root != root.dentry)
2237 goto out2; /* not a mountpoint */ 2231 goto out2; /* not a mountpoint */
2238 if (root.mnt->mnt_parent == root.mnt) 2232 if (root.mnt->mnt_parent == root.mnt)
2239 goto out2; /* not attached */ 2233 goto out2; /* not attached */
2240 if (new_nd.path.mnt->mnt_root != new_nd.path.dentry) 2234 if (new.mnt->mnt_root != new.dentry)
2241 goto out2; /* not a mountpoint */ 2235 goto out2; /* not a mountpoint */
2242 if (new_nd.path.mnt->mnt_parent == new_nd.path.mnt) 2236 if (new.mnt->mnt_parent == new.mnt)
2243 goto out2; /* not attached */ 2237 goto out2; /* not attached */
2244 /* make sure we can reach put_old from new_root */ 2238 /* make sure we can reach put_old from new_root */
2245 tmp = old_nd.path.mnt; 2239 tmp = old.mnt;
2246 spin_lock(&vfsmount_lock); 2240 spin_lock(&vfsmount_lock);
2247 if (tmp != new_nd.path.mnt) { 2241 if (tmp != new.mnt) {
2248 for (;;) { 2242 for (;;) {
2249 if (tmp->mnt_parent == tmp) 2243 if (tmp->mnt_parent == tmp)
2250 goto out3; /* already mounted on put_old */ 2244 goto out3; /* already mounted on put_old */
2251 if (tmp->mnt_parent == new_nd.path.mnt) 2245 if (tmp->mnt_parent == new.mnt)
2252 break; 2246 break;
2253 tmp = tmp->mnt_parent; 2247 tmp = tmp->mnt_parent;
2254 } 2248 }
2255 if (!is_subdir(tmp->mnt_mountpoint, new_nd.path.dentry)) 2249 if (!is_subdir(tmp->mnt_mountpoint, new.dentry))
2256 goto out3; 2250 goto out3;
2257 } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry)) 2251 } else if (!is_subdir(old.dentry, new.dentry))
2258 goto out3; 2252 goto out3;
2259 detach_mnt(new_nd.path.mnt, &parent_path); 2253 detach_mnt(new.mnt, &parent_path);
2260 detach_mnt(root.mnt, &root_parent); 2254 detach_mnt(root.mnt, &root_parent);
2261 /* mount old root on put_old */ 2255 /* mount old root on put_old */
2262 attach_mnt(root.mnt, &old_nd.path); 2256 attach_mnt(root.mnt, &old);
2263 /* mount new_root on / */ 2257 /* mount new_root on / */
2264 attach_mnt(new_nd.path.mnt, &root_parent); 2258 attach_mnt(new.mnt, &root_parent);
2265 touch_mnt_namespace(current->nsproxy->mnt_ns); 2259 touch_mnt_namespace(current->nsproxy->mnt_ns);
2266 spin_unlock(&vfsmount_lock); 2260 spin_unlock(&vfsmount_lock);
2267 chroot_fs_refs(&root, &new_nd.path); 2261 chroot_fs_refs(&root, &new);
2268 security_sb_post_pivotroot(&root, &new_nd.path); 2262 security_sb_post_pivotroot(&root, &new);
2269 error = 0; 2263 error = 0;
2270 path_put(&root_parent); 2264 path_put(&root_parent);
2271 path_put(&parent_path); 2265 path_put(&parent_path);
2272out2: 2266out2:
2273 mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex); 2267 mutex_unlock(&old.dentry->d_inode->i_mutex);
2274 up_write(&namespace_sem); 2268 up_write(&namespace_sem);
2275 path_put(&root); 2269 path_put(&root);
2276 path_put(&old_nd.path); 2270 path_put(&old);
2277out1: 2271out1:
2278 path_put(&new_nd.path); 2272 path_put(&new);
2279out0: 2273out0:
2280 return error; 2274 return error;
2281out3: 2275out3:
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index 011ef0b6d2d4..07e9715b8658 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -266,7 +266,7 @@ leave_me:;
266 266
267 267
268static int 268static int
269__ncp_lookup_validate(struct dentry * dentry, struct nameidata *nd) 269__ncp_lookup_validate(struct dentry *dentry)
270{ 270{
271 struct ncp_server *server; 271 struct ncp_server *server;
272 struct dentry *parent; 272 struct dentry *parent;
@@ -340,7 +340,7 @@ ncp_lookup_validate(struct dentry * dentry, struct nameidata *nd)
340{ 340{
341 int res; 341 int res;
342 lock_kernel(); 342 lock_kernel();
343 res = __ncp_lookup_validate(dentry, nd); 343 res = __ncp_lookup_validate(dentry);
344 unlock_kernel(); 344 unlock_kernel();
345 return res; 345 return res;
346} 346}
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 28a238dab23a..74f92b717f78 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1884,7 +1884,7 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask)
1884 return status; 1884 return status;
1885 nfs_access_add_cache(inode, &cache); 1885 nfs_access_add_cache(inode, &cache);
1886out: 1886out:
1887 if ((cache.mask & mask) == mask) 1887 if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
1888 return 0; 1888 return 0;
1889 return -EACCES; 1889 return -EACCES;
1890} 1890}
@@ -1907,17 +1907,17 @@ int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags)
1907 return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags)); 1907 return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags));
1908} 1908}
1909 1909
1910int nfs_permission(struct inode *inode, int mask, struct nameidata *nd) 1910int nfs_permission(struct inode *inode, int mask)
1911{ 1911{
1912 struct rpc_cred *cred; 1912 struct rpc_cred *cred;
1913 int res = 0; 1913 int res = 0;
1914 1914
1915 nfs_inc_stats(inode, NFSIOS_VFSACCESS); 1915 nfs_inc_stats(inode, NFSIOS_VFSACCESS);
1916 1916
1917 if (mask == 0) 1917 if ((mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0)
1918 goto out; 1918 goto out;
1919 /* Is this sys_access() ? */ 1919 /* Is this sys_access() ? */
1920 if (nd != NULL && (nd->flags & LOOKUP_ACCESS)) 1920 if (mask & MAY_ACCESS)
1921 goto force_lookup; 1921 goto force_lookup;
1922 1922
1923 switch (inode->i_mode & S_IFMT) { 1923 switch (inode->i_mode & S_IFMT) {
@@ -1926,8 +1926,7 @@ int nfs_permission(struct inode *inode, int mask, struct nameidata *nd)
1926 case S_IFREG: 1926 case S_IFREG:
1927 /* NFSv4 has atomic_open... */ 1927 /* NFSv4 has atomic_open... */
1928 if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN) 1928 if (nfs_server_capable(inode, NFS_CAP_ATOMIC_OPEN)
1929 && nd != NULL 1929 && (mask & MAY_OPEN))
1930 && (nd->flags & LOOKUP_OPEN))
1931 goto out; 1930 goto out;
1932 break; 1931 break;
1933 case S_IFDIR: 1932 case S_IFDIR:
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 1955a2702e60..c53e65f8f3a2 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -12,6 +12,7 @@
12#include <linux/time.h> 12#include <linux/time.h>
13#include <linux/errno.h> 13#include <linux/errno.h>
14#include <linux/fs.h> 14#include <linux/fs.h>
15#include <linux/namei.h>
15#include <linux/fcntl.h> 16#include <linux/fcntl.h>
16#include <linux/net.h> 17#include <linux/net.h>
17#include <linux/in.h> 18#include <linux/in.h>
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index f45451eb1e38..ea37c96f0445 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -51,7 +51,7 @@ static int nfsd_acceptable(void *expv, struct dentry *dentry)
51 /* make sure parents give x permission to user */ 51 /* make sure parents give x permission to user */
52 int err; 52 int err;
53 parent = dget_parent(tdentry); 53 parent = dget_parent(tdentry);
54 err = permission(parent->d_inode, MAY_EXEC, NULL); 54 err = inode_permission(parent->d_inode, MAY_EXEC);
55 if (err < 0) { 55 if (err < 0) {
56 dput(parent); 56 dput(parent);
57 break; 57 break;
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 0f4481e0502d..18060bed5267 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1516,7 +1516,6 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
1516 struct dentry *dentry, *dnew; 1516 struct dentry *dentry, *dnew;
1517 __be32 err, cerr; 1517 __be32 err, cerr;
1518 int host_err; 1518 int host_err;
1519 umode_t mode;
1520 1519
1521 err = nfserr_noent; 1520 err = nfserr_noent;
1522 if (!flen || !plen) 1521 if (!flen || !plen)
@@ -1535,11 +1534,6 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
1535 if (IS_ERR(dnew)) 1534 if (IS_ERR(dnew))
1536 goto out_nfserr; 1535 goto out_nfserr;
1537 1536
1538 mode = S_IALLUGO;
1539 /* Only the MODE ATTRibute is even vaguely meaningful */
1540 if (iap && (iap->ia_valid & ATTR_MODE))
1541 mode = iap->ia_mode & S_IALLUGO;
1542
1543 host_err = mnt_want_write(fhp->fh_export->ex_path.mnt); 1537 host_err = mnt_want_write(fhp->fh_export->ex_path.mnt);
1544 if (host_err) 1538 if (host_err)
1545 goto out_nfserr; 1539 goto out_nfserr;
@@ -1551,11 +1545,11 @@ nfsd_symlink(struct svc_rqst *rqstp, struct svc_fh *fhp,
1551 else { 1545 else {
1552 strncpy(path_alloced, path, plen); 1546 strncpy(path_alloced, path, plen);
1553 path_alloced[plen] = 0; 1547 path_alloced[plen] = 0;
1554 host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced, mode); 1548 host_err = vfs_symlink(dentry->d_inode, dnew, path_alloced);
1555 kfree(path_alloced); 1549 kfree(path_alloced);
1556 } 1550 }
1557 } else 1551 } else
1558 host_err = vfs_symlink(dentry->d_inode, dnew, path, mode); 1552 host_err = vfs_symlink(dentry->d_inode, dnew, path);
1559 1553
1560 if (!host_err) { 1554 if (!host_err) {
1561 if (EX_ISSYNC(fhp->fh_export)) 1555 if (EX_ISSYNC(fhp->fh_export))
@@ -1959,12 +1953,12 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp,
1959 return 0; 1953 return 0;
1960 1954
1961 /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC} */ 1955 /* This assumes NFSD_MAY_{READ,WRITE,EXEC} == MAY_{READ,WRITE,EXEC} */
1962 err = permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC), NULL); 1956 err = inode_permission(inode, acc & (MAY_READ|MAY_WRITE|MAY_EXEC));
1963 1957
1964 /* Allow read access to binaries even when mode 111 */ 1958 /* Allow read access to binaries even when mode 111 */
1965 if (err == -EACCES && S_ISREG(inode->i_mode) && 1959 if (err == -EACCES && S_ISREG(inode->i_mode) &&
1966 acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE)) 1960 acc == (NFSD_MAY_READ | NFSD_MAY_OWNER_OVERRIDE))
1967 err = permission(inode, MAY_EXEC, NULL); 1961 err = inode_permission(inode, MAY_EXEC);
1968 1962
1969 return err? nfserrno(err) : 0; 1963 return err? nfserrno(err) : 0;
1970} 1964}
diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
index 3c5550cd11d6..d020866d4232 100644
--- a/fs/ntfs/file.c
+++ b/fs/ntfs/file.c
@@ -2118,7 +2118,7 @@ static ssize_t ntfs_file_aio_write_nolock(struct kiocb *iocb,
2118 goto out; 2118 goto out;
2119 if (!count) 2119 if (!count)
2120 goto out; 2120 goto out;
2121 err = remove_suid(file->f_path.dentry); 2121 err = file_remove_suid(file);
2122 if (err) 2122 if (err)
2123 goto out; 2123 goto out;
2124 file_update_time(file); 2124 file_update_time(file);
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index e8514e8b6ce8..be2dd95d3a1d 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1176,7 +1176,7 @@ bail:
1176 return err; 1176 return err;
1177} 1177}
1178 1178
1179int ocfs2_permission(struct inode *inode, int mask, struct nameidata *nd) 1179int ocfs2_permission(struct inode *inode, int mask)
1180{ 1180{
1181 int ret; 1181 int ret;
1182 1182
diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h
index 048ddcaf5c80..1e27b4d017ea 100644
--- a/fs/ocfs2/file.h
+++ b/fs/ocfs2/file.h
@@ -62,8 +62,7 @@ int ocfs2_lock_allocators(struct inode *inode, struct ocfs2_dinode *di,
62int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); 62int ocfs2_setattr(struct dentry *dentry, struct iattr *attr);
63int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, 63int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
64 struct kstat *stat); 64 struct kstat *stat);
65int ocfs2_permission(struct inode *inode, int mask, 65int ocfs2_permission(struct inode *inode, int mask);
66 struct nameidata *nd);
67 66
68int ocfs2_should_update_atime(struct inode *inode, 67int ocfs2_should_update_atime(struct inode *inode,
69 struct vfsmount *vfsmnt); 68 struct vfsmount *vfsmnt);
diff --git a/fs/open.c b/fs/open.c
index bb98d2fe809f..52647be277a2 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -122,37 +122,37 @@ static int vfs_statfs64(struct dentry *dentry, struct statfs64 *buf)
122 return 0; 122 return 0;
123} 123}
124 124
125asmlinkage long sys_statfs(const char __user * path, struct statfs __user * buf) 125asmlinkage long sys_statfs(const char __user *pathname, struct statfs __user * buf)
126{ 126{
127 struct nameidata nd; 127 struct path path;
128 int error; 128 int error;
129 129
130 error = user_path_walk(path, &nd); 130 error = user_path(pathname, &path);
131 if (!error) { 131 if (!error) {
132 struct statfs tmp; 132 struct statfs tmp;
133 error = vfs_statfs_native(nd.path.dentry, &tmp); 133 error = vfs_statfs_native(path.dentry, &tmp);
134 if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) 134 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
135 error = -EFAULT; 135 error = -EFAULT;
136 path_put(&nd.path); 136 path_put(&path);
137 } 137 }
138 return error; 138 return error;
139} 139}
140 140
141 141
142asmlinkage long sys_statfs64(const char __user *path, size_t sz, struct statfs64 __user *buf) 142asmlinkage long sys_statfs64(const char __user *pathname, size_t sz, struct statfs64 __user *buf)
143{ 143{
144 struct nameidata nd; 144 struct path path;
145 long error; 145 long error;
146 146
147 if (sz != sizeof(*buf)) 147 if (sz != sizeof(*buf))
148 return -EINVAL; 148 return -EINVAL;
149 error = user_path_walk(path, &nd); 149 error = user_path(pathname, &path);
150 if (!error) { 150 if (!error) {
151 struct statfs64 tmp; 151 struct statfs64 tmp;
152 error = vfs_statfs64(nd.path.dentry, &tmp); 152 error = vfs_statfs64(path.dentry, &tmp);
153 if (!error && copy_to_user(buf, &tmp, sizeof(tmp))) 153 if (!error && copy_to_user(buf, &tmp, sizeof(tmp)))
154 error = -EFAULT; 154 error = -EFAULT;
155 path_put(&nd.path); 155 path_put(&path);
156 } 156 }
157 return error; 157 return error;
158} 158}
@@ -223,20 +223,20 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
223 return err; 223 return err;
224} 224}
225 225
226static long do_sys_truncate(const char __user * path, loff_t length) 226static long do_sys_truncate(const char __user *pathname, loff_t length)
227{ 227{
228 struct nameidata nd; 228 struct path path;
229 struct inode * inode; 229 struct inode *inode;
230 int error; 230 int error;
231 231
232 error = -EINVAL; 232 error = -EINVAL;
233 if (length < 0) /* sorry, but loff_t says... */ 233 if (length < 0) /* sorry, but loff_t says... */
234 goto out; 234 goto out;
235 235
236 error = user_path_walk(path, &nd); 236 error = user_path(pathname, &path);
237 if (error) 237 if (error)
238 goto out; 238 goto out;
239 inode = nd.path.dentry->d_inode; 239 inode = path.dentry->d_inode;
240 240
241 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */ 241 /* For directories it's -EISDIR, for other non-regulars - -EINVAL */
242 error = -EISDIR; 242 error = -EISDIR;
@@ -247,16 +247,16 @@ static long do_sys_truncate(const char __user * path, loff_t length)
247 if (!S_ISREG(inode->i_mode)) 247 if (!S_ISREG(inode->i_mode))
248 goto dput_and_out; 248 goto dput_and_out;
249 249
250 error = mnt_want_write(nd.path.mnt); 250 error = mnt_want_write(path.mnt);
251 if (error) 251 if (error)
252 goto dput_and_out; 252 goto dput_and_out;
253 253
254 error = vfs_permission(&nd, MAY_WRITE); 254 error = inode_permission(inode, MAY_WRITE);
255 if (error) 255 if (error)
256 goto mnt_drop_write_and_out; 256 goto mnt_drop_write_and_out;
257 257
258 error = -EPERM; 258 error = -EPERM;
259 if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) 259 if (IS_APPEND(inode))
260 goto mnt_drop_write_and_out; 260 goto mnt_drop_write_and_out;
261 261
262 error = get_write_access(inode); 262 error = get_write_access(inode);
@@ -274,15 +274,15 @@ static long do_sys_truncate(const char __user * path, loff_t length)
274 error = locks_verify_truncate(inode, NULL, length); 274 error = locks_verify_truncate(inode, NULL, length);
275 if (!error) { 275 if (!error) {
276 DQUOT_INIT(inode); 276 DQUOT_INIT(inode);
277 error = do_truncate(nd.path.dentry, length, 0, NULL); 277 error = do_truncate(path.dentry, length, 0, NULL);
278 } 278 }
279 279
280put_write_and_out: 280put_write_and_out:
281 put_write_access(inode); 281 put_write_access(inode);
282mnt_drop_write_and_out: 282mnt_drop_write_and_out:
283 mnt_drop_write(nd.path.mnt); 283 mnt_drop_write(path.mnt);
284dput_and_out: 284dput_and_out:
285 path_put(&nd.path); 285 path_put(&path);
286out: 286out:
287 return error; 287 return error;
288} 288}
@@ -425,7 +425,8 @@ out:
425 */ 425 */
426asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode) 426asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
427{ 427{
428 struct nameidata nd; 428 struct path path;
429 struct inode *inode;
429 int old_fsuid, old_fsgid; 430 int old_fsuid, old_fsgid;
430 kernel_cap_t uninitialized_var(old_cap); /* !SECURE_NO_SETUID_FIXUP */ 431 kernel_cap_t uninitialized_var(old_cap); /* !SECURE_NO_SETUID_FIXUP */
431 int res; 432 int res;
@@ -448,7 +449,7 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
448 * FIXME: There is a race here against sys_capset. The 449 * FIXME: There is a race here against sys_capset. The
449 * capabilities can change yet we will restore the old 450 * capabilities can change yet we will restore the old
450 * value below. We should hold task_capabilities_lock, 451 * value below. We should hold task_capabilities_lock,
451 * but we cannot because user_path_walk can sleep. 452 * but we cannot because user_path_at can sleep.
452 */ 453 */
453#endif /* ndef CONFIG_SECURITY_FILE_CAPABILITIES */ 454#endif /* ndef CONFIG_SECURITY_FILE_CAPABILITIES */
454 if (current->uid) 455 if (current->uid)
@@ -457,14 +458,25 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
457 old_cap = cap_set_effective(current->cap_permitted); 458 old_cap = cap_set_effective(current->cap_permitted);
458 } 459 }
459 460
460 res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd); 461 res = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path);
461 if (res) 462 if (res)
462 goto out; 463 goto out;
463 464
464 res = vfs_permission(&nd, mode); 465 inode = path.dentry->d_inode;
466
467 if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) {
468 /*
469 * MAY_EXEC on regular files is denied if the fs is mounted
470 * with the "noexec" flag.
471 */
472 res = -EACCES;
473 if (path.mnt->mnt_flags & MNT_NOEXEC)
474 goto out_path_release;
475 }
476
477 res = inode_permission(inode, mode | MAY_ACCESS);
465 /* SuS v2 requires we report a read only fs too */ 478 /* SuS v2 requires we report a read only fs too */
466 if(res || !(mode & S_IWOTH) || 479 if (res || !(mode & S_IWOTH) || special_file(inode->i_mode))
467 special_file(nd.path.dentry->d_inode->i_mode))
468 goto out_path_release; 480 goto out_path_release;
469 /* 481 /*
470 * This is a rare case where using __mnt_is_readonly() 482 * This is a rare case where using __mnt_is_readonly()
@@ -476,11 +488,11 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
476 * inherently racy and know that the fs may change 488 * inherently racy and know that the fs may change
477 * state before we even see this result. 489 * state before we even see this result.
478 */ 490 */
479 if (__mnt_is_readonly(nd.path.mnt)) 491 if (__mnt_is_readonly(path.mnt))
480 res = -EROFS; 492 res = -EROFS;
481 493
482out_path_release: 494out_path_release:
483 path_put(&nd.path); 495 path_put(&path);
484out: 496out:
485 current->fsuid = old_fsuid; 497 current->fsuid = old_fsuid;
486 current->fsgid = old_fsgid; 498 current->fsgid = old_fsgid;
@@ -498,22 +510,21 @@ asmlinkage long sys_access(const char __user *filename, int mode)
498 510
499asmlinkage long sys_chdir(const char __user * filename) 511asmlinkage long sys_chdir(const char __user * filename)
500{ 512{
501 struct nameidata nd; 513 struct path path;
502 int error; 514 int error;
503 515
504 error = __user_walk(filename, 516 error = user_path_dir(filename, &path);
505 LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_CHDIR, &nd);
506 if (error) 517 if (error)
507 goto out; 518 goto out;
508 519
509 error = vfs_permission(&nd, MAY_EXEC); 520 error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
510 if (error) 521 if (error)
511 goto dput_and_out; 522 goto dput_and_out;
512 523
513 set_fs_pwd(current->fs, &nd.path); 524 set_fs_pwd(current->fs, &path);
514 525
515dput_and_out: 526dput_and_out:
516 path_put(&nd.path); 527 path_put(&path);
517out: 528out:
518 return error; 529 return error;
519} 530}
@@ -535,7 +546,7 @@ asmlinkage long sys_fchdir(unsigned int fd)
535 if (!S_ISDIR(inode->i_mode)) 546 if (!S_ISDIR(inode->i_mode))
536 goto out_putf; 547 goto out_putf;
537 548
538 error = file_permission(file, MAY_EXEC); 549 error = inode_permission(inode, MAY_EXEC | MAY_ACCESS);
539 if (!error) 550 if (!error)
540 set_fs_pwd(current->fs, &file->f_path); 551 set_fs_pwd(current->fs, &file->f_path);
541out_putf: 552out_putf:
@@ -546,14 +557,14 @@ out:
546 557
547asmlinkage long sys_chroot(const char __user * filename) 558asmlinkage long sys_chroot(const char __user * filename)
548{ 559{
549 struct nameidata nd; 560 struct path path;
550 int error; 561 int error;
551 562
552 error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); 563 error = user_path_dir(filename, &path);
553 if (error) 564 if (error)
554 goto out; 565 goto out;
555 566
556 error = vfs_permission(&nd, MAY_EXEC); 567 error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_ACCESS);
557 if (error) 568 if (error)
558 goto dput_and_out; 569 goto dput_and_out;
559 570
@@ -561,11 +572,10 @@ asmlinkage long sys_chroot(const char __user * filename)
561 if (!capable(CAP_SYS_CHROOT)) 572 if (!capable(CAP_SYS_CHROOT))
562 goto dput_and_out; 573 goto dput_and_out;
563 574
564 set_fs_root(current->fs, &nd.path); 575 set_fs_root(current->fs, &path);
565 set_fs_altroot();
566 error = 0; 576 error = 0;
567dput_and_out: 577dput_and_out:
568 path_put(&nd.path); 578 path_put(&path);
569out: 579out:
570 return error; 580 return error;
571} 581}
@@ -590,9 +600,6 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
590 err = mnt_want_write(file->f_path.mnt); 600 err = mnt_want_write(file->f_path.mnt);
591 if (err) 601 if (err)
592 goto out_putf; 602 goto out_putf;
593 err = -EPERM;
594 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
595 goto out_drop_write;
596 mutex_lock(&inode->i_mutex); 603 mutex_lock(&inode->i_mutex);
597 if (mode == (mode_t) -1) 604 if (mode == (mode_t) -1)
598 mode = inode->i_mode; 605 mode = inode->i_mode;
@@ -600,8 +607,6 @@ asmlinkage long sys_fchmod(unsigned int fd, mode_t mode)
600 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; 607 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
601 err = notify_change(dentry, &newattrs); 608 err = notify_change(dentry, &newattrs);
602 mutex_unlock(&inode->i_mutex); 609 mutex_unlock(&inode->i_mutex);
603
604out_drop_write:
605 mnt_drop_write(file->f_path.mnt); 610 mnt_drop_write(file->f_path.mnt);
606out_putf: 611out_putf:
607 fput(file); 612 fput(file);
@@ -612,36 +617,29 @@ out:
612asmlinkage long sys_fchmodat(int dfd, const char __user *filename, 617asmlinkage long sys_fchmodat(int dfd, const char __user *filename,
613 mode_t mode) 618 mode_t mode)
614{ 619{
615 struct nameidata nd; 620 struct path path;
616 struct inode * inode; 621 struct inode *inode;
617 int error; 622 int error;
618 struct iattr newattrs; 623 struct iattr newattrs;
619 624
620 error = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW, &nd); 625 error = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path);
621 if (error) 626 if (error)
622 goto out; 627 goto out;
623 inode = nd.path.dentry->d_inode; 628 inode = path.dentry->d_inode;
624 629
625 error = mnt_want_write(nd.path.mnt); 630 error = mnt_want_write(path.mnt);
626 if (error) 631 if (error)
627 goto dput_and_out; 632 goto dput_and_out;
628
629 error = -EPERM;
630 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
631 goto out_drop_write;
632
633 mutex_lock(&inode->i_mutex); 633 mutex_lock(&inode->i_mutex);
634 if (mode == (mode_t) -1) 634 if (mode == (mode_t) -1)
635 mode = inode->i_mode; 635 mode = inode->i_mode;
636 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); 636 newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
637 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; 637 newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
638 error = notify_change(nd.path.dentry, &newattrs); 638 error = notify_change(path.dentry, &newattrs);
639 mutex_unlock(&inode->i_mutex); 639 mutex_unlock(&inode->i_mutex);
640 640 mnt_drop_write(path.mnt);
641out_drop_write:
642 mnt_drop_write(nd.path.mnt);
643dput_and_out: 641dput_and_out:
644 path_put(&nd.path); 642 path_put(&path);
645out: 643out:
646 return error; 644 return error;
647} 645}
@@ -653,18 +651,10 @@ asmlinkage long sys_chmod(const char __user *filename, mode_t mode)
653 651
654static int chown_common(struct dentry * dentry, uid_t user, gid_t group) 652static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
655{ 653{
656 struct inode * inode; 654 struct inode *inode = dentry->d_inode;
657 int error; 655 int error;
658 struct iattr newattrs; 656 struct iattr newattrs;
659 657
660 error = -ENOENT;
661 if (!(inode = dentry->d_inode)) {
662 printk(KERN_ERR "chown_common: NULL inode\n");
663 goto out;
664 }
665 error = -EPERM;
666 if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
667 goto out;
668 newattrs.ia_valid = ATTR_CTIME; 658 newattrs.ia_valid = ATTR_CTIME;
669 if (user != (uid_t) -1) { 659 if (user != (uid_t) -1) {
670 newattrs.ia_valid |= ATTR_UID; 660 newattrs.ia_valid |= ATTR_UID;
@@ -680,25 +670,25 @@ static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
680 mutex_lock(&inode->i_mutex); 670 mutex_lock(&inode->i_mutex);
681 error = notify_change(dentry, &newattrs); 671 error = notify_change(dentry, &newattrs);
682 mutex_unlock(&inode->i_mutex); 672 mutex_unlock(&inode->i_mutex);
683out: 673
684 return error; 674 return error;
685} 675}
686 676
687asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group) 677asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group)
688{ 678{
689 struct nameidata nd; 679 struct path path;
690 int error; 680 int error;
691 681
692 error = user_path_walk(filename, &nd); 682 error = user_path(filename, &path);
693 if (error) 683 if (error)
694 goto out; 684 goto out;
695 error = mnt_want_write(nd.path.mnt); 685 error = mnt_want_write(path.mnt);
696 if (error) 686 if (error)
697 goto out_release; 687 goto out_release;
698 error = chown_common(nd.path.dentry, user, group); 688 error = chown_common(path.dentry, user, group);
699 mnt_drop_write(nd.path.mnt); 689 mnt_drop_write(path.mnt);
700out_release: 690out_release:
701 path_put(&nd.path); 691 path_put(&path);
702out: 692out:
703 return error; 693 return error;
704} 694}
@@ -706,7 +696,7 @@ out:
706asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user, 696asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user,
707 gid_t group, int flag) 697 gid_t group, int flag)
708{ 698{
709 struct nameidata nd; 699 struct path path;
710 int error = -EINVAL; 700 int error = -EINVAL;
711 int follow; 701 int follow;
712 702
@@ -714,35 +704,35 @@ asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user,
714 goto out; 704 goto out;
715 705
716 follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW; 706 follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
717 error = __user_walk_fd(dfd, filename, follow, &nd); 707 error = user_path_at(dfd, filename, follow, &path);
718 if (error) 708 if (error)
719 goto out; 709 goto out;
720 error = mnt_want_write(nd.path.mnt); 710 error = mnt_want_write(path.mnt);
721 if (error) 711 if (error)
722 goto out_release; 712 goto out_release;
723 error = chown_common(nd.path.dentry, user, group); 713 error = chown_common(path.dentry, user, group);
724 mnt_drop_write(nd.path.mnt); 714 mnt_drop_write(path.mnt);
725out_release: 715out_release:
726 path_put(&nd.path); 716 path_put(&path);
727out: 717out:
728 return error; 718 return error;
729} 719}
730 720
731asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group) 721asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group)
732{ 722{
733 struct nameidata nd; 723 struct path path;
734 int error; 724 int error;
735 725
736 error = user_path_walk_link(filename, &nd); 726 error = user_lpath(filename, &path);
737 if (error) 727 if (error)
738 goto out; 728 goto out;
739 error = mnt_want_write(nd.path.mnt); 729 error = mnt_want_write(path.mnt);
740 if (error) 730 if (error)
741 goto out_release; 731 goto out_release;
742 error = chown_common(nd.path.dentry, user, group); 732 error = chown_common(path.dentry, user, group);
743 mnt_drop_write(nd.path.mnt); 733 mnt_drop_write(path.mnt);
744out_release: 734out_release:
745 path_put(&nd.path); 735 path_put(&path);
746out: 736out:
747 return error; 737 return error;
748} 738}
@@ -982,7 +972,6 @@ int get_unused_fd_flags(int flags)
982 int fd, error; 972 int fd, error;
983 struct fdtable *fdt; 973 struct fdtable *fdt;
984 974
985 error = -EMFILE;
986 spin_lock(&files->file_lock); 975 spin_lock(&files->file_lock);
987 976
988repeat: 977repeat:
@@ -990,13 +979,6 @@ repeat:
990 fd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fds, 979 fd = find_next_zero_bit(fdt->open_fds->fds_bits, fdt->max_fds,
991 files->next_fd); 980 files->next_fd);
992 981
993 /*
994 * N.B. For clone tasks sharing a files structure, this test
995 * will limit the total number of files that can be opened.
996 */
997 if (fd >= current->signal->rlim[RLIMIT_NOFILE].rlim_cur)
998 goto out;
999
1000 /* Do we need to expand the fd array or fd set? */ 982 /* Do we need to expand the fd array or fd set? */
1001 error = expand_files(files, fd); 983 error = expand_files(files, fd);
1002 if (error < 0) 984 if (error < 0)
@@ -1007,7 +989,6 @@ repeat:
1007 * If we needed to expand the fs array we 989 * If we needed to expand the fs array we
1008 * might have blocked - try again. 990 * might have blocked - try again.
1009 */ 991 */
1010 error = -EMFILE;
1011 goto repeat; 992 goto repeat;
1012 } 993 }
1013 994
diff --git a/fs/pipe.c b/fs/pipe.c
index 10c4e9aa5c49..fcba6542b8d0 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -777,45 +777,10 @@ pipe_rdwr_open(struct inode *inode, struct file *filp)
777/* 777/*
778 * The file_operations structs are not static because they 778 * The file_operations structs are not static because they
779 * are also used in linux/fs/fifo.c to do operations on FIFOs. 779 * are also used in linux/fs/fifo.c to do operations on FIFOs.
780 *
781 * Pipes reuse fifos' file_operations structs.
780 */ 782 */
781const struct file_operations read_fifo_fops = { 783const struct file_operations read_pipefifo_fops = {
782 .llseek = no_llseek,
783 .read = do_sync_read,
784 .aio_read = pipe_read,
785 .write = bad_pipe_w,
786 .poll = pipe_poll,
787 .unlocked_ioctl = pipe_ioctl,
788 .open = pipe_read_open,
789 .release = pipe_read_release,
790 .fasync = pipe_read_fasync,
791};
792
793const struct file_operations write_fifo_fops = {
794 .llseek = no_llseek,
795 .read = bad_pipe_r,
796 .write = do_sync_write,
797 .aio_write = pipe_write,
798 .poll = pipe_poll,
799 .unlocked_ioctl = pipe_ioctl,
800 .open = pipe_write_open,
801 .release = pipe_write_release,
802 .fasync = pipe_write_fasync,
803};
804
805const struct file_operations rdwr_fifo_fops = {
806 .llseek = no_llseek,
807 .read = do_sync_read,
808 .aio_read = pipe_read,
809 .write = do_sync_write,
810 .aio_write = pipe_write,
811 .poll = pipe_poll,
812 .unlocked_ioctl = pipe_ioctl,
813 .open = pipe_rdwr_open,
814 .release = pipe_rdwr_release,
815 .fasync = pipe_rdwr_fasync,
816};
817
818static const struct file_operations read_pipe_fops = {
819 .llseek = no_llseek, 784 .llseek = no_llseek,
820 .read = do_sync_read, 785 .read = do_sync_read,
821 .aio_read = pipe_read, 786 .aio_read = pipe_read,
@@ -827,7 +792,7 @@ static const struct file_operations read_pipe_fops = {
827 .fasync = pipe_read_fasync, 792 .fasync = pipe_read_fasync,
828}; 793};
829 794
830static const struct file_operations write_pipe_fops = { 795const struct file_operations write_pipefifo_fops = {
831 .llseek = no_llseek, 796 .llseek = no_llseek,
832 .read = bad_pipe_r, 797 .read = bad_pipe_r,
833 .write = do_sync_write, 798 .write = do_sync_write,
@@ -839,7 +804,7 @@ static const struct file_operations write_pipe_fops = {
839 .fasync = pipe_write_fasync, 804 .fasync = pipe_write_fasync,
840}; 805};
841 806
842static const struct file_operations rdwr_pipe_fops = { 807const struct file_operations rdwr_pipefifo_fops = {
843 .llseek = no_llseek, 808 .llseek = no_llseek,
844 .read = do_sync_read, 809 .read = do_sync_read,
845 .aio_read = pipe_read, 810 .aio_read = pipe_read,
@@ -927,7 +892,7 @@ static struct inode * get_pipe_inode(void)
927 inode->i_pipe = pipe; 892 inode->i_pipe = pipe;
928 893
929 pipe->readers = pipe->writers = 1; 894 pipe->readers = pipe->writers = 1;
930 inode->i_fop = &rdwr_pipe_fops; 895 inode->i_fop = &rdwr_pipefifo_fops;
931 896
932 /* 897 /*
933 * Mark the inode dirty from the very beginning, 898 * Mark the inode dirty from the very beginning,
@@ -978,7 +943,7 @@ struct file *create_write_pipe(int flags)
978 d_instantiate(dentry, inode); 943 d_instantiate(dentry, inode);
979 944
980 err = -ENFILE; 945 err = -ENFILE;
981 f = alloc_file(pipe_mnt, dentry, FMODE_WRITE, &write_pipe_fops); 946 f = alloc_file(pipe_mnt, dentry, FMODE_WRITE, &write_pipefifo_fops);
982 if (!f) 947 if (!f)
983 goto err_dentry; 948 goto err_dentry;
984 f->f_mapping = inode->i_mapping; 949 f->f_mapping = inode->i_mapping;
@@ -1020,7 +985,7 @@ struct file *create_read_pipe(struct file *wrf, int flags)
1020 985
1021 f->f_pos = 0; 986 f->f_pos = 0;
1022 f->f_flags = O_RDONLY | (flags & O_NONBLOCK); 987 f->f_flags = O_RDONLY | (flags & O_NONBLOCK);
1023 f->f_op = &read_pipe_fops; 988 f->f_op = &read_pipefifo_fops;
1024 f->f_mode = FMODE_READ; 989 f->f_mode = FMODE_READ;
1025 f->f_version = 0; 990 f->f_version = 0;
1026 991
diff --git a/fs/proc/base.c b/fs/proc/base.c
index d744aa3c9f74..e74308bdabd3 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -1859,8 +1859,7 @@ static const struct file_operations proc_fd_operations = {
1859 * /proc/pid/fd needs a special permission handler so that a process can still 1859 * /proc/pid/fd needs a special permission handler so that a process can still
1860 * access /proc/self/fd after it has executed a setuid(). 1860 * access /proc/self/fd after it has executed a setuid().
1861 */ 1861 */
1862static int proc_fd_permission(struct inode *inode, int mask, 1862static int proc_fd_permission(struct inode *inode, int mask)
1863 struct nameidata *nd)
1864{ 1863{
1865 int rv; 1864 int rv;
1866 1865
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index b37f25dc45a5..8bb03f056c28 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -17,6 +17,7 @@
17#include <linux/init.h> 17#include <linux/init.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/smp_lock.h> 19#include <linux/smp_lock.h>
20#include <linux/sysctl.h>
20 21
21#include <asm/system.h> 22#include <asm/system.h>
22#include <asm/uaccess.h> 23#include <asm/uaccess.h>
@@ -65,6 +66,8 @@ static void proc_delete_inode(struct inode *inode)
65 module_put(de->owner); 66 module_put(de->owner);
66 de_put(de); 67 de_put(de);
67 } 68 }
69 if (PROC_I(inode)->sysctl)
70 sysctl_head_put(PROC_I(inode)->sysctl);
68 clear_inode(inode); 71 clear_inode(inode);
69} 72}
70 73
@@ -84,6 +87,8 @@ static struct inode *proc_alloc_inode(struct super_block *sb)
84 ei->fd = 0; 87 ei->fd = 0;
85 ei->op.proc_get_link = NULL; 88 ei->op.proc_get_link = NULL;
86 ei->pde = NULL; 89 ei->pde = NULL;
90 ei->sysctl = NULL;
91 ei->sysctl_entry = NULL;
87 inode = &ei->vfs_inode; 92 inode = &ei->vfs_inode;
88 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 93 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
89 return inode; 94 return inode;
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index 5acc001d49f6..f9a8b892718f 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -10,149 +10,110 @@
10static struct dentry_operations proc_sys_dentry_operations; 10static struct dentry_operations proc_sys_dentry_operations;
11static const struct file_operations proc_sys_file_operations; 11static const struct file_operations proc_sys_file_operations;
12static const struct inode_operations proc_sys_inode_operations; 12static const struct inode_operations proc_sys_inode_operations;
13static const struct file_operations proc_sys_dir_file_operations;
14static const struct inode_operations proc_sys_dir_operations;
13 15
14static void proc_sys_refresh_inode(struct inode *inode, struct ctl_table *table) 16static struct inode *proc_sys_make_inode(struct super_block *sb,
15{ 17 struct ctl_table_header *head, struct ctl_table *table)
16 /* Refresh the cached information bits in the inode */
17 if (table) {
18 inode->i_uid = 0;
19 inode->i_gid = 0;
20 inode->i_mode = table->mode;
21 if (table->proc_handler) {
22 inode->i_mode |= S_IFREG;
23 inode->i_nlink = 1;
24 } else {
25 inode->i_mode |= S_IFDIR;
26 inode->i_nlink = 0; /* It is too hard to figure out */
27 }
28 }
29}
30
31static struct inode *proc_sys_make_inode(struct inode *dir, struct ctl_table *table)
32{ 18{
33 struct inode *inode; 19 struct inode *inode;
34 struct proc_inode *dir_ei, *ei; 20 struct proc_inode *ei;
35 int depth;
36 21
37 inode = new_inode(dir->i_sb); 22 inode = new_inode(sb);
38 if (!inode) 23 if (!inode)
39 goto out; 24 goto out;
40 25
41 /* A directory is always one deeper than it's parent */ 26 sysctl_head_get(head);
42 dir_ei = PROC_I(dir);
43 depth = dir_ei->fd + 1;
44
45 ei = PROC_I(inode); 27 ei = PROC_I(inode);
46 ei->fd = depth; 28 ei->sysctl = head;
29 ei->sysctl_entry = table;
30
47 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; 31 inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
48 inode->i_op = &proc_sys_inode_operations;
49 inode->i_fop = &proc_sys_file_operations;
50 inode->i_flags |= S_PRIVATE; /* tell selinux to ignore this inode */ 32 inode->i_flags |= S_PRIVATE; /* tell selinux to ignore this inode */
51 proc_sys_refresh_inode(inode, table); 33 inode->i_mode = table->mode;
34 if (!table->child) {
35 inode->i_mode |= S_IFREG;
36 inode->i_op = &proc_sys_inode_operations;
37 inode->i_fop = &proc_sys_file_operations;
38 } else {
39 inode->i_mode |= S_IFDIR;
40 inode->i_nlink = 0;
41 inode->i_op = &proc_sys_dir_operations;
42 inode->i_fop = &proc_sys_dir_file_operations;
43 }
52out: 44out:
53 return inode; 45 return inode;
54} 46}
55 47
56static struct dentry *proc_sys_ancestor(struct dentry *dentry, int depth) 48static struct ctl_table *find_in_table(struct ctl_table *p, struct qstr *name)
57{
58 for (;;) {
59 struct proc_inode *ei;
60
61 ei = PROC_I(dentry->d_inode);
62 if (ei->fd == depth)
63 break; /* found */
64
65 dentry = dentry->d_parent;
66 }
67 return dentry;
68}
69
70static struct ctl_table *proc_sys_lookup_table_one(struct ctl_table *table,
71 struct qstr *name)
72{ 49{
73 int len; 50 int len;
74 for ( ; table->ctl_name || table->procname; table++) { 51 for ( ; p->ctl_name || p->procname; p++) {
75 52
76 if (!table->procname) 53 if (!p->procname)
77 continue; 54 continue;
78 55
79 len = strlen(table->procname); 56 len = strlen(p->procname);
80 if (len != name->len) 57 if (len != name->len)
81 continue; 58 continue;
82 59
83 if (memcmp(table->procname, name->name, len) != 0) 60 if (memcmp(p->procname, name->name, len) != 0)
84 continue; 61 continue;
85 62
86 /* I have a match */ 63 /* I have a match */
87 return table; 64 return p;
88 } 65 }
89 return NULL; 66 return NULL;
90} 67}
91 68
92static struct ctl_table *proc_sys_lookup_table(struct dentry *dentry, 69struct ctl_table_header *grab_header(struct inode *inode)
93 struct ctl_table *table)
94{ 70{
95 struct dentry *ancestor; 71 if (PROC_I(inode)->sysctl)
96 struct proc_inode *ei; 72 return sysctl_head_grab(PROC_I(inode)->sysctl);
97 int depth, i; 73 else
74 return sysctl_head_next(NULL);
75}
98 76
99 ei = PROC_I(dentry->d_inode); 77static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry,
100 depth = ei->fd; 78 struct nameidata *nd)
79{
80 struct ctl_table_header *head = grab_header(dir);
81 struct ctl_table *table = PROC_I(dir)->sysctl_entry;
82 struct ctl_table_header *h = NULL;
83 struct qstr *name = &dentry->d_name;
84 struct ctl_table *p;
85 struct inode *inode;
86 struct dentry *err = ERR_PTR(-ENOENT);
101 87
102 if (depth == 0) 88 if (IS_ERR(head))
103 return table; 89 return ERR_CAST(head);
104 90
105 for (i = 1; table && (i <= depth); i++) { 91 if (table && !table->child) {
106 ancestor = proc_sys_ancestor(dentry, i); 92 WARN_ON(1);
107 table = proc_sys_lookup_table_one(table, &ancestor->d_name); 93 goto out;
108 if (table)
109 table = table->child;
110 } 94 }
111 return table;
112
113}
114static struct ctl_table *proc_sys_lookup_entry(struct dentry *dparent,
115 struct qstr *name,
116 struct ctl_table *table)
117{
118 table = proc_sys_lookup_table(dparent, table);
119 if (table)
120 table = proc_sys_lookup_table_one(table, name);
121 return table;
122}
123 95
124static struct ctl_table *do_proc_sys_lookup(struct dentry *parent, 96 table = table ? table->child : head->ctl_table;
125 struct qstr *name,
126 struct ctl_table_header **ptr)
127{
128 struct ctl_table_header *head;
129 struct ctl_table *table = NULL;
130 97
131 for (head = sysctl_head_next(NULL); head; 98 p = find_in_table(table, name);
132 head = sysctl_head_next(head)) { 99 if (!p) {
133 table = proc_sys_lookup_entry(parent, name, head->ctl_table); 100 for (h = sysctl_head_next(NULL); h; h = sysctl_head_next(h)) {
134 if (table) 101 if (h->attached_to != table)
135 break; 102 continue;
103 p = find_in_table(h->attached_by, name);
104 if (p)
105 break;
106 }
136 } 107 }
137 *ptr = head;
138 return table;
139}
140
141static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry,
142 struct nameidata *nd)
143{
144 struct ctl_table_header *head;
145 struct inode *inode;
146 struct dentry *err;
147 struct ctl_table *table;
148 108
149 err = ERR_PTR(-ENOENT); 109 if (!p)
150 table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
151 if (!table)
152 goto out; 110 goto out;
153 111
154 err = ERR_PTR(-ENOMEM); 112 err = ERR_PTR(-ENOMEM);
155 inode = proc_sys_make_inode(dir, table); 113 inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
114 if (h)
115 sysctl_head_finish(h);
116
156 if (!inode) 117 if (!inode)
157 goto out; 118 goto out;
158 119
@@ -168,22 +129,14 @@ out:
168static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf, 129static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf,
169 size_t count, loff_t *ppos, int write) 130 size_t count, loff_t *ppos, int write)
170{ 131{
171 struct dentry *dentry = filp->f_dentry; 132 struct inode *inode = filp->f_path.dentry->d_inode;
172 struct ctl_table_header *head; 133 struct ctl_table_header *head = grab_header(inode);
173 struct ctl_table *table; 134 struct ctl_table *table = PROC_I(inode)->sysctl_entry;
174 ssize_t error; 135 ssize_t error;
175 size_t res; 136 size_t res;
176 137
177 table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); 138 if (IS_ERR(head))
178 /* Has the sysctl entry disappeared on us? */ 139 return PTR_ERR(head);
179 error = -ENOENT;
180 if (!table)
181 goto out;
182
183 /* Has the sysctl entry been replaced by a directory? */
184 error = -EISDIR;
185 if (!table->proc_handler)
186 goto out;
187 140
188 /* 141 /*
189 * At this point we know that the sysctl was not unregistered 142 * At this point we know that the sysctl was not unregistered
@@ -193,6 +146,11 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf,
193 if (sysctl_perm(head->root, table, write ? MAY_WRITE : MAY_READ)) 146 if (sysctl_perm(head->root, table, write ? MAY_WRITE : MAY_READ))
194 goto out; 147 goto out;
195 148
149 /* if that can happen at all, it should be -EINVAL, not -EISDIR */
150 error = -EINVAL;
151 if (!table->proc_handler)
152 goto out;
153
196 /* careful: calling conventions are nasty here */ 154 /* careful: calling conventions are nasty here */
197 res = count; 155 res = count;
198 error = table->proc_handler(table, write, filp, buf, &res, ppos); 156 error = table->proc_handler(table, write, filp, buf, &res, ppos);
@@ -218,82 +176,86 @@ static ssize_t proc_sys_write(struct file *filp, const char __user *buf,
218 176
219 177
220static int proc_sys_fill_cache(struct file *filp, void *dirent, 178static int proc_sys_fill_cache(struct file *filp, void *dirent,
221 filldir_t filldir, struct ctl_table *table) 179 filldir_t filldir,
180 struct ctl_table_header *head,
181 struct ctl_table *table)
222{ 182{
223 struct ctl_table_header *head;
224 struct ctl_table *child_table = NULL;
225 struct dentry *child, *dir = filp->f_path.dentry; 183 struct dentry *child, *dir = filp->f_path.dentry;
226 struct inode *inode; 184 struct inode *inode;
227 struct qstr qname; 185 struct qstr qname;
228 ino_t ino = 0; 186 ino_t ino = 0;
229 unsigned type = DT_UNKNOWN; 187 unsigned type = DT_UNKNOWN;
230 int ret;
231 188
232 qname.name = table->procname; 189 qname.name = table->procname;
233 qname.len = strlen(table->procname); 190 qname.len = strlen(table->procname);
234 qname.hash = full_name_hash(qname.name, qname.len); 191 qname.hash = full_name_hash(qname.name, qname.len);
235 192
236 /* Suppress duplicates.
237 * Only fill a directory entry if it is the value that
238 * an ordinary lookup of that name returns. Hide all
239 * others.
240 *
241 * If we ever cache this translation in the dcache
242 * I should do a dcache lookup first. But for now
243 * it is just simpler not to.
244 */
245 ret = 0;
246 child_table = do_proc_sys_lookup(dir, &qname, &head);
247 sysctl_head_finish(head);
248 if (child_table != table)
249 return 0;
250
251 child = d_lookup(dir, &qname); 193 child = d_lookup(dir, &qname);
252 if (!child) { 194 if (!child) {
253 struct dentry *new; 195 child = d_alloc(dir, &qname);
254 new = d_alloc(dir, &qname); 196 if (child) {
255 if (new) { 197 inode = proc_sys_make_inode(dir->d_sb, head, table);
256 inode = proc_sys_make_inode(dir->d_inode, table); 198 if (!inode) {
257 if (!inode) 199 dput(child);
258 child = ERR_PTR(-ENOMEM); 200 return -ENOMEM;
259 else { 201 } else {
260 new->d_op = &proc_sys_dentry_operations; 202 child->d_op = &proc_sys_dentry_operations;
261 d_add(new, inode); 203 d_add(child, inode);
262 } 204 }
263 if (child) 205 } else {
264 dput(new); 206 return -ENOMEM;
265 else
266 child = new;
267 } 207 }
268 } 208 }
269 if (!child || IS_ERR(child) || !child->d_inode)
270 goto end_instantiate;
271 inode = child->d_inode; 209 inode = child->d_inode;
272 if (inode) { 210 ino = inode->i_ino;
273 ino = inode->i_ino; 211 type = inode->i_mode >> 12;
274 type = inode->i_mode >> 12;
275 }
276 dput(child); 212 dput(child);
277end_instantiate: 213 return !!filldir(dirent, qname.name, qname.len, filp->f_pos, ino, type);
278 if (!ino) 214}
279 ino= find_inode_number(dir, &qname); 215
280 if (!ino) 216static int scan(struct ctl_table_header *head, ctl_table *table,
281 ino = 1; 217 unsigned long *pos, struct file *file,
282 return filldir(dirent, qname.name, qname.len, filp->f_pos, ino, type); 218 void *dirent, filldir_t filldir)
219{
220
221 for (; table->ctl_name || table->procname; table++, (*pos)++) {
222 int res;
223
224 /* Can't do anything without a proc name */
225 if (!table->procname)
226 continue;
227
228 if (*pos < file->f_pos)
229 continue;
230
231 res = proc_sys_fill_cache(file, dirent, filldir, head, table);
232 if (res)
233 return res;
234
235 file->f_pos = *pos + 1;
236 }
237 return 0;
283} 238}
284 239
285static int proc_sys_readdir(struct file *filp, void *dirent, filldir_t filldir) 240static int proc_sys_readdir(struct file *filp, void *dirent, filldir_t filldir)
286{ 241{
287 struct dentry *dentry = filp->f_dentry; 242 struct dentry *dentry = filp->f_path.dentry;
288 struct inode *inode = dentry->d_inode; 243 struct inode *inode = dentry->d_inode;
289 struct ctl_table_header *head = NULL; 244 struct ctl_table_header *head = grab_header(inode);
290 struct ctl_table *table; 245 struct ctl_table *table = PROC_I(inode)->sysctl_entry;
246 struct ctl_table_header *h = NULL;
291 unsigned long pos; 247 unsigned long pos;
292 int ret; 248 int ret = -EINVAL;
249
250 if (IS_ERR(head))
251 return PTR_ERR(head);
293 252
294 ret = -ENOTDIR; 253 if (table && !table->child) {
295 if (!S_ISDIR(inode->i_mode)) 254 WARN_ON(1);
296 goto out; 255 goto out;
256 }
257
258 table = table ? table->child : head->ctl_table;
297 259
298 ret = 0; 260 ret = 0;
299 /* Avoid a switch here: arm builds fail with missing __cmpdi2 */ 261 /* Avoid a switch here: arm builds fail with missing __cmpdi2 */
@@ -311,30 +273,17 @@ static int proc_sys_readdir(struct file *filp, void *dirent, filldir_t filldir)
311 } 273 }
312 pos = 2; 274 pos = 2;
313 275
314 /* - Find each instance of the directory 276 ret = scan(head, table, &pos, filp, dirent, filldir);
315 * - Read all entries in each instance 277 if (ret)
316 * - Before returning an entry to user space lookup the entry 278 goto out;
317 * by name and if I find a different entry don't return
318 * this one because it means it is a buried dup.
319 * For sysctl this should only happen for directory entries.
320 */
321 for (head = sysctl_head_next(NULL); head; head = sysctl_head_next(head)) {
322 table = proc_sys_lookup_table(dentry, head->ctl_table);
323 279
324 if (!table) 280 for (h = sysctl_head_next(NULL); h; h = sysctl_head_next(h)) {
281 if (h->attached_to != table)
325 continue; 282 continue;
326 283 ret = scan(h, h->attached_by, &pos, filp, dirent, filldir);
327 for (; table->ctl_name || table->procname; table++, pos++) { 284 if (ret) {
328 /* Can't do anything without a proc name */ 285 sysctl_head_finish(h);
329 if (!table->procname) 286 break;
330 continue;
331
332 if (pos < filp->f_pos)
333 continue;
334
335 if (proc_sys_fill_cache(filp, dirent, filldir, table) < 0)
336 goto out;
337 filp->f_pos = pos + 1;
338 } 287 }
339 } 288 }
340 ret = 1; 289 ret = 1;
@@ -343,53 +292,24 @@ out:
343 return ret; 292 return ret;
344} 293}
345 294
346static int proc_sys_permission(struct inode *inode, int mask, struct nameidata *nd) 295static int proc_sys_permission(struct inode *inode, int mask)
347{ 296{
348 /* 297 /*
349 * sysctl entries that are not writeable, 298 * sysctl entries that are not writeable,
350 * are _NOT_ writeable, capabilities or not. 299 * are _NOT_ writeable, capabilities or not.
351 */ 300 */
352 struct ctl_table_header *head; 301 struct ctl_table_header *head = grab_header(inode);
353 struct ctl_table *table; 302 struct ctl_table *table = PROC_I(inode)->sysctl_entry;
354 struct dentry *dentry;
355 int mode;
356 int depth;
357 int error; 303 int error;
358 304
359 head = NULL; 305 if (IS_ERR(head))
360 depth = PROC_I(inode)->fd; 306 return PTR_ERR(head);
361
362 /* First check the cached permissions, in case we don't have
363 * enough information to lookup the sysctl table entry.
364 */
365 error = -EACCES;
366 mode = inode->i_mode;
367
368 if (current->euid == 0)
369 mode >>= 6;
370 else if (in_group_p(0))
371 mode >>= 3;
372
373 if ((mode & mask & (MAY_READ|MAY_WRITE|MAY_EXEC)) == mask)
374 error = 0;
375
376 /* If we can't get a sysctl table entry the permission
377 * checks on the cached mode will have to be enough.
378 */
379 if (!nd || !depth)
380 goto out;
381 307
382 dentry = nd->path.dentry; 308 if (!table) /* global root - r-xr-xr-x */
383 table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); 309 error = mask & MAY_WRITE ? -EACCES : 0;
310 else /* Use the permissions on the sysctl table entry */
311 error = sysctl_perm(head->root, table, mask);
384 312
385 /* If the entry does not exist deny permission */
386 error = -EACCES;
387 if (!table)
388 goto out;
389
390 /* Use the permissions on the sysctl table entry */
391 error = sysctl_perm(head->root, table, mask);
392out:
393 sysctl_head_finish(head); 313 sysctl_head_finish(head);
394 return error; 314 return error;
395} 315}
@@ -409,33 +329,70 @@ static int proc_sys_setattr(struct dentry *dentry, struct iattr *attr)
409 return error; 329 return error;
410} 330}
411 331
412/* I'm lazy and don't distinguish between files and directories, 332static int proc_sys_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
413 * until access time. 333{
414 */ 334 struct inode *inode = dentry->d_inode;
335 struct ctl_table_header *head = grab_header(inode);
336 struct ctl_table *table = PROC_I(inode)->sysctl_entry;
337
338 if (IS_ERR(head))
339 return PTR_ERR(head);
340
341 generic_fillattr(inode, stat);
342 if (table)
343 stat->mode = (stat->mode & S_IFMT) | table->mode;
344
345 sysctl_head_finish(head);
346 return 0;
347}
348
415static const struct file_operations proc_sys_file_operations = { 349static const struct file_operations proc_sys_file_operations = {
416 .read = proc_sys_read, 350 .read = proc_sys_read,
417 .write = proc_sys_write, 351 .write = proc_sys_write,
352};
353
354static const struct file_operations proc_sys_dir_file_operations = {
418 .readdir = proc_sys_readdir, 355 .readdir = proc_sys_readdir,
419}; 356};
420 357
421static const struct inode_operations proc_sys_inode_operations = { 358static const struct inode_operations proc_sys_inode_operations = {
359 .permission = proc_sys_permission,
360 .setattr = proc_sys_setattr,
361 .getattr = proc_sys_getattr,
362};
363
364static const struct inode_operations proc_sys_dir_operations = {
422 .lookup = proc_sys_lookup, 365 .lookup = proc_sys_lookup,
423 .permission = proc_sys_permission, 366 .permission = proc_sys_permission,
424 .setattr = proc_sys_setattr, 367 .setattr = proc_sys_setattr,
368 .getattr = proc_sys_getattr,
425}; 369};
426 370
427static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd) 371static int proc_sys_revalidate(struct dentry *dentry, struct nameidata *nd)
428{ 372{
429 struct ctl_table_header *head; 373 return !PROC_I(dentry->d_inode)->sysctl->unregistering;
430 struct ctl_table *table; 374}
431 table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); 375
432 proc_sys_refresh_inode(dentry->d_inode, table); 376static int proc_sys_delete(struct dentry *dentry)
433 sysctl_head_finish(head); 377{
434 return !!table; 378 return !!PROC_I(dentry->d_inode)->sysctl->unregistering;
379}
380
381static int proc_sys_compare(struct dentry *dir, struct qstr *qstr,
382 struct qstr *name)
383{
384 struct dentry *dentry = container_of(qstr, struct dentry, d_name);
385 if (qstr->len != name->len)
386 return 1;
387 if (memcmp(qstr->name, name->name, name->len))
388 return 1;
389 return !sysctl_is_seen(PROC_I(dentry->d_inode)->sysctl);
435} 390}
436 391
437static struct dentry_operations proc_sys_dentry_operations = { 392static struct dentry_operations proc_sys_dentry_operations = {
438 .d_revalidate = proc_sys_revalidate, 393 .d_revalidate = proc_sys_revalidate,
394 .d_delete = proc_sys_delete,
395 .d_compare = proc_sys_compare,
439}; 396};
440 397
441static struct proc_dir_entry *proc_sys_root; 398static struct proc_dir_entry *proc_sys_root;
@@ -443,8 +400,8 @@ static struct proc_dir_entry *proc_sys_root;
443int proc_sys_init(void) 400int proc_sys_init(void)
444{ 401{
445 proc_sys_root = proc_mkdir("sys", NULL); 402 proc_sys_root = proc_mkdir("sys", NULL);
446 proc_sys_root->proc_iops = &proc_sys_inode_operations; 403 proc_sys_root->proc_iops = &proc_sys_dir_operations;
447 proc_sys_root->proc_fops = &proc_sys_file_operations; 404 proc_sys_root->proc_fops = &proc_sys_dir_file_operations;
448 proc_sys_root->nlink = 0; 405 proc_sys_root->nlink = 0;
449 return 0; 406 return 0;
450} 407}
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index d7c4935c1034..bb3cb5b7cdb2 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -1250,7 +1250,7 @@ static int reiserfs_check_acl(struct inode *inode, int mask)
1250 return error; 1250 return error;
1251} 1251}
1252 1252
1253int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd) 1253int reiserfs_permission(struct inode *inode, int mask)
1254{ 1254{
1255 /* 1255 /*
1256 * We don't do permission checks on the internal objects. 1256 * We don't do permission checks on the internal objects.
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index 2294783320cb..e4f8d51a5553 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -408,7 +408,7 @@ smb_file_release(struct inode *inode, struct file * file)
408 * privileges, so we need our own check for this. 408 * privileges, so we need our own check for this.
409 */ 409 */
410static int 410static int
411smb_file_permission(struct inode *inode, int mask, struct nameidata *nd) 411smb_file_permission(struct inode *inode, int mask)
412{ 412{
413 int mode = inode->i_mode; 413 int mode = inode->i_mode;
414 int error = 0; 414 int error = 0;
@@ -417,7 +417,7 @@ smb_file_permission(struct inode *inode, int mask, struct nameidata *nd)
417 417
418 /* Look at user permissions */ 418 /* Look at user permissions */
419 mode >>= 6; 419 mode >>= 6;
420 if ((mode & 7 & mask) != mask) 420 if (mask & ~mode & (MAY_READ | MAY_WRITE | MAY_EXEC))
421 error = -EACCES; 421 error = -EACCES;
422 return error; 422 return error;
423} 423}
diff --git a/fs/splice.c b/fs/splice.c
index 47dc1a445d1f..b30311ba8af6 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -772,7 +772,7 @@ generic_file_splice_write_nolock(struct pipe_inode_info *pipe, struct file *out,
772 ssize_t ret; 772 ssize_t ret;
773 int err; 773 int err;
774 774
775 err = remove_suid(out->f_path.dentry); 775 err = file_remove_suid(out);
776 if (unlikely(err)) 776 if (unlikely(err))
777 return err; 777 return err;
778 778
@@ -830,7 +830,7 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
830 ssize_t ret; 830 ssize_t ret;
831 831
832 inode_double_lock(inode, pipe->inode); 832 inode_double_lock(inode, pipe->inode);
833 ret = remove_suid(out->f_path.dentry); 833 ret = file_remove_suid(out);
834 if (likely(!ret)) 834 if (likely(!ret))
835 ret = __splice_from_pipe(pipe, &sd, pipe_to_file); 835 ret = __splice_from_pipe(pipe, &sd, pipe_to_file);
836 inode_double_unlock(inode, pipe->inode); 836 inode_double_unlock(inode, pipe->inode);
diff --git a/fs/stat.c b/fs/stat.c
index 9cf41f719d50..7c46fbeb8b76 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -57,13 +57,13 @@ EXPORT_SYMBOL(vfs_getattr);
57 57
58int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat) 58int vfs_stat_fd(int dfd, char __user *name, struct kstat *stat)
59{ 59{
60 struct nameidata nd; 60 struct path path;
61 int error; 61 int error;
62 62
63 error = __user_walk_fd(dfd, name, LOOKUP_FOLLOW, &nd); 63 error = user_path_at(dfd, name, LOOKUP_FOLLOW, &path);
64 if (!error) { 64 if (!error) {
65 error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat); 65 error = vfs_getattr(path.mnt, path.dentry, stat);
66 path_put(&nd.path); 66 path_put(&path);
67 } 67 }
68 return error; 68 return error;
69} 69}
@@ -77,13 +77,13 @@ EXPORT_SYMBOL(vfs_stat);
77 77
78int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat) 78int vfs_lstat_fd(int dfd, char __user *name, struct kstat *stat)
79{ 79{
80 struct nameidata nd; 80 struct path path;
81 int error; 81 int error;
82 82
83 error = __user_walk_fd(dfd, name, 0, &nd); 83 error = user_path_at(dfd, name, 0, &path);
84 if (!error) { 84 if (!error) {
85 error = vfs_getattr(nd.path.mnt, nd.path.dentry, stat); 85 error = vfs_getattr(path.mnt, path.dentry, stat);
86 path_put(&nd.path); 86 path_put(&path);
87 } 87 }
88 return error; 88 return error;
89} 89}
@@ -291,29 +291,29 @@ asmlinkage long sys_newfstat(unsigned int fd, struct stat __user *statbuf)
291 return error; 291 return error;
292} 292}
293 293
294asmlinkage long sys_readlinkat(int dfd, const char __user *path, 294asmlinkage long sys_readlinkat(int dfd, const char __user *pathname,
295 char __user *buf, int bufsiz) 295 char __user *buf, int bufsiz)
296{ 296{
297 struct nameidata nd; 297 struct path path;
298 int error; 298 int error;
299 299
300 if (bufsiz <= 0) 300 if (bufsiz <= 0)
301 return -EINVAL; 301 return -EINVAL;
302 302
303 error = __user_walk_fd(dfd, path, 0, &nd); 303 error = user_path_at(dfd, pathname, 0, &path);
304 if (!error) { 304 if (!error) {
305 struct inode *inode = nd.path.dentry->d_inode; 305 struct inode *inode = path.dentry->d_inode;
306 306
307 error = -EINVAL; 307 error = -EINVAL;
308 if (inode->i_op && inode->i_op->readlink) { 308 if (inode->i_op && inode->i_op->readlink) {
309 error = security_inode_readlink(nd.path.dentry); 309 error = security_inode_readlink(path.dentry);
310 if (!error) { 310 if (!error) {
311 touch_atime(nd.path.mnt, nd.path.dentry); 311 touch_atime(path.mnt, path.dentry);
312 error = inode->i_op->readlink(nd.path.dentry, 312 error = inode->i_op->readlink(path.dentry,
313 buf, bufsiz); 313 buf, bufsiz);
314 } 314 }
315 } 315 }
316 path_put(&nd.path); 316 path_put(&path);
317 } 317 }
318 return error; 318 return error;
319} 319}
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 005a3b854d96..8565e586e533 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -53,6 +53,7 @@
53 53
54#include "ubifs.h" 54#include "ubifs.h"
55#include <linux/mount.h> 55#include <linux/mount.h>
56#include <linux/namei.h>
56 57
57static int read_block(struct inode *inode, void *addr, unsigned int block, 58static int read_block(struct inode *inode, void *addr, unsigned int block,
58 struct ubifs_data_node *dn) 59 struct ubifs_data_node *dn)
diff --git a/fs/utimes.c b/fs/utimes.c
index b6b664e7145e..6929e3e91d05 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -48,66 +48,22 @@ static bool nsec_valid(long nsec)
48 return nsec >= 0 && nsec <= 999999999; 48 return nsec >= 0 && nsec <= 999999999;
49} 49}
50 50
51/* If times==NULL, set access and modification to current time, 51static int utimes_common(struct path *path, struct timespec *times)
52 * must be owner or have write permission.
53 * Else, update from *times, must be owner or super user.
54 */
55long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags)
56{ 52{
57 int error; 53 int error;
58 struct nameidata nd;
59 struct dentry *dentry;
60 struct inode *inode;
61 struct iattr newattrs; 54 struct iattr newattrs;
62 struct file *f = NULL; 55 struct inode *inode = path->dentry->d_inode;
63 struct vfsmount *mnt;
64
65 error = -EINVAL;
66 if (times && (!nsec_valid(times[0].tv_nsec) ||
67 !nsec_valid(times[1].tv_nsec))) {
68 goto out;
69 }
70
71 if (flags & ~AT_SYMLINK_NOFOLLOW)
72 goto out;
73
74 if (filename == NULL && dfd != AT_FDCWD) {
75 error = -EINVAL;
76 if (flags & AT_SYMLINK_NOFOLLOW)
77 goto out;
78 56
79 error = -EBADF; 57 error = mnt_want_write(path->mnt);
80 f = fget(dfd);
81 if (!f)
82 goto out;
83 dentry = f->f_path.dentry;
84 mnt = f->f_path.mnt;
85 } else {
86 error = __user_walk_fd(dfd, filename, (flags & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW, &nd);
87 if (error)
88 goto out;
89
90 dentry = nd.path.dentry;
91 mnt = nd.path.mnt;
92 }
93
94 inode = dentry->d_inode;
95
96 error = mnt_want_write(mnt);
97 if (error) 58 if (error)
98 goto dput_and_out; 59 goto out;
99 60
100 if (times && times[0].tv_nsec == UTIME_NOW && 61 if (times && times[0].tv_nsec == UTIME_NOW &&
101 times[1].tv_nsec == UTIME_NOW) 62 times[1].tv_nsec == UTIME_NOW)
102 times = NULL; 63 times = NULL;
103 64
104 /* In most cases, the checks are done in inode_change_ok() */
105 newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME; 65 newattrs.ia_valid = ATTR_CTIME | ATTR_MTIME | ATTR_ATIME;
106 if (times) { 66 if (times) {
107 error = -EPERM;
108 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
109 goto mnt_drop_write_and_out;
110
111 if (times[0].tv_nsec == UTIME_OMIT) 67 if (times[0].tv_nsec == UTIME_OMIT)
112 newattrs.ia_valid &= ~ATTR_ATIME; 68 newattrs.ia_valid &= ~ATTR_ATIME;
113 else if (times[0].tv_nsec != UTIME_NOW) { 69 else if (times[0].tv_nsec != UTIME_NOW) {
@@ -123,21 +79,13 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags
123 newattrs.ia_mtime.tv_nsec = times[1].tv_nsec; 79 newattrs.ia_mtime.tv_nsec = times[1].tv_nsec;
124 newattrs.ia_valid |= ATTR_MTIME_SET; 80 newattrs.ia_valid |= ATTR_MTIME_SET;
125 } 81 }
126
127 /* 82 /*
128 * For the UTIME_OMIT/UTIME_NOW and UTIME_NOW/UTIME_OMIT 83 * Tell inode_change_ok(), that this is an explicit time
129 * cases, we need to make an extra check that is not done by 84 * update, even if neither ATTR_ATIME_SET nor ATTR_MTIME_SET
130 * inode_change_ok(). 85 * were used.
131 */ 86 */
132 if (((times[0].tv_nsec == UTIME_NOW && 87 newattrs.ia_valid |= ATTR_TIMES_SET;
133 times[1].tv_nsec == UTIME_OMIT)
134 ||
135 (times[0].tv_nsec == UTIME_OMIT &&
136 times[1].tv_nsec == UTIME_NOW))
137 && !is_owner_or_cap(inode))
138 goto mnt_drop_write_and_out;
139 } else { 88 } else {
140
141 /* 89 /*
142 * If times is NULL (or both times are UTIME_NOW), 90 * If times is NULL (or both times are UTIME_NOW),
143 * then we need to check permissions, because 91 * then we need to check permissions, because
@@ -148,21 +96,76 @@ long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags
148 goto mnt_drop_write_and_out; 96 goto mnt_drop_write_and_out;
149 97
150 if (!is_owner_or_cap(inode)) { 98 if (!is_owner_or_cap(inode)) {
151 error = permission(inode, MAY_WRITE, NULL); 99 error = inode_permission(inode, MAY_WRITE);
152 if (error) 100 if (error)
153 goto mnt_drop_write_and_out; 101 goto mnt_drop_write_and_out;
154 } 102 }
155 } 103 }
156 mutex_lock(&inode->i_mutex); 104 mutex_lock(&inode->i_mutex);
157 error = notify_change(dentry, &newattrs); 105 error = notify_change(path->dentry, &newattrs);
158 mutex_unlock(&inode->i_mutex); 106 mutex_unlock(&inode->i_mutex);
107
159mnt_drop_write_and_out: 108mnt_drop_write_and_out:
160 mnt_drop_write(mnt); 109 mnt_drop_write(path->mnt);
161dput_and_out: 110out:
162 if (f) 111 return error;
163 fput(f); 112}
164 else 113
165 path_put(&nd.path); 114/*
115 * do_utimes - change times on filename or file descriptor
116 * @dfd: open file descriptor, -1 or AT_FDCWD
117 * @filename: path name or NULL
118 * @times: new times or NULL
119 * @flags: zero or more flags (only AT_SYMLINK_NOFOLLOW for the moment)
120 *
121 * If filename is NULL and dfd refers to an open file, then operate on
122 * the file. Otherwise look up filename, possibly using dfd as a
123 * starting point.
124 *
125 * If times==NULL, set access and modification to current time,
126 * must be owner or have write permission.
127 * Else, update from *times, must be owner or super user.
128 */
129long do_utimes(int dfd, char __user *filename, struct timespec *times, int flags)
130{
131 int error = -EINVAL;
132
133 if (times && (!nsec_valid(times[0].tv_nsec) ||
134 !nsec_valid(times[1].tv_nsec))) {
135 goto out;
136 }
137
138 if (flags & ~AT_SYMLINK_NOFOLLOW)
139 goto out;
140
141 if (filename == NULL && dfd != AT_FDCWD) {
142 struct file *file;
143
144 if (flags & AT_SYMLINK_NOFOLLOW)
145 goto out;
146
147 file = fget(dfd);
148 error = -EBADF;
149 if (!file)
150 goto out;
151
152 error = utimes_common(&file->f_path, times);
153 fput(file);
154 } else {
155 struct path path;
156 int lookup_flags = 0;
157
158 if (!(flags & AT_SYMLINK_NOFOLLOW))
159 lookup_flags |= LOOKUP_FOLLOW;
160
161 error = user_path_at(dfd, filename, lookup_flags, &path);
162 if (error)
163 goto out;
164
165 error = utimes_common(&path, times);
166 path_put(&path);
167 }
168
166out: 169out:
167 return error; 170 return error;
168} 171}
diff --git a/fs/xattr.c b/fs/xattr.c
index 4706a8b1f495..468377e66531 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -63,7 +63,7 @@ xattr_permission(struct inode *inode, const char *name, int mask)
63 return -EPERM; 63 return -EPERM;
64 } 64 }
65 65
66 return permission(inode, mask, NULL); 66 return inode_permission(inode, mask);
67} 67}
68 68
69int 69int
@@ -252,40 +252,40 @@ setxattr(struct dentry *d, const char __user *name, const void __user *value,
252} 252}
253 253
254asmlinkage long 254asmlinkage long
255sys_setxattr(const char __user *path, const char __user *name, 255sys_setxattr(const char __user *pathname, const char __user *name,
256 const void __user *value, size_t size, int flags) 256 const void __user *value, size_t size, int flags)
257{ 257{
258 struct nameidata nd; 258 struct path path;
259 int error; 259 int error;
260 260
261 error = user_path_walk(path, &nd); 261 error = user_path(pathname, &path);
262 if (error) 262 if (error)
263 return error; 263 return error;
264 error = mnt_want_write(nd.path.mnt); 264 error = mnt_want_write(path.mnt);
265 if (!error) { 265 if (!error) {
266 error = setxattr(nd.path.dentry, name, value, size, flags); 266 error = setxattr(path.dentry, name, value, size, flags);
267 mnt_drop_write(nd.path.mnt); 267 mnt_drop_write(path.mnt);
268 } 268 }
269 path_put(&nd.path); 269 path_put(&path);
270 return error; 270 return error;
271} 271}
272 272
273asmlinkage long 273asmlinkage long
274sys_lsetxattr(const char __user *path, const char __user *name, 274sys_lsetxattr(const char __user *pathname, const char __user *name,
275 const void __user *value, size_t size, int flags) 275 const void __user *value, size_t size, int flags)
276{ 276{
277 struct nameidata nd; 277 struct path path;
278 int error; 278 int error;
279 279
280 error = user_path_walk_link(path, &nd); 280 error = user_lpath(pathname, &path);
281 if (error) 281 if (error)
282 return error; 282 return error;
283 error = mnt_want_write(nd.path.mnt); 283 error = mnt_want_write(path.mnt);
284 if (!error) { 284 if (!error) {
285 error = setxattr(nd.path.dentry, name, value, size, flags); 285 error = setxattr(path.dentry, name, value, size, flags);
286 mnt_drop_write(nd.path.mnt); 286 mnt_drop_write(path.mnt);
287 } 287 }
288 path_put(&nd.path); 288 path_put(&path);
289 return error; 289 return error;
290} 290}
291 291
@@ -350,32 +350,32 @@ getxattr(struct dentry *d, const char __user *name, void __user *value,
350} 350}
351 351
352asmlinkage ssize_t 352asmlinkage ssize_t
353sys_getxattr(const char __user *path, const char __user *name, 353sys_getxattr(const char __user *pathname, const char __user *name,
354 void __user *value, size_t size) 354 void __user *value, size_t size)
355{ 355{
356 struct nameidata nd; 356 struct path path;
357 ssize_t error; 357 ssize_t error;
358 358
359 error = user_path_walk(path, &nd); 359 error = user_path(pathname, &path);
360 if (error) 360 if (error)
361 return error; 361 return error;
362 error = getxattr(nd.path.dentry, name, value, size); 362 error = getxattr(path.dentry, name, value, size);
363 path_put(&nd.path); 363 path_put(&path);
364 return error; 364 return error;
365} 365}
366 366
367asmlinkage ssize_t 367asmlinkage ssize_t
368sys_lgetxattr(const char __user *path, const char __user *name, void __user *value, 368sys_lgetxattr(const char __user *pathname, const char __user *name, void __user *value,
369 size_t size) 369 size_t size)
370{ 370{
371 struct nameidata nd; 371 struct path path;
372 ssize_t error; 372 ssize_t error;
373 373
374 error = user_path_walk_link(path, &nd); 374 error = user_lpath(pathname, &path);
375 if (error) 375 if (error)
376 return error; 376 return error;
377 error = getxattr(nd.path.dentry, name, value, size); 377 error = getxattr(path.dentry, name, value, size);
378 path_put(&nd.path); 378 path_put(&path);
379 return error; 379 return error;
380} 380}
381 381
@@ -425,30 +425,30 @@ listxattr(struct dentry *d, char __user *list, size_t size)
425} 425}
426 426
427asmlinkage ssize_t 427asmlinkage ssize_t
428sys_listxattr(const char __user *path, char __user *list, size_t size) 428sys_listxattr(const char __user *pathname, char __user *list, size_t size)
429{ 429{
430 struct nameidata nd; 430 struct path path;
431 ssize_t error; 431 ssize_t error;
432 432
433 error = user_path_walk(path, &nd); 433 error = user_path(pathname, &path);
434 if (error) 434 if (error)
435 return error; 435 return error;
436 error = listxattr(nd.path.dentry, list, size); 436 error = listxattr(path.dentry, list, size);
437 path_put(&nd.path); 437 path_put(&path);
438 return error; 438 return error;
439} 439}
440 440
441asmlinkage ssize_t 441asmlinkage ssize_t
442sys_llistxattr(const char __user *path, char __user *list, size_t size) 442sys_llistxattr(const char __user *pathname, char __user *list, size_t size)
443{ 443{
444 struct nameidata nd; 444 struct path path;
445 ssize_t error; 445 ssize_t error;
446 446
447 error = user_path_walk_link(path, &nd); 447 error = user_lpath(pathname, &path);
448 if (error) 448 if (error)
449 return error; 449 return error;
450 error = listxattr(nd.path.dentry, list, size); 450 error = listxattr(path.dentry, list, size);
451 path_put(&nd.path); 451 path_put(&path);
452 return error; 452 return error;
453} 453}
454 454
@@ -486,38 +486,38 @@ removexattr(struct dentry *d, const char __user *name)
486} 486}
487 487
488asmlinkage long 488asmlinkage long
489sys_removexattr(const char __user *path, const char __user *name) 489sys_removexattr(const char __user *pathname, const char __user *name)
490{ 490{
491 struct nameidata nd; 491 struct path path;
492 int error; 492 int error;
493 493
494 error = user_path_walk(path, &nd); 494 error = user_path(pathname, &path);
495 if (error) 495 if (error)
496 return error; 496 return error;
497 error = mnt_want_write(nd.path.mnt); 497 error = mnt_want_write(path.mnt);
498 if (!error) { 498 if (!error) {
499 error = removexattr(nd.path.dentry, name); 499 error = removexattr(path.dentry, name);
500 mnt_drop_write(nd.path.mnt); 500 mnt_drop_write(path.mnt);
501 } 501 }
502 path_put(&nd.path); 502 path_put(&path);
503 return error; 503 return error;
504} 504}
505 505
506asmlinkage long 506asmlinkage long
507sys_lremovexattr(const char __user *path, const char __user *name) 507sys_lremovexattr(const char __user *pathname, const char __user *name)
508{ 508{
509 struct nameidata nd; 509 struct path path;
510 int error; 510 int error;
511 511
512 error = user_path_walk_link(path, &nd); 512 error = user_lpath(pathname, &path);
513 if (error) 513 if (error)
514 return error; 514 return error;
515 error = mnt_want_write(nd.path.mnt); 515 error = mnt_want_write(path.mnt);
516 if (!error) { 516 if (!error) {
517 error = removexattr(nd.path.dentry, name); 517 error = removexattr(path.dentry, name);
518 mnt_drop_write(nd.path.mnt); 518 mnt_drop_write(path.mnt);
519 } 519 }
520 path_put(&nd.path); 520 path_put(&path);
521 return error; 521 return error;
522} 522}
523 523
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index a42ba9d71156..01939ba2d8de 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -84,17 +84,15 @@ xfs_find_handle(
84 switch (cmd) { 84 switch (cmd) {
85 case XFS_IOC_PATH_TO_FSHANDLE: 85 case XFS_IOC_PATH_TO_FSHANDLE:
86 case XFS_IOC_PATH_TO_HANDLE: { 86 case XFS_IOC_PATH_TO_HANDLE: {
87 struct nameidata nd; 87 struct path path;
88 int error; 88 int error = user_lpath((const char __user *)hreq.path, &path);
89
90 error = user_path_walk_link((const char __user *)hreq.path, &nd);
91 if (error) 89 if (error)
92 return error; 90 return error;
93 91
94 ASSERT(nd.path.dentry); 92 ASSERT(path.dentry);
95 ASSERT(nd.path.dentry->d_inode); 93 ASSERT(path.dentry->d_inode);
96 inode = igrab(nd.path.dentry->d_inode); 94 inode = igrab(path.dentry->d_inode);
97 path_put(&nd.path); 95 path_put(&path);
98 break; 96 break;
99 } 97 }
100 98
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 2bf287ef5489..5fc61c824bb9 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -589,8 +589,7 @@ xfs_check_acl(
589STATIC int 589STATIC int
590xfs_vn_permission( 590xfs_vn_permission(
591 struct inode *inode, 591 struct inode *inode,
592 int mask, 592 int mask)
593 struct nameidata *nd)
594{ 593{
595 return generic_permission(inode, mask, xfs_check_acl); 594 return generic_permission(inode, mask, xfs_check_acl);
596} 595}
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 5e3b57516ec7..82333b3e118e 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -711,7 +711,7 @@ start:
711 !capable(CAP_FSETID)) { 711 !capable(CAP_FSETID)) {
712 error = xfs_write_clear_setuid(xip); 712 error = xfs_write_clear_setuid(xip);
713 if (likely(!error)) 713 if (likely(!error))
714 error = -remove_suid(file->f_path.dentry); 714 error = -file_remove_suid(file);
715 if (unlikely(error)) { 715 if (unlikely(error)) {
716 goto out_unlock_internal; 716 goto out_unlock_internal;
717 } 717 }
diff --git a/include/asm-alpha/namei.h b/include/asm-alpha/namei.h
deleted file mode 100644
index 5cc9bb39499d..000000000000
--- a/include/asm-alpha/namei.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/* $Id: namei.h,v 1.1 1996/12/13 14:48:21 jj Exp $
2 * linux/include/asm-alpha/namei.h
3 *
4 * Included from linux/fs/namei.c
5 */
6
7#ifndef __ALPHA_NAMEI_H
8#define __ALPHA_NAMEI_H
9
10/* This dummy routine maybe changed to something useful
11 * for /usr/gnemul/ emulation stuff.
12 * Look at asm-sparc/namei.h for details.
13 */
14
15#define __emul_prefix() NULL
16
17#endif /* __ALPHA_NAMEI_H */
diff --git a/include/asm-arm/namei.h b/include/asm-arm/namei.h
deleted file mode 100644
index a402d3b9d0f7..000000000000
--- a/include/asm-arm/namei.h
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * linux/include/asm-arm/namei.h
3 *
4 * Routines to handle famous /usr/gnemul
5 * Derived from the Sparc version of this file
6 *
7 * Included from linux/fs/namei.c
8 */
9
10#ifndef __ASMARM_NAMEI_H
11#define __ASMARM_NAMEI_H
12
13#define ARM_BSD_EMUL "usr/gnemul/bsd/"
14
15static inline char *__emul_prefix(void)
16{
17 switch (current->personality) {
18 case PER_BSD:
19 return ARM_BSD_EMUL;
20 default:
21 return NULL;
22 }
23}
24
25#endif /* __ASMARM_NAMEI_H */
diff --git a/include/asm-avr32/namei.h b/include/asm-avr32/namei.h
deleted file mode 100644
index f0a26de06cab..000000000000
--- a/include/asm-avr32/namei.h
+++ /dev/null
@@ -1,7 +0,0 @@
1#ifndef __ASM_AVR32_NAMEI_H
2#define __ASM_AVR32_NAMEI_H
3
4/* This dummy routine may be changed to something useful */
5#define __emul_prefix() NULL
6
7#endif /* __ASM_AVR32_NAMEI_H */
diff --git a/include/asm-blackfin/namei.h b/include/asm-blackfin/namei.h
deleted file mode 100644
index 8b89a2d65cb4..000000000000
--- a/include/asm-blackfin/namei.h
+++ /dev/null
@@ -1,19 +0,0 @@
1/*
2 * linux/include/asm/namei.h
3 *
4 * Included from linux/fs/namei.c
5 *
6 * Changes made by Lineo Inc. May 2001
7 */
8
9#ifndef __BFIN_NAMEI_H
10#define __BFIN_NAMEI_H
11
12/* This dummy routine maybe changed to something useful
13 * for /usr/gnemul/ emulation stuff.
14 * Look at asm-sparc/namei.h for details.
15 */
16
17#define __emul_prefix() NULL
18
19#endif
diff --git a/include/asm-cris/namei.h b/include/asm-cris/namei.h
deleted file mode 100644
index 8a3be7a6d9f6..000000000000
--- a/include/asm-cris/namei.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/* $Id: namei.h,v 1.1 2000/07/10 16:32:31 bjornw Exp $
2 * linux/include/asm-cris/namei.h
3 *
4 * Included from linux/fs/namei.c
5 */
6
7#ifndef __CRIS_NAMEI_H
8#define __CRIS_NAMEI_H
9
10/* used to find file-system prefixes for doing emulations
11 * see for example asm-sparc/namei.h
12 * we don't use it...
13 */
14
15#define __emul_prefix() NULL
16
17#endif /* __CRIS_NAMEI_H */
diff --git a/include/asm-frv/namei.h b/include/asm-frv/namei.h
deleted file mode 100644
index 4ea57171d951..000000000000
--- a/include/asm-frv/namei.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/*
2 * include/asm-frv/namei.h
3 *
4 * Included from linux/fs/namei.c
5 */
6
7#ifndef __ASM_NAMEI_H
8#define __ASM_NAMEI_H
9
10/* This dummy routine maybe changed to something useful
11 * for /usr/gnemul/ emulation stuff.
12 * Look at asm-sparc/namei.h for details.
13 */
14
15#define __emul_prefix() NULL
16
17#endif
18
diff --git a/include/asm-h8300/namei.h b/include/asm-h8300/namei.h
deleted file mode 100644
index ab6f196db6e0..000000000000
--- a/include/asm-h8300/namei.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/*
2 * linux/include/asm-h8300/namei.h
3 *
4 * Included from linux/fs/namei.c
5 */
6
7#ifndef __H8300_NAMEI_H
8#define __H8300_NAMEI_H
9
10/* This dummy routine maybe changed to something useful
11 * for /usr/gnemul/ emulation stuff.
12 * Look at asm-sparc/namei.h for details.
13 */
14
15#define __emul_prefix() NULL
16
17#endif
diff --git a/include/asm-ia64/namei.h b/include/asm-ia64/namei.h
deleted file mode 100644
index 78e768079083..000000000000
--- a/include/asm-ia64/namei.h
+++ /dev/null
@@ -1,25 +0,0 @@
1#ifndef _ASM_IA64_NAMEI_H
2#define _ASM_IA64_NAMEI_H
3
4/*
5 * Modified 1998, 1999, 2001
6 * David Mosberger-Tang <davidm@hpl.hp.com>, Hewlett-Packard Co
7 */
8
9#include <asm/ptrace.h>
10#include <asm/system.h>
11
12#define EMUL_PREFIX_LINUX_IA32 "/emul/ia32-linux/"
13
14static inline char *
15__emul_prefix (void)
16{
17 switch (current->personality) {
18 case PER_LINUX32:
19 return EMUL_PREFIX_LINUX_IA32;
20 default:
21 return NULL;
22 }
23}
24
25#endif /* _ASM_IA64_NAMEI_H */
diff --git a/include/asm-m32r/namei.h b/include/asm-m32r/namei.h
deleted file mode 100644
index 210f8056b805..000000000000
--- a/include/asm-m32r/namei.h
+++ /dev/null
@@ -1,17 +0,0 @@
1#ifndef _ASM_M32R_NAMEI_H
2#define _ASM_M32R_NAMEI_H
3
4/*
5 * linux/include/asm-m32r/namei.h
6 *
7 * Included from linux/fs/namei.c
8 */
9
10/* This dummy routine maybe changed to something useful
11 * for /usr/gnemul/ emulation stuff.
12 * Look at asm-sparc/namei.h for details.
13 */
14
15#define __emul_prefix() NULL
16
17#endif /* _ASM_M32R_NAMEI_H */
diff --git a/include/asm-m68k/namei.h b/include/asm-m68k/namei.h
deleted file mode 100644
index f33f243b644a..000000000000
--- a/include/asm-m68k/namei.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/*
2 * linux/include/asm-m68k/namei.h
3 *
4 * Included from linux/fs/namei.c
5 */
6
7#ifndef __M68K_NAMEI_H
8#define __M68K_NAMEI_H
9
10/* This dummy routine maybe changed to something useful
11 * for /usr/gnemul/ emulation stuff.
12 * Look at asm-sparc/namei.h for details.
13 */
14
15#define __emul_prefix() NULL
16
17#endif
diff --git a/include/asm-m68knommu/namei.h b/include/asm-m68knommu/namei.h
deleted file mode 100644
index 31a85d27b931..000000000000
--- a/include/asm-m68knommu/namei.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-m68k/namei.h>
diff --git a/include/asm-mips/namei.h b/include/asm-mips/namei.h
deleted file mode 100644
index a6605a752469..000000000000
--- a/include/asm-mips/namei.h
+++ /dev/null
@@ -1,11 +0,0 @@
1#ifndef _ASM_NAMEI_H
2#define _ASM_NAMEI_H
3
4/*
5 * This dummy routine maybe changed to something useful
6 * for /usr/gnemul/ emulation stuff.
7 */
8
9#define __emul_prefix() NULL
10
11#endif /* _ASM_NAMEI_H */
diff --git a/include/asm-mn10300/namei.h b/include/asm-mn10300/namei.h
deleted file mode 100644
index bd9ce94aeb65..000000000000
--- a/include/asm-mn10300/namei.h
+++ /dev/null
@@ -1,22 +0,0 @@
1/* Emulation stuff
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#ifndef _ASM_NAMEI_H
13#define _ASM_NAMEI_H
14
15/* This dummy routine maybe changed to something useful
16 * for /usr/gnemul/ emulation stuff.
17 * Look at asm-sparc/namei.h for details.
18 */
19
20#define __emul_prefix() NULL
21
22#endif /* _ASM_NAMEI_H */
diff --git a/include/asm-parisc/namei.h b/include/asm-parisc/namei.h
deleted file mode 100644
index 8d29b3d9fb33..000000000000
--- a/include/asm-parisc/namei.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/* $Id: namei.h,v 1.1 1996/12/13 14:48:21 jj Exp $
2 * linux/include/asm-parisc/namei.h
3 *
4 * Included from linux/fs/namei.c
5 */
6
7#ifndef __PARISC_NAMEI_H
8#define __PARISC_NAMEI_H
9
10/* This dummy routine maybe changed to something useful
11 * for /usr/gnemul/ emulation stuff.
12 * Look at asm-sparc/namei.h for details.
13 */
14
15#define __emul_prefix() NULL
16
17#endif /* __PARISC_NAMEI_H */
diff --git a/include/asm-powerpc/namei.h b/include/asm-powerpc/namei.h
deleted file mode 100644
index 657443474a6a..000000000000
--- a/include/asm-powerpc/namei.h
+++ /dev/null
@@ -1,20 +0,0 @@
1#ifndef _ASM_POWERPC_NAMEI_H
2#define _ASM_POWERPC_NAMEI_H
3
4#ifdef __KERNEL__
5
6/*
7 * Adapted from include/asm-alpha/namei.h
8 *
9 * Included from fs/namei.c
10 */
11
12/* This dummy routine maybe changed to something useful
13 * for /usr/gnemul/ emulation stuff.
14 * Look at asm-sparc/namei.h for details.
15 */
16
17#define __emul_prefix() NULL
18
19#endif /* __KERNEL__ */
20#endif /* _ASM_POWERPC_NAMEI_H */
diff --git a/include/asm-s390/namei.h b/include/asm-s390/namei.h
deleted file mode 100644
index 3e286bdde4b0..000000000000
--- a/include/asm-s390/namei.h
+++ /dev/null
@@ -1,21 +0,0 @@
1/*
2 * include/asm-s390/namei.h
3 *
4 * S390 version
5 *
6 * Derived from "include/asm-i386/namei.h"
7 *
8 * Included from linux/fs/namei.c
9 */
10
11#ifndef __S390_NAMEI_H
12#define __S390_NAMEI_H
13
14/* This dummy routine maybe changed to something useful
15 * for /usr/gnemul/ emulation stuff.
16 * Look at asm-sparc/namei.h for details.
17 */
18
19#define __emul_prefix() NULL
20
21#endif /* __S390_NAMEI_H */
diff --git a/include/asm-sh/namei.h b/include/asm-sh/namei.h
deleted file mode 100644
index 338a5d947143..000000000000
--- a/include/asm-sh/namei.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/* $Id: namei.h,v 1.3 2000/07/04 06:24:49 gniibe Exp $
2 * linux/include/asm-sh/namei.h
3 *
4 * Included from linux/fs/namei.c
5 */
6
7#ifndef __ASM_SH_NAMEI_H
8#define __ASM_SH_NAMEI_H
9
10/* This dummy routine maybe changed to something useful
11 * for /usr/gnemul/ emulation stuff.
12 * Look at asm-sparc/namei.h for details.
13 */
14
15#define __emul_prefix() NULL
16
17#endif /* __ASM_SH_NAMEI_H */
diff --git a/include/asm-sparc/namei.h b/include/asm-sparc/namei.h
deleted file mode 100644
index eff944b8e321..000000000000
--- a/include/asm-sparc/namei.h
+++ /dev/null
@@ -1,8 +0,0 @@
1#ifndef ___ASM_SPARC_NAMEI_H
2#define ___ASM_SPARC_NAMEI_H
3#if defined(__sparc__) && defined(__arch64__)
4#include <asm-sparc/namei_64.h>
5#else
6#include <asm-sparc/namei_32.h>
7#endif
8#endif
diff --git a/include/asm-sparc/namei_32.h b/include/asm-sparc/namei_32.h
deleted file mode 100644
index 0646102fb020..000000000000
--- a/include/asm-sparc/namei_32.h
+++ /dev/null
@@ -1,13 +0,0 @@
1/*
2 * linux/include/asm-sparc/namei.h
3 *
4 * Routines to handle famous /usr/gnemul/s*.
5 * Included from linux/fs/namei.c
6 */
7
8#ifndef __SPARC_NAMEI_H
9#define __SPARC_NAMEI_H
10
11#define __emul_prefix() NULL
12
13#endif /* __SPARC_NAMEI_H */
diff --git a/include/asm-sparc/namei_64.h b/include/asm-sparc/namei_64.h
deleted file mode 100644
index cbc1b4c06891..000000000000
--- a/include/asm-sparc/namei_64.h
+++ /dev/null
@@ -1,13 +0,0 @@
1/*
2 * linux/include/asm-sparc64/namei.h
3 *
4 * Routines to handle famous /usr/gnemul/s*.
5 * Included from linux/fs/namei.c
6 */
7
8#ifndef __SPARC64_NAMEI_H
9#define __SPARC64_NAMEI_H
10
11#define __emul_prefix() NULL
12
13#endif /* __SPARC64_NAMEI_H */
diff --git a/include/asm-sparc64/namei.h b/include/asm-sparc64/namei.h
deleted file mode 100644
index 1344a910ba2f..000000000000
--- a/include/asm-sparc64/namei.h
+++ /dev/null
@@ -1 +0,0 @@
1#include <asm-sparc/namei.h>
diff --git a/include/asm-um/namei.h b/include/asm-um/namei.h
deleted file mode 100644
index 002984d5bc85..000000000000
--- a/include/asm-um/namei.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef __UM_NAMEI_H
2#define __UM_NAMEI_H
3
4#include "asm/arch/namei.h"
5
6#endif
diff --git a/include/asm-v850/namei.h b/include/asm-v850/namei.h
deleted file mode 100644
index ee8339b23843..000000000000
--- a/include/asm-v850/namei.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/*
2 * linux/include/asm-v850/namei.h
3 *
4 * Included from linux/fs/namei.c
5 */
6
7#ifndef __V850_NAMEI_H__
8#define __V850_NAMEI_H__
9
10/* This dummy routine maybe changed to something useful
11 * for /usr/gnemul/ emulation stuff.
12 * Look at asm-sparc/namei.h for details.
13 */
14
15#define __emul_prefix() NULL
16
17#endif /* __V850_NAMEI_H__ */
diff --git a/include/asm-x86/namei.h b/include/asm-x86/namei.h
deleted file mode 100644
index 415ef5d9550e..000000000000
--- a/include/asm-x86/namei.h
+++ /dev/null
@@ -1,11 +0,0 @@
1#ifndef _ASM_X86_NAMEI_H
2#define _ASM_X86_NAMEI_H
3
4/* This dummy routine maybe changed to something useful
5 * for /usr/gnemul/ emulation stuff.
6 * Look at asm-sparc/namei.h for details.
7 */
8
9#define __emul_prefix() NULL
10
11#endif /* _ASM_X86_NAMEI_H */
diff --git a/include/asm-xtensa/namei.h b/include/asm-xtensa/namei.h
deleted file mode 100644
index 3fdff039d27d..000000000000
--- a/include/asm-xtensa/namei.h
+++ /dev/null
@@ -1,26 +0,0 @@
1/*
2 * include/asm-xtensa/namei.h
3 *
4 * Included from linux/fs/namei.c
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 *
10 * Copyright (C) 2001 - 2005 Tensilica Inc.
11 */
12
13#ifndef _XTENSA_NAMEI_H
14#define _XTENSA_NAMEI_H
15
16#ifdef __KERNEL__
17
18/* This dummy routine maybe changed to something useful
19 * for /usr/gnemul/ emulation stuff.
20 * Look at asm-sparc/namei.h for details.
21 */
22
23#define __emul_prefix() NULL
24
25#endif /* __KERNEL__ */
26#endif /* _XTENSA_NAMEI_H */
diff --git a/include/linux/coda_linux.h b/include/linux/coda_linux.h
index 31b75311e2ca..dcc228aa335a 100644
--- a/include/linux/coda_linux.h
+++ b/include/linux/coda_linux.h
@@ -37,7 +37,7 @@ extern const struct file_operations coda_ioctl_operations;
37/* operations shared over more than one file */ 37/* operations shared over more than one file */
38int coda_open(struct inode *i, struct file *f); 38int coda_open(struct inode *i, struct file *f);
39int coda_release(struct inode *i, struct file *f); 39int coda_release(struct inode *i, struct file *f);
40int coda_permission(struct inode *inode, int mask, struct nameidata *nd); 40int coda_permission(struct inode *inode, int mask);
41int coda_revalidate_inode(struct dentry *); 41int coda_revalidate_inode(struct dentry *);
42int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *); 42int coda_getattr(struct vfsmount *, struct dentry *, struct kstat *);
43int coda_setattr(struct dentry *, struct iattr *); 43int coda_setattr(struct dentry *, struct iattr *);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 53d2edb709b3..8252b045e624 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -60,6 +60,8 @@ extern int dir_notify_enable;
60#define MAY_WRITE 2 60#define MAY_WRITE 2
61#define MAY_READ 4 61#define MAY_READ 4
62#define MAY_APPEND 8 62#define MAY_APPEND 8
63#define MAY_ACCESS 16
64#define MAY_OPEN 32
63 65
64#define FMODE_READ 1 66#define FMODE_READ 1
65#define FMODE_WRITE 2 67#define FMODE_WRITE 2
@@ -277,7 +279,7 @@ extern int dir_notify_enable;
277#include <linux/types.h> 279#include <linux/types.h>
278#include <linux/kdev_t.h> 280#include <linux/kdev_t.h>
279#include <linux/dcache.h> 281#include <linux/dcache.h>
280#include <linux/namei.h> 282#include <linux/path.h>
281#include <linux/stat.h> 283#include <linux/stat.h>
282#include <linux/cache.h> 284#include <linux/cache.h>
283#include <linux/kobject.h> 285#include <linux/kobject.h>
@@ -318,22 +320,23 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
318 * Attribute flags. These should be or-ed together to figure out what 320 * Attribute flags. These should be or-ed together to figure out what
319 * has been changed! 321 * has been changed!
320 */ 322 */
321#define ATTR_MODE 1 323#define ATTR_MODE (1 << 0)
322#define ATTR_UID 2 324#define ATTR_UID (1 << 1)
323#define ATTR_GID 4 325#define ATTR_GID (1 << 2)
324#define ATTR_SIZE 8 326#define ATTR_SIZE (1 << 3)
325#define ATTR_ATIME 16 327#define ATTR_ATIME (1 << 4)
326#define ATTR_MTIME 32 328#define ATTR_MTIME (1 << 5)
327#define ATTR_CTIME 64 329#define ATTR_CTIME (1 << 6)
328#define ATTR_ATIME_SET 128 330#define ATTR_ATIME_SET (1 << 7)
329#define ATTR_MTIME_SET 256 331#define ATTR_MTIME_SET (1 << 8)
330#define ATTR_FORCE 512 /* Not a change, but a change it */ 332#define ATTR_FORCE (1 << 9) /* Not a change, but a change it */
331#define ATTR_ATTR_FLAG 1024 333#define ATTR_ATTR_FLAG (1 << 10)
332#define ATTR_KILL_SUID 2048 334#define ATTR_KILL_SUID (1 << 11)
333#define ATTR_KILL_SGID 4096 335#define ATTR_KILL_SGID (1 << 12)
334#define ATTR_FILE 8192 336#define ATTR_FILE (1 << 13)
335#define ATTR_KILL_PRIV 16384 337#define ATTR_KILL_PRIV (1 << 14)
336#define ATTR_OPEN 32768 /* Truncating from open(O_TRUNC) */ 338#define ATTR_OPEN (1 << 15) /* Truncating from open(O_TRUNC) */
339#define ATTR_TIMES_SET (1 << 16)
337 340
338/* 341/*
339 * This is the Inode Attributes structure, used for notify_change(). It 342 * This is the Inode Attributes structure, used for notify_change(). It
@@ -792,7 +795,7 @@ struct file {
792#define f_dentry f_path.dentry 795#define f_dentry f_path.dentry
793#define f_vfsmnt f_path.mnt 796#define f_vfsmnt f_path.mnt
794 const struct file_operations *f_op; 797 const struct file_operations *f_op;
795 atomic_t f_count; 798 atomic_long_t f_count;
796 unsigned int f_flags; 799 unsigned int f_flags;
797 mode_t f_mode; 800 mode_t f_mode;
798 loff_t f_pos; 801 loff_t f_pos;
@@ -821,8 +824,8 @@ extern spinlock_t files_lock;
821#define file_list_lock() spin_lock(&files_lock); 824#define file_list_lock() spin_lock(&files_lock);
822#define file_list_unlock() spin_unlock(&files_lock); 825#define file_list_unlock() spin_unlock(&files_lock);
823 826
824#define get_file(x) atomic_inc(&(x)->f_count) 827#define get_file(x) atomic_long_inc(&(x)->f_count)
825#define file_count(x) atomic_read(&(x)->f_count) 828#define file_count(x) atomic_long_read(&(x)->f_count)
826 829
827#ifdef CONFIG_DEBUG_WRITECOUNT 830#ifdef CONFIG_DEBUG_WRITECOUNT
828static inline void file_take_write(struct file *f) 831static inline void file_take_write(struct file *f)
@@ -1136,7 +1139,7 @@ extern int vfs_permission(struct nameidata *, int);
1136extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *); 1139extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
1137extern int vfs_mkdir(struct inode *, struct dentry *, int); 1140extern int vfs_mkdir(struct inode *, struct dentry *, int);
1138extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t); 1141extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
1139extern int vfs_symlink(struct inode *, struct dentry *, const char *, int); 1142extern int vfs_symlink(struct inode *, struct dentry *, const char *);
1140extern int vfs_link(struct dentry *, struct inode *, struct dentry *); 1143extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
1141extern int vfs_rmdir(struct inode *, struct dentry *); 1144extern int vfs_rmdir(struct inode *, struct dentry *);
1142extern int vfs_unlink(struct inode *, struct dentry *); 1145extern int vfs_unlink(struct inode *, struct dentry *);
@@ -1272,7 +1275,7 @@ struct inode_operations {
1272 void * (*follow_link) (struct dentry *, struct nameidata *); 1275 void * (*follow_link) (struct dentry *, struct nameidata *);
1273 void (*put_link) (struct dentry *, struct nameidata *, void *); 1276 void (*put_link) (struct dentry *, struct nameidata *, void *);
1274 void (*truncate) (struct inode *); 1277 void (*truncate) (struct inode *);
1275 int (*permission) (struct inode *, int, struct nameidata *); 1278 int (*permission) (struct inode *, int);
1276 int (*setattr) (struct dentry *, struct iattr *); 1279 int (*setattr) (struct dentry *, struct iattr *);
1277 int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *); 1280 int (*getattr) (struct vfsmount *mnt, struct dentry *, struct kstat *);
1278 int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); 1281 int (*setxattr) (struct dentry *, const char *,const void *,size_t,int);
@@ -1696,9 +1699,9 @@ extern void init_special_inode(struct inode *, umode_t, dev_t);
1696extern void make_bad_inode(struct inode *); 1699extern void make_bad_inode(struct inode *);
1697extern int is_bad_inode(struct inode *); 1700extern int is_bad_inode(struct inode *);
1698 1701
1699extern const struct file_operations read_fifo_fops; 1702extern const struct file_operations read_pipefifo_fops;
1700extern const struct file_operations write_fifo_fops; 1703extern const struct file_operations write_pipefifo_fops;
1701extern const struct file_operations rdwr_fifo_fops; 1704extern const struct file_operations rdwr_pipefifo_fops;
1702 1705
1703extern int fs_may_remount_ro(struct super_block *); 1706extern int fs_may_remount_ro(struct super_block *);
1704 1707
@@ -1767,7 +1770,7 @@ extern int do_remount_sb(struct super_block *sb, int flags,
1767extern sector_t bmap(struct inode *, sector_t); 1770extern sector_t bmap(struct inode *, sector_t);
1768#endif 1771#endif
1769extern int notify_change(struct dentry *, struct iattr *); 1772extern int notify_change(struct dentry *, struct iattr *);
1770extern int permission(struct inode *, int, struct nameidata *); 1773extern int inode_permission(struct inode *, int);
1771extern int generic_permission(struct inode *, int, 1774extern int generic_permission(struct inode *, int,
1772 int (*check_acl)(struct inode *, int)); 1775 int (*check_acl)(struct inode *, int));
1773 1776
@@ -1831,7 +1834,7 @@ extern void clear_inode(struct inode *);
1831extern void destroy_inode(struct inode *); 1834extern void destroy_inode(struct inode *);
1832extern struct inode *new_inode(struct super_block *); 1835extern struct inode *new_inode(struct super_block *);
1833extern int should_remove_suid(struct dentry *); 1836extern int should_remove_suid(struct dentry *);
1834extern int remove_suid(struct dentry *); 1837extern int file_remove_suid(struct file *);
1835 1838
1836extern void __insert_inode_hash(struct inode *, unsigned long hashval); 1839extern void __insert_inode_hash(struct inode *, unsigned long hashval);
1837extern void remove_inode_hash(struct inode *); 1840extern void remove_inode_hash(struct inode *);
diff --git a/include/linux/fs_struct.h b/include/linux/fs_struct.h
index 282f54219129..9e5a06e78d02 100644
--- a/include/linux/fs_struct.h
+++ b/include/linux/fs_struct.h
@@ -7,7 +7,7 @@ struct fs_struct {
7 atomic_t count; 7 atomic_t count;
8 rwlock_t lock; 8 rwlock_t lock;
9 int umask; 9 int umask;
10 struct path root, pwd, altroot; 10 struct path root, pwd;
11}; 11};
12 12
13#define INIT_FS { \ 13#define INIT_FS { \
@@ -19,7 +19,6 @@ struct fs_struct {
19extern struct kmem_cache *fs_cachep; 19extern struct kmem_cache *fs_cachep;
20 20
21extern void exit_fs(struct task_struct *); 21extern void exit_fs(struct task_struct *);
22extern void set_fs_altroot(void);
23extern void set_fs_root(struct fs_struct *, struct path *); 22extern void set_fs_root(struct fs_struct *, struct path *);
24extern void set_fs_pwd(struct fs_struct *, struct path *); 23extern void set_fs_pwd(struct fs_struct *, struct path *);
25extern struct fs_struct *copy_fs_struct(struct fs_struct *); 24extern struct fs_struct *copy_fs_struct(struct fs_struct *);
diff --git a/include/linux/mount.h b/include/linux/mount.h
index 4374d1adeb4b..b5efaa2132ab 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -47,7 +47,7 @@ struct vfsmount {
47 struct list_head mnt_child; /* and going through their mnt_child */ 47 struct list_head mnt_child; /* and going through their mnt_child */
48 int mnt_flags; 48 int mnt_flags;
49 /* 4 bytes hole on 64bits arches */ 49 /* 4 bytes hole on 64bits arches */
50 char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ 50 const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */
51 struct list_head mnt_list; 51 struct list_head mnt_list;
52 struct list_head mnt_expire; /* link in fs-specific expiry list */ 52 struct list_head mnt_expire; /* link in fs-specific expiry list */
53 struct list_head mnt_share; /* circular list of shared mounts */ 53 struct list_head mnt_share; /* circular list of shared mounts */
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 24d88e98a626..68f8c3203c89 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -47,27 +47,24 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LAST_DOTDOT, LAST_BIND};
47#define LOOKUP_DIRECTORY 2 47#define LOOKUP_DIRECTORY 2
48#define LOOKUP_CONTINUE 4 48#define LOOKUP_CONTINUE 4
49#define LOOKUP_PARENT 16 49#define LOOKUP_PARENT 16
50#define LOOKUP_NOALT 32
51#define LOOKUP_REVAL 64 50#define LOOKUP_REVAL 64
52/* 51/*
53 * Intent data 52 * Intent data
54 */ 53 */
55#define LOOKUP_OPEN (0x0100) 54#define LOOKUP_OPEN (0x0100)
56#define LOOKUP_CREATE (0x0200) 55#define LOOKUP_CREATE (0x0200)
57#define LOOKUP_ACCESS (0x0400) 56
58#define LOOKUP_CHDIR (0x0800) 57extern int user_path_at(int, const char __user *, unsigned, struct path *);
59 58
60extern int __user_walk(const char __user *, unsigned, struct nameidata *); 59#define user_path(name, path) user_path_at(AT_FDCWD, name, LOOKUP_FOLLOW, path)
61extern int __user_walk_fd(int dfd, const char __user *, unsigned, struct nameidata *); 60#define user_lpath(name, path) user_path_at(AT_FDCWD, name, 0, path)
62#define user_path_walk(name,nd) \ 61#define user_path_dir(name, path) \
63 __user_walk_fd(AT_FDCWD, name, LOOKUP_FOLLOW, nd) 62 user_path_at(AT_FDCWD, name, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, path)
64#define user_path_walk_link(name,nd) \ 63
65 __user_walk_fd(AT_FDCWD, name, 0, nd)
66extern int path_lookup(const char *, unsigned, struct nameidata *); 64extern int path_lookup(const char *, unsigned, struct nameidata *);
67extern int vfs_path_lookup(struct dentry *, struct vfsmount *, 65extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
68 const char *, unsigned int, struct nameidata *); 66 const char *, unsigned int, struct nameidata *);
69 67
70extern int __user_path_lookup_open(const char __user *, unsigned lookup_flags, struct nameidata *nd, int open_flags);
71extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags); 68extern int path_lookup_open(int dfd, const char *name, unsigned lookup_flags, struct nameidata *, int open_flags);
72extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, 69extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry,
73 int (*open)(struct inode *, struct file *)); 70 int (*open)(struct inode *, struct file *));
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 29d261918734..78a5922a2f11 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -42,7 +42,6 @@
42#include <linux/in.h> 42#include <linux/in.h>
43#include <linux/kref.h> 43#include <linux/kref.h>
44#include <linux/mm.h> 44#include <linux/mm.h>
45#include <linux/namei.h>
46#include <linux/pagemap.h> 45#include <linux/pagemap.h>
47#include <linux/rbtree.h> 46#include <linux/rbtree.h>
48#include <linux/rwsem.h> 47#include <linux/rwsem.h>
@@ -332,7 +331,7 @@ extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
332extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr); 331extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
333extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr); 332extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr);
334extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *); 333extern int nfs_getattr(struct vfsmount *, struct dentry *, struct kstat *);
335extern int nfs_permission(struct inode *, int, struct nameidata *); 334extern int nfs_permission(struct inode *, int);
336extern int nfs_open(struct inode *, struct file *); 335extern int nfs_open(struct inode *, struct file *);
337extern int nfs_release(struct inode *, struct file *); 336extern int nfs_release(struct inode *, struct file *);
338extern int nfs_attribute_timeout(struct inode *inode); 337extern int nfs_attribute_timeout(struct inode *inode);
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index f560d1705afe..fb61850d1cfc 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -282,11 +282,16 @@ union proc_op {
282 struct task_struct *task); 282 struct task_struct *task);
283}; 283};
284 284
285struct ctl_table_header;
286struct ctl_table;
287
285struct proc_inode { 288struct proc_inode {
286 struct pid *pid; 289 struct pid *pid;
287 int fd; 290 int fd;
288 union proc_op op; 291 union proc_op op;
289 struct proc_dir_entry *pde; 292 struct proc_dir_entry *pde;
293 struct ctl_table_header *sysctl;
294 struct ctl_table *sysctl_entry;
290 struct inode vfs_inode; 295 struct inode vfs_inode;
291}; 296};
292 297
diff --git a/include/linux/reiserfs_xattr.h b/include/linux/reiserfs_xattr.h
index 66a96814d614..af135ae895db 100644
--- a/include/linux/reiserfs_xattr.h
+++ b/include/linux/reiserfs_xattr.h
@@ -55,7 +55,7 @@ int reiserfs_removexattr(struct dentry *dentry, const char *name);
55int reiserfs_delete_xattrs(struct inode *inode); 55int reiserfs_delete_xattrs(struct inode *inode);
56int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs); 56int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs);
57int reiserfs_xattr_init(struct super_block *sb, int mount_flags); 57int reiserfs_xattr_init(struct super_block *sb, int mount_flags);
58int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd); 58int reiserfs_permission(struct inode *inode, int mask);
59 59
60int reiserfs_xattr_del(struct inode *, const char *); 60int reiserfs_xattr_del(struct inode *, const char *);
61int reiserfs_xattr_get(const struct inode *, const char *, void *, size_t); 61int reiserfs_xattr_get(const struct inode *, const char *, void *, size_t);
diff --git a/include/linux/security.h b/include/linux/security.h
index f0e9adb22ac2..fd96e7f8a6f9 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1362,7 +1362,7 @@ struct security_operations {
1362 struct inode *new_dir, struct dentry *new_dentry); 1362 struct inode *new_dir, struct dentry *new_dentry);
1363 int (*inode_readlink) (struct dentry *dentry); 1363 int (*inode_readlink) (struct dentry *dentry);
1364 int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd); 1364 int (*inode_follow_link) (struct dentry *dentry, struct nameidata *nd);
1365 int (*inode_permission) (struct inode *inode, int mask, struct nameidata *nd); 1365 int (*inode_permission) (struct inode *inode, int mask);
1366 int (*inode_setattr) (struct dentry *dentry, struct iattr *attr); 1366 int (*inode_setattr) (struct dentry *dentry, struct iattr *attr);
1367 int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry); 1367 int (*inode_getattr) (struct vfsmount *mnt, struct dentry *dentry);
1368 void (*inode_delete) (struct inode *inode); 1368 void (*inode_delete) (struct inode *inode);
@@ -1628,7 +1628,7 @@ int security_inode_rename(struct inode *old_dir, struct dentry *old_dentry,
1628 struct inode *new_dir, struct dentry *new_dentry); 1628 struct inode *new_dir, struct dentry *new_dentry);
1629int security_inode_readlink(struct dentry *dentry); 1629int security_inode_readlink(struct dentry *dentry);
1630int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd); 1630int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd);
1631int security_inode_permission(struct inode *inode, int mask, struct nameidata *nd); 1631int security_inode_permission(struct inode *inode, int mask);
1632int security_inode_setattr(struct dentry *dentry, struct iattr *attr); 1632int security_inode_setattr(struct dentry *dentry, struct iattr *attr);
1633int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry); 1633int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry);
1634void security_inode_delete(struct inode *inode); 1634void security_inode_delete(struct inode *inode);
@@ -2021,8 +2021,7 @@ static inline int security_inode_follow_link(struct dentry *dentry,
2021 return 0; 2021 return 0;
2022} 2022}
2023 2023
2024static inline int security_inode_permission(struct inode *inode, int mask, 2024static inline int security_inode_permission(struct inode *inode, int mask)
2025 struct nameidata *nd)
2026{ 2025{
2027 return 0; 2026 return 0;
2028} 2027}
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index f2d12d5a21b8..fd83f2584b15 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -43,7 +43,7 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
43} 43}
44 44
45#ifdef CONFIG_TMPFS_POSIX_ACL 45#ifdef CONFIG_TMPFS_POSIX_ACL
46int shmem_permission(struct inode *, int, struct nameidata *); 46int shmem_permission(struct inode *, int);
47int shmem_acl_init(struct inode *, struct inode *); 47int shmem_acl_init(struct inode *, struct inode *);
48void shmem_acl_destroy_inode(struct inode *); 48void shmem_acl_destroy_inode(struct inode *);
49 49
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 24141b4d1a11..d0437f36921f 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -947,6 +947,22 @@ struct ctl_table;
947struct nsproxy; 947struct nsproxy;
948struct ctl_table_root; 948struct ctl_table_root;
949 949
950struct ctl_table_set {
951 struct list_head list;
952 struct ctl_table_set *parent;
953 int (*is_seen)(struct ctl_table_set *);
954};
955
956extern void setup_sysctl_set(struct ctl_table_set *p,
957 struct ctl_table_set *parent,
958 int (*is_seen)(struct ctl_table_set *));
959
960struct ctl_table_header;
961
962extern void sysctl_head_get(struct ctl_table_header *);
963extern void sysctl_head_put(struct ctl_table_header *);
964extern int sysctl_is_seen(struct ctl_table_header *);
965extern struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *);
950extern struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev); 966extern struct ctl_table_header *sysctl_head_next(struct ctl_table_header *prev);
951extern struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces, 967extern struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
952 struct ctl_table_header *prev); 968 struct ctl_table_header *prev);
@@ -1049,8 +1065,8 @@ struct ctl_table
1049 1065
1050struct ctl_table_root { 1066struct ctl_table_root {
1051 struct list_head root_list; 1067 struct list_head root_list;
1052 struct list_head header_list; 1068 struct ctl_table_set default_set;
1053 struct list_head *(*lookup)(struct ctl_table_root *root, 1069 struct ctl_table_set *(*lookup)(struct ctl_table_root *root,
1054 struct nsproxy *namespaces); 1070 struct nsproxy *namespaces);
1055 int (*permissions)(struct ctl_table_root *root, 1071 int (*permissions)(struct ctl_table_root *root,
1056 struct nsproxy *namespaces, struct ctl_table *table); 1072 struct nsproxy *namespaces, struct ctl_table *table);
@@ -1063,9 +1079,14 @@ struct ctl_table_header
1063 struct ctl_table *ctl_table; 1079 struct ctl_table *ctl_table;
1064 struct list_head ctl_entry; 1080 struct list_head ctl_entry;
1065 int used; 1081 int used;
1082 int count;
1066 struct completion *unregistering; 1083 struct completion *unregistering;
1067 struct ctl_table *ctl_table_arg; 1084 struct ctl_table *ctl_table_arg;
1068 struct ctl_table_root *root; 1085 struct ctl_table_root *root;
1086 struct ctl_table_set *set;
1087 struct ctl_table *attached_by;
1088 struct ctl_table *attached_to;
1089 struct ctl_table_header *parent;
1069}; 1090};
1070 1091
1071/* struct ctl_path describes where in the hierarchy a table is added */ 1092/* struct ctl_path describes where in the hierarchy a table is added */
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index 2dfa96b0575e..7dd29b7e461d 100644
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -51,7 +51,7 @@ struct unix_sock {
51 struct sock *peer; 51 struct sock *peer;
52 struct sock *other; 52 struct sock *other;
53 struct list_head link; 53 struct list_head link;
54 atomic_t inflight; 54 atomic_long_t inflight;
55 spinlock_t lock; 55 spinlock_t lock;
56 unsigned int gc_candidate : 1; 56 unsigned int gc_candidate : 1;
57 wait_queue_head_t peer_wait; 57 wait_queue_head_t peer_wait;
diff --git a/include/net/ip.h b/include/net/ip.h
index b5862b975207..250e6ef025a4 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -188,6 +188,8 @@ extern int sysctl_ip_dynaddr;
188 188
189extern void ipfrag_init(void); 189extern void ipfrag_init(void);
190 190
191extern void ip_static_sysctl_init(void);
192
191#ifdef CONFIG_INET 193#ifdef CONFIG_INET
192#include <net/dst.h> 194#include <net/dst.h>
193 195
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 3855620b78a9..a8eb43cf0c7e 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -38,7 +38,9 @@ struct net {
38 struct proc_dir_entry *proc_net; 38 struct proc_dir_entry *proc_net;
39 struct proc_dir_entry *proc_net_stat; 39 struct proc_dir_entry *proc_net_stat;
40 40
41 struct list_head sysctl_table_headers; 41#ifdef CONFIG_SYSCTL
42 struct ctl_table_set sysctls;
43#endif
42 44
43 struct net_device *loopback_dev; /* The loopback */ 45 struct net_device *loopback_dev; /* The loopback */
44 46
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index 474984f9e032..96fb36cd9874 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -638,7 +638,7 @@ static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
638 return ERR_PTR(-EINVAL); 638 return ERR_PTR(-EINVAL);
639 } 639 }
640 640
641 if (permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE], NULL)) { 641 if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) {
642 dput(dentry); 642 dput(dentry);
643 mntput(mqueue_mnt); 643 mntput(mqueue_mnt);
644 return ERR_PTR(-EACCES); 644 return ERR_PTR(-EACCES);
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 89bd6fb7894f..657f8f8d93a5 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -45,6 +45,7 @@
45#include <linux/delayacct.h> 45#include <linux/delayacct.h>
46#include <linux/cgroupstats.h> 46#include <linux/cgroupstats.h>
47#include <linux/hash.h> 47#include <linux/hash.h>
48#include <linux/namei.h>
48 49
49#include <asm/atomic.h> 50#include <asm/atomic.h>
50 51
diff --git a/kernel/exec_domain.c b/kernel/exec_domain.c
index c1ef192aa655..0d407e886735 100644
--- a/kernel/exec_domain.c
+++ b/kernel/exec_domain.c
@@ -168,7 +168,6 @@ __set_personality(u_long personality)
168 current->personality = personality; 168 current->personality = personality;
169 oep = current_thread_info()->exec_domain; 169 oep = current_thread_info()->exec_domain;
170 current_thread_info()->exec_domain = ep; 170 current_thread_info()->exec_domain = ep;
171 set_fs_altroot();
172 171
173 module_put(oep->module); 172 module_put(oep->module);
174 return 0; 173 return 0;
diff --git a/kernel/exit.c b/kernel/exit.c
index 6cdf60712bd2..0caf590548a0 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -565,8 +565,6 @@ void put_fs_struct(struct fs_struct *fs)
565 if (atomic_dec_and_test(&fs->count)) { 565 if (atomic_dec_and_test(&fs->count)) {
566 path_put(&fs->root); 566 path_put(&fs->root);
567 path_put(&fs->pwd); 567 path_put(&fs->pwd);
568 if (fs->altroot.dentry)
569 path_put(&fs->altroot);
570 kmem_cache_free(fs_cachep, fs); 568 kmem_cache_free(fs_cachep, fs);
571 } 569 }
572} 570}
diff --git a/kernel/fork.c b/kernel/fork.c
index abb3ed6298f6..5e050c1317c4 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -657,13 +657,6 @@ static struct fs_struct *__copy_fs_struct(struct fs_struct *old)
657 path_get(&old->root); 657 path_get(&old->root);
658 fs->pwd = old->pwd; 658 fs->pwd = old->pwd;
659 path_get(&old->pwd); 659 path_get(&old->pwd);
660 if (old->altroot.dentry) {
661 fs->altroot = old->altroot;
662 path_get(&old->altroot);
663 } else {
664 fs->altroot.mnt = NULL;
665 fs->altroot.dentry = NULL;
666 }
667 read_unlock(&old->lock); 660 read_unlock(&old->lock);
668 } 661 }
669 return fs; 662 return fs;
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 35a50db9b6ce..911d846f0503 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -160,12 +160,13 @@ static struct ctl_table root_table[];
160static struct ctl_table_root sysctl_table_root; 160static struct ctl_table_root sysctl_table_root;
161static struct ctl_table_header root_table_header = { 161static struct ctl_table_header root_table_header = {
162 .ctl_table = root_table, 162 .ctl_table = root_table,
163 .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.header_list), 163 .ctl_entry = LIST_HEAD_INIT(sysctl_table_root.default_set.list),
164 .root = &sysctl_table_root, 164 .root = &sysctl_table_root,
165 .set = &sysctl_table_root.default_set,
165}; 166};
166static struct ctl_table_root sysctl_table_root = { 167static struct ctl_table_root sysctl_table_root = {
167 .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list), 168 .root_list = LIST_HEAD_INIT(sysctl_table_root.root_list),
168 .header_list = LIST_HEAD_INIT(root_table_header.ctl_entry), 169 .default_set.list = LIST_HEAD_INIT(root_table_header.ctl_entry),
169}; 170};
170 171
171static struct ctl_table kern_table[]; 172static struct ctl_table kern_table[];
@@ -1386,6 +1387,9 @@ static void start_unregistering(struct ctl_table_header *p)
1386 spin_unlock(&sysctl_lock); 1387 spin_unlock(&sysctl_lock);
1387 wait_for_completion(&wait); 1388 wait_for_completion(&wait);
1388 spin_lock(&sysctl_lock); 1389 spin_lock(&sysctl_lock);
1390 } else {
1391 /* anything non-NULL; we'll never dereference it */
1392 p->unregistering = ERR_PTR(-EINVAL);
1389 } 1393 }
1390 /* 1394 /*
1391 * do not remove from the list until nobody holds it; walking the 1395 * do not remove from the list until nobody holds it; walking the
@@ -1394,6 +1398,32 @@ static void start_unregistering(struct ctl_table_header *p)
1394 list_del_init(&p->ctl_entry); 1398 list_del_init(&p->ctl_entry);
1395} 1399}
1396 1400
1401void sysctl_head_get(struct ctl_table_header *head)
1402{
1403 spin_lock(&sysctl_lock);
1404 head->count++;
1405 spin_unlock(&sysctl_lock);
1406}
1407
1408void sysctl_head_put(struct ctl_table_header *head)
1409{
1410 spin_lock(&sysctl_lock);
1411 if (!--head->count)
1412 kfree(head);
1413 spin_unlock(&sysctl_lock);
1414}
1415
1416struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head)
1417{
1418 if (!head)
1419 BUG();
1420 spin_lock(&sysctl_lock);
1421 if (!use_table(head))
1422 head = ERR_PTR(-ENOENT);
1423 spin_unlock(&sysctl_lock);
1424 return head;
1425}
1426
1397void sysctl_head_finish(struct ctl_table_header *head) 1427void sysctl_head_finish(struct ctl_table_header *head)
1398{ 1428{
1399 if (!head) 1429 if (!head)
@@ -1403,14 +1433,20 @@ void sysctl_head_finish(struct ctl_table_header *head)
1403 spin_unlock(&sysctl_lock); 1433 spin_unlock(&sysctl_lock);
1404} 1434}
1405 1435
1436static struct ctl_table_set *
1437lookup_header_set(struct ctl_table_root *root, struct nsproxy *namespaces)
1438{
1439 struct ctl_table_set *set = &root->default_set;
1440 if (root->lookup)
1441 set = root->lookup(root, namespaces);
1442 return set;
1443}
1444
1406static struct list_head * 1445static struct list_head *
1407lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces) 1446lookup_header_list(struct ctl_table_root *root, struct nsproxy *namespaces)
1408{ 1447{
1409 struct list_head *header_list; 1448 struct ctl_table_set *set = lookup_header_set(root, namespaces);
1410 header_list = &root->header_list; 1449 return &set->list;
1411 if (root->lookup)
1412 header_list = root->lookup(root, namespaces);
1413 return header_list;
1414} 1450}
1415 1451
1416struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces, 1452struct ctl_table_header *__sysctl_head_next(struct nsproxy *namespaces,
@@ -1480,9 +1516,9 @@ static int do_sysctl_strategy(struct ctl_table_root *root,
1480 int op = 0, rc; 1516 int op = 0, rc;
1481 1517
1482 if (oldval) 1518 if (oldval)
1483 op |= 004; 1519 op |= MAY_READ;
1484 if (newval) 1520 if (newval)
1485 op |= 002; 1521 op |= MAY_WRITE;
1486 if (sysctl_perm(root, table, op)) 1522 if (sysctl_perm(root, table, op))
1487 return -EPERM; 1523 return -EPERM;
1488 1524
@@ -1524,7 +1560,7 @@ repeat:
1524 if (n == table->ctl_name) { 1560 if (n == table->ctl_name) {
1525 int error; 1561 int error;
1526 if (table->child) { 1562 if (table->child) {
1527 if (sysctl_perm(root, table, 001)) 1563 if (sysctl_perm(root, table, MAY_EXEC))
1528 return -EPERM; 1564 return -EPERM;
1529 name++; 1565 name++;
1530 nlen--; 1566 nlen--;
@@ -1599,7 +1635,7 @@ static int test_perm(int mode, int op)
1599 mode >>= 6; 1635 mode >>= 6;
1600 else if (in_egroup_p(0)) 1636 else if (in_egroup_p(0))
1601 mode >>= 3; 1637 mode >>= 3;
1602 if ((mode & op & 0007) == op) 1638 if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0)
1603 return 0; 1639 return 0;
1604 return -EACCES; 1640 return -EACCES;
1605} 1641}
@@ -1609,7 +1645,7 @@ int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)
1609 int error; 1645 int error;
1610 int mode; 1646 int mode;
1611 1647
1612 error = security_sysctl(table, op); 1648 error = security_sysctl(table, op & (MAY_READ | MAY_WRITE | MAY_EXEC));
1613 if (error) 1649 if (error)
1614 return error; 1650 return error;
1615 1651
@@ -1644,6 +1680,52 @@ static __init int sysctl_init(void)
1644 1680
1645core_initcall(sysctl_init); 1681core_initcall(sysctl_init);
1646 1682
1683static int is_branch_in(struct ctl_table *branch, struct ctl_table *table)
1684{
1685 struct ctl_table *p;
1686 const char *s = branch->procname;
1687
1688 /* branch should have named subdirectory as its first element */
1689 if (!s || !branch->child)
1690 return 0;
1691
1692 /* ... and nothing else */
1693 if (branch[1].procname || branch[1].ctl_name)
1694 return 0;
1695
1696 /* table should contain subdirectory with the same name */
1697 for (p = table; p->procname || p->ctl_name; p++) {
1698 if (!p->child)
1699 continue;
1700 if (p->procname && strcmp(p->procname, s) == 0)
1701 return 1;
1702 }
1703 return 0;
1704}
1705
1706/* see if attaching q to p would be an improvement */
1707static void try_attach(struct ctl_table_header *p, struct ctl_table_header *q)
1708{
1709 struct ctl_table *to = p->ctl_table, *by = q->ctl_table;
1710 int is_better = 0;
1711 int not_in_parent = !p->attached_by;
1712
1713 while (is_branch_in(by, to)) {
1714 if (by == q->attached_by)
1715 is_better = 1;
1716 if (to == p->attached_by)
1717 not_in_parent = 1;
1718 by = by->child;
1719 to = to->child;
1720 }
1721
1722 if (is_better && not_in_parent) {
1723 q->attached_by = by;
1724 q->attached_to = to;
1725 q->parent = p;
1726 }
1727}
1728
1647/** 1729/**
1648 * __register_sysctl_paths - register a sysctl hierarchy 1730 * __register_sysctl_paths - register a sysctl hierarchy
1649 * @root: List of sysctl headers to register on 1731 * @root: List of sysctl headers to register on
@@ -1720,10 +1802,10 @@ struct ctl_table_header *__register_sysctl_paths(
1720 struct nsproxy *namespaces, 1802 struct nsproxy *namespaces,
1721 const struct ctl_path *path, struct ctl_table *table) 1803 const struct ctl_path *path, struct ctl_table *table)
1722{ 1804{
1723 struct list_head *header_list;
1724 struct ctl_table_header *header; 1805 struct ctl_table_header *header;
1725 struct ctl_table *new, **prevp; 1806 struct ctl_table *new, **prevp;
1726 unsigned int n, npath; 1807 unsigned int n, npath;
1808 struct ctl_table_set *set;
1727 1809
1728 /* Count the path components */ 1810 /* Count the path components */
1729 for (npath = 0; path[npath].ctl_name || path[npath].procname; ++npath) 1811 for (npath = 0; path[npath].ctl_name || path[npath].procname; ++npath)
@@ -1765,6 +1847,7 @@ struct ctl_table_header *__register_sysctl_paths(
1765 header->unregistering = NULL; 1847 header->unregistering = NULL;
1766 header->root = root; 1848 header->root = root;
1767 sysctl_set_parent(NULL, header->ctl_table); 1849 sysctl_set_parent(NULL, header->ctl_table);
1850 header->count = 1;
1768#ifdef CONFIG_SYSCTL_SYSCALL_CHECK 1851#ifdef CONFIG_SYSCTL_SYSCALL_CHECK
1769 if (sysctl_check_table(namespaces, header->ctl_table)) { 1852 if (sysctl_check_table(namespaces, header->ctl_table)) {
1770 kfree(header); 1853 kfree(header);
@@ -1772,8 +1855,20 @@ struct ctl_table_header *__register_sysctl_paths(
1772 } 1855 }
1773#endif 1856#endif
1774 spin_lock(&sysctl_lock); 1857 spin_lock(&sysctl_lock);
1775 header_list = lookup_header_list(root, namespaces); 1858 header->set = lookup_header_set(root, namespaces);
1776 list_add_tail(&header->ctl_entry, header_list); 1859 header->attached_by = header->ctl_table;
1860 header->attached_to = root_table;
1861 header->parent = &root_table_header;
1862 for (set = header->set; set; set = set->parent) {
1863 struct ctl_table_header *p;
1864 list_for_each_entry(p, &set->list, ctl_entry) {
1865 if (p->unregistering)
1866 continue;
1867 try_attach(p, header);
1868 }
1869 }
1870 header->parent->count++;
1871 list_add_tail(&header->ctl_entry, &header->set->list);
1777 spin_unlock(&sysctl_lock); 1872 spin_unlock(&sysctl_lock);
1778 1873
1779 return header; 1874 return header;
@@ -1828,8 +1923,37 @@ void unregister_sysctl_table(struct ctl_table_header * header)
1828 1923
1829 spin_lock(&sysctl_lock); 1924 spin_lock(&sysctl_lock);
1830 start_unregistering(header); 1925 start_unregistering(header);
1926 if (!--header->parent->count) {
1927 WARN_ON(1);
1928 kfree(header->parent);
1929 }
1930 if (!--header->count)
1931 kfree(header);
1831 spin_unlock(&sysctl_lock); 1932 spin_unlock(&sysctl_lock);
1832 kfree(header); 1933}
1934
1935int sysctl_is_seen(struct ctl_table_header *p)
1936{
1937 struct ctl_table_set *set = p->set;
1938 int res;
1939 spin_lock(&sysctl_lock);
1940 if (p->unregistering)
1941 res = 0;
1942 else if (!set->is_seen)
1943 res = 1;
1944 else
1945 res = set->is_seen(set);
1946 spin_unlock(&sysctl_lock);
1947 return res;
1948}
1949
1950void setup_sysctl_set(struct ctl_table_set *p,
1951 struct ctl_table_set *parent,
1952 int (*is_seen)(struct ctl_table_set *))
1953{
1954 INIT_LIST_HEAD(&p->list);
1955 p->parent = parent ? parent : &sysctl_table_root.default_set;
1956 p->is_seen = is_seen;
1833} 1957}
1834 1958
1835#else /* !CONFIG_SYSCTL */ 1959#else /* !CONFIG_SYSCTL */
@@ -1848,6 +1972,16 @@ void unregister_sysctl_table(struct ctl_table_header * table)
1848{ 1972{
1849} 1973}
1850 1974
1975void setup_sysctl_set(struct ctl_table_set *p,
1976 struct ctl_table_set *parent,
1977 int (*is_seen)(struct ctl_table_set *))
1978{
1979}
1980
1981void sysctl_head_put(struct ctl_table_header *head)
1982{
1983}
1984
1851#endif /* CONFIG_SYSCTL */ 1985#endif /* CONFIG_SYSCTL */
1852 1986
1853/* 1987/*
diff --git a/mm/filemap.c b/mm/filemap.c
index 2ed8b0389c51..5de7633e1dbe 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1758,8 +1758,9 @@ static int __remove_suid(struct dentry *dentry, int kill)
1758 return notify_change(dentry, &newattrs); 1758 return notify_change(dentry, &newattrs);
1759} 1759}
1760 1760
1761int remove_suid(struct dentry *dentry) 1761int file_remove_suid(struct file *file)
1762{ 1762{
1763 struct dentry *dentry = file->f_path.dentry;
1763 int killsuid = should_remove_suid(dentry); 1764 int killsuid = should_remove_suid(dentry);
1764 int killpriv = security_inode_need_killpriv(dentry); 1765 int killpriv = security_inode_need_killpriv(dentry);
1765 int error = 0; 1766 int error = 0;
@@ -1773,7 +1774,7 @@ int remove_suid(struct dentry *dentry)
1773 1774
1774 return error; 1775 return error;
1775} 1776}
1776EXPORT_SYMBOL(remove_suid); 1777EXPORT_SYMBOL(file_remove_suid);
1777 1778
1778static size_t __iovec_copy_from_user_inatomic(char *vaddr, 1779static size_t __iovec_copy_from_user_inatomic(char *vaddr,
1779 const struct iovec *iov, size_t base, size_t bytes) 1780 const struct iovec *iov, size_t base, size_t bytes)
@@ -2529,7 +2530,7 @@ __generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
2529 if (count == 0) 2530 if (count == 0)
2530 goto out; 2531 goto out;
2531 2532
2532 err = remove_suid(file->f_path.dentry); 2533 err = file_remove_suid(file);
2533 if (err) 2534 if (err)
2534 goto out; 2535 goto out;
2535 2536
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index 3e744abcce9d..98a3f31ccd6a 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -380,7 +380,7 @@ xip_file_write(struct file *filp, const char __user *buf, size_t len,
380 if (count == 0) 380 if (count == 0)
381 goto out_backing; 381 goto out_backing;
382 382
383 ret = remove_suid(filp->f_path.dentry); 383 ret = file_remove_suid(filp);
384 if (ret) 384 if (ret)
385 goto out_backing; 385 goto out_backing;
386 386
diff --git a/mm/shmem_acl.c b/mm/shmem_acl.c
index f5664c5b9eb1..8e5aadd7dcd6 100644
--- a/mm/shmem_acl.c
+++ b/mm/shmem_acl.c
@@ -191,7 +191,7 @@ shmem_check_acl(struct inode *inode, int mask)
191 * shmem_permission - permission() inode operation 191 * shmem_permission - permission() inode operation
192 */ 192 */
193int 193int
194shmem_permission(struct inode *inode, int mask, struct nameidata *nd) 194shmem_permission(struct inode *inode, int mask)
195{ 195{
196 return generic_permission(inode, mask, shmem_check_acl); 196 return generic_permission(inode, mask, shmem_check_acl);
197} 197}
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index d9f15ddac316..8a3ac1fa71a9 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1439,6 +1439,10 @@ static int __init inet_init(void)
1439 1439
1440 (void)sock_register(&inet_family_ops); 1440 (void)sock_register(&inet_family_ops);
1441 1441
1442#ifdef CONFIG_SYSCTL
1443 ip_static_sysctl_init();
1444#endif
1445
1442 /* 1446 /*
1443 * Add all the base protocols. 1447 * Add all the base protocols.
1444 */ 1448 */
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index 14ef202a2254..d63e9388d92d 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -882,4 +882,11 @@ static __init int sysctl_ipv4_init(void)
882 return 0; 882 return 0;
883} 883}
884 884
885/* set enough of tree skeleton to get rid of ordering problems */
886void __init ip_static_sysctl_init(void)
887{
888 static ctl_table table[1];
889 register_sysctl_paths(net_ipv4_ctl_path, table);
890}
891
885__initcall(sysctl_ipv4_init); 892__initcall(sysctl_ipv4_init);
diff --git a/net/sched/sch_atm.c b/net/sched/sch_atm.c
index 04faa835be17..6b517b9dac5b 100644
--- a/net/sched/sch_atm.c
+++ b/net/sched/sch_atm.c
@@ -162,7 +162,7 @@ static void atm_tc_put(struct Qdisc *sch, unsigned long cl)
162 qdisc_destroy(flow->q); 162 qdisc_destroy(flow->q);
163 tcf_destroy_chain(&flow->filter_list); 163 tcf_destroy_chain(&flow->filter_list);
164 if (flow->sock) { 164 if (flow->sock) {
165 pr_debug("atm_tc_put: f_count %d\n", 165 pr_debug("atm_tc_put: f_count %ld\n",
166 file_count(flow->sock->file)); 166 file_count(flow->sock->file));
167 flow->vcc->pop = flow->old_pop; 167 flow->vcc->pop = flow->old_pop;
168 sockfd_put(flow->sock); 168 sockfd_put(flow->sock);
@@ -259,7 +259,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
259 sock = sockfd_lookup(fd, &error); 259 sock = sockfd_lookup(fd, &error);
260 if (!sock) 260 if (!sock)
261 return error; /* f_count++ */ 261 return error; /* f_count++ */
262 pr_debug("atm_tc_change: f_count %d\n", file_count(sock->file)); 262 pr_debug("atm_tc_change: f_count %ld\n", file_count(sock->file));
263 if (sock->ops->family != PF_ATMSVC && sock->ops->family != PF_ATMPVC) { 263 if (sock->ops->family != PF_ATMSVC && sock->ops->family != PF_ATMPVC) {
264 error = -EPROTOTYPE; 264 error = -EPROTOTYPE;
265 goto err_out; 265 goto err_out;
diff --git a/net/sysctl_net.c b/net/sysctl_net.c
index 63ada437fc2f..cefbc367d8be 100644
--- a/net/sysctl_net.c
+++ b/net/sysctl_net.c
@@ -29,10 +29,15 @@
29#include <linux/if_tr.h> 29#include <linux/if_tr.h>
30#endif 30#endif
31 31
32static struct list_head * 32static struct ctl_table_set *
33net_ctl_header_lookup(struct ctl_table_root *root, struct nsproxy *namespaces) 33net_ctl_header_lookup(struct ctl_table_root *root, struct nsproxy *namespaces)
34{ 34{
35 return &namespaces->net_ns->sysctl_table_headers; 35 return &namespaces->net_ns->sysctls;
36}
37
38static int is_seen(struct ctl_table_set *set)
39{
40 return &current->nsproxy->net_ns->sysctls == set;
36} 41}
37 42
38/* Return standard mode bits for table entry. */ 43/* Return standard mode bits for table entry. */
@@ -53,13 +58,6 @@ static struct ctl_table_root net_sysctl_root = {
53 .permissions = net_ctl_permissions, 58 .permissions = net_ctl_permissions,
54}; 59};
55 60
56static LIST_HEAD(net_sysctl_ro_tables);
57static struct list_head *net_ctl_ro_header_lookup(struct ctl_table_root *root,
58 struct nsproxy *namespaces)
59{
60 return &net_sysctl_ro_tables;
61}
62
63static int net_ctl_ro_header_perms(struct ctl_table_root *root, 61static int net_ctl_ro_header_perms(struct ctl_table_root *root,
64 struct nsproxy *namespaces, struct ctl_table *table) 62 struct nsproxy *namespaces, struct ctl_table *table)
65{ 63{
@@ -70,19 +68,18 @@ static int net_ctl_ro_header_perms(struct ctl_table_root *root,
70} 68}
71 69
72static struct ctl_table_root net_sysctl_ro_root = { 70static struct ctl_table_root net_sysctl_ro_root = {
73 .lookup = net_ctl_ro_header_lookup,
74 .permissions = net_ctl_ro_header_perms, 71 .permissions = net_ctl_ro_header_perms,
75}; 72};
76 73
77static int sysctl_net_init(struct net *net) 74static int sysctl_net_init(struct net *net)
78{ 75{
79 INIT_LIST_HEAD(&net->sysctl_table_headers); 76 setup_sysctl_set(&net->sysctls, NULL, is_seen);
80 return 0; 77 return 0;
81} 78}
82 79
83static void sysctl_net_exit(struct net *net) 80static void sysctl_net_exit(struct net *net)
84{ 81{
85 WARN_ON(!list_empty(&net->sysctl_table_headers)); 82 WARN_ON(!list_empty(&net->sysctls.list));
86 return; 83 return;
87} 84}
88 85
@@ -98,6 +95,7 @@ static __init int sysctl_init(void)
98 if (ret) 95 if (ret)
99 goto out; 96 goto out;
100 register_sysctl_root(&net_sysctl_root); 97 register_sysctl_root(&net_sysctl_root);
98 setup_sysctl_set(&net_sysctl_ro_root.default_set, NULL, NULL);
101 register_sysctl_root(&net_sysctl_ro_root); 99 register_sysctl_root(&net_sysctl_ro_root);
102out: 100out:
103 return ret; 101 return ret;
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 24eb214581d5..015606b54d9b 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -603,7 +603,7 @@ static struct sock * unix_create1(struct net *net, struct socket *sock)
603 u->dentry = NULL; 603 u->dentry = NULL;
604 u->mnt = NULL; 604 u->mnt = NULL;
605 spin_lock_init(&u->lock); 605 spin_lock_init(&u->lock);
606 atomic_set(&u->inflight, 0); 606 atomic_long_set(&u->inflight, 0);
607 INIT_LIST_HEAD(&u->link); 607 INIT_LIST_HEAD(&u->link);
608 mutex_init(&u->readlock); /* single task reading lock */ 608 mutex_init(&u->readlock); /* single task reading lock */
609 init_waitqueue_head(&u->peer_wait); 609 init_waitqueue_head(&u->peer_wait);
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index ebdff3d877a1..2a27b84f740b 100644
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -127,7 +127,7 @@ void unix_inflight(struct file *fp)
127 if(s) { 127 if(s) {
128 struct unix_sock *u = unix_sk(s); 128 struct unix_sock *u = unix_sk(s);
129 spin_lock(&unix_gc_lock); 129 spin_lock(&unix_gc_lock);
130 if (atomic_inc_return(&u->inflight) == 1) { 130 if (atomic_long_inc_return(&u->inflight) == 1) {
131 BUG_ON(!list_empty(&u->link)); 131 BUG_ON(!list_empty(&u->link));
132 list_add_tail(&u->link, &gc_inflight_list); 132 list_add_tail(&u->link, &gc_inflight_list);
133 } else { 133 } else {
@@ -145,7 +145,7 @@ void unix_notinflight(struct file *fp)
145 struct unix_sock *u = unix_sk(s); 145 struct unix_sock *u = unix_sk(s);
146 spin_lock(&unix_gc_lock); 146 spin_lock(&unix_gc_lock);
147 BUG_ON(list_empty(&u->link)); 147 BUG_ON(list_empty(&u->link));
148 if (atomic_dec_and_test(&u->inflight)) 148 if (atomic_long_dec_and_test(&u->inflight))
149 list_del_init(&u->link); 149 list_del_init(&u->link);
150 unix_tot_inflight--; 150 unix_tot_inflight--;
151 spin_unlock(&unix_gc_lock); 151 spin_unlock(&unix_gc_lock);
@@ -237,17 +237,17 @@ static void scan_children(struct sock *x, void (*func)(struct unix_sock *),
237 237
238static void dec_inflight(struct unix_sock *usk) 238static void dec_inflight(struct unix_sock *usk)
239{ 239{
240 atomic_dec(&usk->inflight); 240 atomic_long_dec(&usk->inflight);
241} 241}
242 242
243static void inc_inflight(struct unix_sock *usk) 243static void inc_inflight(struct unix_sock *usk)
244{ 244{
245 atomic_inc(&usk->inflight); 245 atomic_long_inc(&usk->inflight);
246} 246}
247 247
248static void inc_inflight_move_tail(struct unix_sock *u) 248static void inc_inflight_move_tail(struct unix_sock *u)
249{ 249{
250 atomic_inc(&u->inflight); 250 atomic_long_inc(&u->inflight);
251 /* 251 /*
252 * If this is still a candidate, move it to the end of the 252 * If this is still a candidate, move it to the end of the
253 * list, so that it's checked even if it was already passed 253 * list, so that it's checked even if it was already passed
@@ -288,11 +288,11 @@ void unix_gc(void)
288 * before the detach without atomicity guarantees. 288 * before the detach without atomicity guarantees.
289 */ 289 */
290 list_for_each_entry_safe(u, next, &gc_inflight_list, link) { 290 list_for_each_entry_safe(u, next, &gc_inflight_list, link) {
291 int total_refs; 291 long total_refs;
292 int inflight_refs; 292 long inflight_refs;
293 293
294 total_refs = file_count(u->sk.sk_socket->file); 294 total_refs = file_count(u->sk.sk_socket->file);
295 inflight_refs = atomic_read(&u->inflight); 295 inflight_refs = atomic_long_read(&u->inflight);
296 296
297 BUG_ON(inflight_refs < 1); 297 BUG_ON(inflight_refs < 1);
298 BUG_ON(total_refs < inflight_refs); 298 BUG_ON(total_refs < inflight_refs);
@@ -324,7 +324,7 @@ void unix_gc(void)
324 /* Move cursor to after the current position. */ 324 /* Move cursor to after the current position. */
325 list_move(&cursor, &u->link); 325 list_move(&cursor, &u->link);
326 326
327 if (atomic_read(&u->inflight) > 0) { 327 if (atomic_long_read(&u->inflight) > 0) {
328 list_move_tail(&u->link, &gc_inflight_list); 328 list_move_tail(&u->link, &gc_inflight_list);
329 u->gc_candidate = 0; 329 u->gc_candidate = 0;
330 scan_children(&u->sk, inc_inflight_move_tail, NULL); 330 scan_children(&u->sk, inc_inflight_move_tail, NULL);
diff --git a/security/capability.c b/security/capability.c
index 5b01c0b02422..63d10da515a5 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -211,8 +211,7 @@ static int cap_inode_follow_link(struct dentry *dentry,
211 return 0; 211 return 0;
212} 212}
213 213
214static int cap_inode_permission(struct inode *inode, int mask, 214static int cap_inode_permission(struct inode *inode, int mask)
215 struct nameidata *nd)
216{ 215{
217 return 0; 216 return 0;
218} 217}
diff --git a/security/security.c b/security/security.c
index 59f23b5918b3..ff7068727757 100644
--- a/security/security.c
+++ b/security/security.c
@@ -429,11 +429,11 @@ int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd)
429 return security_ops->inode_follow_link(dentry, nd); 429 return security_ops->inode_follow_link(dentry, nd);
430} 430}
431 431
432int security_inode_permission(struct inode *inode, int mask, struct nameidata *nd) 432int security_inode_permission(struct inode *inode, int mask)
433{ 433{
434 if (unlikely(IS_PRIVATE(inode))) 434 if (unlikely(IS_PRIVATE(inode)))
435 return 0; 435 return 0;
436 return security_ops->inode_permission(inode, mask, nd); 436 return security_ops->inode_permission(inode, mask);
437} 437}
438 438
439int security_inode_setattr(struct dentry *dentry, struct iattr *attr) 439int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
@@ -442,6 +442,7 @@ int security_inode_setattr(struct dentry *dentry, struct iattr *attr)
442 return 0; 442 return 0;
443 return security_ops->inode_setattr(dentry, attr); 443 return security_ops->inode_setattr(dentry, attr);
444} 444}
445EXPORT_SYMBOL_GPL(security_inode_setattr);
445 446
446int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry) 447int security_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
447{ 448{
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index da36dac6535f..40d06c533f89 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2624,12 +2624,11 @@ static int selinux_inode_follow_link(struct dentry *dentry, struct nameidata *na
2624 return dentry_has_perm(current, NULL, dentry, FILE__READ); 2624 return dentry_has_perm(current, NULL, dentry, FILE__READ);
2625} 2625}
2626 2626
2627static int selinux_inode_permission(struct inode *inode, int mask, 2627static int selinux_inode_permission(struct inode *inode, int mask)
2628 struct nameidata *nd)
2629{ 2628{
2630 int rc; 2629 int rc;
2631 2630
2632 rc = secondary_ops->inode_permission(inode, mask, nd); 2631 rc = secondary_ops->inode_permission(inode, mask);
2633 if (rc) 2632 if (rc)
2634 return rc; 2633 return rc;
2635 2634
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index ee5a51cbc5eb..1b40e558f983 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -522,8 +522,7 @@ static int smack_inode_rename(struct inode *old_inode,
522 * 522 *
523 * Returns 0 if access is permitted, -EACCES otherwise 523 * Returns 0 if access is permitted, -EACCES otherwise
524 */ 524 */
525static int smack_inode_permission(struct inode *inode, int mask, 525static int smack_inode_permission(struct inode *inode, int mask)
526 struct nameidata *nd)
527{ 526{
528 /* 527 /*
529 * No permission to check. Existence test. Yup, it's there. 528 * No permission to check. Existence test. Yup, it's there.