aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2013-06-04 14:21:02 -0400
committerTheodore Ts'o <tytso@mit.edu>2013-06-04 14:21:02 -0400
commit2e8fa54e3b48e4ce8c4e9ca4674ffbc973f58be5 (patch)
treeef95b6ad8bac51264484db5c37db66b8047b8bd7 /fs/ext4/super.c
parent6b523df4fb5ae281ddbc817f40504b33e6226554 (diff)
ext4: split extent conversion lists to reserved & unreserved parts
Now that we have extent conversions with reserved transaction, we have to prevent extent conversions without reserved transaction (from DIO code) to block these (as that would effectively void any transaction reservation we did). So split lists, work items, and work queues to reserved and unreserved parts. Reviewed-by: Zheng Liu <wenqing.lz@taobao.com> Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c38
1 files changed, 27 insertions, 11 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index eac4d3081ba4..7c8e1713e203 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -750,8 +750,10 @@ static void ext4_put_super(struct super_block *sb)
750 ext4_unregister_li_request(sb); 750 ext4_unregister_li_request(sb);
751 dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); 751 dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
752 752
753 flush_workqueue(sbi->dio_unwritten_wq); 753 flush_workqueue(sbi->unrsv_conversion_wq);
754 destroy_workqueue(sbi->dio_unwritten_wq); 754 flush_workqueue(sbi->rsv_conversion_wq);
755 destroy_workqueue(sbi->unrsv_conversion_wq);
756 destroy_workqueue(sbi->rsv_conversion_wq);
755 757
756 if (sbi->s_journal) { 758 if (sbi->s_journal) {
757 err = jbd2_journal_destroy(sbi->s_journal); 759 err = jbd2_journal_destroy(sbi->s_journal);
@@ -859,13 +861,15 @@ static struct inode *ext4_alloc_inode(struct super_block *sb)
859 ei->i_reserved_quota = 0; 861 ei->i_reserved_quota = 0;
860#endif 862#endif
861 ei->jinode = NULL; 863 ei->jinode = NULL;
862 INIT_LIST_HEAD(&ei->i_completed_io_list); 864 INIT_LIST_HEAD(&ei->i_rsv_conversion_list);
865 INIT_LIST_HEAD(&ei->i_unrsv_conversion_list);
863 spin_lock_init(&ei->i_completed_io_lock); 866 spin_lock_init(&ei->i_completed_io_lock);
864 ei->i_sync_tid = 0; 867 ei->i_sync_tid = 0;
865 ei->i_datasync_tid = 0; 868 ei->i_datasync_tid = 0;
866 atomic_set(&ei->i_ioend_count, 0); 869 atomic_set(&ei->i_ioend_count, 0);
867 atomic_set(&ei->i_unwritten, 0); 870 atomic_set(&ei->i_unwritten, 0);
868 INIT_WORK(&ei->i_unwritten_work, ext4_end_io_work); 871 INIT_WORK(&ei->i_rsv_conversion_work, ext4_end_io_rsv_work);
872 INIT_WORK(&ei->i_unrsv_conversion_work, ext4_end_io_unrsv_work);
869 873
870 return &ei->vfs_inode; 874 return &ei->vfs_inode;
871} 875}
@@ -3936,12 +3940,20 @@ no_journal:
3936 * The maximum number of concurrent works can be high and 3940 * The maximum number of concurrent works can be high and
3937 * concurrency isn't really necessary. Limit it to 1. 3941 * concurrency isn't really necessary. Limit it to 1.
3938 */ 3942 */
3939 EXT4_SB(sb)->dio_unwritten_wq = 3943 EXT4_SB(sb)->rsv_conversion_wq =
3940 alloc_workqueue("ext4-dio-unwritten", WQ_MEM_RECLAIM | WQ_UNBOUND, 1); 3944 alloc_workqueue("ext4-rsv-conversion", WQ_MEM_RECLAIM | WQ_UNBOUND, 1);
3941 if (!EXT4_SB(sb)->dio_unwritten_wq) { 3945 if (!EXT4_SB(sb)->rsv_conversion_wq) {
3942 printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); 3946 printk(KERN_ERR "EXT4-fs: failed to create workqueue\n");
3943 ret = -ENOMEM; 3947 ret = -ENOMEM;
3944 goto failed_mount_wq; 3948 goto failed_mount4;
3949 }
3950
3951 EXT4_SB(sb)->unrsv_conversion_wq =
3952 alloc_workqueue("ext4-unrsv-conversion", WQ_MEM_RECLAIM | WQ_UNBOUND, 1);
3953 if (!EXT4_SB(sb)->unrsv_conversion_wq) {
3954 printk(KERN_ERR "EXT4-fs: failed to create workqueue\n");
3955 ret = -ENOMEM;
3956 goto failed_mount4;
3945 } 3957 }
3946 3958
3947 /* 3959 /*
@@ -4095,7 +4107,10 @@ failed_mount4a:
4095 sb->s_root = NULL; 4107 sb->s_root = NULL;
4096failed_mount4: 4108failed_mount4:
4097 ext4_msg(sb, KERN_ERR, "mount failed"); 4109 ext4_msg(sb, KERN_ERR, "mount failed");
4098 destroy_workqueue(EXT4_SB(sb)->dio_unwritten_wq); 4110 if (EXT4_SB(sb)->rsv_conversion_wq)
4111 destroy_workqueue(EXT4_SB(sb)->rsv_conversion_wq);
4112 if (EXT4_SB(sb)->unrsv_conversion_wq)
4113 destroy_workqueue(EXT4_SB(sb)->unrsv_conversion_wq);
4099failed_mount_wq: 4114failed_mount_wq:
4100 if (sbi->s_journal) { 4115 if (sbi->s_journal) {
4101 jbd2_journal_destroy(sbi->s_journal); 4116 jbd2_journal_destroy(sbi->s_journal);
@@ -4541,7 +4556,8 @@ static int ext4_sync_fs(struct super_block *sb, int wait)
4541 struct ext4_sb_info *sbi = EXT4_SB(sb); 4556 struct ext4_sb_info *sbi = EXT4_SB(sb);
4542 4557
4543 trace_ext4_sync_fs(sb, wait); 4558 trace_ext4_sync_fs(sb, wait);
4544 flush_workqueue(sbi->dio_unwritten_wq); 4559 flush_workqueue(sbi->rsv_conversion_wq);
4560 flush_workqueue(sbi->unrsv_conversion_wq);
4545 /* 4561 /*
4546 * Writeback quota in non-journalled quota case - journalled quota has 4562 * Writeback quota in non-journalled quota case - journalled quota has
4547 * no dirty dquots 4563 * no dirty dquots