Commit 47237687d73cbeae1dd7a133c3fc3d7239094568
1 parent
a8277b9baa
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
->atomic_open() prototype change - pass int * instead of bool *
... and let finish_open() report having opened the file via that sucker. Next step: don't modify od->filp at all. [AV: FILE_CREATE was already used by cifs; Miklos' fix folded] Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Showing 14 changed files with 63 additions and 52 deletions Side-by-side Diff
Documentation/filesystems/Locking
... | ... | @@ -64,7 +64,7 @@ |
64 | 64 | void (*update_time)(struct inode *, struct timespec *, int); |
65 | 65 | struct file * (*atomic_open)(struct inode *, struct dentry *, |
66 | 66 | struct opendata *, unsigned open_flag, |
67 | - umode_t create_mode, bool *created); | |
67 | + umode_t create_mode, int *opened); | |
68 | 68 | |
69 | 69 | locking rules: |
70 | 70 | all may block |
Documentation/filesystems/vfs.txt
... | ... | @@ -366,7 +366,7 @@ |
366 | 366 | void (*update_time)(struct inode *, struct timespec *, int); |
367 | 367 | struct file * (*atomic_open)(struct inode *, struct dentry *, |
368 | 368 | struct opendata *, unsigned open_flag, |
369 | - umode_t create_mode, bool *created); | |
369 | + umode_t create_mode, int *opened); | |
370 | 370 | }; |
371 | 371 | |
372 | 372 | Again, all methods are called without any locks being held, unless |
fs/9p/vfs_inode.c
... | ... | @@ -859,7 +859,7 @@ |
859 | 859 | static struct file * |
860 | 860 | v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, |
861 | 861 | struct opendata *od, unsigned flags, umode_t mode, |
862 | - bool *created) | |
862 | + int *opened) | |
863 | 863 | { |
864 | 864 | int err; |
865 | 865 | u32 perm; |
... | ... | @@ -918,7 +918,7 @@ |
918 | 918 | v9inode->writeback_fid = (void *) inode_fid; |
919 | 919 | } |
920 | 920 | mutex_unlock(&v9inode->v_mutex); |
921 | - filp = finish_open(od, dentry, generic_file_open); | |
921 | + filp = finish_open(od, dentry, generic_file_open, opened); | |
922 | 922 | if (IS_ERR(filp)) { |
923 | 923 | err = PTR_ERR(filp); |
924 | 924 | goto error; |
... | ... | @@ -930,7 +930,7 @@ |
930 | 930 | v9fs_cache_inode_set_cookie(dentry->d_inode, filp); |
931 | 931 | #endif |
932 | 932 | |
933 | - *created = true; | |
933 | + *opened |= FILE_CREATED; | |
934 | 934 | out: |
935 | 935 | dput(res); |
936 | 936 | return filp; |
fs/9p/vfs_inode_dotl.c
... | ... | @@ -243,7 +243,7 @@ |
243 | 243 | static struct file * |
244 | 244 | v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, |
245 | 245 | struct opendata *od, unsigned flags, umode_t omode, |
246 | - bool *created) | |
246 | + int *opened) | |
247 | 247 | { |
248 | 248 | int err = 0; |
249 | 249 | gid_t gid; |
... | ... | @@ -357,7 +357,7 @@ |
357 | 357 | } |
358 | 358 | mutex_unlock(&v9inode->v_mutex); |
359 | 359 | /* Since we are opening a file, assign the open fid to the file */ |
360 | - filp = finish_open(od, dentry, generic_file_open); | |
360 | + filp = finish_open(od, dentry, generic_file_open, opened); | |
361 | 361 | if (IS_ERR(filp)) { |
362 | 362 | err = PTR_ERR(filp); |
363 | 363 | goto err_clunk_old_fid; |
... | ... | @@ -367,7 +367,7 @@ |
367 | 367 | if (v9ses->cache) |
368 | 368 | v9fs_cache_inode_set_cookie(inode, filp); |
369 | 369 | #endif |
370 | - *created = true; | |
370 | + *opened |= FILE_CREATED; | |
371 | 371 | out: |
372 | 372 | dput(res); |
373 | 373 | return filp; |
fs/ceph/dir.c
... | ... | @@ -636,7 +636,7 @@ |
636 | 636 | |
637 | 637 | struct file *ceph_atomic_open(struct inode *dir, struct dentry *dentry, |
638 | 638 | struct opendata *od, unsigned flags, umode_t mode, |
639 | - bool *created) | |
639 | + int *opened) | |
640 | 640 | { |
641 | 641 | int err; |
642 | 642 | struct dentry *res = NULL; |
... | ... | @@ -650,7 +650,7 @@ |
650 | 650 | if (err < 0) |
651 | 651 | return ERR_PTR(err); |
652 | 652 | |
653 | - return ceph_lookup_open(dir, dentry, od, flags, mode); | |
653 | + return ceph_lookup_open(dir, dentry, od, flags, mode, opened); | |
654 | 654 | } |
655 | 655 | |
656 | 656 | if (d_unhashed(dentry)) { |
... | ... | @@ -668,8 +668,8 @@ |
668 | 668 | return NULL; |
669 | 669 | } |
670 | 670 | |
671 | - *created = true; | |
672 | - filp = ceph_lookup_open(dir, dentry, od, flags, mode); | |
671 | + *opened |= FILE_CREATED; | |
672 | + filp = ceph_lookup_open(dir, dentry, od, flags, mode, opened); | |
673 | 673 | dput(res); |
674 | 674 | |
675 | 675 | return filp; |
fs/ceph/file.c
... | ... | @@ -214,7 +214,8 @@ |
214 | 214 | * ceph_release gets called). So fear not! |
215 | 215 | */ |
216 | 216 | struct file *ceph_lookup_open(struct inode *dir, struct dentry *dentry, |
217 | - struct opendata *od, unsigned flags, umode_t mode) | |
217 | + struct opendata *od, unsigned flags, umode_t mode, | |
218 | + int *opened) | |
218 | 219 | { |
219 | 220 | struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); |
220 | 221 | struct ceph_mds_client *mdsc = fsc->mdsc; |
... | ... | @@ -247,7 +248,7 @@ |
247 | 248 | err = ceph_handle_notrace_create(dir, dentry); |
248 | 249 | if (err) |
249 | 250 | goto out; |
250 | - file = finish_open(od, req->r_dentry, ceph_open); | |
251 | + file = finish_open(od, req->r_dentry, ceph_open, opened); | |
251 | 252 | if (IS_ERR(file)) |
252 | 253 | err = PTR_ERR(file); |
253 | 254 | out: |
fs/ceph/super.h
... | ... | @@ -808,7 +808,7 @@ |
808 | 808 | extern int ceph_open(struct inode *inode, struct file *file); |
809 | 809 | extern struct file *ceph_lookup_open(struct inode *dir, struct dentry *dentry, |
810 | 810 | struct opendata *od, unsigned flags, |
811 | - umode_t mode); | |
811 | + umode_t mode, int *opened); | |
812 | 812 | extern int ceph_release(struct inode *inode, struct file *filp); |
813 | 813 | |
814 | 814 | /* dir.c */ |
fs/cifs/cifsfs.h
... | ... | @@ -48,7 +48,7 @@ |
48 | 48 | struct nameidata *); |
49 | 49 | extern struct file *cifs_atomic_open(struct inode *, struct dentry *, |
50 | 50 | struct opendata *, unsigned, umode_t, |
51 | - bool *); | |
51 | + int *); | |
52 | 52 | extern struct dentry *cifs_lookup(struct inode *, struct dentry *, |
53 | 53 | struct nameidata *); |
54 | 54 | extern int cifs_unlink(struct inode *dir, struct dentry *dentry); |
fs/cifs/dir.c
... | ... | @@ -160,7 +160,7 @@ |
160 | 160 | static int cifs_do_create(struct inode *inode, struct dentry *direntry, |
161 | 161 | int xid, struct tcon_link *tlink, unsigned oflags, |
162 | 162 | umode_t mode, __u32 *oplock, __u16 *fileHandle, |
163 | - bool *created) | |
163 | + int *created) | |
164 | 164 | { |
165 | 165 | int rc = -ENOENT; |
166 | 166 | int create_options = CREATE_NOT_DIR; |
... | ... | @@ -311,7 +311,7 @@ |
311 | 311 | .device = 0, |
312 | 312 | }; |
313 | 313 | |
314 | - *created = true; | |
314 | + *created |= FILE_CREATED; | |
315 | 315 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { |
316 | 316 | args.uid = (__u64) current_fsuid(); |
317 | 317 | if (inode->i_mode & S_ISGID) |
... | ... | @@ -379,7 +379,7 @@ |
379 | 379 | struct file * |
380 | 380 | cifs_atomic_open(struct inode *inode, struct dentry *direntry, |
381 | 381 | struct opendata *od, unsigned oflags, umode_t mode, |
382 | - bool *created) | |
382 | + int *opened) | |
383 | 383 | { |
384 | 384 | int rc; |
385 | 385 | int xid; |
386 | 386 | |
... | ... | @@ -426,14 +426,14 @@ |
426 | 426 | tcon = tlink_tcon(tlink); |
427 | 427 | |
428 | 428 | rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, |
429 | - &oplock, &fileHandle, created); | |
429 | + &oplock, &fileHandle, opened); | |
430 | 430 | |
431 | 431 | if (rc) { |
432 | 432 | filp = ERR_PTR(rc); |
433 | 433 | goto out; |
434 | 434 | } |
435 | 435 | |
436 | - filp = finish_open(od, direntry, generic_file_open); | |
436 | + filp = finish_open(od, direntry, generic_file_open, opened); | |
437 | 437 | if (IS_ERR(filp)) { |
438 | 438 | CIFSSMBClose(xid, tcon, fileHandle); |
439 | 439 | goto out; |
... | ... | @@ -469,7 +469,7 @@ |
469 | 469 | struct tcon_link *tlink; |
470 | 470 | __u16 fileHandle; |
471 | 471 | __u32 oplock; |
472 | - bool created = true; | |
472 | + int created = FILE_CREATED; | |
473 | 473 | |
474 | 474 | cFYI(1, "cifs_create parent inode = 0x%p name is: %s and dentry = 0x%p", |
475 | 475 | inode, direntry->d_name.name, direntry); |
fs/fuse/dir.c
... | ... | @@ -371,7 +371,7 @@ |
371 | 371 | */ |
372 | 372 | static struct file *fuse_create_open(struct inode *dir, struct dentry *entry, |
373 | 373 | struct opendata *od, unsigned flags, |
374 | - umode_t mode) | |
374 | + umode_t mode, int *opened) | |
375 | 375 | { |
376 | 376 | int err; |
377 | 377 | struct inode *inode; |
... | ... | @@ -450,7 +450,7 @@ |
450 | 450 | d_instantiate(entry, inode); |
451 | 451 | fuse_change_entry_timeout(entry, &outentry); |
452 | 452 | fuse_invalidate_attr(dir); |
453 | - file = finish_open(od, entry, generic_file_open); | |
453 | + file = finish_open(od, entry, generic_file_open, opened); | |
454 | 454 | if (IS_ERR(file)) { |
455 | 455 | fuse_sync_release(ff, flags); |
456 | 456 | } else { |
... | ... | @@ -472,7 +472,7 @@ |
472 | 472 | static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t); |
473 | 473 | static struct file *fuse_atomic_open(struct inode *dir, struct dentry *entry, |
474 | 474 | struct opendata *od, unsigned flags, |
475 | - umode_t mode, bool *created) | |
475 | + umode_t mode, int *opened) | |
476 | 476 | { |
477 | 477 | int err; |
478 | 478 | struct fuse_conn *fc = get_fuse_conn(dir); |
479 | 479 | |
... | ... | @@ -492,12 +492,12 @@ |
492 | 492 | goto no_open; |
493 | 493 | |
494 | 494 | /* Only creates */ |
495 | - *created = true; | |
495 | + *opened |= FILE_CREATED; | |
496 | 496 | |
497 | 497 | if (fc->no_create) |
498 | 498 | goto mknod; |
499 | 499 | |
500 | - file = fuse_create_open(dir, entry, od, flags, mode); | |
500 | + file = fuse_create_open(dir, entry, od, flags, mode, opened); | |
501 | 501 | if (PTR_ERR(file) == -ENOSYS) { |
502 | 502 | fc->no_create = 1; |
503 | 503 | goto mknod; |
fs/namei.c
... | ... | @@ -2197,7 +2197,7 @@ |
2197 | 2197 | struct path *path, struct opendata *od, |
2198 | 2198 | const struct open_flags *op, |
2199 | 2199 | bool *want_write, bool need_lookup, |
2200 | - bool *created) | |
2200 | + int *opened) | |
2201 | 2201 | { |
2202 | 2202 | struct inode *dir = nd->path.dentry->d_inode; |
2203 | 2203 | unsigned open_flag = open_to_namei_flags(op->open_flag); |
... | ... | @@ -2222,7 +2222,7 @@ |
2222 | 2222 | |
2223 | 2223 | if (open_flag & O_EXCL) { |
2224 | 2224 | open_flag &= ~O_TRUNC; |
2225 | - *created = true; | |
2225 | + *opened |= FILE_CREATED; | |
2226 | 2226 | } |
2227 | 2227 | |
2228 | 2228 | /* |
... | ... | @@ -2272,7 +2272,7 @@ |
2272 | 2272 | od->dentry = DENTRY_NOT_SET; |
2273 | 2273 | od->mnt = nd->path.mnt; |
2274 | 2274 | filp = dir->i_op->atomic_open(dir, dentry, od, open_flag, mode, |
2275 | - created); | |
2275 | + opened); | |
2276 | 2276 | if (IS_ERR(filp)) { |
2277 | 2277 | if (WARN_ON(od->dentry != DENTRY_NOT_SET)) |
2278 | 2278 | dput(od->dentry); |
... | ... | @@ -2283,7 +2283,7 @@ |
2283 | 2283 | } |
2284 | 2284 | |
2285 | 2285 | acc_mode = op->acc_mode; |
2286 | - if (*created) { | |
2286 | + if (*opened & FILE_CREATED) { | |
2287 | 2287 | fsnotify_create(dir, dentry); |
2288 | 2288 | acc_mode = MAY_OPEN; |
2289 | 2289 | } |
... | ... | @@ -2353,7 +2353,7 @@ |
2353 | 2353 | static struct file *lookup_open(struct nameidata *nd, struct path *path, |
2354 | 2354 | struct opendata *od, |
2355 | 2355 | const struct open_flags *op, |
2356 | - bool *want_write, bool *created) | |
2356 | + bool *want_write, int *opened) | |
2357 | 2357 | { |
2358 | 2358 | struct dentry *dir = nd->path.dentry; |
2359 | 2359 | struct inode *dir_inode = dir->d_inode; |
... | ... | @@ -2361,7 +2361,7 @@ |
2361 | 2361 | int error; |
2362 | 2362 | bool need_lookup; |
2363 | 2363 | |
2364 | - *created = false; | |
2364 | + *opened &= ~FILE_CREATED; | |
2365 | 2365 | dentry = lookup_dcache(&nd->last, dir, nd, &need_lookup); |
2366 | 2366 | if (IS_ERR(dentry)) |
2367 | 2367 | return ERR_CAST(dentry); |
... | ... | @@ -2372,7 +2372,7 @@ |
2372 | 2372 | |
2373 | 2373 | if ((nd->flags & LOOKUP_OPEN) && dir_inode->i_op->atomic_open) { |
2374 | 2374 | return atomic_open(nd, dentry, path, od, op, want_write, |
2375 | - need_lookup, created); | |
2375 | + need_lookup, opened); | |
2376 | 2376 | } |
2377 | 2377 | |
2378 | 2378 | if (need_lookup) { |
... | ... | @@ -2399,7 +2399,7 @@ |
2399 | 2399 | if (error) |
2400 | 2400 | goto out_dput; |
2401 | 2401 | *want_write = true; |
2402 | - *created = true; | |
2402 | + *opened |= FILE_CREATED; | |
2403 | 2403 | error = security_path_mknod(&nd->path, dentry, mode, 0); |
2404 | 2404 | if (error) |
2405 | 2405 | goto out_dput; |
... | ... | @@ -2422,7 +2422,7 @@ |
2422 | 2422 | */ |
2423 | 2423 | static struct file *do_last(struct nameidata *nd, struct path *path, |
2424 | 2424 | struct opendata *od, const struct open_flags *op, |
2425 | - const char *pathname) | |
2425 | + int *opened, const char *pathname) | |
2426 | 2426 | { |
2427 | 2427 | struct dentry *dir = nd->path.dentry; |
2428 | 2428 | int open_flag = op->open_flag; |
... | ... | @@ -2431,7 +2431,6 @@ |
2431 | 2431 | int acc_mode = op->acc_mode; |
2432 | 2432 | struct file *filp; |
2433 | 2433 | struct inode *inode; |
2434 | - bool created; | |
2435 | 2434 | bool symlink_ok = false; |
2436 | 2435 | struct path save_parent = { .dentry = NULL, .mnt = NULL }; |
2437 | 2436 | bool retried = false; |
2438 | 2437 | |
2439 | 2438 | |
... | ... | @@ -2499,21 +2498,22 @@ |
2499 | 2498 | |
2500 | 2499 | retry_lookup: |
2501 | 2500 | mutex_lock(&dir->d_inode->i_mutex); |
2502 | - filp = lookup_open(nd, path, od, op, &want_write, &created); | |
2501 | + filp = lookup_open(nd, path, od, op, &want_write, opened); | |
2503 | 2502 | mutex_unlock(&dir->d_inode->i_mutex); |
2504 | 2503 | |
2505 | 2504 | if (filp) { |
2506 | 2505 | if (IS_ERR(filp)) |
2507 | 2506 | goto out; |
2508 | 2507 | |
2509 | - if (created || !S_ISREG(filp->f_path.dentry->d_inode->i_mode)) | |
2508 | + if ((*opened & FILE_CREATED) || | |
2509 | + !S_ISREG(filp->f_path.dentry->d_inode->i_mode)) | |
2510 | 2510 | will_truncate = false; |
2511 | 2511 | |
2512 | 2512 | audit_inode(pathname, filp->f_path.dentry); |
2513 | 2513 | goto opened; |
2514 | 2514 | } |
2515 | 2515 | |
2516 | - if (created) { | |
2516 | + if (*opened & FILE_CREATED) { | |
2517 | 2517 | /* Don't check for write permission, don't truncate */ |
2518 | 2518 | open_flag &= ~O_TRUNC; |
2519 | 2519 | will_truncate = false; |
... | ... | @@ -2606,7 +2606,7 @@ |
2606 | 2606 | if (error) |
2607 | 2607 | goto exit; |
2608 | 2608 | od->mnt = nd->path.mnt; |
2609 | - filp = finish_open(od, nd->path.dentry, NULL); | |
2609 | + filp = finish_open(od, nd->path.dentry, NULL, opened); | |
2610 | 2610 | if (IS_ERR(filp)) { |
2611 | 2611 | if (filp == ERR_PTR(-EOPENSTALE)) |
2612 | 2612 | goto stale_open; |
... | ... | @@ -2667,6 +2667,7 @@ |
2667 | 2667 | struct opendata od; |
2668 | 2668 | struct file *res; |
2669 | 2669 | struct path path; |
2670 | + int opened = 0; | |
2670 | 2671 | int error; |
2671 | 2672 | |
2672 | 2673 | od.filp = get_empty_filp(); |
... | ... | @@ -2684,7 +2685,7 @@ |
2684 | 2685 | if (unlikely(error)) |
2685 | 2686 | goto out_filp; |
2686 | 2687 | |
2687 | - res = do_last(nd, &path, &od, op, pathname); | |
2688 | + res = do_last(nd, &path, &od, op, &opened, pathname); | |
2688 | 2689 | while (unlikely(!res)) { /* trailing symlink */ |
2689 | 2690 | struct path link = path; |
2690 | 2691 | void *cookie; |
... | ... | @@ -2699,7 +2700,7 @@ |
2699 | 2700 | error = follow_link(&link, nd, &cookie); |
2700 | 2701 | if (unlikely(error)) |
2701 | 2702 | goto out_filp; |
2702 | - res = do_last(nd, &path, &od, op, pathname); | |
2703 | + res = do_last(nd, &path, &od, op, &opened, pathname); | |
2703 | 2704 | put_link(nd, &link, cookie); |
2704 | 2705 | } |
2705 | 2706 | out: |
fs/nfs/dir.c
... | ... | @@ -113,7 +113,7 @@ |
113 | 113 | |
114 | 114 | static struct file *nfs_atomic_open(struct inode *, struct dentry *, |
115 | 115 | struct opendata *, unsigned, umode_t, |
116 | - bool *); | |
116 | + int *); | |
117 | 117 | const struct inode_operations nfs4_dir_inode_operations = { |
118 | 118 | .create = nfs_create, |
119 | 119 | .lookup = nfs_lookup, |
... | ... | @@ -1389,7 +1389,8 @@ |
1389 | 1389 | |
1390 | 1390 | static struct file *nfs_finish_open(struct nfs_open_context *ctx, |
1391 | 1391 | struct dentry *dentry, |
1392 | - struct opendata *od, unsigned open_flags) | |
1392 | + struct opendata *od, unsigned open_flags, | |
1393 | + int *opened) | |
1393 | 1394 | { |
1394 | 1395 | struct file *filp; |
1395 | 1396 | int err; |
... | ... | @@ -1408,7 +1409,7 @@ |
1408 | 1409 | } |
1409 | 1410 | } |
1410 | 1411 | |
1411 | - filp = finish_open(od, dentry, do_open); | |
1412 | + filp = finish_open(od, dentry, do_open, opened); | |
1412 | 1413 | if (!IS_ERR(filp)) |
1413 | 1414 | nfs_file_set_open_context(filp, ctx); |
1414 | 1415 | |
... | ... | @@ -1419,7 +1420,7 @@ |
1419 | 1420 | |
1420 | 1421 | static struct file *nfs_atomic_open(struct inode *dir, struct dentry *dentry, |
1421 | 1422 | struct opendata *od, unsigned open_flags, |
1422 | - umode_t mode, bool *created) | |
1423 | + umode_t mode, int *opened) | |
1423 | 1424 | { |
1424 | 1425 | struct nfs_open_context *ctx; |
1425 | 1426 | struct dentry *res; |
... | ... | @@ -1497,7 +1498,7 @@ |
1497 | 1498 | nfs_unblock_sillyrename(dentry->d_parent); |
1498 | 1499 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
1499 | 1500 | |
1500 | - filp = nfs_finish_open(ctx, dentry, od, open_flags); | |
1501 | + filp = nfs_finish_open(ctx, dentry, od, open_flags, opened); | |
1501 | 1502 | |
1502 | 1503 | dput(res); |
1503 | 1504 | return filp; |
fs/open.c
... | ... | @@ -782,7 +782,8 @@ |
782 | 782 | * filesystem callback is substituted. |
783 | 783 | */ |
784 | 784 | struct file *finish_open(struct opendata *od, struct dentry *dentry, |
785 | - int (*open)(struct inode *, struct file *)) | |
785 | + int (*open)(struct inode *, struct file *), | |
786 | + int *opened) | |
786 | 787 | { |
787 | 788 | struct file *res; |
788 | 789 | |
789 | 790 | |
... | ... | @@ -790,8 +791,10 @@ |
790 | 791 | dget(dentry); |
791 | 792 | |
792 | 793 | res = do_dentry_open(dentry, od->mnt, od->filp, open, current_cred()); |
793 | - if (!IS_ERR(res)) | |
794 | + if (!IS_ERR(res)) { | |
795 | + *opened |= FILE_OPENED; | |
794 | 796 | od->filp = NULL; |
797 | + } | |
795 | 798 | |
796 | 799 | return res; |
797 | 800 | } |
include/linux/fs.h
... | ... | @@ -1696,7 +1696,7 @@ |
1696 | 1696 | int (*update_time)(struct inode *, struct timespec *, int); |
1697 | 1697 | struct file * (*atomic_open)(struct inode *, struct dentry *, |
1698 | 1698 | struct opendata *, unsigned open_flag, |
1699 | - umode_t create_mode, bool *created); | |
1699 | + umode_t create_mode, int *opened); | |
1700 | 1700 | } ____cacheline_aligned; |
1701 | 1701 | |
1702 | 1702 | struct seq_file; |
1703 | 1703 | |
... | ... | @@ -2065,8 +2065,13 @@ |
2065 | 2065 | const struct cred *); |
2066 | 2066 | extern int filp_close(struct file *, fl_owner_t id); |
2067 | 2067 | extern char * getname(const char __user *); |
2068 | +enum { | |
2069 | + FILE_CREATED = 1, | |
2070 | + FILE_OPENED = 2 | |
2071 | +}; | |
2068 | 2072 | extern struct file *finish_open(struct opendata *od, struct dentry *dentry, |
2069 | - int (*open)(struct inode *, struct file *)); | |
2073 | + int (*open)(struct inode *, struct file *), | |
2074 | + int *opened); | |
2070 | 2075 | extern void finish_no_open(struct opendata *od, struct dentry *dentry); |
2071 | 2076 | |
2072 | 2077 | /* fs/ioctl.c */ |