aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
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/ext4
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/ext4')
-rw-r--r--fs/ext4/inode.c15
-rw-r--r--fs/ext4/mmp.c6
-rw-r--r--fs/ext4/super.c31
3 files changed, 23 insertions, 29 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 89b59cb7f9b8..6324f74e0342 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -233,6 +233,11 @@ void ext4_evict_inode(struct inode *inode)
233 if (is_bad_inode(inode)) 233 if (is_bad_inode(inode))
234 goto no_delete; 234 goto no_delete;
235 235
236 /*
237 * Protect us against freezing - iput() caller didn't have to have any
238 * protection against it
239 */
240 sb_start_intwrite(inode->i_sb);
236 handle = ext4_journal_start(inode, ext4_blocks_for_truncate(inode)+3); 241 handle = ext4_journal_start(inode, ext4_blocks_for_truncate(inode)+3);
237 if (IS_ERR(handle)) { 242 if (IS_ERR(handle)) {
238 ext4_std_error(inode->i_sb, PTR_ERR(handle)); 243 ext4_std_error(inode->i_sb, PTR_ERR(handle));
@@ -242,6 +247,7 @@ void ext4_evict_inode(struct inode *inode)
242 * cleaned up. 247 * cleaned up.
243 */ 248 */
244 ext4_orphan_del(NULL, inode); 249 ext4_orphan_del(NULL, inode);
250 sb_end_intwrite(inode->i_sb);
245 goto no_delete; 251 goto no_delete;
246 } 252 }
247 253
@@ -273,6 +279,7 @@ void ext4_evict_inode(struct inode *inode)
273 stop_handle: 279 stop_handle:
274 ext4_journal_stop(handle); 280 ext4_journal_stop(handle);
275 ext4_orphan_del(NULL, inode); 281 ext4_orphan_del(NULL, inode);
282 sb_end_intwrite(inode->i_sb);
276 goto no_delete; 283 goto no_delete;
277 } 284 }
278 } 285 }
@@ -301,6 +308,7 @@ void ext4_evict_inode(struct inode *inode)
301 else 308 else
302 ext4_free_inode(handle, inode); 309 ext4_free_inode(handle, inode);
303 ext4_journal_stop(handle); 310 ext4_journal_stop(handle);
311 sb_end_intwrite(inode->i_sb);
304 return; 312 return;
305no_delete: 313no_delete:
306 ext4_clear_inode(inode); /* We must guarantee clearing of inode... */ 314 ext4_clear_inode(inode); /* We must guarantee clearing of inode... */
@@ -4779,11 +4787,7 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
4779 get_block_t *get_block; 4787 get_block_t *get_block;
4780 int retries = 0; 4788 int retries = 0;
4781 4789
4782 /* 4790 sb_start_pagefault(inode->i_sb);
4783 * This check is racy but catches the common case. We rely on
4784 * __block_page_mkwrite() to do a reliable check.
4785 */
4786 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
4787 /* Delalloc case is easy... */ 4791 /* Delalloc case is easy... */
4788 if (test_opt(inode->i_sb, DELALLOC) && 4792 if (test_opt(inode->i_sb, DELALLOC) &&
4789 !ext4_should_journal_data(inode) && 4793 !ext4_should_journal_data(inode) &&
@@ -4851,5 +4855,6 @@ retry_alloc:
4851out_ret: 4855out_ret:
4852 ret = block_page_mkwrite_return(ret); 4856 ret = block_page_mkwrite_return(ret);
4853out: 4857out:
4858 sb_end_pagefault(inode->i_sb);
4854 return ret; 4859 return ret;
4855} 4860}
diff --git a/fs/ext4/mmp.c b/fs/ext4/mmp.c
index f99a1311e847..fe7c63f4717e 100644
--- a/fs/ext4/mmp.c
+++ b/fs/ext4/mmp.c
@@ -44,6 +44,11 @@ static int write_mmp_block(struct super_block *sb, struct buffer_head *bh)
44{ 44{
45 struct mmp_struct *mmp = (struct mmp_struct *)(bh->b_data); 45 struct mmp_struct *mmp = (struct mmp_struct *)(bh->b_data);
46 46
47 /*
48 * We protect against freezing so that we don't create dirty buffers
49 * on frozen filesystem.
50 */
51 sb_start_write(sb);
47 ext4_mmp_csum_set(sb, mmp); 52 ext4_mmp_csum_set(sb, mmp);
48 mark_buffer_dirty(bh); 53 mark_buffer_dirty(bh);
49 lock_buffer(bh); 54 lock_buffer(bh);
@@ -51,6 +56,7 @@ static int write_mmp_block(struct super_block *sb, struct buffer_head *bh)
51 get_bh(bh); 56 get_bh(bh);
52 submit_bh(WRITE_SYNC, bh); 57 submit_bh(WRITE_SYNC, bh);
53 wait_on_buffer(bh); 58 wait_on_buffer(bh);
59 sb_end_write(sb);
54 if (unlikely(!buffer_uptodate(bh))) 60 if (unlikely(!buffer_uptodate(bh)))
55 return 1; 61 return 1;
56 62
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 2d51cd9af225..d76ec8277d3f 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -331,33 +331,17 @@ static void ext4_put_nojournal(handle_t *handle)
331 * journal_end calls result in the superblock being marked dirty, so 331 * journal_end calls result in the superblock being marked dirty, so
332 * that sync() will call the filesystem's write_super callback if 332 * that sync() will call the filesystem's write_super callback if
333 * appropriate. 333 * appropriate.
334 *
335 * To avoid j_barrier hold in userspace when a user calls freeze(),
336 * ext4 prevents a new handle from being started by s_frozen, which
337 * is in an upper layer.
338 */ 334 */
339handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks) 335handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks)
340{ 336{
341 journal_t *journal; 337 journal_t *journal;
342 handle_t *handle;
343 338
344 trace_ext4_journal_start(sb, nblocks, _RET_IP_); 339 trace_ext4_journal_start(sb, nblocks, _RET_IP_);
345 if (sb->s_flags & MS_RDONLY) 340 if (sb->s_flags & MS_RDONLY)
346 return ERR_PTR(-EROFS); 341 return ERR_PTR(-EROFS);
347 342
343 WARN_ON(sb->s_writers.frozen == SB_FREEZE_COMPLETE);
348 journal = EXT4_SB(sb)->s_journal; 344 journal = EXT4_SB(sb)->s_journal;
349 handle = ext4_journal_current_handle();
350
351 /*
352 * If a handle has been started, it should be allowed to
353 * finish, otherwise deadlock could happen between freeze
354 * and others(e.g. truncate) due to the restart of the
355 * journal handle if the filesystem is forzen and active
356 * handles are not stopped.
357 */
358 if (!handle)
359 vfs_check_frozen(sb, SB_FREEZE_TRANS);
360
361 if (!journal) 345 if (!journal)
362 return ext4_get_nojournal(); 346 return ext4_get_nojournal();
363 /* 347 /*
@@ -2747,6 +2731,7 @@ static int ext4_run_li_request(struct ext4_li_request *elr)
2747 sb = elr->lr_super; 2731 sb = elr->lr_super;
2748 ngroups = EXT4_SB(sb)->s_groups_count; 2732 ngroups = EXT4_SB(sb)->s_groups_count;
2749 2733
2734 sb_start_write(sb);
2750 for (group = elr->lr_next_group; group < ngroups; group++) { 2735 for (group = elr->lr_next_group; group < ngroups; group++) {
2751 gdp = ext4_get_group_desc(sb, group, NULL); 2736 gdp = ext4_get_group_desc(sb, group, NULL);
2752 if (!gdp) { 2737 if (!gdp) {
@@ -2773,6 +2758,7 @@ static int ext4_run_li_request(struct ext4_li_request *elr)
2773 elr->lr_next_sched = jiffies + elr->lr_timeout; 2758 elr->lr_next_sched = jiffies + elr->lr_timeout;
2774 elr->lr_next_group = group + 1; 2759 elr->lr_next_group = group + 1;
2775 } 2760 }
2761 sb_end_write(sb);
2776 2762
2777 return ret; 2763 return ret;
2778} 2764}
@@ -4460,10 +4446,8 @@ int ext4_force_commit(struct super_block *sb)
4460 return 0; 4446 return 0;
4461 4447
4462 journal = EXT4_SB(sb)->s_journal; 4448 journal = EXT4_SB(sb)->s_journal;
4463 if (journal) { 4449 if (journal)
4464 vfs_check_frozen(sb, SB_FREEZE_TRANS);
4465 ret = ext4_journal_force_commit(journal); 4450 ret = ext4_journal_force_commit(journal);
4466 }
4467 4451
4468 return ret; 4452 return ret;
4469} 4453}
@@ -4493,9 +4477,8 @@ static int ext4_sync_fs(struct super_block *sb, int wait)
4493 * gives us a chance to flush the journal completely and mark the fs clean. 4477 * gives us a chance to flush the journal completely and mark the fs clean.
4494 * 4478 *
4495 * Note that only this function cannot bring a filesystem to be in a clean 4479 * Note that only this function cannot bring a filesystem to be in a clean
4496 * state independently, because ext4 prevents a new handle from being started 4480 * state independently. It relies on upper layer to stop all data & metadata
4497 * by @sb->s_frozen, which stays in an upper layer. It thus needs help from 4481 * modifications.
4498 * the upper layer.
4499 */ 4482 */
4500static int ext4_freeze(struct super_block *sb) 4483static int ext4_freeze(struct super_block *sb)
4501{ 4484{
@@ -4522,7 +4505,7 @@ static int ext4_freeze(struct super_block *sb)
4522 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); 4505 EXT4_CLEAR_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER);
4523 error = ext4_commit_super(sb, 1); 4506 error = ext4_commit_super(sb, 1);
4524out: 4507out:
4525 /* we rely on s_frozen to stop further updates */ 4508 /* we rely on upper layer to stop further updates */
4526 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); 4509 jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal);
4527 return error; 4510 return error;
4528} 4511}