diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2017-12-01 17:51:39 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2018-01-05 11:54:35 -0500 |
commit | 066cc813e94a344ae4482af310d324739955c3b5 (patch) | |
tree | 7dce904dc5585502f73c4f65c59ed0fd907b3e50 /ipc | |
parent | 05c1b29038acb05a52dc113ae2ab646f9a92bbfd (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.c | 77 |
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 | /* | 716 | static 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 | */ | ||
719 | static 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 */ | ||
728 | static 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 | ||
739 | static int do_mq_open(const char __user *u_name, int oflag, umode_t mode, | 750 | static 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); | ||
802 | out: | ||
803 | path_put(&path); | 788 | path_put(&path); |
804 | out_putfd: | 789 | out_putfd: |
805 | if (error) { | 790 | if (error) { |