aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2014-03-14 10:56:20 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2014-05-31 00:52:12 -0400
commit68ad89c73da6085d14e18f18ec7298821d408b2d (patch)
treec426b7c447d78b45a9d0a1f07e8be23ea3056799
parentcd09dfbdad430e807be3dee98ce03f452b7ef001 (diff)
don't bother with {get,put}_write_access() on non-regular files
commit dd20908a8a06b22c171f6c3fcdbdbd65bed07505 upstream. 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). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--fs/file_table.c4
-rw-r--r--fs/open.c26
2 files changed, 9 insertions, 21 deletions
diff --git a/fs/file_table.c b/fs/file_table.c
index 485dc0eddd67..54a34be444f9 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -211,10 +211,10 @@ static void drop_file_write_access(struct file *file)
211 struct dentry *dentry = file->f_path.dentry; 211 struct dentry *dentry = file->f_path.dentry;
212 struct inode *inode = dentry->d_inode; 212 struct inode *inode = dentry->d_inode;
213 213
214 put_write_access(inode);
215
216 if (special_file(inode->i_mode)) 214 if (special_file(inode->i_mode))
217 return; 215 return;
216
217 put_write_access(inode);
218 if (file_check_writeable(file) != 0) 218 if (file_check_writeable(file) != 0)
219 return; 219 return;
220 __mnt_drop_write(mnt); 220 __mnt_drop_write(mnt);
diff --git a/fs/open.c b/fs/open.c
index 8c741002f947..86092bde31f4 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -628,23 +628,12 @@ out:
628static inline int __get_file_write_access(struct inode *inode, 628static inline int __get_file_write_access(struct inode *inode,
629 struct vfsmount *mnt) 629 struct vfsmount *mnt)
630{ 630{
631 int error; 631 int error = get_write_access(inode);
632 error = get_write_access(inode);
633 if (error) 632 if (error)
634 return error; 633 return error;
635 /* 634 error = __mnt_want_write(mnt);
636 * Do not take mount writer counts on 635 if (error)
637 * special files since no writes to 636 put_write_access(inode);
638 * the mount itself will occur.
639 */
640 if (!special_file(inode->i_mode)) {
641 /*
642 * Balanced in __fput()
643 */
644 error = __mnt_want_write(mnt);
645 if (error)
646 put_write_access(inode);
647 }
648 return error; 637 return error;
649} 638}
650 639
@@ -677,12 +666,11 @@ static int do_dentry_open(struct file *f,
677 666
678 path_get(&f->f_path); 667 path_get(&f->f_path);
679 inode = f->f_inode = f->f_path.dentry->d_inode; 668 inode = f->f_inode = f->f_path.dentry->d_inode;
680 if (f->f_mode & FMODE_WRITE) { 669 if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) {
681 error = __get_file_write_access(inode, f->f_path.mnt); 670 error = __get_file_write_access(inode, f->f_path.mnt);
682 if (error) 671 if (error)
683 goto cleanup_file; 672 goto cleanup_file;
684 if (!special_file(inode->i_mode)) 673 file_take_write(f);
685 file_take_write(f);
686 } 674 }
687 675
688 f->f_mapping = inode->i_mapping; 676 f->f_mapping = inode->i_mapping;
@@ -723,7 +711,6 @@ cleanup_all:
723 fops_put(f->f_op); 711 fops_put(f->f_op);
724 file_sb_list_del(f); 712 file_sb_list_del(f);
725 if (f->f_mode & FMODE_WRITE) { 713 if (f->f_mode & FMODE_WRITE) {
726 put_write_access(inode);
727 if (!special_file(inode->i_mode)) { 714 if (!special_file(inode->i_mode)) {
728 /* 715 /*
729 * We don't consider this a real 716 * We don't consider this a real
@@ -731,6 +718,7 @@ cleanup_all:
731 * because it all happenend right 718 * because it all happenend right
732 * here, so just reset the state. 719 * here, so just reset the state.
733 */ 720 */
721 put_write_access(inode);
734 file_reset_write(f); 722 file_reset_write(f);
735 __mnt_drop_write(f->f_path.mnt); 723 __mnt_drop_write(f->f_path.mnt);
736 } 724 }