diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-21 15:38:14 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-21 15:38:14 -0700 |
| commit | fd9be4ce2e1eb407a8152f823698cc0d652bbec8 (patch) | |
| tree | b1cc279fa5b1f90995253f007564f001aa20c743 /ipc/mqueue.c | |
| parent | b1af9ccce9cff5b48c37424dbdbb3aa9021915db (diff) | |
| parent | ad775f5a8faa5845377f093ca11caf577404add9 (diff) | |
Merge branch 'ro-bind.b6' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6
* 'ro-bind.b6' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs-2.6: (24 commits)
[PATCH] r/o bind mounts: debugging for missed calls
[PATCH] r/o bind mounts: honor mount writer counts at remount
[PATCH] r/o bind mounts: track numbers of writers to mounts
[PATCH] r/o bind mounts: check mnt instead of superblock directly
[PATCH] r/o bind mounts: elevate count for xfs timestamp updates
[PATCH] r/o bind mounts: make access() use new r/o helper
[PATCH] r/o bind mounts: write counts for truncate()
[PATCH] r/o bind mounts: elevate write count for chmod/chown callers
[PATCH] r/o bind mounts: elevate write count for open()s
[PATCH] r/o bind mounts: elevate write count for ioctls()
[PATCH] r/o bind mounts: write count for file_update_time()
[PATCH] r/o bind mounts: elevate write count for do_utimes()
[PATCH] r/o bind mounts: write counts for touch_atime()
[PATCH] r/o bind mounts: elevate write count for ncp_ioctl()
[PATCH] r/o bind mounts: elevate write count for xattr_permission() callers
[PATCH] r/o bind mounts: get write access for vfs_rename() callers
[PATCH] r/o bind mounts: write counts for link/symlink
[PATCH] r/o bind mounts: get callers of vfs_mknod/create/mkdir()
[PATCH] r/o bind mounts: elevate write count for rmdir and unlink.
[PATCH] r/o bind mounts: drop write during emergency remount
...
Diffstat (limited to 'ipc/mqueue.c')
| -rw-r--r-- | ipc/mqueue.c | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 60f7a27f7a9..94fd3b08fb7 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -598,6 +598,7 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry, int oflag, mode_t mode, struct mq_attr __user *u_attr) { struct mq_attr attr; + struct file *result; int ret; if (u_attr) { @@ -612,13 +613,24 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry, } mode &= ~current->fs->umask; + ret = mnt_want_write(mqueue_mnt); + if (ret) + goto out; ret = vfs_create(dir->d_inode, dentry, mode, NULL); dentry->d_fsdata = NULL; if (ret) - goto out; - - return dentry_open(dentry, mqueue_mnt, oflag); - + goto out_drop_write; + + result = dentry_open(dentry, mqueue_mnt, oflag); + /* + * dentry_open() took a persistent mnt_want_write(), + * so we can now drop this one. + */ + mnt_drop_write(mqueue_mnt); + return result; + +out_drop_write: + mnt_drop_write(mqueue_mnt); out: dput(dentry); mntput(mqueue_mnt); @@ -742,8 +754,11 @@ asmlinkage long sys_mq_unlink(const char __user *u_name) inode = dentry->d_inode; if (inode) atomic_inc(&inode->i_count); - + err = mnt_want_write(mqueue_mnt); + if (err) + goto out_err; err = vfs_unlink(dentry->d_parent->d_inode, dentry); + mnt_drop_write(mqueue_mnt); out_err: dput(dentry); |
