diff options
-rw-r--r-- | fs/namei.c | 61 |
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 | ||
1150 | static 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 | */ | ||
1158 | int 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 | */ | ||
1181 | int 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 | */ | ||
1197 | static 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 | |||
1205 | static struct dentry *__lookup_hash(struct qstr *name, | 1180 | static 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: | |||
1831 | exit: | 1813 | exit: |
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); |
1816 | exit_parent: | ||
1834 | path_put(&nd.path); | 1817 | path_put(&nd.path); |
1835 | return ERR_PTR(error); | 1818 | return ERR_PTR(error); |
1836 | 1819 | ||