aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/namei.c43
-rw-r--r--fs/open.c22
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
1680static 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 */
1685static 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*/
1720static 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 */
1712int open_namei(int dfd, const char *pathname, int flag, 1736int 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;
diff --git a/fs/open.c b/fs/open.c
index 3fa4e4ffce4c..5ab3f3f079c0 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -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 */
813static struct file *do_filp_open(int dfd, const char *filename, int flags, 799static 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