aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c88
1 files changed, 9 insertions, 79 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 5e4206f45371..9c7fa946abe1 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2169,13 +2169,6 @@ exit:
2169 return ERR_PTR(error); 2169 return ERR_PTR(error);
2170} 2170}
2171 2171
2172struct open_flags {
2173 int open_flag;
2174 int mode;
2175 int acc_mode;
2176 int intent;
2177};
2178
2179/* 2172/*
2180 * Handle O_CREAT case for do_filp_open 2173 * Handle O_CREAT case for do_filp_open
2181 */ 2174 */
@@ -2305,74 +2298,28 @@ exit:
2305 * open_to_namei_flags() for more details. 2298 * open_to_namei_flags() for more details.
2306 */ 2299 */
2307struct file *do_filp_open(int dfd, const char *pathname, 2300struct file *do_filp_open(int dfd, const char *pathname,
2308 int open_flag, int mode, int acc_mode) 2301 const struct open_flags *op, int flags)
2309{ 2302{
2310 struct file *filp; 2303 struct file *filp;
2311 struct nameidata nd; 2304 struct nameidata nd;
2312 int error; 2305 int error;
2313 struct path path; 2306 struct path path;
2314 int count = 0; 2307 int count = 0;
2315 int flag = open_to_namei_flags(open_flag);
2316 int flags = 0;
2317 struct open_flags op;
2318
2319 if (!(open_flag & O_CREAT))
2320 mode = 0;
2321
2322 /* Must never be set by userspace */
2323 open_flag &= ~FMODE_NONOTIFY;
2324
2325 /*
2326 * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only
2327 * check for O_DSYNC if the need any syncing at all we enforce it's
2328 * always set instead of having to deal with possibly weird behaviour
2329 * for malicious applications setting only __O_SYNC.
2330 */
2331 if (open_flag & __O_SYNC)
2332 open_flag |= O_DSYNC;
2333
2334 op.open_flag = open_flag;
2335
2336 if (!acc_mode)
2337 acc_mode = MAY_OPEN | ACC_MODE(open_flag);
2338
2339 /* O_TRUNC implies we need access checks for write permissions */
2340 if (open_flag & O_TRUNC)
2341 acc_mode |= MAY_WRITE;
2342
2343 /* Allow the LSM permission hook to distinguish append
2344 access from general write access. */
2345 if (open_flag & O_APPEND)
2346 acc_mode |= MAY_APPEND;
2347
2348 op.acc_mode = acc_mode;
2349
2350 op.intent = LOOKUP_OPEN;
2351 if (open_flag & O_CREAT) {
2352 op.intent |= LOOKUP_CREATE;
2353 if (open_flag & O_EXCL)
2354 op.intent |= LOOKUP_EXCL;
2355 }
2356
2357 if (open_flag & O_DIRECTORY)
2358 flags |= LOOKUP_DIRECTORY;
2359 if (!(open_flag & O_NOFOLLOW))
2360 flags |= LOOKUP_FOLLOW;
2361 2308
2362 filp = get_empty_filp(); 2309 filp = get_empty_filp();
2363 if (!filp) 2310 if (!filp)
2364 return ERR_PTR(-ENFILE); 2311 return ERR_PTR(-ENFILE);
2365 2312
2366 filp->f_flags = open_flag; 2313 filp->f_flags = op->open_flag;
2367 nd.intent.open.file = filp; 2314 nd.intent.open.file = filp;
2368 nd.intent.open.flags = flag; 2315 nd.intent.open.flags = open_to_namei_flags(op->open_flag);
2369 nd.intent.open.create_mode = mode; 2316 nd.intent.open.create_mode = op->mode;
2370 2317
2371 if (open_flag & O_CREAT) 2318 if (op->open_flag & O_CREAT)
2372 goto creat; 2319 goto creat;
2373 2320
2374 /* !O_CREAT, simple open */ 2321 /* !O_CREAT, simple open */
2375 error = do_path_lookup(dfd, pathname, flags | op.intent, &nd); 2322 error = do_path_lookup(dfd, pathname, flags | op->intent, &nd);
2376 if (unlikely(error)) 2323 if (unlikely(error))
2377 goto out_filp2; 2324 goto out_filp2;
2378 error = -ELOOP; 2325 error = -ELOOP;
@@ -2386,7 +2333,7 @@ struct file *do_filp_open(int dfd, const char *pathname,
2386 goto out_path2; 2333 goto out_path2;
2387 } 2334 }
2388 audit_inode(pathname, nd.path.dentry); 2335 audit_inode(pathname, nd.path.dentry);
2389 filp = finish_open(&nd, open_flag, acc_mode); 2336 filp = finish_open(&nd, op->open_flag, op->acc_mode);
2390out2: 2337out2:
2391 release_open_intent(&nd); 2338 release_open_intent(&nd);
2392 return filp; 2339 return filp;
@@ -2416,7 +2363,7 @@ reval:
2416 /* 2363 /*
2417 * We have the parent and last component. 2364 * We have the parent and last component.
2418 */ 2365 */
2419 filp = do_last(&nd, &path, &op, pathname); 2366 filp = do_last(&nd, &path, op, pathname);
2420 while (unlikely(!filp)) { /* trailing symlink */ 2367 while (unlikely(!filp)) { /* trailing symlink */
2421 struct path link = path; 2368 struct path link = path;
2422 struct inode *linki = link.dentry->d_inode; 2369 struct inode *linki = link.dentry->d_inode;
@@ -2443,7 +2390,7 @@ reval:
2443 if (unlikely(error)) 2390 if (unlikely(error))
2444 filp = ERR_PTR(error); 2391 filp = ERR_PTR(error);
2445 else 2392 else
2446 filp = do_last(&nd, &path, &op, pathname); 2393 filp = do_last(&nd, &path, op, pathname);
2447 if (!IS_ERR(cookie) && linki->i_op->put_link) 2394 if (!IS_ERR(cookie) && linki->i_op->put_link)
2448 linki->i_op->put_link(link.dentry, &nd, cookie); 2395 linki->i_op->put_link(link.dentry, &nd, cookie);
2449 path_put(&link); 2396 path_put(&link);
@@ -2466,23 +2413,6 @@ out_filp:
2466} 2413}
2467 2414
2468/** 2415/**
2469 * filp_open - open file and return file pointer
2470 *
2471 * @filename: path to open
2472 * @flags: open flags as per the open(2) second argument
2473 * @mode: mode for the new file if O_CREAT is set, else ignored
2474 *
2475 * This is the helper to open a file from kernelspace if you really
2476 * have to. But in generally you should not do this, so please move
2477 * along, nothing to see here..
2478 */
2479struct file *filp_open(const char *filename, int flags, int mode)
2480{
2481 return do_filp_open(AT_FDCWD, filename, flags, mode, 0);
2482}
2483EXPORT_SYMBOL(filp_open);
2484
2485/**
2486 * lookup_create - lookup a dentry, creating it if it doesn't exist 2416 * lookup_create - lookup a dentry, creating it if it doesn't exist
2487 * @nd: nameidata info 2417 * @nd: nameidata info
2488 * @is_dir: directory flag 2418 * @is_dir: directory flag