diff options
Diffstat (limited to 'ipc')
| -rw-r--r-- | ipc/mqueue.c | 49 | ||||
| -rw-r--r-- | ipc/msgutil.c | 7 | ||||
| -rw-r--r-- | ipc/namespace.c | 3 |
3 files changed, 23 insertions, 36 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index d3a588d0dcf6..56e811f9e5fa 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -896,22 +896,23 @@ static struct file *mqueue_file_open(struct filename *name, struct vfsmount *mnt, int oflag, bool ro, umode_t mode, struct mq_attr *attr) { - struct path path __free(path_put) = {}; struct dentry *dentry; + struct file *file; int ret; - dentry = lookup_noperm(&QSTR(name->name), mnt->mnt_root); + dentry = start_creating_noperm(mnt->mnt_root, &QSTR(name->name)); if (IS_ERR(dentry)) return ERR_CAST(dentry); - path.dentry = dentry; - path.mnt = mntget(mnt); - - ret = prepare_open(path.dentry, oflag, ro, mode, name, attr); - if (ret) - return ERR_PTR(ret); + ret = prepare_open(dentry, oflag, ro, mode, name, attr); + file = ERR_PTR(ret); + if (!ret) { + const struct path path = { .mnt = mnt, .dentry = dentry }; + file = dentry_open(&path, oflag, current_cred()); + } - return dentry_open(&path, oflag, current_cred()); + end_creating(dentry); + return file; } static int do_mq_open(const char __user *u_name, int oflag, umode_t mode, @@ -919,9 +920,7 @@ static int do_mq_open(const char __user *u_name, int oflag, umode_t mode, { struct filename *name __free(putname) = NULL;; struct vfsmount *mnt = current->nsproxy->ipc_ns->mq_mnt; - struct dentry *root = mnt->mnt_root; - int fd; - int ro; + int fd, ro; audit_mq_open(oflag, mode, attr); @@ -930,9 +929,7 @@ static int do_mq_open(const char __user *u_name, int oflag, umode_t mode, return PTR_ERR(name); ro = mnt_want_write(mnt); /* we'll drop it in any case */ - inode_lock(d_inode(root)); fd = FD_ADD(O_CLOEXEC, mqueue_file_open(name, mnt, oflag, ro, mode, attr)); - inode_unlock(d_inode(root)); if (!ro) mnt_drop_write(mnt); return fd; @@ -953,7 +950,7 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name) int err; struct filename *name; struct dentry *dentry; - struct inode *inode = NULL; + struct inode *inode; struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; struct vfsmount *mnt = ipc_ns->mq_mnt; @@ -965,26 +962,20 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name) err = mnt_want_write(mnt); if (err) goto out_name; - inode_lock_nested(d_inode(mnt->mnt_root), I_MUTEX_PARENT); - dentry = lookup_noperm(&QSTR(name->name), mnt->mnt_root); + dentry = start_removing_noperm(mnt->mnt_root, &QSTR(name->name)); if (IS_ERR(dentry)) { err = PTR_ERR(dentry); - goto out_unlock; + goto out_drop_write; } inode = d_inode(dentry); - if (!inode) { - err = -ENOENT; - } else { - ihold(inode); - err = vfs_unlink(&nop_mnt_idmap, d_inode(dentry->d_parent), - dentry, NULL); - } - dput(dentry); - -out_unlock: - inode_unlock(d_inode(mnt->mnt_root)); + ihold(inode); + err = vfs_unlink(&nop_mnt_idmap, d_inode(mnt->mnt_root), + dentry, NULL); + end_removing(dentry); iput(inode); + +out_drop_write: mnt_drop_write(mnt); out_name: putname(name); diff --git a/ipc/msgutil.c b/ipc/msgutil.c index 7a03f6d03de3..e28f0cecb2ec 100644 --- a/ipc/msgutil.c +++ b/ipc/msgutil.c @@ -27,13 +27,8 @@ DEFINE_SPINLOCK(mq_lock); * and not CONFIG_IPC_NS. */ struct ipc_namespace init_ipc_ns = { - .ns.__ns_ref = REFCOUNT_INIT(1), + .ns = NS_COMMON_INIT(init_ipc_ns), .user_ns = &init_user_ns, - .ns.inum = ns_init_inum(&init_ipc_ns), -#ifdef CONFIG_IPC_NS - .ns.ops = &ipcns_operations, -#endif - .ns.ns_type = ns_common_type(&init_ipc_ns), }; struct msg_msgseg { diff --git a/ipc/namespace.c b/ipc/namespace.c index 59b12fcb40bd..c0dbfdd9015f 100644 --- a/ipc/namespace.c +++ b/ipc/namespace.c @@ -66,6 +66,7 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns, if (err) goto fail_free; + ns_tree_gen_id(ns); ns->user_ns = get_user_ns(user_ns); ns->ucounts = ucounts; @@ -86,7 +87,7 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns, sem_init_ns(ns); shm_init_ns(ns); - ns_tree_add(ns); + ns_tree_add_raw(ns); return ns; |