aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/filesystems/Locking2
-rw-r--r--Documentation/filesystems/vfs.txt2
-rw-r--r--fs/9p/vfs_inode.c15
-rw-r--r--fs/9p/vfs_inode_dotl.c15
-rw-r--r--fs/ceph/dir.c8
-rw-r--r--fs/ceph/file.c7
-rw-r--r--fs/ceph/super.h2
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/dir.c9
-rw-r--r--fs/fuse/dir.c15
-rw-r--r--fs/internal.h3
-rw-r--r--fs/namei.c48
-rw-r--r--fs/nfs/dir.c20
-rw-r--r--fs/open.c20
-rw-r--r--include/linux/fs.h11
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
69locking rules: 69locking 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
859static int 859static int
860v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry, 860v9fs_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
243static int 243static int
244v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry, 244v9fs_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;
371out: 368out:
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
637int ceph_atomic_open(struct inode *dir, struct dentry *dentry, 637int 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 */
216int ceph_lookup_open(struct inode *dir, struct dentry *dentry, 216int 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);
254out: 251out:
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,
807extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags); 807extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags);
808extern int ceph_open(struct inode *inode, struct file *file); 808extern int ceph_open(struct inode *inode, struct file *file);
809extern int ceph_lookup_open(struct inode *dir, struct dentry *dentry, 809extern 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);
812extern int ceph_release(struct inode *inode, struct file *filp); 812extern 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 *);
47extern int cifs_create(struct inode *, struct dentry *, umode_t, 47extern int cifs_create(struct inode *, struct dentry *, umode_t,
48 struct nameidata *); 48 struct nameidata *);
49extern int cifs_atomic_open(struct inode *, struct dentry *, 49extern int cifs_atomic_open(struct inode *, struct dentry *,
50 struct opendata *, unsigned, umode_t, 50 struct file *, unsigned, umode_t,
51 int *); 51 int *);
52extern struct dentry *cifs_lookup(struct inode *, struct dentry *, 52extern 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
379int 379int
380cifs_atomic_open(struct inode *inode, struct dentry *direntry, 380cifs_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 */
372static int fuse_create_open(struct inode *dir, struct dentry *entry, 372static 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
474static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t); 471static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
475static int fuse_atomic_open(struct inode *dir, struct dentry *entry, 472static 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;
514no_open: 511no_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 */
85struct opendata {
86 struct file *filp;
87};
88struct open_flags { 85struct 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
2196static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry, 2196static 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 */
2352static struct file *lookup_open(struct nameidata *nd, struct path *path, 2352static 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 */
2422static struct file *do_last(struct nameidata *nd, struct path *path, 2422static 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
2498retry_lookup: 2498retry_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;
2614opened: 2616opened:
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 }
2705out: 2707out:
@@ -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
114static int nfs_atomic_open(struct inode *, struct dentry *, 114static int nfs_atomic_open(struct inode *, struct dentry *,
115 struct opendata *, unsigned, umode_t, 115 struct file *, unsigned, umode_t,
116 int *); 116 int *);
117const struct inode_operations nfs4_dir_inode_operations = { 117const 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
1390static int nfs_finish_open(struct nfs_open_context *ctx, 1390static 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
1418out: 1414out:
1419 put_nfs_open_context(ctx); 1415 put_nfs_open_context(ctx);
@@ -1421,7 +1417,7 @@ out:
1421} 1417}
1422 1418
1423static int nfs_atomic_open(struct inode *dir, struct dentry *dentry, 1419static 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);
1503out: 1499out:
@@ -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
diff --git a/fs/open.c b/fs/open.c
index 2b1654d8bfbd..fc829d6c3a4b 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -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 */
784struct file *finish_open(struct opendata *od, struct dentry *dentry, 784int 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}
800EXPORT_SYMBOL(finish_open); 802EXPORT_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 */
811void finish_no_open(struct opendata *od, struct dentry *dentry) 813void 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}
815EXPORT_SYMBOL(finish_no_open); 817EXPORT_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;
427struct vm_area_struct; 427struct vm_area_struct;
428struct vfsmount; 428struct vfsmount;
429struct cred; 429struct cred;
430struct opendata;
431 430
432extern void __init inode_init(void); 431extern void __init inode_init(void);
433extern void __init inode_init_early(void); 432extern 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};
2072extern struct file *finish_open(struct opendata *od, struct dentry *dentry, 2071extern 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);
2075extern void finish_no_open(struct opendata *od, struct dentry *dentry); 2074extern void finish_no_open(struct file *file, struct dentry *dentry);
2076 2075
2077/* fs/ioctl.c */ 2076/* fs/ioctl.c */
2078 2077