fold __open_namei_create() and open_will_truncate() into do_last()
authorAl Viro <viro@zeniv.linux.org.uk>
Wed, 9 Mar 2011 05:59:59 +0000 (00:59 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 14 Mar 2011 13:15:27 +0000 (09:15 -0400)
... and clean up a bit more

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/namei.c

index 6384477..441f110 100644 (file)
@@ -2048,30 +2048,6 @@ static int handle_truncate(struct file *filp)
        return error;
 }
 
-/*
- * Be careful about ever adding any more callers of this
- * function.  Its flags must be in the namei format, not
- * what get passed to sys_open().
- */
-static int __open_namei_create(struct nameidata *nd, struct path *path,
-                               int open_flag, int mode)
-{
-       int error;
-       struct dentry *dir = nd->path.dentry;
-
-       if (!IS_POSIXACL(dir->d_inode))
-               mode &= ~current_umask();
-       error = security_path_mknod(&nd->path, path->dentry, mode, 0);
-       if (error)
-               goto out_unlock;
-       error = vfs_create(dir->d_inode, path->dentry, mode, nd);
-out_unlock:
-       mutex_unlock(&dir->d_inode->i_mutex);
-       dput(nd->path.dentry);
-       nd->path.dentry = path->dentry;
-       return error;
-}
-
 /*
  * Note that while the flag value (low two bits) for sys_open means:
  *     00 - read-only
@@ -2096,17 +2072,6 @@ static inline int open_to_namei_flags(int flag)
        return flag;
 }
 
-static int open_will_truncate(int flag, struct inode *inode)
-{
-       /*
-        * We'll never write to the fs underlying
-        * a device file.
-        */
-       if (special_file(inode->i_mode))
-               return 0;
-       return (flag & O_TRUNC);
-}
-
 /*
  * Handle the last step of open()
  */
@@ -2114,8 +2079,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
                            const struct open_flags *op, const char *pathname)
 {
        struct dentry *dir = nd->path.dentry;
+       struct dentry *dentry;
        int open_flag = op->open_flag;
-       int will_truncate;
+       int will_truncate = open_flag & O_TRUNC;
        int want_write = 0;
        int skip_perm = 0;
        struct file *filp;
@@ -2207,25 +2173,29 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
 
        mutex_lock(&dir->d_inode->i_mutex);
 
-       path->dentry = lookup_hash(nd);
-       path->mnt = nd->path.mnt;
-
-       error = PTR_ERR(path->dentry);
-       if (IS_ERR(path->dentry)) {
+       dentry = lookup_hash(nd);
+       error = PTR_ERR(dentry);
+       if (IS_ERR(dentry)) {
                mutex_unlock(&dir->d_inode->i_mutex);
                goto exit;
        }
 
+       path->dentry = dentry;
+       path->mnt = nd->path.mnt;
+
        if (IS_ERR(nd->intent.open.file)) {
                error = PTR_ERR(nd->intent.open.file);
                goto exit_mutex_unlock;
        }
 
        /* Negative dentry, just create the file */
-       if (!path->dentry->d_inode) {
+       if (!dentry->d_inode) {
+               int mode = op->mode;
+               if (!IS_POSIXACL(dir->d_inode))
+                       mode &= ~current_umask();
                /*
                 * This write is needed to ensure that a
-                * ro->rw transition does not occur between
+                * rw->ro transition does not occur between
                 * the time when the file is created and when
                 * a permanent write count is taken through
                 * the 'struct file' in nameidata_to_filp().
@@ -2234,13 +2204,19 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
                if (error)
                        goto exit_mutex_unlock;
                want_write = 1;
-               will_truncate = 0;
-               error = __open_namei_create(nd, path, open_flag, op->mode);
-               if (error)
-                       goto exit;
                /* Don't check for write permission, don't truncate */
                open_flag &= ~O_TRUNC;
+               will_truncate = 0;
                skip_perm = 1;
+               error = security_path_mknod(&nd->path, dentry, mode, 0);
+               if (error)
+                       goto exit_mutex_unlock;
+               error = vfs_create(dir->d_inode, dentry, mode, nd);
+               if (error)
+                       goto exit_mutex_unlock;
+               mutex_unlock(&dir->d_inode->i_mutex);
+               dput(nd->path.dentry);
+               nd->path.dentry = dentry;
                goto common;
        }
 
@@ -2271,7 +2247,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
        if (S_ISDIR(nd->inode->i_mode))
                goto exit;
 ok:
-       will_truncate = open_will_truncate(open_flag, nd->path.dentry->d_inode);
+       if (!S_ISREG(nd->inode->i_mode))
+               will_truncate = 0;
+
        if (will_truncate) {
                error = mnt_want_write(nd->path.mnt);
                if (error)