diff options
| -rw-r--r-- | fs/namei.c | 43 | ||||
| -rw-r--r-- | fs/open.c | 22 |
2 files changed, 36 insertions, 29 deletions
diff --git a/fs/namei.c b/fs/namei.c index 8cf9bb9c2fc0..c70dbf720109 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
| @@ -1677,7 +1677,12 @@ int may_open(struct nameidata *nd, int acc_mode, int flag) | |||
| 1677 | return 0; | 1677 | return 0; |
| 1678 | } | 1678 | } |
| 1679 | 1679 | ||
| 1680 | static int open_namei_create(struct nameidata *nd, struct path *path, | 1680 | /* |
| 1681 | * Be careful about ever adding any more callers of this | ||
| 1682 | * function. Its flags must be in the namei format, not | ||
| 1683 | * what get passed to sys_open(). | ||
| 1684 | */ | ||
| 1685 | static int __open_namei_create(struct nameidata *nd, struct path *path, | ||
| 1681 | int flag, int mode) | 1686 | int flag, int mode) |
| 1682 | { | 1687 | { |
| 1683 | int error; | 1688 | int error; |
| @@ -1696,26 +1701,46 @@ static int open_namei_create(struct nameidata *nd, struct path *path, | |||
| 1696 | } | 1701 | } |
| 1697 | 1702 | ||
| 1698 | /* | 1703 | /* |
| 1704 | * Note that while the flag value (low two bits) for sys_open means: | ||
| 1705 | * 00 - read-only | ||
| 1706 | * 01 - write-only | ||
| 1707 | * 10 - read-write | ||
| 1708 | * 11 - special | ||
| 1709 | * it is changed into | ||
| 1710 | * 00 - no permissions needed | ||
| 1711 | * 01 - read-permission | ||
| 1712 | * 10 - write-permission | ||
| 1713 | * 11 - read-write | ||
| 1714 | * for the internal routines (ie open_namei()/follow_link() etc) | ||
| 1715 | * This is more logical, and also allows the 00 "no perm needed" | ||
| 1716 | * to be used for symlinks (where the permissions are checked | ||
| 1717 | * later). | ||
| 1718 | * | ||
| 1719 | */ | ||
| 1720 | static inline int open_to_namei_flags(int flag) | ||
| 1721 | { | ||
| 1722 | if ((flag+1) & O_ACCMODE) | ||
| 1723 | flag++; | ||
| 1724 | return flag; | ||
| 1725 | } | ||
| 1726 | |||
| 1727 | /* | ||
| 1699 | * open_namei() | 1728 | * open_namei() |
| 1700 | * | 1729 | * |
| 1701 | * namei for open - this is in fact almost the whole open-routine. | 1730 | * namei for open - this is in fact almost the whole open-routine. |
| 1702 | * | 1731 | * |
| 1703 | * Note that the low bits of "flag" aren't the same as in the open | 1732 | * Note that the low bits of "flag" aren't the same as in the open |
| 1704 | * system call - they are 00 - no permissions needed | 1733 | * system call. See open_to_namei_flags(). |
| 1705 | * 01 - read permission needed | ||
| 1706 | * 10 - write permission needed | ||
| 1707 | * 11 - read/write permissions needed | ||
| 1708 | * which is a lot more logical, and also allows the "no perm" needed | ||
| 1709 | * for symlinks (where the permissions are checked later). | ||
| 1710 | * SMP-safe | 1734 | * SMP-safe |
| 1711 | */ | 1735 | */ |
| 1712 | int open_namei(int dfd, const char *pathname, int flag, | 1736 | int open_namei(int dfd, const char *pathname, int open_flag, |
| 1713 | int mode, struct nameidata *nd) | 1737 | int mode, struct nameidata *nd) |
| 1714 | { | 1738 | { |
| 1715 | int acc_mode, error; | 1739 | int acc_mode, error; |
| 1716 | struct path path; | 1740 | struct path path; |
| 1717 | struct dentry *dir; | 1741 | struct dentry *dir; |
| 1718 | int count = 0; | 1742 | int count = 0; |
| 1743 | int flag = open_to_namei_flags(open_flag); | ||
| 1719 | 1744 | ||
| 1720 | acc_mode = ACC_MODE(flag); | 1745 | acc_mode = ACC_MODE(flag); |
| 1721 | 1746 | ||
| @@ -1776,7 +1801,7 @@ do_last: | |||
| 1776 | 1801 | ||
| 1777 | /* Negative dentry, just create the file */ | 1802 | /* Negative dentry, just create the file */ |
| 1778 | if (!path.dentry->d_inode) { | 1803 | if (!path.dentry->d_inode) { |
| 1779 | error = open_namei_create(nd, &path, flag, mode); | 1804 | error = __open_namei_create(nd, &path, flag, mode); |
| 1780 | if (error) | 1805 | if (error) |
| 1781 | goto exit; | 1806 | goto exit; |
| 1782 | return 0; | 1807 | return 0; |
| @@ -796,31 +796,13 @@ cleanup_file: | |||
| 796 | return ERR_PTR(error); | 796 | return ERR_PTR(error); |
| 797 | } | 797 | } |
| 798 | 798 | ||
| 799 | /* | ||
| 800 | * Note that while the flag value (low two bits) for sys_open means: | ||
| 801 | * 00 - read-only | ||
| 802 | * 01 - write-only | ||
| 803 | * 10 - read-write | ||
| 804 | * 11 - special | ||
| 805 | * it is changed into | ||
| 806 | * 00 - no permissions needed | ||
| 807 | * 01 - read-permission | ||
| 808 | * 10 - write-permission | ||
| 809 | * 11 - read-write | ||
| 810 | * for the internal routines (ie open_namei()/follow_link() etc). 00 is | ||
| 811 | * used by symlinks. | ||
| 812 | */ | ||
| 813 | static struct file *do_filp_open(int dfd, const char *filename, int flags, | 799 | static struct file *do_filp_open(int dfd, const char *filename, int flags, |
| 814 | int mode) | 800 | int mode) |
| 815 | { | 801 | { |
| 816 | int namei_flags, error; | 802 | int error; |
| 817 | struct nameidata nd; | 803 | struct nameidata nd; |
| 818 | 804 | ||
| 819 | namei_flags = flags; | 805 | error = open_namei(dfd, filename, flags, mode, &nd); |
| 820 | if ((namei_flags+1) & O_ACCMODE) | ||
| 821 | namei_flags++; | ||
| 822 | |||
| 823 | error = open_namei(dfd, filename, namei_flags, mode, &nd); | ||
| 824 | if (!error) | 806 | if (!error) |
| 825 | return nameidata_to_filp(&nd, flags); | 807 | return nameidata_to_filp(&nd, flags); |
| 826 | 808 | ||
