aboutsummaryrefslogtreecommitdiffstats
path: root/fs/open.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 13:26:23 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-08-01 13:26:23 -0400
commita0e881b7c189fa2bd76c024dbff91e79511c971d (patch)
tree0c801918565b08921d21aceee5b326f64d998f5f /fs/open.c
parenteff0d13f3823f35d70228cd151d2a2c89288ff32 (diff)
parentdbc6e0222d79e78925fe20733844a796a4b72cf9 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull second vfs pile from Al Viro: "The stuff in there: fsfreeze deadlock fixes by Jan (essentially, the deadlock reproduced by xfstests 068), symlink and hardlink restriction patches, plus assorted cleanups and fixes. Note that another fsfreeze deadlock (emergency thaw one) is *not* dealt with - the series by Fernando conflicts a lot with Jan's, breaks userland ABI (FIFREEZE semantics gets changed) and trades the deadlock for massive vfsmount leak; this is going to be handled next cycle. There probably will be another pull request, but that stuff won't be in it." Fix up trivial conflicts due to unrelated changes next to each other in drivers/{staging/gdm72xx/usb_boot.c, usb/gadget/storage_common.c} * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (54 commits) delousing target_core_file a bit Documentation: Correct s_umount state for freeze_fs/unfreeze_fs fs: Remove old freezing mechanism ext2: Implement freezing btrfs: Convert to new freezing mechanism nilfs2: Convert to new freezing mechanism ntfs: Convert to new freezing mechanism fuse: Convert to new freezing mechanism gfs2: Convert to new freezing mechanism ocfs2: Convert to new freezing mechanism xfs: Convert to new freezing code ext4: Convert to new freezing mechanism fs: Protect write paths by sb_start_write - sb_end_write fs: Skip atime update on frozen filesystem fs: Add freezing handling to mnt_want_write() / mnt_drop_write() fs: Improve filesystem freezing handling switch the protection of percpu_counter list to spinlock nfsd: Push mnt_want_write() outside of i_mutex btrfs: Push mnt_want_write() outside of i_mutex fat: Push mnt_want_write() outside of i_mutex ...
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/fs/open.c b/fs/open.c
index 1e914b397e12..f3d96e7e7b19 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -164,11 +164,13 @@ static long do_sys_ftruncate(unsigned int fd, loff_t length, int small)
164 if (IS_APPEND(inode)) 164 if (IS_APPEND(inode))
165 goto out_putf; 165 goto out_putf;
166 166
167 sb_start_write(inode->i_sb);
167 error = locks_verify_truncate(inode, file, length); 168 error = locks_verify_truncate(inode, file, length);
168 if (!error) 169 if (!error)
169 error = security_path_truncate(&file->f_path); 170 error = security_path_truncate(&file->f_path);
170 if (!error) 171 if (!error)
171 error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file); 172 error = do_truncate(dentry, length, ATTR_MTIME|ATTR_CTIME, file);
173 sb_end_write(inode->i_sb);
172out_putf: 174out_putf:
173 fput(file); 175 fput(file);
174out: 176out:
@@ -266,7 +268,10 @@ int do_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
266 if (!file->f_op->fallocate) 268 if (!file->f_op->fallocate)
267 return -EOPNOTSUPP; 269 return -EOPNOTSUPP;
268 270
269 return file->f_op->fallocate(file, mode, offset, len); 271 sb_start_write(inode->i_sb);
272 ret = file->f_op->fallocate(file, mode, offset, len);
273 sb_end_write(inode->i_sb);
274 return ret;
270} 275}
271 276
272SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len) 277SYSCALL_DEFINE(fallocate)(int fd, int mode, loff_t offset, loff_t len)
@@ -620,7 +625,7 @@ static inline int __get_file_write_access(struct inode *inode,
620 /* 625 /*
621 * Balanced in __fput() 626 * Balanced in __fput()
622 */ 627 */
623 error = mnt_want_write(mnt); 628 error = __mnt_want_write(mnt);
624 if (error) 629 if (error)
625 put_write_access(inode); 630 put_write_access(inode);
626 } 631 }
@@ -654,6 +659,7 @@ static int do_dentry_open(struct file *f,
654 if (unlikely(f->f_flags & O_PATH)) 659 if (unlikely(f->f_flags & O_PATH))
655 f->f_mode = FMODE_PATH; 660 f->f_mode = FMODE_PATH;
656 661
662 path_get(&f->f_path);
657 inode = f->f_path.dentry->d_inode; 663 inode = f->f_path.dentry->d_inode;
658 if (f->f_mode & FMODE_WRITE) { 664 if (f->f_mode & FMODE_WRITE) {
659 error = __get_file_write_access(inode, f->f_path.mnt); 665 error = __get_file_write_access(inode, f->f_path.mnt);
@@ -739,9 +745,7 @@ int finish_open(struct file *file, struct dentry *dentry,
739 int error; 745 int error;
740 BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */ 746 BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
741 747
742 mntget(file->f_path.mnt); 748 file->f_path.dentry = dentry;
743 file->f_path.dentry = dget(dentry);
744
745 error = do_dentry_open(file, open, current_cred()); 749 error = do_dentry_open(file, open, current_cred());
746 if (!error) 750 if (!error)
747 *opened |= FILE_OPENED; 751 *opened |= FILE_OPENED;
@@ -784,7 +788,6 @@ struct file *dentry_open(const struct path *path, int flags,
784 788
785 f->f_flags = flags; 789 f->f_flags = flags;
786 f->f_path = *path; 790 f->f_path = *path;
787 path_get(&f->f_path);
788 error = do_dentry_open(f, NULL, cred); 791 error = do_dentry_open(f, NULL, cred);
789 if (!error) { 792 if (!error) {
790 error = open_check_o_direct(f); 793 error = open_check_o_direct(f);