Commit c3e380b0b3cfa613189fb91513efd88a65e1d9d8

Authored by Al Viro
1 parent f1afe9efc8

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

... ... @@ -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);