aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-18 20:22:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-18 20:22:22 -0400
commit3fe03debfc58aba8f5ddb32abd7343237d07714c (patch)
treef17d2fbf390810404f5d28f45ed5b379fa13c6ef
parent9baa5059485d6559081d27d9b1fe1714f3fccab1 (diff)
parent8061a6fa564fe0e71601632758b78d2ba737663c (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull vfs fixes from Al Viro: "atomic_open-related fixes (Miklos' series, with EEXIST-related parts replaced with fix in fs/namei.c:atomic_open() instead of messing with the instances) + race fix in autofs + leak on failure exit in 9p" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: 9p: don't forget to destroy inode cache if fscache registration fails atomic_open: take care of EEXIST in no-open case with O_CREAT|O_EXCL in fs/namei.c vfs: don't set FILE_CREATED before calling ->atomic_open() nfs: set FILE_CREATED gfs2: set FILE_CREATED cifs: fix filp leak in cifs_atomic_open() vfs: improve i_op->atomic_open() documentation autofs4: close the races around autofs4_notify_daemon()
-rw-r--r--Documentation/filesystems/vfs.txt14
-rw-r--r--fs/9p/v9fs.c7
-rw-r--r--fs/9p/vfs_inode_dotl.c8
-rw-r--r--fs/autofs4/waitq.c13
-rw-r--r--fs/cifs/dir.c1
-rw-r--r--fs/gfs2/inode.c4
-rw-r--r--fs/namei.c34
-rw-r--r--fs/nfs/dir.c3
-rw-r--r--fs/open.c21
9 files changed, 62 insertions, 43 deletions
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index f93a88250a44..deb48b5fd883 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -359,11 +359,9 @@ struct inode_operations {
359 ssize_t (*listxattr) (struct dentry *, char *, size_t); 359 ssize_t (*listxattr) (struct dentry *, char *, size_t);
360 int (*removexattr) (struct dentry *, const char *); 360 int (*removexattr) (struct dentry *, const char *);
361 void (*update_time)(struct inode *, struct timespec *, int); 361 void (*update_time)(struct inode *, struct timespec *, int);
362 int (*atomic_open)(struct inode *, struct dentry *, 362 int (*atomic_open)(struct inode *, struct dentry *, struct file *,
363 unsigned open_flag, umode_t create_mode, int *opened);
363 int (*tmpfile) (struct inode *, struct dentry *, umode_t); 364 int (*tmpfile) (struct inode *, struct dentry *, umode_t);
364} ____cacheline_aligned;
365 struct file *, unsigned open_flag,
366 umode_t create_mode, int *opened);
367}; 365};
368 366
369Again, all methods are called without any locks being held, unless 367Again, all methods are called without any locks being held, unless
@@ -470,9 +468,11 @@ otherwise noted.
470 method the filesystem can look up, possibly create and open the file in 468 method the filesystem can look up, possibly create and open the file in
471 one atomic operation. If it cannot perform this (e.g. the file type 469 one atomic operation. If it cannot perform this (e.g. the file type
472 turned out to be wrong) it may signal this by returning 1 instead of 470 turned out to be wrong) it may signal this by returning 1 instead of
473 usual 0 or -ve . This method is only called if the last 471 usual 0 or -ve . This method is only called if the last component is
474 component is negative or needs lookup. Cached positive dentries are 472 negative or needs lookup. Cached positive dentries are still handled by
475 still handled by f_op->open(). 473 f_op->open(). If the file was created, the FILE_CREATED flag should be
474 set in "opened". In case of O_EXCL the method must only succeed if the
475 file didn't exist and hence FILE_CREATED shall always be set on success.
476 476
477 tmpfile: called in the end of O_TMPFILE open(). Optional, equivalent to 477 tmpfile: called in the end of O_TMPFILE open(). Optional, equivalent to
478 atomically creating, opening and unlinking a file in given directory. 478 atomically creating, opening and unlinking a file in given directory.
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 58e6cbce4156..08f2e1e9a7e6 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -603,10 +603,11 @@ static int v9fs_cache_register(void)
603 if (ret < 0) 603 if (ret < 0)
604 return ret; 604 return ret;
605#ifdef CONFIG_9P_FSCACHE 605#ifdef CONFIG_9P_FSCACHE
606 return fscache_register_netfs(&v9fs_cache_netfs); 606 ret = fscache_register_netfs(&v9fs_cache_netfs);
607#else 607 if (ret < 0)
608 return ret; 608 v9fs_destroy_inode_cache();
609#endif 609#endif
610 return ret;
610} 611}
611 612
612static void v9fs_cache_unregister(void) 613static void v9fs_cache_unregister(void)
diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
index 53687bbf2296..a7c481402c46 100644
--- a/fs/9p/vfs_inode_dotl.c
+++ b/fs/9p/vfs_inode_dotl.c
@@ -267,14 +267,8 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
267 } 267 }
268 268
269 /* Only creates */ 269 /* Only creates */
270 if (!(flags & O_CREAT)) 270 if (!(flags & O_CREAT) || dentry->d_inode)
271 return finish_no_open(file, res); 271 return finish_no_open(file, res);
272 else if (dentry->d_inode) {
273 if ((flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
274 return -EEXIST;
275 else
276 return finish_no_open(file, res);
277 }
278 272
279 v9ses = v9fs_inode2v9ses(dir); 273 v9ses = v9fs_inode2v9ses(dir);
280 274
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
index 3db70dae40d3..689e40d983ad 100644
--- a/fs/autofs4/waitq.c
+++ b/fs/autofs4/waitq.c
@@ -109,13 +109,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi,
109 109
110 pkt.hdr.proto_version = sbi->version; 110 pkt.hdr.proto_version = sbi->version;
111 pkt.hdr.type = type; 111 pkt.hdr.type = type;
112 mutex_lock(&sbi->wq_mutex);
113 112
114 /* Check if we have become catatonic */
115 if (sbi->catatonic) {
116 mutex_unlock(&sbi->wq_mutex);
117 return;
118 }
119 switch (type) { 113 switch (type) {
120 /* Kernel protocol v4 missing and expire packets */ 114 /* Kernel protocol v4 missing and expire packets */
121 case autofs_ptype_missing: 115 case autofs_ptype_missing:
@@ -427,7 +421,6 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
427 wq->tgid = current->tgid; 421 wq->tgid = current->tgid;
428 wq->status = -EINTR; /* Status return if interrupted */ 422 wq->status = -EINTR; /* Status return if interrupted */
429 wq->wait_ctr = 2; 423 wq->wait_ctr = 2;
430 mutex_unlock(&sbi->wq_mutex);
431 424
432 if (sbi->version < 5) { 425 if (sbi->version < 5) {
433 if (notify == NFY_MOUNT) 426 if (notify == NFY_MOUNT)
@@ -449,15 +442,15 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
449 (unsigned long) wq->wait_queue_token, wq->name.len, 442 (unsigned long) wq->wait_queue_token, wq->name.len,
450 wq->name.name, notify); 443 wq->name.name, notify);
451 444
452 /* autofs4_notify_daemon() may block */ 445 /* autofs4_notify_daemon() may block; it will unlock ->wq_mutex */
453 autofs4_notify_daemon(sbi, wq, type); 446 autofs4_notify_daemon(sbi, wq, type);
454 } else { 447 } else {
455 wq->wait_ctr++; 448 wq->wait_ctr++;
456 mutex_unlock(&sbi->wq_mutex);
457 kfree(qstr.name);
458 DPRINTK("existing wait id = 0x%08lx, name = %.*s, nfy=%d", 449 DPRINTK("existing wait id = 0x%08lx, name = %.*s, nfy=%d",
459 (unsigned long) wq->wait_queue_token, wq->name.len, 450 (unsigned long) wq->wait_queue_token, wq->name.len,
460 wq->name.name, notify); 451 wq->name.name, notify);
452 mutex_unlock(&sbi->wq_mutex);
453 kfree(qstr.name);
461 } 454 }
462 455
463 /* 456 /*
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index d3e2eaa503a6..5384c2a640ca 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -500,6 +500,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
500 if (server->ops->close) 500 if (server->ops->close)
501 server->ops->close(xid, tcon, &fid); 501 server->ops->close(xid, tcon, &fid);
502 cifs_del_pending_open(&open); 502 cifs_del_pending_open(&open);
503 fput(file);
503 rc = -ENOMEM; 504 rc = -ENOMEM;
504 } 505 }
505 506
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c
index 64915eeae5a7..ced3257f06e8 100644
--- a/fs/gfs2/inode.c
+++ b/fs/gfs2/inode.c
@@ -694,8 +694,10 @@ static int gfs2_create_inode(struct inode *dir, struct dentry *dentry,
694 694
695 mark_inode_dirty(inode); 695 mark_inode_dirty(inode);
696 d_instantiate(dentry, inode); 696 d_instantiate(dentry, inode);
697 if (file) 697 if (file) {
698 *opened |= FILE_CREATED;
698 error = finish_open(file, dentry, gfs2_open_common, opened); 699 error = finish_open(file, dentry, gfs2_open_common, opened);
700 }
699 gfs2_glock_dq_uninit(ghs); 701 gfs2_glock_dq_uninit(ghs);
700 gfs2_glock_dq_uninit(ghs + 1); 702 gfs2_glock_dq_uninit(ghs + 1);
701 return error; 703 return error;
diff --git a/fs/namei.c b/fs/namei.c
index 0dc4cbf21f37..645268f23eb6 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2656,6 +2656,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
2656 int acc_mode; 2656 int acc_mode;
2657 int create_error = 0; 2657 int create_error = 0;
2658 struct dentry *const DENTRY_NOT_SET = (void *) -1UL; 2658 struct dentry *const DENTRY_NOT_SET = (void *) -1UL;
2659 bool excl;
2659 2660
2660 BUG_ON(dentry->d_inode); 2661 BUG_ON(dentry->d_inode);
2661 2662
@@ -2669,10 +2670,9 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
2669 if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) 2670 if ((open_flag & O_CREAT) && !IS_POSIXACL(dir))
2670 mode &= ~current_umask(); 2671 mode &= ~current_umask();
2671 2672
2672 if ((open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT)) { 2673 excl = (open_flag & (O_EXCL | O_CREAT)) == (O_EXCL | O_CREAT);
2674 if (excl)
2673 open_flag &= ~O_TRUNC; 2675 open_flag &= ~O_TRUNC;
2674 *opened |= FILE_CREATED;
2675 }
2676 2676
2677 /* 2677 /*
2678 * Checking write permission is tricky, bacuse we don't know if we are 2678 * Checking write permission is tricky, bacuse we don't know if we are
@@ -2725,12 +2725,6 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
2725 goto out; 2725 goto out;
2726 } 2726 }
2727 2727
2728 acc_mode = op->acc_mode;
2729 if (*opened & FILE_CREATED) {
2730 fsnotify_create(dir, dentry);
2731 acc_mode = MAY_OPEN;
2732 }
2733
2734 if (error) { /* returned 1, that is */ 2728 if (error) { /* returned 1, that is */
2735 if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) { 2729 if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) {
2736 error = -EIO; 2730 error = -EIO;
@@ -2740,9 +2734,19 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
2740 dput(dentry); 2734 dput(dentry);
2741 dentry = file->f_path.dentry; 2735 dentry = file->f_path.dentry;
2742 } 2736 }
2743 if (create_error && dentry->d_inode == NULL) { 2737 if (*opened & FILE_CREATED)
2744 error = create_error; 2738 fsnotify_create(dir, dentry);
2745 goto out; 2739 if (!dentry->d_inode) {
2740 WARN_ON(*opened & FILE_CREATED);
2741 if (create_error) {
2742 error = create_error;
2743 goto out;
2744 }
2745 } else {
2746 if (excl && !(*opened & FILE_CREATED)) {
2747 error = -EEXIST;
2748 goto out;
2749 }
2746 } 2750 }
2747 goto looked_up; 2751 goto looked_up;
2748 } 2752 }
@@ -2751,6 +2755,12 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry,
2751 * We didn't have the inode before the open, so check open permission 2755 * We didn't have the inode before the open, so check open permission
2752 * here. 2756 * here.
2753 */ 2757 */
2758 acc_mode = op->acc_mode;
2759 if (*opened & FILE_CREATED) {
2760 WARN_ON(!(open_flag & O_CREAT));
2761 fsnotify_create(dir, dentry);
2762 acc_mode = MAY_OPEN;
2763 }
2754 error = may_open(&file->f_path, acc_mode, open_flag); 2764 error = may_open(&file->f_path, acc_mode, open_flag);
2755 if (error) 2765 if (error)
2756 fput(file); 2766 fput(file);
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index de434f309af0..854a8f05a610 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1392,6 +1392,9 @@ static int nfs_finish_open(struct nfs_open_context *ctx,
1392{ 1392{
1393 int err; 1393 int err;
1394 1394
1395 if ((open_flags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
1396 *opened |= FILE_CREATED;
1397
1395 err = finish_open(file, dentry, do_open, opened); 1398 err = finish_open(file, dentry, do_open, opened);
1396 if (err) 1399 if (err)
1397 goto out; 1400 goto out;
diff --git a/fs/open.c b/fs/open.c
index 2a731b0d08bc..d420331ca32a 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -744,14 +744,24 @@ cleanup_file:
744 744
745/** 745/**
746 * finish_open - finish opening a file 746 * finish_open - finish opening a file
747 * @od: opaque open data 747 * @file: file pointer
748 * @dentry: pointer to dentry 748 * @dentry: pointer to dentry
749 * @open: open callback 749 * @open: open callback
750 * @opened: state of open
750 * 751 *
751 * This can be used to finish opening a file passed to i_op->atomic_open(). 752 * This can be used to finish opening a file passed to i_op->atomic_open().
752 * 753 *
753 * If the open callback is set to NULL, then the standard f_op->open() 754 * If the open callback is set to NULL, then the standard f_op->open()
754 * filesystem callback is substituted. 755 * filesystem callback is substituted.
756 *
757 * NB: the dentry reference is _not_ consumed. If, for example, the dentry is
758 * the return value of d_splice_alias(), then the caller needs to perform dput()
759 * on it after finish_open().
760 *
761 * On successful return @file is a fully instantiated open file. After this, if
762 * an error occurs in ->atomic_open(), it needs to clean up with fput().
763 *
764 * Returns zero on success or -errno if the open failed.
755 */ 765 */
756int finish_open(struct file *file, struct dentry *dentry, 766int finish_open(struct file *file, struct dentry *dentry,
757 int (*open)(struct inode *, struct file *), 767 int (*open)(struct inode *, struct file *),
@@ -772,11 +782,16 @@ EXPORT_SYMBOL(finish_open);
772/** 782/**
773 * finish_no_open - finish ->atomic_open() without opening the file 783 * finish_no_open - finish ->atomic_open() without opening the file
774 * 784 *
775 * @od: opaque open data 785 * @file: file pointer
776 * @dentry: dentry or NULL (as returned from ->lookup()) 786 * @dentry: dentry or NULL (as returned from ->lookup())
777 * 787 *
778 * This can be used to set the result of a successful lookup in ->atomic_open(). 788 * This can be used to set the result of a successful lookup in ->atomic_open().
779 * The filesystem's atomic_open() method shall return NULL after calling this. 789 *
790 * NB: unlike finish_open() this function does consume the dentry reference and
791 * the caller need not dput() it.
792 *
793 * Returns "1" which must be the return value of ->atomic_open() after having
794 * called this function.
780 */ 795 */
781int finish_no_open(struct file *file, struct dentry *dentry) 796int finish_no_open(struct file *file, struct dentry *dentry)
782{ 797{