Commit 6c0d46c493217cf48999b3f8808910ae534aa085
1 parent
ca344a894b
Exists in
master
and in
20 other branches
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>
Showing 1 changed file with 26 additions and 48 deletions Side-by-side Diff
fs/namei.c
... | ... | @@ -2049,30 +2049,6 @@ |
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 | 2052 | * Note that while the flag value (low two bits) for sys_open means: |
2077 | 2053 | * 00 - read-only |
2078 | 2054 | * 01 - write-only |
... | ... | @@ -2096,17 +2072,6 @@ |
2096 | 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 | 2076 | * Handle the last step of open() |
2112 | 2077 | */ |
2113 | 2078 | |
... | ... | @@ -2114,8 +2079,9 @@ |
2114 | 2079 | const struct open_flags *op, const char *pathname) |
2115 | 2080 | { |
2116 | 2081 | struct dentry *dir = nd->path.dentry; |
2082 | + struct dentry *dentry; | |
2117 | 2083 | int open_flag = op->open_flag; |
2118 | - int will_truncate; | |
2084 | + int will_truncate = open_flag & O_TRUNC; | |
2119 | 2085 | int want_write = 0; |
2120 | 2086 | int skip_perm = 0; |
2121 | 2087 | struct file *filp; |
2122 | 2088 | |
2123 | 2089 | |
2124 | 2090 | |
... | ... | @@ -2207,25 +2173,29 @@ |
2207 | 2173 | |
2208 | 2174 | mutex_lock(&dir->d_inode->i_mutex); |
2209 | 2175 | |
2210 | - path->dentry = lookup_hash(nd); | |
2211 | - path->mnt = nd->path.mnt; | |
2212 | - | |
2213 | - error = PTR_ERR(path->dentry); | |
2214 | - if (IS_ERR(path->dentry)) { | |
2176 | + dentry = lookup_hash(nd); | |
2177 | + error = PTR_ERR(dentry); | |
2178 | + if (IS_ERR(dentry)) { | |
2215 | 2179 | mutex_unlock(&dir->d_inode->i_mutex); |
2216 | 2180 | goto exit; |
2217 | 2181 | } |
2218 | 2182 | |
2183 | + path->dentry = dentry; | |
2184 | + path->mnt = nd->path.mnt; | |
2185 | + | |
2219 | 2186 | if (IS_ERR(nd->intent.open.file)) { |
2220 | 2187 | error = PTR_ERR(nd->intent.open.file); |
2221 | 2188 | goto exit_mutex_unlock; |
2222 | 2189 | } |
2223 | 2190 | |
2224 | 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 | 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 | 2199 | * the time when the file is created and when |
2230 | 2200 | * a permanent write count is taken through |
2231 | 2201 | * the 'struct file' in nameidata_to_filp(). |
2232 | 2202 | |
2233 | 2203 | |
... | ... | @@ -2234,13 +2204,19 @@ |
2234 | 2204 | if (error) |
2235 | 2205 | goto exit_mutex_unlock; |
2236 | 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 | 2207 | /* Don't check for write permission, don't truncate */ |
2242 | 2208 | open_flag &= ~O_TRUNC; |
2209 | + will_truncate = 0; | |
2243 | 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 | 2220 | goto common; |
2245 | 2221 | } |
2246 | 2222 | |
... | ... | @@ -2271,7 +2247,9 @@ |
2271 | 2247 | if (S_ISDIR(nd->inode->i_mode)) |
2272 | 2248 | goto exit; |
2273 | 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 | 2253 | if (will_truncate) { |
2276 | 2254 | error = mnt_want_write(nd->path.mnt); |
2277 | 2255 | if (error) |