aboutsummaryrefslogtreecommitdiffstats
path: root/fs/buffer.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/buffer.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/buffer.c')
-rw-r--r--fs/buffer.c28
1 files changed, 10 insertions, 18 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index c7062c896d7c..9f6d2e41281d 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2306,8 +2306,8 @@ EXPORT_SYMBOL(block_commit_write);
2306 * beyond EOF, then the page is guaranteed safe against truncation until we 2306 * beyond EOF, then the page is guaranteed safe against truncation until we
2307 * unlock the page. 2307 * unlock the page.
2308 * 2308 *
2309 * Direct callers of this function should call vfs_check_frozen() so that page 2309 * Direct callers of this function should protect against filesystem freezing
2310 * fault does not busyloop until the fs is thawed. 2310 * using sb_start_write() - sb_end_write() functions.
2311 */ 2311 */
2312int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, 2312int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
2313 get_block_t get_block) 2313 get_block_t get_block)
@@ -2318,6 +2318,12 @@ int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
2318 loff_t size; 2318 loff_t size;
2319 int ret; 2319 int ret;
2320 2320
2321 /*
2322 * Update file times before taking page lock. We may end up failing the
2323 * fault so this update may be superfluous but who really cares...
2324 */
2325 file_update_time(vma->vm_file);
2326
2321 lock_page(page); 2327 lock_page(page);
2322 size = i_size_read(inode); 2328 size = i_size_read(inode);
2323 if ((page->mapping != inode->i_mapping) || 2329 if ((page->mapping != inode->i_mapping) ||
@@ -2339,18 +2345,7 @@ int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
2339 2345
2340 if (unlikely(ret < 0)) 2346 if (unlikely(ret < 0))
2341 goto out_unlock; 2347 goto out_unlock;
2342 /*
2343 * Freezing in progress? We check after the page is marked dirty and
2344 * with page lock held so if the test here fails, we are sure freezing
2345 * code will wait during syncing until the page fault is done - at that
2346 * point page will be dirty and unlocked so freezing code will write it
2347 * and writeprotect it again.
2348 */
2349 set_page_dirty(page); 2348 set_page_dirty(page);
2350 if (inode->i_sb->s_frozen != SB_UNFROZEN) {
2351 ret = -EAGAIN;
2352 goto out_unlock;
2353 }
2354 wait_on_page_writeback(page); 2349 wait_on_page_writeback(page);
2355 return 0; 2350 return 0;
2356out_unlock: 2351out_unlock:
@@ -2365,12 +2360,9 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
2365 int ret; 2360 int ret;
2366 struct super_block *sb = vma->vm_file->f_path.dentry->d_inode->i_sb; 2361 struct super_block *sb = vma->vm_file->f_path.dentry->d_inode->i_sb;
2367 2362
2368 /* 2363 sb_start_pagefault(sb);
2369 * This check is racy but catches the common case. The check in
2370 * __block_page_mkwrite() is reliable.
2371 */
2372 vfs_check_frozen(sb, SB_FREEZE_WRITE);
2373 ret = __block_page_mkwrite(vma, vmf, get_block); 2364 ret = __block_page_mkwrite(vma, vmf, get_block);
2365 sb_end_pagefault(sb);
2374 return block_page_mkwrite_return(ret); 2366 return block_page_mkwrite_return(ret);
2375} 2367}
2376EXPORT_SYMBOL(block_page_mkwrite); 2368EXPORT_SYMBOL(block_page_mkwrite);