aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-06-22 04:39:14 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-07-14 08:33:35 -0400
commitd95852777bc8ba6b3ad3397d495c5f9dd8ca8383 (patch)
tree96e9d8b1d33c4f6f7b5ba5be0fa4fd8f77c7a67f
parent3d8a00d2099ebc6d5a6e95fadaf861709d9919a8 (diff)
make ->atomic_open() return int
Change of calling conventions: old new NULL 1 file 0 ERR_PTR(-ve) -ve Caller *knows* that struct file *; no need to return it. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--Documentation/filesystems/Locking2
-rw-r--r--Documentation/filesystems/vfs.txt6
-rw-r--r--fs/9p/vfs_inode.c10
-rw-r--r--fs/9p/vfs_inode_dotl.c14
-rw-r--r--fs/ceph/dir.c19
-rw-r--r--fs/ceph/file.c12
-rw-r--r--fs/ceph/super.h6
-rw-r--r--fs/cifs/cifsfs.h6
-rw-r--r--fs/cifs/dir.c17
-rw-r--r--fs/fuse/dir.c33
-rw-r--r--fs/namei.c14
-rw-r--r--fs/nfs/dir.c57
-rw-r--r--include/linux/fs.h6
13 files changed, 97 insertions, 105 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index af4e45bd6cf..46a24a6ed09 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -62,7 +62,7 @@ ata *);
62 int (*removexattr) (struct dentry *, const char *); 62 int (*removexattr) (struct dentry *, const char *);
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 struct file * (*atomic_open)(struct inode *, struct dentry *, 65 int (*atomic_open)(struct inode *, struct dentry *,
66 struct opendata *, unsigned open_flag, 66 struct opendata *, unsigned open_flag,
67 umode_t create_mode, int *opened); 67 umode_t create_mode, int *opened);
68 68
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index d7121051afc..d0d690bbc4c 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -364,7 +364,7 @@ struct inode_operations {
364 ssize_t (*listxattr) (struct dentry *, char *, size_t); 364 ssize_t (*listxattr) (struct dentry *, char *, size_t);
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 struct file * (*atomic_open)(struct inode *, struct dentry *, 367 int (*atomic_open)(struct inode *, struct dentry *,
368 struct opendata *, unsigned open_flag, 368 struct opendata *, unsigned open_flag,
369 umode_t create_mode, int *opened); 369 umode_t create_mode, int *opened);
370}; 370};
@@ -482,8 +482,8 @@ otherwise noted.
482 atomic_open: called on the last component of an open. Using this optional 482 atomic_open: called on the last component of an open. Using this optional
483 method the filesystem can look up, possibly create and open the file in 483 method the filesystem can look up, possibly create and open the file in
484 one atomic operation. If it cannot perform this (e.g. the file type 484 one atomic operation. If it cannot perform this (e.g. the file type
485 turned out to be wrong) it may signal this by returning NULL instead of 485 turned out to be wrong) it may signal this by returning 1 instead of
486 an open struct file pointer. This method is only called if the last 486 usual 0 or -ve . This method is only called if the last
487 component is negative or needs lookup. Cached positive dentries are 487 component is negative or needs lookup. Cached positive dentries are
488 still handled by f_op->open(). 488 still handled by f_op->open().
489 489
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index de626b3b342..62ce8daefa9 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -856,7 +856,7 @@ error:
856 return ERR_PTR(result); 856 return ERR_PTR(result);
857} 857}
858 858
859static struct file * 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 opendata *od, unsigned flags, umode_t mode,
862 int *opened) 862 int *opened)
@@ -872,7 +872,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
872 if (d_unhashed(dentry)) { 872 if (d_unhashed(dentry)) {
873 res = v9fs_vfs_lookup(dir, dentry, NULL); 873 res = v9fs_vfs_lookup(dir, dentry, NULL);
874 if (IS_ERR(res)) 874 if (IS_ERR(res))
875 return ERR_CAST(res); 875 return PTR_ERR(res);
876 876
877 if (res) 877 if (res)
878 dentry = res; 878 dentry = res;
@@ -881,7 +881,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
881 /* Only creates */ 881 /* Only creates */
882 if (!(flags & O_CREAT) || dentry->d_inode) { 882 if (!(flags & O_CREAT) || dentry->d_inode) {
883 finish_no_open(od, res); 883 finish_no_open(od, res);
884 return NULL; 884 return 1;
885 } 885 }
886 886
887 err = 0; 887 err = 0;
@@ -933,13 +933,11 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
933 *opened |= FILE_CREATED; 933 *opened |= FILE_CREATED;
934out: 934out:
935 dput(res); 935 dput(res);
936 return filp; 936 return err;
937 937
938error: 938error:
939 if (fid) 939 if (fid)
940 p9_client_clunk(fid); 940 p9_client_clunk(fid);
941
942 filp = ERR_PTR(err);
943 goto out; 941 goto out;
944} 942}
945 943
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index 3db55471bc9..69f05109f75 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -240,7 +240,7 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
240 return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0); 240 return v9fs_vfs_mknod_dotl(dir, dentry, omode, 0);
241} 241}
242 242
243static struct file * 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 opendata *od, unsigned flags, umode_t omode,
246 int *opened) 246 int *opened)
@@ -262,7 +262,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
262 if (d_unhashed(dentry)) { 262 if (d_unhashed(dentry)) {
263 res = v9fs_vfs_lookup(dir, dentry, NULL); 263 res = v9fs_vfs_lookup(dir, dentry, NULL);
264 if (IS_ERR(res)) 264 if (IS_ERR(res))
265 return ERR_CAST(res); 265 return PTR_ERR(res);
266 266
267 if (res) 267 if (res)
268 dentry = res; 268 dentry = res;
@@ -271,7 +271,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
271 /* Only creates */ 271 /* Only creates */
272 if (!(flags & O_CREAT) || dentry->d_inode) { 272 if (!(flags & O_CREAT) || dentry->d_inode) {
273 finish_no_open(od, res); 273 finish_no_open(od, res);
274 return NULL; 274 return 1;
275 } 275 }
276 276
277 v9ses = v9fs_inode2v9ses(dir); 277 v9ses = v9fs_inode2v9ses(dir);
@@ -284,7 +284,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
284 if (IS_ERR(dfid)) { 284 if (IS_ERR(dfid)) {
285 err = PTR_ERR(dfid); 285 err = PTR_ERR(dfid);
286 p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err); 286 p9_debug(P9_DEBUG_VFS, "fid lookup failed %d\n", err);
287 goto err_return; 287 goto out;
288 } 288 }
289 289
290 /* clone a fid to use for creation */ 290 /* clone a fid to use for creation */
@@ -292,7 +292,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
292 if (IS_ERR(ofid)) { 292 if (IS_ERR(ofid)) {
293 err = PTR_ERR(ofid); 293 err = PTR_ERR(ofid);
294 p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err); 294 p9_debug(P9_DEBUG_VFS, "p9_client_walk failed %d\n", err);
295 goto err_return; 295 goto out;
296 } 296 }
297 297
298 gid = v9fs_get_fsgid_for_create(dir); 298 gid = v9fs_get_fsgid_for_create(dir);
@@ -370,7 +370,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
370 *opened |= FILE_CREATED; 370 *opened |= FILE_CREATED;
371out: 371out:
372 dput(res); 372 dput(res);
373 return filp; 373 return err;
374 374
375error: 375error:
376 if (fid) 376 if (fid)
@@ -379,8 +379,6 @@ err_clunk_old_fid:
379 if (ofid) 379 if (ofid)
380 p9_client_clunk(ofid); 380 p9_client_clunk(ofid);
381 v9fs_set_create_acl(NULL, &dacl, &pacl); 381 v9fs_set_create_acl(NULL, &dacl, &pacl);
382err_return:
383 filp = ERR_PTR(err);
384 goto out; 382 goto out;
385} 383}
386 384
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 81e5e908df9..d8bfabeeaa2 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -634,21 +634,20 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
634 return dentry; 634 return dentry;
635} 635}
636 636
637struct file *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 opendata *od, unsigned flags, umode_t mode,
639 int *opened) 639 int *opened)
640{ 640{
641 int err; 641 int err;
642 struct dentry *res = NULL; 642 struct dentry *res = NULL;
643 struct file *filp;
644 643
645 if (!(flags & O_CREAT)) { 644 if (!(flags & O_CREAT)) {
646 if (dentry->d_name.len > NAME_MAX) 645 if (dentry->d_name.len > NAME_MAX)
647 return ERR_PTR(-ENAMETOOLONG); 646 return -ENAMETOOLONG;
648 647
649 err = ceph_init_dentry(dentry); 648 err = ceph_init_dentry(dentry);
650 if (err < 0) 649 if (err < 0)
651 return ERR_PTR(err); 650 return err;
652 651
653 return ceph_lookup_open(dir, dentry, od, flags, mode, opened); 652 return ceph_lookup_open(dir, dentry, od, flags, mode, opened);
654 } 653 }
@@ -656,7 +655,7 @@ struct file *ceph_atomic_open(struct inode *dir, struct dentry *dentry,
656 if (d_unhashed(dentry)) { 655 if (d_unhashed(dentry)) {
657 res = ceph_lookup(dir, dentry, NULL); 656 res = ceph_lookup(dir, dentry, NULL);
658 if (IS_ERR(res)) 657 if (IS_ERR(res))
659 return ERR_CAST(res); 658 return PTR_ERR(res);
660 659
661 if (res) 660 if (res)
662 dentry = res; 661 dentry = res;
@@ -665,14 +664,14 @@ struct file *ceph_atomic_open(struct inode *dir, struct dentry *dentry,
665 /* We don't deal with positive dentries here */ 664 /* We don't deal with positive dentries here */
666 if (dentry->d_inode) { 665 if (dentry->d_inode) {
667 finish_no_open(od, res); 666 finish_no_open(od, res);
668 return NULL; 667 return 1;
669 } 668 }
670 669
671 *opened |= FILE_CREATED; 670 *opened |= FILE_CREATED;
672 filp = ceph_lookup_open(dir, dentry, od, flags, mode, opened); 671 err = ceph_lookup_open(dir, dentry, od, flags, mode, opened);
673 dput(res); 672 dput(res);
674 673
675 return filp; 674 return err;
676} 675}
677 676
678/* 677/*
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 4c304a90d04..b8cc3ee5401 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -213,9 +213,9 @@ out:
213 * may_open() fails, the struct *file gets cleaned up (i.e. 213 * may_open() fails, the struct *file gets cleaned up (i.e.
214 * ceph_release gets called). So fear not! 214 * ceph_release gets called). So fear not!
215 */ 215 */
216struct file *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 opendata *od, 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;
@@ -230,7 +230,7 @@ struct file *ceph_lookup_open(struct inode *dir, struct dentry *dentry,
230 /* do the open */ 230 /* do the open */
231 req = prepare_open_request(dir->i_sb, flags, mode); 231 req = prepare_open_request(dir->i_sb, flags, mode);
232 if (IS_ERR(req)) 232 if (IS_ERR(req))
233 return ERR_CAST(req); 233 return PTR_ERR(req);
234 req->r_dentry = dget(dentry); 234 req->r_dentry = dget(dentry);
235 req->r_num_caps = 2; 235 req->r_num_caps = 2;
236 if (flags & O_CREAT) { 236 if (flags & O_CREAT) {
@@ -257,10 +257,10 @@ out:
257 dout("ceph_lookup_open result=%p\n", ret); 257 dout("ceph_lookup_open result=%p\n", ret);
258 258
259 if (IS_ERR(ret)) 259 if (IS_ERR(ret))
260 return ERR_CAST(ret); 260 return PTR_ERR(ret);
261 261
262 dput(ret); 262 dput(ret);
263 return err ? ERR_PTR(err) : file; 263 return err;
264} 264}
265 265
266int ceph_release(struct inode *inode, struct file *file) 266int ceph_release(struct inode *inode, struct file *file)
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index f9a325108b4..f7e8e82ec47 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -806,9 +806,9 @@ extern int ceph_copy_from_page_vector(struct page **pages,
806 loff_t off, size_t len); 806 loff_t off, size_t len);
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 struct file *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 opendata *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
814/* dir.c */ 814/* dir.c */
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 92a7c3d8a03..58d9aca46a4 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -46,9 +46,9 @@ extern const struct inode_operations cifs_dir_inode_ops;
46extern struct inode *cifs_root_iget(struct super_block *); 46extern 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 struct file *cifs_atomic_open(struct inode *, struct dentry *, 49extern int cifs_atomic_open(struct inode *, struct dentry *,
50 struct opendata *, unsigned, umode_t, 50 struct opendata *, 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 *);
54extern int cifs_unlink(struct inode *dir, struct dentry *dentry); 54extern int cifs_unlink(struct inode *dir, struct dentry *dentry);
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 6cdf23fd70e..8ca70b102b9 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -376,7 +376,7 @@ out:
376 return rc; 376 return rc;
377} 377}
378 378
379struct file * 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 opendata *od, unsigned oflags, umode_t mode,
382 int *opened) 382 int *opened)
@@ -403,15 +403,15 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
403 if (!(oflags & O_CREAT)) { 403 if (!(oflags & O_CREAT)) {
404 struct dentry *res = cifs_lookup(inode, direntry, NULL); 404 struct dentry *res = cifs_lookup(inode, direntry, NULL);
405 if (IS_ERR(res)) 405 if (IS_ERR(res))
406 return ERR_CAST(res); 406 return PTR_ERR(res);
407 407
408 finish_no_open(od, res); 408 finish_no_open(od, res);
409 return NULL; 409 return 1;
410 } 410 }
411 411
412 rc = check_name(direntry); 412 rc = check_name(direntry);
413 if (rc) 413 if (rc)
414 return ERR_PTR(rc); 414 return rc;
415 415
416 xid = GetXid(); 416 xid = GetXid();
417 417
@@ -428,13 +428,12 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
428 rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, 428 rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
429 &oplock, &fileHandle, opened); 429 &oplock, &fileHandle, opened);
430 430
431 if (rc) { 431 if (rc)
432 filp = ERR_PTR(rc);
433 goto out; 432 goto out;
434 }
435 433
436 filp = finish_open(od, direntry, generic_file_open, opened); 434 filp = finish_open(od, direntry, generic_file_open, opened);
437 if (IS_ERR(filp)) { 435 if (IS_ERR(filp)) {
436 rc = PTR_ERR(filp);
438 CIFSSMBClose(xid, tcon, fileHandle); 437 CIFSSMBClose(xid, tcon, fileHandle);
439 goto out; 438 goto out;
440 } 439 }
@@ -443,14 +442,14 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
443 if (pfile_info == NULL) { 442 if (pfile_info == NULL) {
444 CIFSSMBClose(xid, tcon, fileHandle); 443 CIFSSMBClose(xid, tcon, fileHandle);
445 fput(filp); 444 fput(filp);
446 filp = ERR_PTR(-ENOMEM); 445 rc = -ENOMEM;
447 } 446 }
448 447
449out: 448out:
450 cifs_put_tlink(tlink); 449 cifs_put_tlink(tlink);
451free_xid: 450free_xid:
452 FreeXid(xid); 451 FreeXid(xid);
453 return filp; 452 return rc;
454} 453}
455 454
456int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, 455int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index 345f78ee5c9..8a9ca09e87d 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -369,9 +369,9 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
369 * If the filesystem doesn't support this, then fall back to separate 369 * If the filesystem doesn't support this, then fall back to separate
370 * 'mknod' + 'open' requests. 370 * 'mknod' + 'open' requests.
371 */ 371 */
372static struct file *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 opendata *od, unsigned flags,
374 umode_t mode, int *opened) 374 umode_t mode, int *opened)
375{ 375{
376 int err; 376 int err;
377 struct inode *inode; 377 struct inode *inode;
@@ -452,12 +452,14 @@ static struct file *fuse_create_open(struct inode *dir, struct dentry *entry,
452 fuse_invalidate_attr(dir); 452 fuse_invalidate_attr(dir);
453 file = finish_open(od, entry, generic_file_open, opened); 453 file = finish_open(od, entry, generic_file_open, opened);
454 if (IS_ERR(file)) { 454 if (IS_ERR(file)) {
455 err = PTR_ERR(file);
455 fuse_sync_release(ff, flags); 456 fuse_sync_release(ff, flags);
456 } else { 457 } else {
457 file->private_data = fuse_file_get(ff); 458 file->private_data = fuse_file_get(ff);
458 fuse_finish_open(inode, file); 459 fuse_finish_open(inode, file);
460 err = 0;
459 } 461 }
460 return file; 462 return err;
461 463
462out_free_ff: 464out_free_ff:
463 fuse_file_free(ff); 465 fuse_file_free(ff);
@@ -466,23 +468,22 @@ out_put_request:
466out_put_forget_req: 468out_put_forget_req:
467 kfree(forget); 469 kfree(forget);
468out_err: 470out_err:
469 return ERR_PTR(err); 471 return err;
470} 472}
471 473
472static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t); 474static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
473static struct file *fuse_atomic_open(struct inode *dir, struct dentry *entry, 475static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
474 struct opendata *od, unsigned flags, 476 struct opendata *od, unsigned flags,
475 umode_t mode, int *opened) 477 umode_t mode, int *opened)
476{ 478{
477 int err; 479 int err;
478 struct fuse_conn *fc = get_fuse_conn(dir); 480 struct fuse_conn *fc = get_fuse_conn(dir);
479 struct file *file;
480 struct dentry *res = NULL; 481 struct dentry *res = NULL;
481 482
482 if (d_unhashed(entry)) { 483 if (d_unhashed(entry)) {
483 res = fuse_lookup(dir, entry, NULL); 484 res = fuse_lookup(dir, entry, NULL);
484 if (IS_ERR(res)) 485 if (IS_ERR(res))
485 return ERR_CAST(res); 486 return PTR_ERR(res);
486 487
487 if (res) 488 if (res)
488 entry = res; 489 entry = res;
@@ -497,24 +498,22 @@ static struct file *fuse_atomic_open(struct inode *dir, struct dentry *entry,
497 if (fc->no_create) 498 if (fc->no_create)
498 goto mknod; 499 goto mknod;
499 500
500 file = fuse_create_open(dir, entry, od, flags, mode, opened); 501 err = fuse_create_open(dir, entry, od, flags, mode, opened);
501 if (PTR_ERR(file) == -ENOSYS) { 502 if (err == -ENOSYS) {
502 fc->no_create = 1; 503 fc->no_create = 1;
503 goto mknod; 504 goto mknod;
504 } 505 }
505out_dput: 506out_dput:
506 dput(res); 507 dput(res);
507 return file; 508 return err;
508 509
509mknod: 510mknod:
510 err = fuse_mknod(dir, entry, mode, 0); 511 err = fuse_mknod(dir, entry, mode, 0);
511 if (err) { 512 if (err)
512 file = ERR_PTR(err);
513 goto out_dput; 513 goto out_dput;
514 }
515no_open: 514no_open:
516 finish_no_open(od, res); 515 finish_no_open(od, res);
517 return NULL; 516 return 1;
518} 517}
519 518
520/* 519/*
diff --git a/fs/namei.c b/fs/namei.c
index 18b9326d951..f0dae0057ec 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2204,7 +2204,7 @@ static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry,
2204 umode_t mode; 2204 umode_t mode;
2205 int error; 2205 int error;
2206 int acc_mode; 2206 int acc_mode;
2207 struct file *filp; 2207 struct file *filp = NULL;
2208 int create_error = 0; 2208 int create_error = 0;
2209 struct dentry *const DENTRY_NOT_SET = (void *) -1UL; 2209 struct dentry *const DENTRY_NOT_SET = (void *) -1UL;
2210 2210
@@ -2271,14 +2271,15 @@ static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry,
2271 2271
2272 od->dentry = DENTRY_NOT_SET; 2272 od->dentry = DENTRY_NOT_SET;
2273 od->mnt = nd->path.mnt; 2273 od->mnt = nd->path.mnt;
2274 filp = dir->i_op->atomic_open(dir, dentry, od, open_flag, mode, 2274 error = dir->i_op->atomic_open(dir, dentry, od, open_flag, mode,
2275 opened); 2275 opened);
2276 if (IS_ERR(filp)) { 2276 if (error < 0) {
2277 if (WARN_ON(od->dentry != DENTRY_NOT_SET)) 2277 if (WARN_ON(od->dentry != DENTRY_NOT_SET))
2278 dput(od->dentry); 2278 dput(od->dentry);
2279 2279
2280 if (create_error && PTR_ERR(filp) == -ENOENT) 2280 if (create_error && error == -ENOENT)
2281 filp = ERR_PTR(create_error); 2281 error = create_error;
2282 filp = ERR_PTR(error);
2282 goto out; 2283 goto out;
2283 } 2284 }
2284 2285
@@ -2288,7 +2289,7 @@ static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry,
2288 acc_mode = MAY_OPEN; 2289 acc_mode = MAY_OPEN;
2289 } 2290 }
2290 2291
2291 if (!filp) { 2292 if (error) { /* returned 1, that is */
2292 if (WARN_ON(od->dentry == DENTRY_NOT_SET)) { 2293 if (WARN_ON(od->dentry == DENTRY_NOT_SET)) {
2293 filp = ERR_PTR(-EIO); 2294 filp = ERR_PTR(-EIO);
2294 goto out; 2295 goto out;
@@ -2304,6 +2305,7 @@ static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry,
2304 * We didn't have the inode before the open, so check open permission 2305 * We didn't have the inode before the open, so check open permission
2305 * here. 2306 * here.
2306 */ 2307 */
2308 filp = od->filp;
2307 error = may_open(&filp->f_path, acc_mode, open_flag); 2309 error = may_open(&filp->f_path, acc_mode, open_flag);
2308 if (error) { 2310 if (error) {
2309 fput(filp); 2311 fput(filp);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 6deb2549ead..b56f4b36ed4 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -111,9 +111,9 @@ const struct inode_operations nfs3_dir_inode_operations = {
111 111
112#ifdef CONFIG_NFS_V4 112#ifdef CONFIG_NFS_V4
113 113
114static struct file *nfs_atomic_open(struct inode *, struct dentry *, 114static int nfs_atomic_open(struct inode *, struct dentry *,
115 struct opendata *, unsigned, umode_t, 115 struct opendata *, 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,
119 .lookup = nfs_lookup, 119 .lookup = nfs_lookup,
@@ -1387,10 +1387,10 @@ static int do_open(struct inode *inode, struct file *filp)
1387 return 0; 1387 return 0;
1388} 1388}
1389 1389
1390static struct file *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 opendata *od, unsigned open_flags,
1393 int *opened) 1393 int *opened)
1394{ 1394{
1395 struct file *filp; 1395 struct file *filp;
1396 int err; 1396 int err;
@@ -1403,30 +1403,31 @@ static struct file *nfs_finish_open(struct nfs_open_context *ctx,
1403 /* If the open_intent is for execute, we have an extra check to make */ 1403 /* If the open_intent is for execute, we have an extra check to make */
1404 if (ctx->mode & FMODE_EXEC) { 1404 if (ctx->mode & FMODE_EXEC) {
1405 err = nfs_may_open(dentry->d_inode, ctx->cred, open_flags); 1405 err = nfs_may_open(dentry->d_inode, ctx->cred, open_flags);
1406 if (err < 0) { 1406 if (err < 0)
1407 filp = ERR_PTR(err);
1408 goto out; 1407 goto out;
1409 }
1410 } 1408 }
1411 1409
1412 filp = finish_open(od, dentry, do_open, opened); 1410 filp = finish_open(od, dentry, do_open, opened);
1413 if (!IS_ERR(filp)) 1411 if (IS_ERR(filp)) {
1414 nfs_file_set_open_context(filp, ctx); 1412 err = PTR_ERR(filp);
1413 goto out;
1414 }
1415 nfs_file_set_open_context(filp, ctx);
1416 err = 0;
1415 1417
1416out: 1418out:
1417 put_nfs_open_context(ctx); 1419 put_nfs_open_context(ctx);
1418 return filp; 1420 return err;
1419} 1421}
1420 1422
1421static struct file *nfs_atomic_open(struct inode *dir, struct dentry *dentry, 1423static int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1422 struct opendata *od, unsigned open_flags, 1424 struct opendata *od, unsigned open_flags,
1423 umode_t mode, int *opened) 1425 umode_t mode, int *opened)
1424{ 1426{
1425 struct nfs_open_context *ctx; 1427 struct nfs_open_context *ctx;
1426 struct dentry *res; 1428 struct dentry *res;
1427 struct iattr attr = { .ia_valid = ATTR_OPEN }; 1429 struct iattr attr = { .ia_valid = ATTR_OPEN };
1428 struct inode *inode; 1430 struct inode *inode;
1429 struct file *filp;
1430 int err; 1431 int err;
1431 1432
1432 /* Expect a negative dentry */ 1433 /* Expect a negative dentry */
@@ -1437,21 +1438,19 @@ static struct file *nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1437 1438
1438 /* NFS only supports OPEN on regular files */ 1439 /* NFS only supports OPEN on regular files */
1439 if ((open_flags & O_DIRECTORY)) { 1440 if ((open_flags & O_DIRECTORY)) {
1440 err = -ENOENT;
1441 if (!d_unhashed(dentry)) { 1441 if (!d_unhashed(dentry)) {
1442 /* 1442 /*
1443 * Hashed negative dentry with O_DIRECTORY: dentry was 1443 * Hashed negative dentry with O_DIRECTORY: dentry was
1444 * revalidated and is fine, no need to perform lookup 1444 * revalidated and is fine, no need to perform lookup
1445 * again 1445 * again
1446 */ 1446 */
1447 goto out_err; 1447 return -ENOENT;
1448 } 1448 }
1449 goto no_open; 1449 goto no_open;
1450 } 1450 }
1451 1451
1452 err = -ENAMETOOLONG;
1453 if (dentry->d_name.len > NFS_SERVER(dir)->namelen) 1452 if (dentry->d_name.len > NFS_SERVER(dir)->namelen)
1454 goto out_err; 1453 return -ENAMETOOLONG;
1455 1454
1456 if (open_flags & O_CREAT) { 1455 if (open_flags & O_CREAT) {
1457 attr.ia_valid |= ATTR_MODE; 1456 attr.ia_valid |= ATTR_MODE;
@@ -1465,7 +1464,7 @@ static struct file *nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1465 ctx = create_nfs_open_context(dentry, open_flags); 1464 ctx = create_nfs_open_context(dentry, open_flags);
1466 err = PTR_ERR(ctx); 1465 err = PTR_ERR(ctx);
1467 if (IS_ERR(ctx)) 1466 if (IS_ERR(ctx))
1468 goto out_err; 1467 goto out;
1469 1468
1470 nfs_block_sillyrename(dentry->d_parent); 1469 nfs_block_sillyrename(dentry->d_parent);
1471 inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr); 1470 inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr);
@@ -1489,7 +1488,7 @@ static struct file *nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1489 default: 1488 default:
1490 break; 1489 break;
1491 } 1490 }
1492 goto out_err; 1491 goto out;
1493 } 1492 }
1494 res = d_add_unique(dentry, inode); 1493 res = d_add_unique(dentry, inode);
1495 if (res != NULL) 1494 if (res != NULL)
@@ -1498,22 +1497,20 @@ static struct file *nfs_atomic_open(struct inode *dir, struct dentry *dentry,
1498 nfs_unblock_sillyrename(dentry->d_parent); 1497 nfs_unblock_sillyrename(dentry->d_parent);
1499 nfs_set_verifier(dentry, nfs_save_change_attribute(dir)); 1498 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
1500 1499
1501 filp = nfs_finish_open(ctx, dentry, od, open_flags, opened); 1500 err = nfs_finish_open(ctx, dentry, od, open_flags, opened);
1502 1501
1503 dput(res); 1502 dput(res);
1504 return filp; 1503out:
1505 1504 return err;
1506out_err:
1507 return ERR_PTR(err);
1508 1505
1509no_open: 1506no_open:
1510 res = nfs_lookup(dir, dentry, NULL); 1507 res = nfs_lookup(dir, dentry, NULL);
1511 err = PTR_ERR(res); 1508 err = PTR_ERR(res);
1512 if (IS_ERR(res)) 1509 if (IS_ERR(res))
1513 goto out_err; 1510 goto out;
1514 1511
1515 finish_no_open(od, res); 1512 finish_no_open(od, res);
1516 return NULL; 1513 return 1;
1517} 1514}
1518 1515
1519static int nfs4_lookup_revalidate(struct dentry *dentry, struct nameidata *nd) 1516static int nfs4_lookup_revalidate(struct dentry *dentry, struct nameidata *nd)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index a7618cf28d0..33bda922988 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1694,9 +1694,9 @@ struct inode_operations {
1694 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, 1694 int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start,
1695 u64 len); 1695 u64 len);
1696 int (*update_time)(struct inode *, struct timespec *, int); 1696 int (*update_time)(struct inode *, struct timespec *, int);
1697 struct file * (*atomic_open)(struct inode *, struct dentry *, 1697 int (*atomic_open)(struct inode *, struct dentry *,
1698 struct opendata *, unsigned open_flag, 1698 struct opendata *, unsigned open_flag,
1699 umode_t create_mode, int *opened); 1699 umode_t create_mode, int *opened);
1700} ____cacheline_aligned; 1700} ____cacheline_aligned;
1701 1701
1702struct seq_file; 1702struct seq_file;