Commit c3e380b0b3cfa613189fb91513efd88a65e1d9d8
1 parent
f1afe9efc8
Exists in
master
and in
20 other branches
Collect "operation mode" arguments of do_last() into a structure
No point messing with passing shitloads of "operation mode" arguments to do_open() one by one, especially since they are not going to change during do_filp_open(). Collect them into a struct, fill it and pass to do_last() by reference. Make sure that lookup intent flags are correctly set and removed - we want them for do_last(), but they make no sense for __do_follow_link(). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 1 changed file with 35 additions and 22 deletions Side-by-side Diff
fs/namei.c
... | ... | @@ -2169,17 +2169,26 @@ |
2169 | 2169 | return ERR_PTR(error); |
2170 | 2170 | } |
2171 | 2171 | |
2172 | +struct open_flags { | |
2173 | + int open_flag; | |
2174 | + int mode; | |
2175 | + int acc_mode; | |
2176 | + int intent; | |
2177 | +}; | |
2178 | + | |
2172 | 2179 | /* |
2173 | 2180 | * Handle O_CREAT case for do_filp_open |
2174 | 2181 | */ |
2175 | 2182 | static struct file *do_last(struct nameidata *nd, struct path *path, |
2176 | - int open_flag, int acc_mode, | |
2177 | - int mode, const char *pathname) | |
2183 | + const struct open_flags *op, const char *pathname) | |
2178 | 2184 | { |
2179 | 2185 | struct dentry *dir = nd->path.dentry; |
2180 | 2186 | struct file *filp; |
2181 | 2187 | int error; |
2182 | 2188 | |
2189 | + nd->flags &= ~LOOKUP_PARENT; | |
2190 | + nd->flags |= op->intent; | |
2191 | + | |
2183 | 2192 | switch (nd->last_type) { |
2184 | 2193 | case LAST_DOTDOT: |
2185 | 2194 | follow_dotdot(nd); |
... | ... | @@ -2233,7 +2242,7 @@ |
2233 | 2242 | error = mnt_want_write(nd->path.mnt); |
2234 | 2243 | if (error) |
2235 | 2244 | goto exit_mutex_unlock; |
2236 | - error = __open_namei_create(nd, path, open_flag, mode); | |
2245 | + error = __open_namei_create(nd, path, op->open_flag, op->mode); | |
2237 | 2246 | if (error) { |
2238 | 2247 | mnt_drop_write(nd->path.mnt); |
2239 | 2248 | goto exit; |
... | ... | @@ -2242,7 +2251,7 @@ |
2242 | 2251 | mnt_drop_write(nd->path.mnt); |
2243 | 2252 | path_put(&nd->path); |
2244 | 2253 | if (!IS_ERR(filp)) { |
2245 | - error = ima_file_check(filp, acc_mode); | |
2254 | + error = ima_file_check(filp, op->acc_mode); | |
2246 | 2255 | if (error) { |
2247 | 2256 | fput(filp); |
2248 | 2257 | filp = ERR_PTR(error); |
... | ... | @@ -2258,7 +2267,7 @@ |
2258 | 2267 | audit_inode(pathname, path->dentry); |
2259 | 2268 | |
2260 | 2269 | error = -EEXIST; |
2261 | - if (open_flag & O_EXCL) | |
2270 | + if (op->open_flag & O_EXCL) | |
2262 | 2271 | goto exit_dput; |
2263 | 2272 | |
2264 | 2273 | error = follow_managed(path, nd->flags); |
... | ... | @@ -2278,7 +2287,7 @@ |
2278 | 2287 | if (S_ISDIR(nd->inode->i_mode)) |
2279 | 2288 | goto exit; |
2280 | 2289 | ok: |
2281 | - filp = finish_open(nd, open_flag, acc_mode); | |
2290 | + filp = finish_open(nd, op->open_flag, op->acc_mode); | |
2282 | 2291 | return filp; |
2283 | 2292 | |
2284 | 2293 | exit_mutex_unlock: |
... | ... | @@ -2304,7 +2313,8 @@ |
2304 | 2313 | struct path path; |
2305 | 2314 | int count = 0; |
2306 | 2315 | int flag = open_to_namei_flags(open_flag); |
2307 | - int flags; | |
2316 | + int flags = 0; | |
2317 | + struct open_flags op; | |
2308 | 2318 | |
2309 | 2319 | if (!(open_flag & O_CREAT)) |
2310 | 2320 | mode = 0; |
... | ... | @@ -2321,6 +2331,8 @@ |
2321 | 2331 | if (open_flag & __O_SYNC) |
2322 | 2332 | open_flag |= O_DSYNC; |
2323 | 2333 | |
2334 | + op.open_flag = open_flag; | |
2335 | + | |
2324 | 2336 | if (!acc_mode) |
2325 | 2337 | acc_mode = MAY_OPEN | ACC_MODE(open_flag); |
2326 | 2338 | |
2327 | 2339 | |
2328 | 2340 | |
2329 | 2341 | |
... | ... | @@ -2333,12 +2345,15 @@ |
2333 | 2345 | if (open_flag & O_APPEND) |
2334 | 2346 | acc_mode |= MAY_APPEND; |
2335 | 2347 | |
2336 | - flags = LOOKUP_OPEN; | |
2348 | + op.acc_mode = acc_mode; | |
2349 | + | |
2350 | + op.intent = LOOKUP_OPEN; | |
2337 | 2351 | if (open_flag & O_CREAT) { |
2338 | - flags |= LOOKUP_CREATE; | |
2352 | + op.intent |= LOOKUP_CREATE; | |
2339 | 2353 | if (open_flag & O_EXCL) |
2340 | - flags |= LOOKUP_EXCL; | |
2354 | + op.intent |= LOOKUP_EXCL; | |
2341 | 2355 | } |
2356 | + | |
2342 | 2357 | if (open_flag & O_DIRECTORY) |
2343 | 2358 | flags |= LOOKUP_DIRECTORY; |
2344 | 2359 | if (!(open_flag & O_NOFOLLOW)) |
... | ... | @@ -2357,7 +2372,7 @@ |
2357 | 2372 | goto creat; |
2358 | 2373 | |
2359 | 2374 | /* !O_CREAT, simple open */ |
2360 | - error = do_path_lookup(dfd, pathname, flags, &nd); | |
2375 | + error = do_path_lookup(dfd, pathname, flags | op.intent, &nd); | |
2361 | 2376 | if (unlikely(error)) |
2362 | 2377 | goto out_filp2; |
2363 | 2378 | error = -ELOOP; |
2364 | 2379 | |
2365 | 2380 | |
... | ... | @@ -2384,14 +2399,14 @@ |
2384 | 2399 | |
2385 | 2400 | creat: |
2386 | 2401 | /* OK, have to create the file. Find the parent. */ |
2387 | - error = path_lookupat(dfd, pathname, LOOKUP_PARENT | LOOKUP_RCU, &nd); | |
2402 | + error = path_lookupat(dfd, pathname, | |
2403 | + LOOKUP_PARENT | LOOKUP_RCU | flags, &nd); | |
2388 | 2404 | if (unlikely(error == -ECHILD)) |
2389 | - error = path_lookupat(dfd, pathname, LOOKUP_PARENT, &nd); | |
2405 | + error = path_lookupat(dfd, pathname, LOOKUP_PARENT | flags, &nd); | |
2390 | 2406 | if (unlikely(error == -ESTALE)) { |
2391 | 2407 | reval: |
2392 | 2408 | flags |= LOOKUP_REVAL; |
2393 | - error = path_lookupat(dfd, pathname, | |
2394 | - LOOKUP_PARENT | LOOKUP_REVAL, &nd); | |
2409 | + error = path_lookupat(dfd, pathname, LOOKUP_PARENT | flags, &nd); | |
2395 | 2410 | } |
2396 | 2411 | if (unlikely(error)) |
2397 | 2412 | goto out_filp; |
... | ... | @@ -2401,8 +2416,7 @@ |
2401 | 2416 | /* |
2402 | 2417 | * We have the parent and last component. |
2403 | 2418 | */ |
2404 | - nd.flags = (nd.flags & ~LOOKUP_PARENT) | flags; | |
2405 | - filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname); | |
2419 | + filp = do_last(&nd, &path, &op, pathname); | |
2406 | 2420 | while (unlikely(!filp)) { /* trailing symlink */ |
2407 | 2421 | struct path link = path; |
2408 | 2422 | struct inode *linki = link.dentry->d_inode; |
2409 | 2423 | |
2410 | 2424 | |
... | ... | @@ -2424,13 +2438,12 @@ |
2424 | 2438 | * just set LAST_BIND. |
2425 | 2439 | */ |
2426 | 2440 | nd.flags |= LOOKUP_PARENT; |
2441 | + nd.flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL); | |
2427 | 2442 | error = __do_follow_link(&link, &nd, &cookie); |
2428 | - if (unlikely(error)) { | |
2443 | + if (unlikely(error)) | |
2429 | 2444 | filp = ERR_PTR(error); |
2430 | - } else { | |
2431 | - nd.flags &= ~LOOKUP_PARENT; | |
2432 | - filp = do_last(&nd, &path, open_flag, acc_mode, mode, pathname); | |
2433 | - } | |
2445 | + else | |
2446 | + filp = do_last(&nd, &path, &op, pathname); | |
2434 | 2447 | if (!IS_ERR(cookie) && linki->i_op->put_link) |
2435 | 2448 | linki->i_op->put_link(link.dentry, &nd, cookie); |
2436 | 2449 | path_put(&link); |