aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-03-14 10:56:20 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2014-04-01 23:19:11 -0400
commitdd20908a8a06b22c171f6c3fcdbdbd65bed07505 (patch)
tree447e2df881b2f056608098d3b24ab6d9734ce992 /fs/open.c
parent44ba8406d0005400e56c6b6a279a669eb761d1b8 (diff)
don't bother with {get,put}_write_access() on non-regular files
it's pointless and actually leads to wrong behaviour in at least one moderately convoluted case (pipe(), close one end, try to get to another via /proc/*/fd and run into ETXTBUSY). Cc: stable@vger.kernel.org Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c26
1 files changed, 7 insertions, 19 deletions
diff --git a/fs/open.c b/fs/open.c
index b9ed8b25c108..2ed7325f713e 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -641,23 +641,12 @@ out:
641static inline int __get_file_write_access(struct inode *inode, 641static inline int __get_file_write_access(struct inode *inode,
642 struct vfsmount *mnt) 642 struct vfsmount *mnt)
643{ 643{
644 int error; 644 int error = get_write_access(inode);
645 error = get_write_access(inode);
646 if (error) 645 if (error)
647 return error; 646 return error;
648 /* 647 error = __mnt_want_write(mnt);
649 * Do not take mount writer counts on 648 if (error)
650 * special files since no writes to 649 put_write_access(inode);
651 * the mount itself will occur.
652 */
653 if (!special_file(inode->i_mode)) {
654 /*
655 * Balanced in __fput()
656 */
657 error = __mnt_want_write(mnt);
658 if (error)
659 put_write_access(inode);
660 }
661 return error; 650 return error;
662} 651}
663 652
@@ -690,12 +679,11 @@ static int do_dentry_open(struct file *f,
690 679
691 path_get(&f->f_path); 680 path_get(&f->f_path);
692 inode = f->f_inode = f->f_path.dentry->d_inode; 681 inode = f->f_inode = f->f_path.dentry->d_inode;
693 if (f->f_mode & FMODE_WRITE) { 682 if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
694 error = __get_file_write_access(inode, f->f_path.mnt); 683 error = __get_file_write_access(inode, f->f_path.mnt);
695 if (error) 684 if (error)
696 goto cleanup_file; 685 goto cleanup_file;
697 if (!special_file(inode->i_mode)) 686 file_take_write(f);
698 file_take_write(f);
699 } 687 }
700 688
701 f->f_mapping = inode->i_mapping; 689 f->f_mapping = inode->i_mapping;
@@ -742,7 +730,6 @@ static int do_dentry_open(struct file *f,
742cleanup_all: 730cleanup_all:
743 fops_put(f->f_op); 731 fops_put(f->f_op);
744 if (f->f_mode & FMODE_WRITE) { 732 if (f->f_mode & FMODE_WRITE) {
745 put_write_access(inode);
746 if (!special_file(inode->i_mode)) { 733 if (!special_file(inode->i_mode)) {
747 /* 734 /*
748 * We don't consider this a real 735 * We don't consider this a real
@@ -750,6 +737,7 @@ cleanup_all:
750 * because it all happenend right 737 * because it all happenend right
751 * here, so just reset the state. 738 * here, so just reset the state.
752 */ 739 */
740 put_write_access(inode);
753 file_reset_write(f); 741 file_reset_write(f);
754 __mnt_drop_write(f->f_path.mnt); 742 __mnt_drop_write(f->f_path.mnt);
755 } 743 }