aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/namei.c61
1 files changed, 22 insertions, 39 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 4a56f9b59e8c..e584f04745b5 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1147,9 +1147,16 @@ int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
1147 1147
1148} 1148}
1149 1149
1150static int __path_lookup_intent_open(int dfd, const char *name, 1150/**
1151 unsigned int lookup_flags, struct nameidata *nd, 1151 * path_lookup_open - lookup a file path with open intent
1152 int open_flags, int create_mode) 1152 * @dfd: the directory to use as base, or AT_FDCWD
1153 * @name: pointer to file name
1154 * @lookup_flags: lookup intent flags
1155 * @nd: pointer to nameidata
1156 * @open_flags: open intent flags
1157 */
1158int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags,
1159 struct nameidata *nd, int open_flags)
1153{ 1160{
1154 struct file *filp = get_empty_filp(); 1161 struct file *filp = get_empty_filp();
1155 int err; 1162 int err;
@@ -1158,7 +1165,7 @@ static int __path_lookup_intent_open(int dfd, const char *name,
1158 return -ENFILE; 1165 return -ENFILE;
1159 nd->intent.open.file = filp; 1166 nd->intent.open.file = filp;
1160 nd->intent.open.flags = open_flags; 1167 nd->intent.open.flags = open_flags;
1161 nd->intent.open.create_mode = create_mode; 1168 nd->intent.open.create_mode = 0;
1162 err = do_path_lookup(dfd, name, lookup_flags|LOOKUP_OPEN, nd); 1169 err = do_path_lookup(dfd, name, lookup_flags|LOOKUP_OPEN, nd);
1163 if (IS_ERR(nd->intent.open.file)) { 1170 if (IS_ERR(nd->intent.open.file)) {
1164 if (err == 0) { 1171 if (err == 0) {
@@ -1170,38 +1177,6 @@ static int __path_lookup_intent_open(int dfd, const char *name,
1170 return err; 1177 return err;
1171} 1178}
1172 1179
1173/**
1174 * path_lookup_open - lookup a file path with open intent
1175 * @dfd: the directory to use as base, or AT_FDCWD
1176 * @name: pointer to file name
1177 * @lookup_flags: lookup intent flags
1178 * @nd: pointer to nameidata
1179 * @open_flags: open intent flags
1180 */
1181int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags,
1182 struct nameidata *nd, int open_flags)
1183{
1184 return __path_lookup_intent_open(dfd, name, lookup_flags, nd,
1185 open_flags, 0);
1186}
1187
1188/**
1189 * path_lookup_create - lookup a file path with open + create intent
1190 * @dfd: the directory to use as base, or AT_FDCWD
1191 * @name: pointer to file name
1192 * @lookup_flags: lookup intent flags
1193 * @nd: pointer to nameidata
1194 * @open_flags: open intent flags
1195 * @create_mode: create intent flags
1196 */
1197static int path_lookup_create(int dfd, const char *name,
1198 unsigned int lookup_flags, struct nameidata *nd,
1199 int open_flags, int create_mode)
1200{
1201 return __path_lookup_intent_open(dfd, name, lookup_flags|LOOKUP_CREATE,
1202 nd, open_flags, create_mode);
1203}
1204
1205static struct dentry *__lookup_hash(struct qstr *name, 1180static struct dentry *__lookup_hash(struct qstr *name,
1206 struct dentry *base, struct nameidata *nd) 1181 struct dentry *base, struct nameidata *nd)
1207{ 1182{
@@ -1711,8 +1686,7 @@ struct file *do_filp_open(int dfd, const char *pathname,
1711 /* 1686 /*
1712 * Create - we need to know the parent. 1687 * Create - we need to know the parent.
1713 */ 1688 */
1714 error = path_lookup_create(dfd, pathname, LOOKUP_PARENT, 1689 error = do_path_lookup(dfd, pathname, LOOKUP_PARENT, &nd);
1715 &nd, flag, mode);
1716 if (error) 1690 if (error)
1717 return ERR_PTR(error); 1691 return ERR_PTR(error);
1718 1692
@@ -1723,10 +1697,18 @@ struct file *do_filp_open(int dfd, const char *pathname,
1723 */ 1697 */
1724 error = -EISDIR; 1698 error = -EISDIR;
1725 if (nd.last_type != LAST_NORM || nd.last.name[nd.last.len]) 1699 if (nd.last_type != LAST_NORM || nd.last.name[nd.last.len])
1726 goto exit; 1700 goto exit_parent;
1727 1701
1702 error = -ENFILE;
1703 filp = get_empty_filp();
1704 if (filp == NULL)
1705 goto exit_parent;
1706 nd.intent.open.file = filp;
1707 nd.intent.open.flags = flag;
1708 nd.intent.open.create_mode = mode;
1728 dir = nd.path.dentry; 1709 dir = nd.path.dentry;
1729 nd.flags &= ~LOOKUP_PARENT; 1710 nd.flags &= ~LOOKUP_PARENT;
1711 nd.flags |= LOOKUP_CREATE | LOOKUP_OPEN;
1730 mutex_lock(&dir->d_inode->i_mutex); 1712 mutex_lock(&dir->d_inode->i_mutex);
1731 path.dentry = lookup_hash(&nd); 1713 path.dentry = lookup_hash(&nd);
1732 path.mnt = nd.path.mnt; 1714 path.mnt = nd.path.mnt;
@@ -1831,6 +1813,7 @@ exit_dput:
1831exit: 1813exit:
1832 if (!IS_ERR(nd.intent.open.file)) 1814 if (!IS_ERR(nd.intent.open.file))
1833 release_open_intent(&nd); 1815 release_open_intent(&nd);
1816exit_parent:
1834 path_put(&nd.path); 1817 path_put(&nd.path);
1835 return ERR_PTR(error); 1818 return ERR_PTR(error);
1836 1819