diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 43 |
1 files changed, 34 insertions, 9 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; |