[PATCH] r/o bind mounts: prepare for write access checks: collapse if()
authorDave Hansen <haveblue@us.ibm.com>
Sun, 1 Oct 2006 06:29:01 +0000 (23:29 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sun, 1 Oct 2006 07:39:30 +0000 (00:39 -0700)
We're shortly going to be adding a bunch more permission checks in these
functions.  That requires adding either a bunch of new if() conditions, or
some gotos.  This patch collapses existing if()s and uses gotos instead to
prepare for the upcoming changes.

Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
Acked-by: Christoph Hellwig <hch@lst.de>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/namei.c
fs/open.c

index 2892e68d3a8647981e5aa7caf3c53e708584d4bf..7bdceedd254cc9f7fe2530cf940edac6e8e3de35 100644 (file)
@@ -1934,30 +1934,32 @@ asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode)
 {
        int error = 0;
        char * tmp;
+       struct dentry *dentry;
+       struct nameidata nd;
 
        tmp = getname(pathname);
        error = PTR_ERR(tmp);
-       if (!IS_ERR(tmp)) {
-               struct dentry *dentry;
-               struct nameidata nd;
+       if (IS_ERR(tmp))
+               goto out_err;
 
-               error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd);
-               if (error)
-                       goto out;
-               dentry = lookup_create(&nd, 1);
-               error = PTR_ERR(dentry);
-               if (!IS_ERR(dentry)) {
-                       if (!IS_POSIXACL(nd.dentry->d_inode))
-                               mode &= ~current->fs->umask;
-                       error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
-                       dput(dentry);
-               }
-               mutex_unlock(&nd.dentry->d_inode->i_mutex);
-               path_release(&nd);
-out:
-               putname(tmp);
-       }
+       error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd);
+       if (error)
+               goto out;
+       dentry = lookup_create(&nd, 1);
+       error = PTR_ERR(dentry);
+       if (IS_ERR(dentry))
+               goto out_unlock;
 
+       if (!IS_POSIXACL(nd.dentry->d_inode))
+               mode &= ~current->fs->umask;
+       error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
+       dput(dentry);
+out_unlock:
+       mutex_unlock(&nd.dentry->d_inode->i_mutex);
+       path_release(&nd);
+out:
+       putname(tmp);
+out_err:
        return error;
 }
 
@@ -2056,10 +2058,11 @@ static long do_rmdir(int dfd, const char __user *pathname)
        mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
        dentry = lookup_hash(&nd);
        error = PTR_ERR(dentry);
-       if (!IS_ERR(dentry)) {
-               error = vfs_rmdir(nd.dentry->d_inode, dentry);
-               dput(dentry);
-       }
+       if (IS_ERR(dentry))
+               goto exit2;
+       error = vfs_rmdir(nd.dentry->d_inode, dentry);
+       dput(dentry);
+exit2:
        mutex_unlock(&nd.dentry->d_inode->i_mutex);
 exit1:
        path_release(&nd);
@@ -2199,30 +2202,33 @@ asmlinkage long sys_symlinkat(const char __user *oldname,
        int error = 0;
        char * from;
        char * to;
+       struct dentry *dentry;
+       struct nameidata nd;
 
        from = getname(oldname);
        if(IS_ERR(from))
                return PTR_ERR(from);
        to = getname(newname);
        error = PTR_ERR(to);
-       if (!IS_ERR(to)) {
-               struct dentry *dentry;
-               struct nameidata nd;
+       if (IS_ERR(to))
+               goto out_putname;
 
-               error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd);
-               if (error)
-                       goto out;
-               dentry = lookup_create(&nd, 0);
-               error = PTR_ERR(dentry);
-               if (!IS_ERR(dentry)) {
-                       error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
-                       dput(dentry);
-               }
-               mutex_unlock(&nd.dentry->d_inode->i_mutex);
-               path_release(&nd);
+       error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd);
+       if (error)
+               goto out;
+       dentry = lookup_create(&nd, 0);
+       error = PTR_ERR(dentry);
+       if (IS_ERR(dentry))
+               goto out_unlock;
+
+       error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
+       dput(dentry);
+out_unlock:
+       mutex_unlock(&nd.dentry->d_inode->i_mutex);
+       path_release(&nd);
 out:
