diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-09 00:59:59 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2011-03-14 09:15:27 -0400 |
commit | 6c0d46c493217cf48999b3f8808910ae534aa085 (patch) | |
tree | 4c36a27f499ce8a8fb70807c78187c247e79dc65 | |
parent | ca344a894b41a133dab07dfbbdf652c053f6658c (diff) |
fold __open_namei_create() and open_will_truncate() into do_last()
... and clean up a bit more
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/namei.c | 74 |
1 files changed, 26 insertions, 48 deletions
diff --git a/fs/namei.c b/fs/namei.c index 63844776484c..441f1106de08 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2049,30 +2049,6 @@ static int handle_truncate(struct file *filp) | |||
2049 | } | 2049 | } |
2050 | 2050 | ||
2051 | /* | 2051 | /* |
2052 | * Be careful about ever adding any more callers of this | ||
2053 | * function. Its flags must be in the namei format, not | ||
2054 | * what get passed to sys_open(). | ||
2055 | */ | ||
2056 | static int __open_namei_create(struct nameidata *nd, struct path *path, | ||
2057 | int open_flag, int mode) | ||
2058 | { | ||
2059 | int error; | ||
2060 | struct dentry *dir = nd->path.dentry; | ||
2061 | |||
2062 | if (!IS_POSIXACL(dir->d_inode)) | ||
2063 | mode &= ~current_umask(); | ||
2064 | error = security_path_mknod(&nd->path, path->dentry, mode, 0); | ||
2065 | if (error) | ||
2066 | goto out_unlock; | ||
2067 | error = vfs_create(dir->d_inode, path->dentry, mode, nd); | ||
2068 | out_unlock: | ||
2069 | mutex_unlock(&dir->d_inode->i_mutex); | ||
2070 | dput(nd->path.dentry); | ||
2071 | nd->path.dentry = path->dentry; | ||
2072 | return error; | ||
2073 | } | ||
2074 | |||
2075 | /* | ||
2076 | * Note that while the flag value (low two bits) for sys_open means: | 2052 | * Note that while the flag value (low two bits) for sys_open means: |
2077 | * 00 - read-only | 2053 | * 00 - read-only |
2078 | * 01 - write-only | 2054 | * 01 - write-only |
@@ -2096,17 +2072,6 @@ static inline int open_to_namei_flags(int flag) | |||
2096 | return flag; | 2072 | return flag; |
2097 | } | 2073 | } |
2098 | 2074 | ||
2099 | static int open_will_truncate(int flag, struct inode *inode) | ||
2100 | { | ||
2101 | /* | ||
2102 | * We'll never write to the fs underlying | ||
2103 | * a device file. | ||
2104 | */ | ||
2105 | if (special_file(inode->i_mode)) | ||
2106 | return 0; | ||
2107 | return (flag & O_TRUNC); | ||
2108 | } | ||
2109 | |||
2110 | /* | 2075 | /* |
2111 | * Handle the last step of open() | 2076 | * Handle the last step of open() |
2112 | */ | 2077 | */ |
@@ -2114,8 +2079,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
2114 | const struct open_flags *op, const char *pathname) | 2079 | const struct open_flags *op, const char *pathname) |
2115 | { | 2080 | { |
2116 | struct dentry *dir = nd->path.dentry; | 2081 | struct dentry *dir = nd->path.dentry; |
2082 | struct dentry *dentry; | ||
2117 | int open_flag = op->open_flag; | 2083 | int open_flag = op->open_flag; |
2118 | int will_truncate; | 2084 | int will_truncate = open_flag & O_TRUNC; |
2119 | int want_write = 0; | 2085 | int want_write = 0; |
2120 | int skip_perm = 0; | 2086 | int skip_perm = 0; |
2121 | struct file *filp; | 2087 | struct file *filp; |
@@ -2207,25 +2173,29 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
2207 | 2173 | ||
2208 | mutex_lock(&dir->d_inode->i_mutex); | 2174 | mutex_lock(&dir->d_inode->i_mutex); |
2209 | 2175 | ||
2210 | path->dentry = lookup_hash(nd); | 2176 | dentry = lookup_hash(nd); |
2211 | path->mnt = nd->path.mnt; | 2177 | error = PTR_ERR(dentry); |
2212 | 2178 | if (IS_ERR(dentry)) { | |
2213 | error = PTR_ERR(path->dentry); | ||
2214 | if (IS_ERR(path->dentry)) { | ||
2215 | mutex_unlock(&dir->d_inode->i_mutex); | 2179 | mutex_unlock(&dir->d_inode->i_mutex); |
2216 | goto exit; | 2180 | goto exit; |
2217 | } | 2181 | } |
2218 | 2182 | ||
2183 | path->dentry = dentry; | ||
2184 | path->mnt = nd->path.mnt; | ||
2185 | |||
2219 | if (IS_ERR(nd->intent.open.file)) { | 2186 | if (IS_ERR(nd->intent.open.file)) { |
2220 | error = PTR_ERR(nd->intent.open.file); | 2187 | error = PTR_ERR(nd->intent.open.file); |
2221 | goto exit_mutex_unlock; | 2188 | goto exit_mutex_unlock; |
2222 | } | 2189 | } |
2223 | 2190 | ||
2224 | /* Negative dentry, just create the file */ | 2191 | /* Negative dentry, just create the file */ |
2225 | if (!path->dentry->d_inode) { | 2192 | if (!dentry->d_inode) { |
2193 | int mode = op->mode; | ||
2194 | if (!IS_POSIXACL(dir->d_inode)) | ||
2195 | mode &= ~current_umask(); | ||
2226 | /* | 2196 | /* |
2227 | * This write is needed to ensure that a | 2197 | * This write is needed to ensure that a |
2228 | * ro->rw transition does not occur between | 2198 | * rw->ro transition does not occur between |
2229 | * the time when the file is created and when | 2199 | * the time when the file is created and when |
2230 | * a permanent write count is taken through | 2200 | * a permanent write count is taken through |
2231 | * the 'struct file' in nameidata_to_filp(). | 2201 | * the 'struct file' in nameidata_to_filp(). |
@@ -2234,13 +2204,19 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
2234 | if (error) | 2204 | if (error) |
2235 | goto exit_mutex_unlock; | 2205 | goto exit_mutex_unlock; |
2236 | want_write = 1; | 2206 | want_write = 1; |
2237 | will_truncate = 0; | ||
2238 | error = __open_namei_create(nd, path, open_flag, op->mode); | ||
2239 | if (error) | ||
2240 | goto exit; | ||
2241 | /* Don't check for write permission, don't truncate */ | 2207 | /* Don't check for write permission, don't truncate */ |
2242 | open_flag &= ~O_TRUNC; | 2208 | open_flag &= ~O_TRUNC; |
2209 | will_truncate = 0; | ||
2243 | skip_perm = 1; | 2210 | skip_perm = 1; |
2211 | error = security_path_mknod(&nd->path, dentry, mode, 0); | ||
2212 | if (error) | ||
2213 | goto exit_mutex_unlock; | ||
2214 | error = vfs_create(dir->d_inode, dentry, mode, nd); | ||
2215 | if (error) | ||
2216 | goto exit_mutex_unlock; | ||
2217 | mutex_unlock(&dir->d_inode->i_mutex); | ||
2218 | dput(nd->path.dentry); | ||
2219 | nd->path.dentry = dentry; | ||
2244 | goto common; | 2220 | goto common; |
2245 | } | 2221 | } |
2246 | 2222 | ||
@@ -2271,7 +2247,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
2271 | if (S_ISDIR(nd->inode->i_mode)) | 2247 | if (S_ISDIR(nd->inode->i_mode)) |
2272 | goto exit; | 2248 | goto exit; |
2273 | ok: | 2249 | ok: |
2274 | will_truncate = open_will_truncate(open_flag, nd->path.dentry->d_inode); | 2250 | if (!S_ISREG(nd->inode->i_mode)) |
2251 | will_truncate = 0; | ||
2252 | |||
2275 | if (will_truncate) { | 2253 | if (will_truncate) { |
2276 | error = mnt_want_write(nd->path.mnt); | 2254 | error = mnt_want_write(nd->path.mnt); |
2277 | if (error) | 2255 | if (error) |