aboutsummaryrefslogtreecommitdiffstats
path: root/fs
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 /fs
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>
Diffstat (limited to 'fs')
-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
10 files changed, 90 insertions, 98 deletions
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index de626b3b342f..62ce8daefa95 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 3db55471bc93..69f05109f75d 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 81e5e908df9d..d8bfabeeaa25 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 4c304a90d046..b8cc3ee5401e 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 f9a325108b49..f7e8e82ec47f 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 92a7c3d8a031..58d9aca46a40 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 6cdf23fd70ee..8ca70b102b95 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 345f78ee5c9d..8a9ca09e87d4 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 18b9326d951f..f0dae0057ec9 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 6deb2549ead5..b56f4b36ed41 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)