Loading ipc/mqueue.c +28 −33 Original line number Original line Diff line number Diff line Loading @@ -726,7 +726,6 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct inode *dir, struct mq_attr *attr) struct mq_attr *attr) { { const struct cred *cred = current_cred(); const struct cred *cred = current_cred(); struct file *result; int ret; int ret; if (attr) { if (attr) { Loading @@ -748,21 +747,11 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct inode *dir, } } mode &= ~current_umask(); mode &= ~current_umask(); ret = mnt_want_write(path->mnt); if (ret) return ERR_PTR(ret); ret = vfs_create(dir, path->dentry, mode, true); ret = vfs_create(dir, path->dentry, mode, true); path->dentry->d_fsdata = NULL; path->dentry->d_fsdata = NULL; if (!ret) if (ret) result = dentry_open(path, oflag, cred); return ERR_PTR(ret); else return dentry_open(path, oflag, cred); result = ERR_PTR(ret); /* * dentry_open() took a persistent mnt_want_write(), * so we can now drop this one. */ mnt_drop_write(path->mnt); return result; } } /* Opens existing queue */ /* Opens existing queue */ Loading @@ -788,7 +777,9 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, struct mq_attr attr; struct mq_attr attr; int fd, error; int fd, error; struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; struct dentry *root = ipc_ns->mq_mnt->mnt_root; struct vfsmount *mnt = ipc_ns->mq_mnt; struct dentry *root = mnt->mnt_root; int ro; if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr))) if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr))) return -EFAULT; return -EFAULT; Loading @@ -802,6 +793,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, if (fd < 0) if (fd < 0) goto out_putname; goto out_putname; ro = mnt_want_write(mnt); /* we'll drop it in any case */ error = 0; error = 0; mutex_lock(&root->d_inode->i_mutex); mutex_lock(&root->d_inode->i_mutex); path.dentry = lookup_one_len(name, root, strlen(name)); path.dentry = lookup_one_len(name, root, strlen(name)); Loading @@ -809,7 +801,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, error = PTR_ERR(path.dentry); error = PTR_ERR(path.dentry); goto out_putfd; goto out_putfd; } } path.mnt = mntget(ipc_ns->mq_mnt); path.mnt = mntget(mnt); if (oflag & O_CREAT) { if (oflag & O_CREAT) { if (path.dentry->d_inode) { /* entry already exists */ if (path.dentry->d_inode) { /* entry already exists */ Loading @@ -820,6 +812,10 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, } } filp = do_open(&path, oflag); filp = do_open(&path, oflag); } else { } else { if (ro) { error = ro; goto out; } filp = do_create(ipc_ns, root->d_inode, filp = do_create(ipc_ns, root->d_inode, &path, oflag, mode, &path, oflag, mode, u_attr ? &attr : NULL); u_attr ? &attr : NULL); Loading @@ -845,6 +841,7 @@ out_putfd: fd = error; fd = error; } } mutex_unlock(&root->d_inode->i_mutex); mutex_unlock(&root->d_inode->i_mutex); mnt_drop_write(mnt); out_putname: out_putname: putname(name); putname(name); return fd; return fd; Loading @@ -857,40 +854,38 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name) struct dentry *dentry; struct dentry *dentry; struct inode *inode = NULL; struct inode *inode = NULL; struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; struct vfsmount *mnt = ipc_ns->mq_mnt; name = getname(u_name); name = getname(u_name); if (IS_ERR(name)) if (IS_ERR(name)) return PTR_ERR(name); return PTR_ERR(name); mutex_lock_nested(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex, err = mnt_want_write(mnt); I_MUTEX_PARENT); if (err) dentry = lookup_one_len(name, ipc_ns->mq_mnt->mnt_root, strlen(name)); goto out_name; mutex_lock_nested(&mnt->mnt_root->d_inode->i_mutex, I_MUTEX_PARENT); dentry = lookup_one_len(name, mnt->mnt_root, strlen(name)); if (IS_ERR(dentry)) { if (IS_ERR(dentry)) { err = PTR_ERR(dentry); err = PTR_ERR(dentry); goto out_unlock; goto out_unlock; } } if (!dentry->d_inode) { err = -ENOENT; goto out_err; } inode = dentry->d_inode; inode = dentry->d_inode; if (inode) if (!inode) { err = -ENOENT; } else { ihold(inode); ihold(inode); err = mnt_want_write(ipc_ns->mq_mnt); if (err) goto out_err; err = vfs_unlink(dentry->d_parent->d_inode, dentry); err = vfs_unlink(dentry->d_parent->d_inode, dentry); mnt_drop_write(ipc_ns->mq_mnt); } out_err: dput(dentry); dput(dentry); out_unlock: out_unlock: mutex_unlock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex); mutex_unlock(&mnt->mnt_root->d_inode->i_mutex); putname(name); if (inode) if (inode) iput(inode); iput(inode); mnt_drop_write(mnt); out_name: putname(name); return err; return err; } } Loading Loading
ipc/mqueue.c +28 −33 Original line number Original line Diff line number Diff line Loading @@ -726,7 +726,6 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct inode *dir, struct mq_attr *attr) struct mq_attr *attr) { { const struct cred *cred = current_cred(); const struct cred *cred = current_cred(); struct file *result; int ret; int ret; if (attr) { if (attr) { Loading @@ -748,21 +747,11 @@ static struct file *do_create(struct ipc_namespace *ipc_ns, struct inode *dir, } } mode &= ~current_umask(); mode &= ~current_umask(); ret = mnt_want_write(path->mnt); if (ret) return ERR_PTR(ret); ret = vfs_create(dir, path->dentry, mode, true); ret = vfs_create(dir, path->dentry, mode, true); path->dentry->d_fsdata = NULL; path->dentry->d_fsdata = NULL; if (!ret) if (ret) result = dentry_open(path, oflag, cred); return ERR_PTR(ret); else return dentry_open(path, oflag, cred); result = ERR_PTR(ret); /* * dentry_open() took a persistent mnt_want_write(), * so we can now drop this one. */ mnt_drop_write(path->mnt); return result; } } /* Opens existing queue */ /* Opens existing queue */ Loading @@ -788,7 +777,9 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, struct mq_attr attr; struct mq_attr attr; int fd, error; int fd, error; struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; struct dentry *root = ipc_ns->mq_mnt->mnt_root; struct vfsmount *mnt = ipc_ns->mq_mnt; struct dentry *root = mnt->mnt_root; int ro; if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr))) if (u_attr && copy_from_user(&attr, u_attr, sizeof(struct mq_attr))) return -EFAULT; return -EFAULT; Loading @@ -802,6 +793,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, if (fd < 0) if (fd < 0) goto out_putname; goto out_putname; ro = mnt_want_write(mnt); /* we'll drop it in any case */ error = 0; error = 0; mutex_lock(&root->d_inode->i_mutex); mutex_lock(&root->d_inode->i_mutex); path.dentry = lookup_one_len(name, root, strlen(name)); path.dentry = lookup_one_len(name, root, strlen(name)); Loading @@ -809,7 +801,7 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, error = PTR_ERR(path.dentry); error = PTR_ERR(path.dentry); goto out_putfd; goto out_putfd; } } path.mnt = mntget(ipc_ns->mq_mnt); path.mnt = mntget(mnt); if (oflag & O_CREAT) { if (oflag & O_CREAT) { if (path.dentry->d_inode) { /* entry already exists */ if (path.dentry->d_inode) { /* entry already exists */ Loading @@ -820,6 +812,10 @@ SYSCALL_DEFINE4(mq_open, const char __user *, u_name, int, oflag, umode_t, mode, } } filp = do_open(&path, oflag); filp = do_open(&path, oflag); } else { } else { if (ro) { error = ro; goto out; } filp = do_create(ipc_ns, root->d_inode, filp = do_create(ipc_ns, root->d_inode, &path, oflag, mode, &path, oflag, mode, u_attr ? &attr : NULL); u_attr ? &attr : NULL); Loading @@ -845,6 +841,7 @@ out_putfd: fd = error; fd = error; } } mutex_unlock(&root->d_inode->i_mutex); mutex_unlock(&root->d_inode->i_mutex); mnt_drop_write(mnt); out_putname: out_putname: putname(name); putname(name); return fd; return fd; Loading @@ -857,40 +854,38 @@ SYSCALL_DEFINE1(mq_unlink, const char __user *, u_name) struct dentry *dentry; struct dentry *dentry; struct inode *inode = NULL; struct inode *inode = NULL; struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; struct ipc_namespace *ipc_ns = current->nsproxy->ipc_ns; struct vfsmount *mnt = ipc_ns->mq_mnt; name = getname(u_name); name = getname(u_name); if (IS_ERR(name)) if (IS_ERR(name)) return PTR_ERR(name); return PTR_ERR(name); mutex_lock_nested(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex, err = mnt_want_write(mnt); I_MUTEX_PARENT); if (err) dentry = lookup_one_len(name, ipc_ns->mq_mnt->mnt_root, strlen(name)); goto out_name; mutex_lock_nested(&mnt->mnt_root->d_inode->i_mutex, I_MUTEX_PARENT); dentry = lookup_one_len(name, mnt->mnt_root, strlen(name)); if (IS_ERR(dentry)) { if (IS_ERR(dentry)) { err = PTR_ERR(dentry); err = PTR_ERR(dentry); goto out_unlock; goto out_unlock; } } if (!dentry->d_inode) { err = -ENOENT; goto out_err; } inode = dentry->d_inode; inode = dentry->d_inode; if (inode) if (!inode) { err = -ENOENT; } else { ihold(inode); ihold(inode); err = mnt_want_write(ipc_ns->mq_mnt); if (err) goto out_err; err = vfs_unlink(dentry->d_parent->d_inode, dentry); err = vfs_unlink(dentry->d_parent->d_inode, dentry); mnt_drop_write(ipc_ns->mq_mnt); } out_err: dput(dentry); dput(dentry); out_unlock: out_unlock: mutex_unlock(&ipc_ns->mq_mnt->mnt_root->d_inode->i_mutex); mutex_unlock(&mnt->mnt_root->d_inode->i_mutex); putname(name); if (inode) if (inode) iput(inode); iput(inode); mnt_drop_write(mnt); out_name: putname(name); return err; return err; } } Loading