diff options
-rw-r--r-- | Documentation/filesystems/Locking | 2 | ||||
-rw-r--r-- | Documentation/filesystems/vfs.txt | 2 | ||||
-rw-r--r-- | fs/9p/vfs_inode.c | 15 | ||||
-rw-r--r-- | fs/9p/vfs_inode_dotl.c | 15 | ||||
-rw-r--r-- | fs/ceph/dir.c | 8 | ||||
-rw-r--r-- | fs/ceph/file.c | 7 | ||||
-rw-r--r-- | fs/ceph/super.h | 2 | ||||
-rw-r--r-- | fs/cifs/cifsfs.h | 2 | ||||
-rw-r--r-- | fs/cifs/dir.c | 9 | ||||
-rw-r--r-- | fs/fuse/dir.c | 15 | ||||
-rw-r--r-- | fs/internal.h | 3 | ||||
-rw-r--r-- | fs/namei.c | 48 | ||||
-rw-r--r-- | fs/nfs/dir.c | 20 | ||||
-rw-r--r-- | fs/open.c | 20 | ||||
-rw-r--r-- | include/linux/fs.h | 11 |
15 files changed, 81 insertions, 98 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 46a24a6ed095..33e5243948f0 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -63,7 +63,7 @@ ata *); | |||
63 | int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); | 63 | int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); |
64 | void (*update_time)(struct inode *, struct timespec *, int); | 64 | void (*update_time)(struct inode *, struct timespec *, int); |
65 | int (*atomic_open)(struct inode *, struct dentry *, | 65 | int (*atomic_open)(struct inode *, struct dentry *, |
66 | struct opendata *, unsigned open_flag, | 66 | struct file *, unsigned open_flag, |
67 | umode_t create_mode, int *opened); | 67 | umode_t create_mode, int *opened); |
68 | 68 | ||
69 | locking rules: | 69 | locking rules: |
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index d0d690bbc4c7..279de2190365 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
@@ -365,7 +365,7 @@ struct inode_operations { | |||
365 | int (*removexattr) (struct dentry *, const char *); | 365 | int (*removexattr) (struct dentry *, const char *); |
366 | void (*update_time)(struct inode *, struct timespec *, int); | 366 | void (*update_time)(struct inode *, struct timespec *, int); |
367 | int (*atomic_open)(struct inode *, struct dentry *, | 367 | int (*atomic_open)(struct inode *, struct dentry *, |
368 | struct opendata *, unsigned open_flag, | 368 | struct file *, unsigned open_flag, |
369 | umode_t create_mode, int *opened); | 369 | umode_t create_mode, int *opened); |
370 | }; | 370 | }; |
371 | 371 | ||
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c index 62ce8daefa95..2b05651e0c3d 100644 --- a/fs/9p/vfs_inode.c +++ b/fs/9p/vfs_inode.c | |||
@@ -858,12 +858,11 @@ error: | |||
858 | 858 | ||
859 | static int | 859 | static int |
860 | v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, | 860 | v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, |
861 | struct opendata *od, unsigned flags, umode_t mode, | 861 | struct file *file, unsigned flags, umode_t mode, |
862 | int *opened) | 862 | int *opened) |
863 | { | 863 | { |
864 | int err; | 864 | int err; |
865 | u32 perm; | 865 | u32 perm; |
866 | struct file *filp; | ||
867 | struct v9fs_inode *v9inode; | 866 | struct v9fs_inode *v9inode; |
868 | struct v9fs_session_info *v9ses; | 867 | struct v9fs_session_info *v9ses; |
869 | struct p9_fid *fid, *inode_fid; | 868 | struct p9_fid *fid, *inode_fid; |
@@ -880,7 +879,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, | |||
880 | 879 | ||
881 | /* Only creates */ | 880 | /* Only creates */ |
882 | if (!(flags & O_CREAT) || dentry->d_inode) { | 881 | if (!(flags & O_CREAT) || dentry->d_inode) { |
883 | finish_no_open(od, res); | 882 | finish_no_open(file, res); |
884 | return 1; | 883 | return 1; |
885 | } | 884 | } |
886 | 885 | ||
@@ -918,16 +917,14 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, | |||
918 | v9inode->writeback_fid = (void *) inode_fid; | 917 | v9inode->writeback_fid = (void *) inode_fid; |
919 | } | 918 | } |
920 | mutex_unlock(&v9inode->v_mutex); | 919 | mutex_unlock(&v9inode->v_mutex); |
921 | filp = finish_open(od, dentry, generic_file_open, opened); | 920 | err = finish_open(file, dentry, generic_file_open, opened); |
922 | if (IS_ERR(filp)) { | 921 | if (err) |
923 | err = PTR_ERR(filp); | ||
924 | goto error; | 922 | goto error; |
925 | } | ||
926 | 923 | ||
927 | filp->private_data = fid; | 924 | file->private_data = fid; |
928 | #ifdef CONFIG_9P_FSCACHE | 925 | #ifdef CONFIG_9P_FSCACHE |
929 | if (v9ses->cache) | 926 | if (v9ses->cache) |
930 | v9fs_cache_inode_set_cookie(dentry->d_inode, filp); | 927 | v9fs_cache_inode_set_cookie(dentry->d_inode, file); |
931 | #endif | 928 | #endif |
932 | 929 | ||
933 | *opened |= FILE_CREATED; | 930 | *opened |= FILE_CREATED; |
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c index 69f05109f75d..cfaebdef9743 100644 --- a/fs/9p/vfs_inode_dotl.c +++ b/fs/9p/vfs_inode_dotl.c | |||
@@ -242,14 +242,13 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode, | |||
242 | 242 | ||
243 | static int | 243 | static int |
244 | v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, | 244 | v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, |
245 | struct opendata *od, unsigned flags, umode_t omode, | 245 | struct file *file, unsigned flags, umode_t omode, |
246 | int *opened) | 246 | int *opened) |
247 | { | 247 | { |
248 | int err = 0; | 248 | int err = 0; |
249 | gid_t gid; | 249 | gid_t gid; |
250 | umode_t mode; | 250 | umode_t mode; |
251 | char *name = NULL; | 251 | char *name = NULL; |
252 | struct file *filp; | ||
253 | struct p9_qid qid; | 252 | struct p9_qid qid; |
254 | struct inode *inode; | 253 | struct inode *inode; |
255 | struct p9_fid *fid = NULL; | 254 | struct p9_fid *fid = NULL; |
@@ -270,7 +269,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, | |||
270 | 269 | ||
271 | /* Only creates */ | 270 | /* Only creates */ |
272 | if (!(flags & O_CREAT) || dentry->d_inode) { | 271 | if (!(flags & O_CREAT) || dentry->d_inode) { |
273 | finish_no_open(od, res); | 272 | finish_no_open(file, res); |
274 | return 1; | 273 | return 1; |
275 | } | 274 | } |
276 | 275 | ||
@@ -357,15 +356,13 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, | |||
357 | } | 356 | } |
358 | mutex_unlock(&v9inode->v_mutex); | 357 | mutex_unlock(&v9inode->v_mutex); |
359 | /* Since we are opening a file, assign the open fid to the file */ | 358 | /* Since we are opening a file, assign the open fid to the file */ |
360 | filp = finish_open(od, dentry, generic_file_open, opened); | 359 | err = finish_open(file, dentry, generic_file_open, opened); |
361 | if (IS_ERR(filp)) { | 360 | if (err) |
362 | err = PTR_ERR(filp); | ||
363 | goto err_clunk_old_fid; | 361 | goto err_clunk_old_fid; |
364 | } | 362 | file->private_data = ofid; |
365 | filp->private_data = ofid; | ||
366 | #ifdef CONFIG_9P_FSCACHE | 363 | #ifdef CONFIG_9P_FSCACHE |
367 | if (v9ses->cache) | 364 | if (v9ses->cache) |
368 | v9fs_cache_inode_set_cookie(inode, filp); | 365 | v9fs_cache_inode_set_cookie(inode, file); |
369 | #endif | 366 | #endif |
370 | *opened |= FILE_CREATED; | 367 | *opened |= FILE_CREATED; |
371 | out: | 368 | out: |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index d8bfabeeaa25..80c848e05390 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -635,7 +635,7 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, | |||
635 | } | 635 | } |
636 | 636 | ||
637 | int ceph_atomic_open(struct inode *dir, struct dentry *dentry, | 637 | int ceph_atomic_open(struct inode *dir, struct dentry *dentry, |
638 | struct opendata *od, unsigned flags, umode_t mode, | 638 | struct file *file, unsigned flags, umode_t mode, |
639 | int *opened) | 639 | int *opened) |
640 | { | 640 | { |
641 | int err; | 641 | int err; |
@@ -649,7 +649,7 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry, | |||
649 | if (err < 0) | 649 | if (err < 0) |
650 | return err; | 650 | return err; |
651 | 651 | ||
652 | return ceph_lookup_open(dir, dentry, od, flags, mode, opened); | 652 | return ceph_lookup_open(dir, dentry, file, flags, mode, opened); |
653 | } | 653 | } |
654 | 654 | ||
655 | if (d_unhashed(dentry)) { | 655 | if (d_unhashed(dentry)) { |
@@ -663,12 +663,12 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry, | |||
663 | 663 | ||
664 | /* We don't deal with positive dentries here */ | 664 | /* We don't deal with positive dentries here */ |
665 | if (dentry->d_inode) { | 665 | if (dentry->d_inode) { |
666 | finish_no_open(od, res); | 666 | finish_no_open(file, res); |
667 | return 1; | 667 | return 1; |
668 | } | 668 | } |
669 | 669 | ||
670 | *opened |= FILE_CREATED; | 670 | *opened |= FILE_CREATED; |
671 | err = ceph_lookup_open(dir, dentry, od, flags, mode, opened); | 671 | err = ceph_lookup_open(dir, dentry, file, flags, mode, opened); |
672 | dput(res); | 672 | dput(res); |
673 | 673 | ||
674 | return err; | 674 | return err; |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index b8cc3ee5401e..1b81d6c31878 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -214,12 +214,11 @@ out: | |||
214 | * ceph_release gets called). So fear not! | 214 | * ceph_release gets called). So fear not! |
215 | */ | 215 | */ |
216 | int ceph_lookup_open(struct inode *dir, struct dentry *dentry, | 216 | int ceph_lookup_open(struct inode *dir, struct dentry *dentry, |
217 | struct opendata *od, unsigned flags, umode_t mode, | 217 | struct file *file, unsigned flags, umode_t mode, |
218 | int *opened) | 218 | int *opened) |
219 | { | 219 | { |
220 | struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); | 220 | struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); |
221 | struct ceph_mds_client *mdsc = fsc->mdsc; | 221 | struct ceph_mds_client *mdsc = fsc->mdsc; |
222 | struct file *file = NULL; | ||
223 | struct ceph_mds_request *req; | 222 | struct ceph_mds_request *req; |
224 | struct dentry *ret; | 223 | struct dentry *ret; |
225 | int err; | 224 | int err; |
@@ -248,9 +247,7 @@ int ceph_lookup_open(struct inode *dir, struct dentry *dentry, | |||
248 | err = ceph_handle_notrace_create(dir, dentry); | 247 | err = ceph_handle_notrace_create(dir, dentry); |
249 | if (err) | 248 | if (err) |
250 | goto out; | 249 | goto out; |
251 | file = finish_open(od, req->r_dentry, ceph_open, opened); | 250 | err = finish_open(file, req->r_dentry, ceph_open, opened); |
252 | if (IS_ERR(file)) | ||
253 | err = PTR_ERR(file); | ||
254 | out: | 251 | out: |
255 | ret = ceph_finish_lookup(req, dentry, err); | 252 | ret = ceph_finish_lookup(req, dentry, err); |
256 | ceph_mdsc_put_request(req); | 253 | ceph_mdsc_put_request(req); |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index f7e8e82ec47f..f4d5522cb619 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -807,7 +807,7 @@ extern int ceph_copy_from_page_vector(struct page **pages, | |||
807 | extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags); | 807 | extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags); |
808 | extern int ceph_open(struct inode *inode, struct file *file); | 808 | extern int ceph_open(struct inode *inode, struct file *file); |
809 | extern int ceph_lookup_open(struct inode *dir, struct dentry *dentry, | 809 | extern int ceph_lookup_open(struct inode *dir, struct dentry *dentry, |
810 | struct opendata *od, unsigned flags, | 810 | struct file *od, unsigned flags, |
811 | umode_t mode, int *opened); | 811 | umode_t mode, int *opened); |
812 | extern int ceph_release(struct inode *inode, struct file *filp); | 812 | extern int ceph_release(struct inode *inode, struct file *filp); |
813 | 813 | ||
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 58d9aca46a40..48bb474ce294 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -47,7 +47,7 @@ extern struct inode *cifs_root_iget(struct super_block *); | |||
47 | extern int cifs_create(struct inode *, struct dentry *, umode_t, | 47 | extern int cifs_create(struct inode *, struct dentry *, umode_t, |
48 | struct nameidata *); | 48 | struct nameidata *); |
49 | extern int cifs_atomic_open(struct inode *, struct dentry *, | 49 | extern int cifs_atomic_open(struct inode *, struct dentry *, |
50 | struct opendata *, unsigned, umode_t, | 50 | struct file *, unsigned, umode_t, |
51 | int *); | 51 | int *); |
52 | extern struct dentry *cifs_lookup(struct inode *, struct dentry *, | 52 | extern struct dentry *cifs_lookup(struct inode *, struct dentry *, |
53 | struct nameidata *); | 53 | struct nameidata *); |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 8ca70b102b95..c00c192f17e9 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -378,7 +378,7 @@ out: | |||
378 | 378 | ||
379 | int | 379 | int |
380 | cifs_atomic_open(struct inode *inode, struct dentry *direntry, | 380 | cifs_atomic_open(struct inode *inode, struct dentry *direntry, |
381 | struct opendata *od, unsigned oflags, umode_t mode, | 381 | struct file *file, unsigned oflags, umode_t mode, |
382 | int *opened) | 382 | int *opened) |
383 | { | 383 | { |
384 | int rc; | 384 | int rc; |
@@ -405,7 +405,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, | |||
405 | if (IS_ERR(res)) | 405 | if (IS_ERR(res)) |
406 | return PTR_ERR(res); | 406 | return PTR_ERR(res); |
407 | 407 | ||
408 | finish_no_open(od, res); | 408 | finish_no_open(file, res); |
409 | return 1; | 409 | return 1; |
410 | } | 410 | } |
411 | 411 | ||
@@ -431,9 +431,8 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, | |||
431 | if (rc) | 431 | if (rc) |
432 | goto out; | 432 | goto out; |
433 | 433 | ||
434 | filp = finish_open(od, direntry, generic_file_open, opened); | 434 | rc = finish_open(file, direntry, generic_file_open, opened); |
435 | if (IS_ERR(filp)) { | 435 | if (rc) { |
436 | rc = PTR_ERR(filp); | ||
437 | CIFSSMBClose(xid, tcon, fileHandle); | 436 | CIFSSMBClose(xid, tcon, fileHandle); |
438 | goto out; | 437 | goto out; |
439 | } | 438 | } |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 8a9ca09e87d4..110db5425dc1 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -370,7 +370,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
370 | * 'mknod' + 'open' requests. | 370 | * 'mknod' + 'open' requests. |
371 | */ | 371 | */ |
372 | static int fuse_create_open(struct inode *dir, struct dentry *entry, | 372 | static int fuse_create_open(struct inode *dir, struct dentry *entry, |
373 | struct opendata *od, unsigned flags, | 373 | struct file *file, unsigned flags, |
374 | umode_t mode, int *opened) | 374 | umode_t mode, int *opened) |
375 | { | 375 | { |
376 | int err; | 376 | int err; |
@@ -382,7 +382,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, | |||
382 | struct fuse_open_out outopen; | 382 | struct fuse_open_out outopen; |
383 | struct fuse_entry_out outentry; | 383 | struct fuse_entry_out outentry; |
384 | struct fuse_file *ff; | 384 | struct fuse_file *ff; |
385 | struct file *file; | ||
386 | 385 | ||
387 | forget = fuse_alloc_forget(); | 386 | forget = fuse_alloc_forget(); |
388 | err = -ENOMEM; | 387 | err = -ENOMEM; |
@@ -450,14 +449,12 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, | |||
450 | d_instantiate(entry, inode); | 449 | d_instantiate(entry, inode); |
451 | fuse_change_entry_timeout(entry, &outentry); | 450 | fuse_change_entry_timeout(entry, &outentry); |
452 | fuse_invalidate_attr(dir); | 451 | fuse_invalidate_attr(dir); |
453 | file = finish_open(od, entry, generic_file_open, opened); | 452 | err = finish_open(file, entry, generic_file_open, opened); |
454 | if (IS_ERR(file)) { | 453 | if (err) { |
455 | err = PTR_ERR(file); | ||
456 | fuse_sync_release(ff, flags); | 454 | fuse_sync_release(ff, flags); |
457 | } else { | 455 | } else { |
458 | file->private_data = fuse_file_get(ff); | 456 | file->private_data = fuse_file_get(ff); |
459 | fuse_finish_open(inode, file); | 457 | fuse_finish_open(inode, file); |
460 | err = 0; | ||
461 | } | 458 | } |
462 | return err; | 459 | return err; |
463 | 460 | ||
@@ -473,7 +470,7 @@ out_err: | |||
473 | 470 | ||
474 | static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t); | 471 | static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t); |
475 | static int fuse_atomic_open(struct inode *dir, struct dentry *entry, | 472 | static int fuse_atomic_open(struct inode *dir, struct dentry *entry, |
476 | struct opendata *od, unsigned flags, | 473 | struct file *file, unsigned flags, |
477 | umode_t mode, int *opened) | 474 | umode_t mode, int *opened) |
478 | { | 475 | { |
479 | int err; | 476 | int err; |
@@ -498,7 +495,7 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry, | |||
498 | if (fc->no_create) | 495 | if (fc->no_create) |
499 | goto mknod; | 496 | goto mknod; |
500 | 497 | ||
501 | err = fuse_create_open(dir, entry, od, flags, mode, opened); | 498 | err = fuse_create_open(dir, entry, file, flags, mode, opened); |
502 | if (err == -ENOSYS) { | 499 | if (err == -ENOSYS) { |
503 | fc->no_create = 1; | 500 | fc->no_create = 1; |
504 | goto mknod; | 501 | goto mknod; |
@@ -512,7 +509,7 @@ mknod: | |||
512 | if (err) | 509 | if (err) |
513 | goto out_dput; | 510 | goto out_dput; |
514 | no_open: | 511 | no_open: |
515 | finish_no_open(od, res); | 512 | finish_no_open(file, res); |
516 | return 1; | 513 | return 1; |
517 | } | 514 | } |
518 | 515 | ||
diff --git a/fs/internal.h b/fs/internal.h index 09003a02292d..8a9f5fa840f1 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -82,9 +82,6 @@ extern struct super_block *user_get_super(dev_t); | |||
82 | /* | 82 | /* |
83 | * open.c | 83 | * open.c |
84 | */ | 84 | */ |
85 | struct opendata { | ||
86 | struct file *filp; | ||
87 | }; | ||
88 | struct open_flags { | 85 | struct open_flags { |
89 | int open_flag; | 86 | int open_flag; |
90 | umode_t mode; | 87 | umode_t mode; |
diff --git a/fs/namei.c b/fs/namei.c index af83ede92a4f..aaff8a862151 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2194,7 +2194,7 @@ static int may_o_create(struct path *dir, struct dentry *dentry, umode_t mode) | |||
2194 | } | 2194 | } |
2195 | 2195 | ||
2196 | static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry, | 2196 | static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry, |
2197 | struct path *path, struct opendata *od, | 2197 | struct path *path, struct file *file, |
2198 | const struct open_flags *op, | 2198 | const struct open_flags *op, |
2199 | bool *want_write, bool need_lookup, | 2199 | bool *want_write, bool need_lookup, |
2200 | int *opened) | 2200 | int *opened) |
@@ -2269,9 +2269,9 @@ static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2269 | if (nd->flags & LOOKUP_DIRECTORY) | 2269 | if (nd->flags & LOOKUP_DIRECTORY) |
2270 | open_flag |= O_DIRECTORY; | 2270 | open_flag |= O_DIRECTORY; |
2271 | 2271 | ||
2272 | od->filp->f_path.dentry = DENTRY_NOT_SET; | 2272 | file->f_path.dentry = DENTRY_NOT_SET; |
2273 | od->filp->f_path.mnt = nd->path.mnt; | 2273 | file->f_path.mnt = nd->path.mnt; |
2274 | error = dir->i_op->atomic_open(dir, dentry, od, open_flag, mode, | 2274 | error = dir->i_op->atomic_open(dir, dentry, file, open_flag, mode, |
2275 | opened); | 2275 | opened); |
2276 | if (error < 0) { | 2276 | if (error < 0) { |
2277 | if (create_error && error == -ENOENT) | 2277 | if (create_error && error == -ENOENT) |
@@ -2287,13 +2287,13 @@ static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2287 | } | 2287 | } |
2288 | 2288 | ||
2289 | if (error) { /* returned 1, that is */ | 2289 | if (error) { /* returned 1, that is */ |
2290 | if (WARN_ON(od->filp->f_path.dentry == DENTRY_NOT_SET)) { | 2290 | if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) { |
2291 | filp = ERR_PTR(-EIO); | 2291 | filp = ERR_PTR(-EIO); |
2292 | goto out; | 2292 | goto out; |
2293 | } | 2293 | } |
2294 | if (od->filp->f_path.dentry) { | 2294 | if (file->f_path.dentry) { |
2295 | dput(dentry); | 2295 | dput(dentry); |
2296 | dentry = od->filp->f_path.dentry; | 2296 | dentry = file->f_path.dentry; |
2297 | } | 2297 | } |
2298 | goto looked_up; | 2298 | goto looked_up; |
2299 | } | 2299 | } |
@@ -2302,7 +2302,7 @@ static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2302 | * We didn't have the inode before the open, so check open permission | 2302 | * We didn't have the inode before the open, so check open permission |
2303 | * here. | 2303 | * here. |
2304 | */ | 2304 | */ |
2305 | filp = od->filp; | 2305 | filp = file; |
2306 | error = may_open(&filp->f_path, acc_mode, open_flag); | 2306 | error = may_open(&filp->f_path, acc_mode, open_flag); |
2307 | if (error) { | 2307 | if (error) { |
2308 | fput(filp); | 2308 | fput(filp); |
@@ -2350,7 +2350,7 @@ looked_up: | |||
2350 | * was performed, only lookup. | 2350 | * was performed, only lookup. |
2351 | */ | 2351 | */ |
2352 | static struct file *lookup_open(struct nameidata *nd, struct path *path, | 2352 | static struct file *lookup_open(struct nameidata *nd, struct path *path, |
2353 | struct opendata *od, | 2353 | struct file *file, |
2354 | const struct open_flags *op, | 2354 | const struct open_flags *op, |
2355 | bool *want_write, int *opened) | 2355 | bool *want_write, int *opened) |
2356 | { | 2356 | { |
@@ -2370,7 +2370,7 @@ static struct file *lookup_open(struct nameidata *nd, struct path *path, | |||
2370 | goto out_no_open; | 2370 | goto out_no_open; |
2371 | 2371 | ||
2372 | if ((nd->flags & LOOKUP_OPEN) && dir_inode->i_op->atomic_open) { | 2372 | if ((nd->flags & LOOKUP_OPEN) && dir_inode->i_op->atomic_open) { |
2373 | return atomic_open(nd, dentry, path, od, op, want_write, | 2373 | return atomic_open(nd, dentry, path, file, op, want_write, |
2374 | need_lookup, opened); | 2374 | need_lookup, opened); |
2375 | } | 2375 | } |
2376 | 2376 | ||
@@ -2420,7 +2420,7 @@ out_dput: | |||
2420 | * Handle the last step of open() | 2420 | * Handle the last step of open() |
2421 | */ | 2421 | */ |
2422 | static struct file *do_last(struct nameidata *nd, struct path *path, | 2422 | static struct file *do_last(struct nameidata *nd, struct path *path, |
2423 | struct opendata *od, const struct open_flags *op, | 2423 | struct file *file, const struct open_flags *op, |
2424 | int *opened, const char *pathname) | 2424 | int *opened, const char *pathname) |
2425 | { | 2425 | { |
2426 | struct dentry *dir = nd->path.dentry; | 2426 | struct dentry *dir = nd->path.dentry; |
@@ -2497,7 +2497,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path, | |||
2497 | 2497 | ||
2498 | retry_lookup: | 2498 | retry_lookup: |
2499 | mutex_lock(&dir->d_inode->i_mutex); | 2499 | mutex_lock(&dir->d_inode->i_mutex); |
2500 | filp = lookup_open(nd, path, od, op, &want_write, opened); | 2500 | filp = lookup_open(nd, path, file, op, &want_write, opened); |
2501 | mutex_unlock(&dir->d_inode->i_mutex); | 2501 | mutex_unlock(&dir->d_inode->i_mutex); |
2502 | 2502 | ||
2503 | if (filp) { | 2503 | if (filp) { |
@@ -2604,13 +2604,15 @@ finish_open_created: | |||
2604 | error = may_open(&nd->path, acc_mode, open_flag); | 2604 | error = may_open(&nd->path, acc_mode, open_flag); |
2605 | if (error) | 2605 | if (error) |
2606 | goto exit; | 2606 | goto exit; |
2607 | od->filp->f_path.mnt = nd->path.mnt; | 2607 | file->f_path.mnt = nd->path.mnt; |
2608 | filp = finish_open(od, nd->path.dentry, NULL, opened); | 2608 | error = finish_open(file, nd->path.dentry, NULL, opened); |
2609 | if (IS_ERR(filp)) { | 2609 | if (error) { |
2610 | if (filp == ERR_PTR(-EOPENSTALE)) | 2610 | filp = ERR_PTR(error); |
2611 | if (error == -EOPENSTALE) | ||
2611 | goto stale_open; | 2612 | goto stale_open; |
2612 | goto out; | 2613 | goto out; |
2613 | } | 2614 | } |
2615 | filp = file; | ||
2614 | opened: | 2616 | opened: |
2615 | error = open_check_o_direct(filp); | 2617 | error = open_check_o_direct(filp); |
2616 | if (error) | 2618 | if (error) |
@@ -2663,17 +2665,17 @@ static struct file *path_openat(int dfd, const char *pathname, | |||
2663 | struct nameidata *nd, const struct open_flags *op, int flags) | 2665 | struct nameidata *nd, const struct open_flags *op, int flags) |
2664 | { | 2666 | { |
2665 | struct file *base = NULL; | 2667 | struct file *base = NULL; |
2666 | struct opendata od; | 2668 | struct file *file; |
2667 | struct file *res; | 2669 | struct file *res; |
2668 | struct path path; | 2670 | struct path path; |
2669 | int opened = 0; | 2671 | int opened = 0; |
2670 | int error; | 2672 | int error; |
2671 | 2673 | ||
2672 | od.filp = get_empty_filp(); | 2674 | file = get_empty_filp(); |
2673 | if (!od.filp) | 2675 | if (!file) |
2674 | return ERR_PTR(-ENFILE); | 2676 | return ERR_PTR(-ENFILE); |
2675 | 2677 | ||
2676 | od.filp->f_flags = op->open_flag; | 2678 | file->f_flags = op->open_flag; |
2677 | 2679 | ||
2678 | error = path_init(dfd, pathname, flags | LOOKUP_PARENT, nd, &base); | 2680 | error = path_init(dfd, pathname, flags | LOOKUP_PARENT, nd, &base); |
2679 | if (unlikely(error)) | 2681 | if (unlikely(error)) |
@@ -2684,7 +2686,7 @@ static struct file *path_openat(int dfd, const char *pathname, | |||
2684 | if (unlikely(error)) | 2686 | if (unlikely(error)) |
2685 | goto out_filp; | 2687 | goto out_filp; |
2686 | 2688 | ||
2687 | res = do_last(nd, &path, &od, op, &opened, pathname); | 2689 | res = do_last(nd, &path, file, op, &opened, pathname); |
2688 | while (unlikely(!res)) { /* trailing symlink */ | 2690 | while (unlikely(!res)) { /* trailing symlink */ |
2689 | struct path link = path; | 2691 | struct path link = path; |
2690 | void *cookie; | 2692 | void *cookie; |
@@ -2699,7 +2701,7 @@ static struct file *path_openat(int dfd, const char *pathname, | |||
2699 | error = follow_link(&link, nd, &cookie); | 2701 | error = follow_link(&link, nd, &cookie); |
2700 | if (unlikely(error)) | 2702 | if (unlikely(error)) |
2701 | goto out_filp; | 2703 | goto out_filp; |
2702 | res = do_last(nd, &path, &od, op, &opened, pathname); | 2704 | res = do_last(nd, &path, file, op, &opened, pathname); |
2703 | put_link(nd, &link, cookie); | 2705 | put_link(nd, &link, cookie); |
2704 | } | 2706 | } |
2705 | out: | 2707 | out: |
@@ -2708,7 +2710,7 @@ out: | |||
2708 | if (base) | 2710 | if (base) |
2709 | fput(base); | 2711 | fput(base); |
2710 | if (!(opened & FILE_OPENED)) | 2712 | if (!(opened & FILE_OPENED)) |
2711 | put_filp(od.filp); | 2713 | put_filp(file); |
2712 | if (res == ERR_PTR(-EOPENSTALE)) { | 2714 | if (res == ERR_PTR(-EOPENSTALE)) { |
2713 | if (flags & LOOKUP_RCU) | 2715 | if (flags & LOOKUP_RCU) |
2714 | res = ERR_PTR(-ECHILD); | 2716 | res = ERR_PTR(-ECHILD); |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index b56f4b36ed41..dafc86c1c35e 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -112,7 +112,7 @@ const struct inode_operations nfs3_dir_inode_operations = { | |||
112 | #ifdef CONFIG_NFS_V4 | 112 | #ifdef CONFIG_NFS_V4 |
113 | 113 | ||
114 | static int nfs_atomic_open(struct inode *, struct dentry *, | 114 | static int nfs_atomic_open(struct inode *, struct dentry *, |
115 | struct opendata *, unsigned, umode_t, | 115 | struct file *, unsigned, umode_t, |
116 | int *); | 116 | int *); |
117 | const struct inode_operations nfs4_dir_inode_operations = { | 117 | const struct inode_operations nfs4_dir_inode_operations = { |
118 | .create = nfs_create, | 118 | .create = nfs_create, |
@@ -1389,10 +1389,9 @@ static int do_open(struct inode *inode, struct file *filp) | |||
1389 | 1389 | ||
1390 | static int nfs_finish_open(struct nfs_open_context *ctx, | 1390 | static int nfs_finish_open(struct nfs_open_context *ctx, |
1391 | struct dentry *dentry, | 1391 | struct dentry *dentry, |
1392 | struct opendata *od, unsigned open_flags, | 1392 | struct file *file, unsigned open_flags, |
1393 | int *opened) | 1393 | int *opened) |
1394 | { | 1394 | { |
1395 | struct file *filp; | ||
1396 | int err; | 1395 | int err; |
1397 | 1396 | ||
1398 | if (ctx->dentry != dentry) { | 1397 | if (ctx->dentry != dentry) { |
@@ -1407,13 +1406,10 @@ static int nfs_finish_open(struct nfs_open_context *ctx, | |||
1407 | goto out; | 1406 | goto out; |
1408 | } | 1407 | } |
1409 | 1408 | ||
1410 | filp = finish_open(od, dentry, do_open, opened); | 1409 | err = finish_open(file, dentry, do_open, opened); |
1411 | if (IS_ERR(filp)) { | 1410 | if (err) |
1412 | err = PTR_ERR(filp); | ||
1413 | goto out; | 1411 | goto out; |
1414 | } | 1412 | nfs_file_set_open_context(file, ctx); |
1415 | nfs_file_set_open_context(filp, ctx); | ||
1416 | err = 0; | ||
1417 | 1413 | ||
1418 | out: | 1414 | out: |
1419 | put_nfs_open_context(ctx); | 1415 | put_nfs_open_context(ctx); |
@@ -1421,7 +1417,7 @@ out: | |||
1421 | } | 1417 | } |
1422 | 1418 | ||
1423 | static int nfs_atomic_open(struct inode *dir, struct dentry *dentry, | 1419 | static int nfs_atomic_open(struct inode *dir, struct dentry *dentry, |
1424 | struct opendata *od, unsigned open_flags, | 1420 | struct file *file, unsigned open_flags, |
1425 | umode_t mode, int *opened) | 1421 | umode_t mode, int *opened) |
1426 | { | 1422 | { |
1427 | struct nfs_open_context *ctx; | 1423 | struct nfs_open_context *ctx; |
@@ -1497,7 +1493,7 @@ static int nfs_atomic_open(struct inode *dir, struct dentry *dentry, | |||
1497 | nfs_unblock_sillyrename(dentry->d_parent); | 1493 | nfs_unblock_sillyrename(dentry->d_parent); |
1498 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); | 1494 | nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); |
1499 | 1495 | ||
1500 | err = nfs_finish_open(ctx, dentry, od, open_flags, opened); | 1496 | err = nfs_finish_open(ctx, dentry, file, open_flags, opened); |
1501 | 1497 | ||
1502 | dput(res); | 1498 | dput(res); |
1503 | out: | 1499 | out: |
@@ -1509,7 +1505,7 @@ no_open: | |||
1509 | if (IS_ERR(res)) | 1505 | if (IS_ERR(res)) |
1510 | goto out; | 1506 | goto out; |
1511 | 1507 | ||
1512 | finish_no_open(od, res); | 1508 | finish_no_open(file, res); |
1513 | return 1; | 1509 | return 1; |
1514 | } | 1510 | } |
1515 | 1511 | ||
@@ -781,21 +781,23 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt, | |||
781 | * If the open callback is set to NULL, then the standard f_op->open() | 781 | * If the open callback is set to NULL, then the standard f_op->open() |
782 | * filesystem callback is substituted. | 782 | * filesystem callback is substituted. |
783 | */ | 783 | */ |
784 | struct file *finish_open(struct opendata *od, struct dentry *dentry, | 784 | int finish_open(struct file *file, struct dentry *dentry, |
785 | int (*open)(struct inode *, struct file *), | 785 | int (*open)(struct inode *, struct file *), |
786 | int *opened) | 786 | int *opened) |
787 | { | 787 | { |
788 | struct file *res; | 788 | struct file *res; |
789 | BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */ | 789 | BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */ |
790 | 790 | ||
791 | mntget(od->filp->f_path.mnt); | 791 | mntget(file->f_path.mnt); |
792 | dget(dentry); | 792 | dget(dentry); |
793 | 793 | ||
794 | res = do_dentry_open(dentry, od->filp->f_path.mnt, od->filp, open, current_cred()); | 794 | res = do_dentry_open(dentry, file->f_path.mnt, file, open, current_cred()); |
795 | if (!IS_ERR(res)) | 795 | if (!IS_ERR(res)) { |
796 | *opened |= FILE_OPENED; | 796 | *opened |= FILE_OPENED; |
797 | return 0; | ||
798 | } | ||
797 | 799 | ||
798 | return res; | 800 | return PTR_ERR(res); |
799 | } | 801 | } |
800 | EXPORT_SYMBOL(finish_open); | 802 | EXPORT_SYMBOL(finish_open); |
801 | 803 | ||
@@ -808,9 +810,9 @@ EXPORT_SYMBOL(finish_open); | |||
808 | * This can be used to set the result of a successful lookup in ->atomic_open(). | 810 | * This can be used to set the result of a successful lookup in ->atomic_open(). |
809 | * The filesystem's atomic_open() method shall return NULL after calling this. | 811 | * The filesystem's atomic_open() method shall return NULL after calling this. |
810 | */ | 812 | */ |
811 | void finish_no_open(struct opendata *od, struct dentry *dentry) | 813 | void finish_no_open(struct file *file, struct dentry *dentry) |
812 | { | 814 | { |
813 | od->filp->f_path.dentry = dentry; | 815 | file->f_path.dentry = dentry; |
814 | } | 816 | } |
815 | EXPORT_SYMBOL(finish_no_open); | 817 | EXPORT_SYMBOL(finish_no_open); |
816 | 818 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index 33bda922988a..1dcc75c95763 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -427,7 +427,6 @@ struct kstatfs; | |||
427 | struct vm_area_struct; | 427 | struct vm_area_struct; |
428 | struct vfsmount; | 428 | struct vfsmount; |
429 | struct cred; | 429 | struct cred; |
430 | struct opendata; | ||
431 | 430 | ||
432 | extern void __init inode_init(void); | 431 | extern void __init inode_init(void); |
433 | extern void __init inode_init_early(void); | 432 | extern void __init inode_init_early(void); |
@@ -1695,7 +1694,7 @@ struct inode_operations { | |||
1695 | u64 len); | 1694 | u64 len); |
1696 | int (*update_time)(struct inode *, struct timespec *, int); | 1695 | int (*update_time)(struct inode *, struct timespec *, int); |
1697 | int (*atomic_open)(struct inode *, struct dentry *, | 1696 | int (*atomic_open)(struct inode *, struct dentry *, |
1698 | struct opendata *, unsigned open_flag, | 1697 | struct file *, unsigned open_flag, |
1699 | umode_t create_mode, int *opened); | 1698 | umode_t create_mode, int *opened); |
1700 | } ____cacheline_aligned; | 1699 | } ____cacheline_aligned; |
1701 | 1700 | ||
@@ -2069,10 +2068,10 @@ enum { | |||
2069 | FILE_CREATED = 1, | 2068 | FILE_CREATED = 1, |
2070 | FILE_OPENED = 2 | 2069 | FILE_OPENED = 2 |
2071 | }; | 2070 | }; |
2072 | extern struct file *finish_open(struct opendata *od, struct dentry *dentry, | 2071 | extern int finish_open(struct file *file, struct dentry *dentry, |
2073 | int (*open)(struct inode *, struct file *), | 2072 | int (*open)(struct inode *, struct file *), |
2074 | int *opened); | 2073 | int *opened); |
2075 | extern void finish_no_open(struct opendata *od, struct dentry *dentry); | 2074 | extern void finish_no_open(struct file *file, struct dentry *dentry); |
2076 | 2075 | ||
2077 | /* fs/ioctl.c */ | 2076 | /* fs/ioctl.c */ |
2078 | 2077 | ||