mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-22 06:32:08 +00:00
switch dentry_open() to struct path, make it grab references itself
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
bf349a4470
commit
765927b2d5
15 changed files with 106 additions and 151 deletions
117
ipc/mqueue.c
117
ipc/mqueue.c
|
@ -721,8 +721,8 @@ static int mq_attr_ok(struct ipc_namespace *ipc_ns, struct mq_attr *attr)
|
|||
/*
|
||||
* Invoked when creating a new queue via sys_mq_open
|
||||
*/
|
||||
static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir,
|
||||
struct dentry *dentry, int oflag, umode_t mode,
|
||||
static struct file *do_create(struct ipc_namespace *ipc_ns, struct inode *dir,
|
||||
struct path *path, int oflag, umode_t mode,
|
||||
struct mq_attr *attr)
|
||||
{
|
||||
const struct cred *cred = current_cred();
|
||||
|
@ -732,9 +732,9 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir,
|
|||
if (attr) {
|
||||
ret = mq_attr_ok(ipc_ns, attr);
|
||||
if (ret)
|
||||
goto out;
|
||||
return ERR_PTR(ret);
|
||||
/* store for use during create */
|
||||
dentry->d_fsdata = attr;
|
||||
path->dentry->d_fsdata = attr;
|
||||
} else {
|
||||
struct mq_attr def_attr;
|
||||
|
||||
|
@ -744,71 +744,51 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct dentry *dir,
|
|||
ipc_ns->mq_msgsize_default);
|
||||
ret = mq_attr_ok(ipc_ns, &def_attr);
|
||||
if (ret)
|
||||
goto out;
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
mode &= ~current_umask();
|
||||
ret = mnt_want_write(ipc_ns->mq_mnt);
|
||||
ret = mnt_want_write(path->mnt);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = vfs_create(dir->d_inode, dentry, mode, true);
|
||||
dentry->d_fsdata = NULL;
|
||||
if (ret)
|
||||
goto out_drop_write;
|
||||
|
||||
result = dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred);
|
||||
return ERR_PTR(ret);
|
||||
ret = vfs_create(dir, path->dentry, mode, true);
|
||||
path->dentry->d_fsdata = NULL;
|
||||
if (!ret)
|
||||
result = dentry_open(path, oflag, cred);
|
||||
else
|
||||
result = ERR_PTR(ret);
|
||||
/*
|
||||
* dentry_open() took a persistent mnt_want_write(),
|
||||
* so we can now drop this one.
|
||||
*/
|
||||
mnt_drop_write(ipc_ns->mq_mnt);
|
||||
mnt_drop_write(path->mnt);
|
||||
return result;
|
||||
|
||||
out_drop_write:
|
||||
mnt_drop_write(ipc_ns->mq_mnt);
|
||||
out:
|
||||
dput(dentry);
|
||||
mntput(ipc_ns->mq_mnt);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
/* Opens existing queue */
|
||||
static struct file *do_open(struct ipc_namespace *ipc_ns,
|
||||
struct dentry *dentry, int oflag)
|
||||
static struct file *do_open(struct path *path, int oflag)
|
||||
{
|
||||
int ret;
|
||||
const struct cred *cred = current_cred();
|
||||
|
||||
static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
|
||||
MAY_READ | MAY_WRITE };
|
||||
|
||||
if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) {
|
||||
ret = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (inode_permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE])) {
|
||||
ret = -EACCES;
|
||||
goto err;
|
||||
}
|
||||
|
||||
return dentry_open(dentry, ipc_ns->mq_mnt, oflag, cred);
|
||||
|
||||
err:
|
||||
dput(dentry);
|
||||
mntput(ipc_ns->mq_mnt);
|
||||
return ERR_PTR(ret);
|
||||
int acc;
|
||||
if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY))
|
||||
return ERR_PTR(-EINVAL);
|
||||
acc = oflag2acc[oflag & O_ACCMODE];
|
||||
if (inode_permission(path->dentry->d_inode, acc))
|
||||
return ERR_PTR(-EACCES);
|
||||
return dentry_open(path, oflag, current_cred());
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
|
||||
struct mq_attr __user *, u_attr)
|
||||
{
|
||||
struct dentry *dentry;
|
||||
struct path path;
|
||||
struct file *filp;
|
||||
char *name;
|
||||
struct mq_attr attr;
|
||||
int fd, error;
|
||||
struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
|
||||
struct dentry *root = ipc_ns->mq_mnt->mnt_root;
|
||||
|
||||
if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr)))
|
||||
return -EFAULT;
|
||||
|
@ -822,52 +802,49 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode,
|
|||
if (fd < 0)
|
||||
goto out_putname;
|
||||
|
||||
mutex_lock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex);
|
||||
dentry = lookup_one_len(name, ipc_ns->mq_mnt->mnt_root, strlen(name));
|
||||
if (IS_ERR(dentry)) {
|
||||
error = PTR_ERR(dentry);
|
||||
error = 0;
|
||||
mutex_lock(&root->d_inode->i_mutex);
|
||||
path.dentry = lookup_one_len(name, root, strlen(name));
|
||||
if (IS_ERR(path.dentry)) {
|
||||
error = PTR_ERR(path.dentry);
|
||||
goto out_putfd;
|
||||
}
|
||||
mntget(ipc_ns->mq_mnt);
|
||||
path.mnt = mntget(ipc_ns->mq_mnt);
|
||||
|
||||
if (oflag & O_CREAT) {
|
||||
if (dentry->d_inode) { /* entry already exists */
|
||||
audit_inode(name, dentry);
|
||||
if (path.dentry->d_inode) { /* entry already exists */
|
||||
audit_inode(name, path.dentry);
|
||||
if (oflag & O_EXCL) {
|
||||
error = -EEXIST;
|
||||
goto out;
|
||||
}
|
||||
filp = do_open(ipc_ns, dentry, oflag);
|
||||
filp = do_open(&path, oflag);
|
||||
} else {
|
||||
filp = do_create(ipc_ns, ipc_ns->mq_mnt->mnt_root,
|
||||
dentry, oflag, mode,
|
||||
filp = do_create(ipc_ns, root->d_inode,
|
||||
&path, oflag, mode,
|
||||
u_attr ? &attr : NULL);
|
||||
}
|
||||
} else {
|
||||
if (!dentry->d_inode) {
|
||||
if (!path.dentry->d_inode) {
|
||||
error = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
audit_inode(name, dentry);
|
||||
filp = do_open(ipc_ns, dentry, oflag);
|
||||
audit_inode(name, path.dentry);
|
||||
filp = do_open(&path, oflag);
|
||||
}
|
||||
|
||||
if (IS_ERR(filp)) {
|
||||
if (!IS_ERR(filp))
|
||||
fd_install(fd, filp);
|
||||
else
|
||||
error = PTR_ERR(filp);
|
||||
goto out_putfd;
|
||||
}
|
||||
|
||||
fd_install(fd, filp);
|
||||
goto out_upsem;
|
||||
|
||||
out:
|
||||
dput(dentry);
|
||||
mntput(ipc_ns->mq_mnt);
|
||||
path_put(&path);
|
||||
out_putfd:
|
||||
put_unused_fd(fd);
|
||||
fd = error;
|
||||
out_upsem:
|
||||
mutex_unlock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex);
|
||||
if (error) {
|
||||
put_unused_fd(fd);
|
||||
fd = error;
|
||||
}
|
||||
mutex_unlock(&root->d_inode->i_mutex);
|
||||
out_putname:
|
||||
putname(name);
|
||||
return fd;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue