aboutsummaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2017-12-01 17:51:39 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2018-01-05 11:54:35 -0500
commit066cc813e94a344ae4482af310d324739955c3b5 (patch)
tree7dce904dc5585502f73c4f65c59ed0fd907b3e50 /ipc
parent05c1b29038acb05a52dc113ae2ab646f9a92bbfd (diff)
do_mq_open(): move all work prior to dentry_open() into a helper
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'ipc')
-rw-r--r--ipc/mqueue.c77
1 files changed, 31 insertions, 46 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index a2483524b633..e8a872e9c808 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -713,34 +713,44 @@ static void remove_notification(struct mqueue_inode_info *info)
713 info->notify_user_ns = NULL; 713 info->notify_user_ns = NULL;
714} 714}
715 715
716/* 716static int prepare_open(struct dentry *dentry, int oflag, int ro,
717 * Invoked when creating a new queue via sys_mq_open 717 umode_t mode, struct filename *name,
718 */
719static int do_create(struct ipc_namespace *ipc_ns, struct inode *dir,
720 struct path *path, int oflag, umode_t mode,
721 struct mq_attr *attr) 718 struct mq_attr *attr)
722{ 719{
723 return vfs_mkobj(path->dentry, mode & ~current_umask(),
724 mqueue_create_attr, attr);
725}
726
727/* Opens existing queue */
728static int do_open(struct path *path, int oflag)
729{
730 static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, 720 static const int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE,
731 MAY_READ | MAY_WRITE }; 721 MAY_READ | MAY_WRITE };
732 int acc; 722 int acc;
723
724 if (oflag & O_CREAT) {
725 if (d_really_is_positive(dentry)) { /* entry already exists */
726 audit_inode(name, dentry, 0);
727 if (oflag & O_EXCL)
728 return -EEXIST;
729 } else {
730 if (ro)
731 return ro;
732
733 audit_inode_parent_hidden(name, dentry->d_parent);
734 return vfs_mkobj(dentry, mode & ~current_umask(),
735 mqueue_create_attr, attr);
736 }
737 } else {
738 if (d_really_is_negative(dentry)) {
739 return -ENOENT;
740 } else {
741 audit_inode(name, dentry, 0);
742 }
743 }
733 if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) 744 if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY))
734 return -EINVAL; 745 return -EINVAL;
735 acc = oflag2acc[oflag & O_ACCMODE]; 746 acc = oflag2acc[oflag & O_ACCMODE];
736 return inode_permission(d_inode(path->dentry), acc); 747 return inode_permission(d_inode(dentry), acc);
737} 748}
738 749
739static int do_mq_open(const char __user *u_name, int oflag, umode_t mode, 750static int do_mq_open(const char __user *u_name, int oflag, umode_t mode,
740 struct mq_attr *attr) 751 struct mq_attr *attr)
741{ 752{
742 struct path path; 753 struct path path;
743 struct file *filp;
744 struct filename *name; 754 struct filename *name;
745 int fd, error; 755 int fd, error;
746 struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; 756 struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns;
@@ -767,39 +777,14 @@ static int do_mq_open(const char __user *u_name, int oflag, umode_t mode,
767 } 777 }
768 path.mnt = mntget(mnt); 778 path.mnt = mntget(mnt);
769 779
770 if (oflag & O_CREAT) { 780 error = prepare_open(path.dentry, oflag, ro, mode, name, attr);
771 if (d_really_is_positive(path.dentry)) { /* entry already exists */ 781 if (!error) {
772 audit_inode(name, path.dentry, 0); 782 struct file *file = dentry_open(&path, oflag, current_cred());
773 if (oflag & O_EXCL) 783 if (!IS_ERR(file))
774 error = -EEXIST; 784 fd_install(fd, file);
775 else 785 else
776 error = do_open(&path, oflag); 786 error = PTR_ERR(file);
777 } else {
778 if (ro) {
779 error = ro;
780 } else {
781 audit_inode_parent_hidden(name, root);
782 error = do_create(ipc_ns, d_inode(root), &path,
783 oflag, mode, attr);
784 }
785 }
786 } else {
787 if (d_really_is_negative(path.dentry)) {
788 error = -ENOENT;
789 } else {
790 audit_inode(name, path.dentry, 0);
791 error = do_open(&path, oflag);
792 }
793 } 787 }
794 if (error)
795 goto out;
796 filp = dentry_open(&path, oflag, current_cred());
797
798 if (!IS_ERR(filp))
799 fd_install(fd, filp);
800 else
801 error = PTR_ERR(filp);
802out:
803 path_put(&path); 788 path_put(&path);
804out_putfd: 789out_putfd:
805 if (error) { 790 if (error) {