diff options
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 88 |
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 | ||
2172 | struct 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 | */ |
2307 | struct file *do_filp_open(int dfd, const char *pathname, | 2300 | struct 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); |
2390 | out2: | 2337 | out2: |
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 | */ | ||
2479 | struct file *filp_open(const char *filename, int flags, int mode) | ||
2480 | { | ||
2481 | return do_filp_open(AT_FDCWD, filename, flags, mode, 0); | ||
2482 | } | ||
2483 | EXPORT_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 |