#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>
if (retval)
return retval;
+ retval = devcgroup_inode_permission(inode, mask);
+ if (retval)
+ return retval;
+
return security_inode_permission(inode, mask, 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);
}
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 &&
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;
}
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;
{
struct nameidata nd;
void *cookie;
+ int res;
nd.depth = 0;
cookie = dentry->d_inode->i_op->follow_link(dentry, &nd);
- if (!IS_ERR(cookie)) {
- int res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
- if (dentry->d_inode->i_op->put_link)
- dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
- cookie = ERR_PTR(res);
- }
- return PTR_ERR(cookie);
+ if (IS_ERR(cookie))
+ return PTR_ERR(cookie);
+
+ res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd));
+ if (dentry->d_inode->i_op->put_link)
+ dentry->d_inode->i_op->put_link(dentry, &nd, cookie);
+ return res;
}
int vfs_follow_link(struct nameidata *nd, const char *link)