diff options
-rw-r--r-- | fs/open.c | 25 |
1 files changed, 6 insertions, 19 deletions
@@ -632,24 +632,6 @@ out: | |||
632 | return error; | 632 | return error; |
633 | } | 633 | } |
634 | 634 | ||
635 | /* | ||
636 | * You have to be very careful that these write | ||
637 | * counts get cleaned up in error cases and | ||
638 | * upon __fput(). This should probably never | ||
639 | * be called outside of __dentry_open(). | ||
640 | */ | ||
641 | static inline int __get_file_write_access(struct inode *inode, | ||
642 | struct vfsmount *mnt) | ||
643 | { | ||
644 | int error = get_write_access(inode); | ||
645 | if (error) | ||
646 | return error; | ||
647 | error = __mnt_want_write(mnt); | ||
648 | if (error) | ||
649 | put_write_access(inode); | ||
650 | return error; | ||
651 | } | ||
652 | |||
653 | int open_check_o_direct(struct file *f) | 635 | int open_check_o_direct(struct file *f) |
654 | { | 636 | { |
655 | /* NB: we're sure to have correct a_ops only after f_op->open */ | 637 | /* NB: we're sure to have correct a_ops only after f_op->open */ |
@@ -680,9 +662,14 @@ static int do_dentry_open(struct file *f, | |||
680 | path_get(&f->f_path); | 662 | path_get(&f->f_path); |
681 | inode = f->f_inode = f->f_path.dentry->d_inode; | 663 | inode = f->f_inode = f->f_path.dentry->d_inode; |
682 | if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) { | 664 | if (f->f_mode & FMODE_WRITE && !special_file(inode->i_mode)) { |
683 | error = __get_file_write_access(inode, f->f_path.mnt); | 665 | error = get_write_access(inode); |
684 | if (error) | 666 | if (error) |
685 | goto cleanup_file; | 667 | goto cleanup_file; |
668 | error = __mnt_want_write(f->f_path.mnt); | ||
669 | if (error) { | ||
670 | put_write_access(inode); | ||
671 | goto cleanup_file; | ||
672 | } | ||
686 | } | 673 | } |
687 | 674 | ||
688 | f->f_mapping = inode->i_mapping; | 675 | f->f_mapping = inode->i_mapping; |