|
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; |