]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - fs/namei.c
[patch 1/4] vfs: path_{get,put}() cleanups
[net-next-2.6.git] / fs / namei.c
index e179f71bfcb058df613f83cb1ff923d47ffc4618..ee1544696e831659d3bf9f0aa905774d5717207d 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/capability.h>
 #include <linux/file.h>
 #include <linux/fcntl.h>
+#include <linux/device_cgroup.h>
 #include <asm/namei.h>
 #include <asm/uaccess.h>
 
@@ -281,6 +282,10 @@ int permission(struct inode *inode, int mask, struct nameidata *nd)
        if (retval)
                return retval;
 
+       retval = devcgroup_inode_permission(inode, mask);
+       if (retval)
+               return retval;
+
        return security_inode_permission(inode, mask, nd);
 }
 
@@ -576,15 +581,13 @@ static __always_inline int link_path_walk(const char *name, struct nameidata *nd
        int result;
 
        /* make sure the stuff we saved doesn't go away */
-       dget(save.dentry);
-       mntget(save.mnt);
+       path_get(&save);
 
        result = __link_path_walk(name, nd);
        if (result == -ESTALE) {
                /* nd->path had been dropped */
                nd->path = save;
-               dget(nd->path.dentry);
-               mntget(nd->path.mnt);
+               path_get(&nd->path);
                nd->flags |= LOOKUP_REVAL;
                result = __link_path_walk(name, nd);
        }
@@ -1211,8 +1214,9 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
        nd->flags = flags;
        nd->depth = 0;
 
-       nd->path.mnt = mntget(mnt);
-       nd->path.dentry = dget(dentry);
+       nd->path.dentry = dentry;
+       nd->path.mnt = mnt;
+       path_get(&nd->path);
 
        retval = path_walk(name, nd);
        if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
@@ -1998,18 +2002,22 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir)
        if (IS_ERR(dentry))
                goto fail;
 
+       if (dentry->d_inode)
+               goto eexist;
        /*
         * Special case - lookup gave negative, but... we had foo/bar/
         * From the vfs_mknod() POV we just have a negative dentry -
         * all is fine. Let's be bastards - you had / on the end, you've
         * been asking for (non-existent) directory. -ENOENT for you.
         */
-       if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode)
-               goto enoent;
+       if (unlikely(!is_dir && nd->last.name[nd->last.len])) {
+               dput(dentry);
+               dentry = ERR_PTR(-ENOENT);
+       }
        return dentry;
-enoent:
+eexist:
        dput(dentry);
-       dentry = ERR_PTR(-ENOENT);
+       dentry = ERR_PTR(-EEXIST);
 fail:
        return dentry;
 }
@@ -2028,6 +2036,10 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
        if (!dir->i_op || !dir->i_op->mknod)
                return -EPERM;
 
+       error = devcgroup_inode_mknod(mode, dev);
+       if (error)
+               return error;
+
        error = security_inode_mknod(dir, dentry, mode, dev);
        if (error)
                return error;