Lines 599-613
Link Here
|
599 |
static struct file *do_create(struct dentry *dir, struct dentry *dentry, |
599 |
static struct file *do_create(struct dentry *dir, struct dentry *dentry, |
600 |
int oflag, mode_t mode, struct mq_attr __user *u_attr) |
600 |
int oflag, mode_t mode, struct mq_attr __user *u_attr) |
601 |
{ |
601 |
{ |
602 |
struct file *filp; |
|
|
603 |
struct mq_attr attr; |
602 |
struct mq_attr attr; |
604 |
int ret; |
603 |
int ret; |
605 |
|
604 |
|
606 |
if (u_attr != NULL) { |
605 |
if (u_attr) { |
|
|
606 |
ret = -EFAULT; |
607 |
if (copy_from_user(&attr, u_attr, sizeof(attr))) |
607 |
if (copy_from_user(&attr, u_attr, sizeof(attr))) |
608 |
return ERR_PTR(-EFAULT); |
608 |
goto out; |
|
|
609 |
ret = -EINVAL; |
609 |
if (!mq_attr_ok(&attr)) |
610 |
if (!mq_attr_ok(&attr)) |
610 |
return ERR_PTR(-EINVAL); |
611 |
goto out; |
611 |
/* store for use during create */ |
612 |
/* store for use during create */ |
612 |
dentry->d_fsdata = &attr; |
613 |
dentry->d_fsdata = &attr; |
613 |
} |
614 |
} |
Lines 616-628
Link Here
|
616 |
ret = vfs_create(dir->d_inode, dentry, mode, NULL); |
617 |
ret = vfs_create(dir->d_inode, dentry, mode, NULL); |
617 |
dentry->d_fsdata = NULL; |
618 |
dentry->d_fsdata = NULL; |
618 |
if (ret) |
619 |
if (ret) |
619 |
return ERR_PTR(ret); |
620 |
goto out; |
620 |
|
621 |
|
621 |
filp = dentry_open(dentry, mqueue_mnt, oflag); |
622 |
return dentry_open(dentry, mqueue_mnt, oflag); |
622 |
if (!IS_ERR(filp)) |
|
|
623 |
dget(dentry); |
624 |
|
623 |
|
625 |
return filp; |
624 |
out: |
|
|
625 |
dput(dentry); |
626 |
mntput(mqueue_mnt); |
627 |
return ERR_PTR(ret); |
626 |
} |
628 |
} |
627 |
|
629 |
|
628 |
/* Opens existing queue */ |
630 |
/* Opens existing queue */ |
Lines 630-649
Link Here
|
630 |
{ |
632 |
{ |
631 |
static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, |
633 |
static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, |
632 |
MAY_READ | MAY_WRITE }; |
634 |
MAY_READ | MAY_WRITE }; |
633 |
struct file *filp; |
|
|
634 |
|
635 |
|
635 |
if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) |
636 |
if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) { |
|
|
637 |
dput(dentry); |
638 |
mntput(mqueue_mnt); |
636 |
return ERR_PTR(-EINVAL); |
639 |
return ERR_PTR(-EINVAL); |
|
|
640 |
} |
637 |
|
641 |
|
638 |
if (permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE], NULL)) |
642 |
if (permission(dentry->d_inode, oflag2acc[oflag & O_ACCMODE], NULL)) { |
|
|
643 |
dput(dentry); |
644 |
mntput(mqueue_mnt); |
639 |
return ERR_PTR(-EACCES); |
645 |
return ERR_PTR(-EACCES); |
|
|
646 |
} |
640 |
|
647 |
|
641 |
filp = dentry_open(dentry, mqueue_mnt, oflag); |
648 |
return dentry_open(dentry, mqueue_mnt, oflag); |
642 |
|
|
|
643 |
if (!IS_ERR(filp)) |
644 |
dget(dentry); |
645 |
|
646 |
return filp; |
647 |
} |
649 |
} |
648 |
|
650 |
|
649 |
asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, |
651 |
asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, |
Lines 671-687
Link Here
|
671 |
|
673 |
|
672 |
if (oflag & O_CREAT) { |
674 |
if (oflag & O_CREAT) { |
673 |
if (dentry->d_inode) { /* entry already exists */ |
675 |
if (dentry->d_inode) { /* entry already exists */ |
674 |
filp = (oflag & O_EXCL) ? ERR_PTR(-EEXIST) : |
676 |
error = -EEXIST; |
675 |
do_open(dentry, oflag); |
677 |
if (oflag & O_EXCL) |
|
|
678 |
goto out; |
679 |
filp = do_open(dentry, oflag); |
676 |
} else { |
680 |
} else { |
677 |
filp = do_create(mqueue_mnt->mnt_root, dentry, |
681 |
filp = do_create(mqueue_mnt->mnt_root, dentry, |
678 |
oflag, mode, u_attr); |
682 |
oflag, mode, u_attr); |
679 |
} |
683 |
} |
680 |
} else |
684 |
} else { |
681 |
filp = (dentry->d_inode) ? do_open(dentry, oflag) : |
685 |
error = -ENOENT; |
682 |
ERR_PTR(-ENOENT); |
686 |
if (!dentry->d_inode) |
683 |
|
687 |
goto out; |
684 |
dput(dentry); |
688 |
filp = do_open(dentry, oflag); |
|
|
689 |
} |
685 |
|
690 |
|
686 |
if (IS_ERR(filp)) { |
691 |
if (IS_ERR(filp)) { |
687 |
error = PTR_ERR(filp); |
692 |
error = PTR_ERR(filp); |
Lines 692-699
Link Here
|
692 |
fd_install(fd, filp); |
697 |
fd_install(fd, filp); |
693 |
goto out_upsem; |
698 |
goto out_upsem; |
694 |
|
699 |
|
695 |
out_putfd: |
700 |
out: |
|
|
701 |
dput(dentry); |
696 |
mntput(mqueue_mnt); |
702 |
mntput(mqueue_mnt); |
|
|
703 |
out_putfd: |
697 |
put_unused_fd(fd); |
704 |
put_unused_fd(fd); |
698 |
out_err: |
705 |
out_err: |
699 |
fd = error; |
706 |
fd = error; |