-               putname(to);
-       }
+       putname(to);
+out_putname:
        putname(from);
        return error;
 }
@@ -2308,10 +2314,11 @@ asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
                goto out_release;
        new_dentry = lookup_create(&nd, 0);
        error = PTR_ERR(new_dentry);
-       if (!IS_ERR(new_dentry)) {
-               error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
-               dput(new_dentry);
-       }
+       if (IS_ERR(new_dentry))
+               goto out_unlock;
+       error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
+       dput(new_dentry);
+out_unlock:
        mutex_unlock(&nd.dentry->d_inode->i_mutex);
 out_release:
        path_release(&nd);
index 35c3e454458ea4e434db071fcd380eda574ce919..89e0c237a636987d5b131e5816e8d9d9f238f210 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -386,15 +386,21 @@ asmlinkage long sys_faccessat(int dfd, const char __user *filename, int mode)
                current->cap_effective = current->cap_permitted;
 
        res = __user_walk_fd(dfd, filename, LOOKUP_FOLLOW|LOOKUP_ACCESS, &nd);
-       if (!res) {
-               res = vfs_permission(&nd, mode);
-               /* SuS v2 requires we report a read only fs too */
-               if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode)
-                  && !special_file(nd.dentry->d_inode->i_mode))
-                       res = -EROFS;
-               path_release(&nd);
-       }
+       if (res)
+               goto out;
+
+       res = vfs_permission(&nd, mode);
+       /* SuS v2 requires we report a read only fs too */
+       if(res || !(mode & S_IWOTH) ||
+          special_file(nd.dentry->d_inode->i_mode))
+               goto out_path_release;
+
+       if(IS_RDONLY(nd.dentry->d_inode))
+               res = -EROFS;
 
+out_path_release:
+       path_release(&nd);
+out:
        current->fsuid = old_fsuid;
        current->fsgid = old_fsgid;
        current->cap_effective = old_cap;
@@ -603,10 +609,11 @@ asmlinkage long sys_chown(const char __user * filename, uid_t user, gid_t group)
        int error;
 
        error = user_path_walk(filename, &nd);
-       if (!error) {
-               error = chown_common(nd.dentry, user, group);
-               path_release(&nd);
-       }
+       if (error)
+               goto out;
+       error = chown_common(nd.dentry, user, group);
+       path_release(&nd);
+out:
        return error;
 }
 
@@ -622,10 +629,10 @@ asmlinkage long sys_fchownat(int dfd, const char __user *filename, uid_t user,
 
        follow = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
        error = __user_walk_fd(dfd, filename, follow, &nd);
-       if (!error) {
-               error = chown_common(nd.dentry, user, group);
-               path_release(&nd);
-       }
+       if (error)
+               goto out;
+       error = chown_common(nd.dentry, user, group);
+       path_release(&nd);
 out:
        return error;
 }
@@ -636,10 +643,11 @@ asmlinkage long sys_lchown(const char __user * filename, uid_t user, gid_t group
        int error;
 
        error = user_path_walk_link(filename, &nd);
-       if (!error) {
-               error = chown_common(nd.dentry, user, group);
-               path_release(&nd);
-       }
+       if (error)
+               goto out;
+       error = chown_common(nd.dentry, user, group);
+       path_release(&nd);
+out:
        return error;
 }
 
@@ -648,15 +656,17 @@ asmlinkage long sys_fchown(unsigned int fd, uid_t user, gid_t group)
 {
        struct file * file;
        int error = -EBADF;
+       struct dentry * dentry;
 
        file = fget(fd);
-       if (file) {
-               struct dentry * dentry;
-               dentry = file->f_dentry;
-               audit_inode(NULL, dentry->d_inode);
-               error = chown_common(dentry, user, group);
-               fput(file);
-       }
+       if (!file)
+               goto out;
+
+       dentry = file->f_dentry;
+       audit_inode(NULL, dentry->d_inode);
+       error = chown_common(dentry, user, group);
+       fput(file);
+out:
        return error;
 }