diff options
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/mqueue.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c index 34262c11f480..94fd3b08fb77 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c | |||
@@ -598,6 +598,7 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry, | |||
598 | int oflag, mode_t mode, struct mq_attr __user *u_attr) | 598 | int oflag, mode_t mode, struct mq_attr __user *u_attr) |
599 | { | 599 | { |
600 | struct mq_attr attr; | 600 | struct mq_attr attr; |
601 | struct file *result; | ||
601 | int ret; | 602 | int ret; |
602 | 603 | ||
603 | if (u_attr) { | 604 | if (u_attr) { |
@@ -612,13 +613,24 @@ static struct file *do_create(struct dentry *dir, struct dentry *dentry, | |||
612 | } | 613 | } |
613 | 614 | ||
614 | mode &= ~current->fs->umask; | 615 | mode &= ~current->fs->umask; |
616 | ret = mnt_want_write(mqueue_mnt); | ||
617 | if (ret) | ||
618 | goto out; | ||
615 | ret = vfs_create(dir->d_inode, dentry, mode, NULL); | 619 | ret = vfs_create(dir->d_inode, dentry, mode, NULL); |
616 | dentry->d_fsdata = NULL; | 620 | dentry->d_fsdata = NULL; |
617 | if (ret) | 621 | if (ret) |
618 | goto out; | 622 | goto out_drop_write; |
619 | 623 | ||
620 | return dentry_open(dentry, mqueue_mnt, oflag); | 624 | result = dentry_open(dentry, mqueue_mnt, oflag); |
625 | /* | ||
626 | * dentry_open() took a persistent mnt_want_write(), | ||
627 | * so we can now drop this one. | ||
628 | */ | ||
629 | mnt_drop_write(mqueue_mnt); | ||
630 | return result; | ||
621 | 631 | ||
632 | out_drop_write: | ||
633 | mnt_drop_write(mqueue_mnt); | ||
622 | out: | 634 | out: |
623 | dput(dentry); | 635 | dput(dentry); |
624 | mntput(mqueue_mnt); | 636 | mntput(mqueue_mnt); |