add patch move-error-report-out-of-atomic-context
[ext4-patch-queue.git] / move-error-report-out-of-atomic-context
blob71d6bcc84a3d965a83044c4c7903895b3327e0e9
1 ext4: move error report out of atomic context in ext4_init_block_bitmap()
3 From: Dmitry Monakhov <dmonakhov@openvz.org>
5 Error report likely result in IO so it is bad idea to do it from
6 atomic context.
8 This patch should fix following issue:
10 BUG: sleeping function called from invalid context at include/linux/buffer_head.h:349
11 in_atomic(): 1, irqs_disabled(): 0, pid: 137, name: kworker/u128:1
12 5 locks held by kworker/u128:1/137:
13  #0:  ("writeback"){......}, at: [<ffffffff81085618>] process_one_work+0x228/0x4d0
14  #1:  ((&(&wb->dwork)->work)){......}, at: [<ffffffff81085618>] process_one_work+0x228/0x4d0
15  #2:  (jbd2_handle){......}, at: [<ffffffff81242622>] start_this_handle+0x712/0x7b0
16  #3:  (&ei->i_data_sem){......}, at: [<ffffffff811fa387>] ext4_map_blocks+0x297/0x430
17  #4:  (&(&bgl->locks[i].lock)->rlock){......}, at: [<ffffffff811f3180>] ext4_read_block_bitmap_nowait+0x5d0/0x630
18 CPU: 3 PID: 137 Comm: kworker/u128:1 Not tainted 3.17.0-rc2-00184-g82752e4 #165
19 Hardware name: Intel Corporation W2600CR/W2600CR, BIOS SE5C600.86B.99.99.x028.061320111235 06/13/2011
20 Workqueue: writeback bdi_writeback_workfn (flush-1:0)
21  0000000000000411 ffff880813777288 ffffffff815c7fdc ffff880813777288
22  ffff880813a8bba0 ffff8808137772a8 ffffffff8108fb30 ffff880803e01e38
23  ffff880803e01e38 ffff8808137772c8 ffffffff811a8d53 ffff88080ecc6000
24 Call Trace:
25  [<ffffffff815c7fdc>] dump_stack+0x51/0x6d
26  [<ffffffff8108fb30>] __might_sleep+0xf0/0x100
27  [<ffffffff811a8d53>] __sync_dirty_buffer+0x43/0xe0
28  [<ffffffff811a8e03>] sync_dirty_buffer+0x13/0x20
29  [<ffffffff8120f581>] ext4_commit_super+0x1d1/0x230
30  [<ffffffff8120fa03>] save_error_info+0x23/0x30
31  [<ffffffff8120fd06>] __ext4_error+0xb6/0xd0
32  [<ffffffff8120f260>] ? ext4_group_desc_csum+0x140/0x190
33  [<ffffffff811f2d8c>] ext4_read_block_bitmap_nowait+0x1dc/0x630
34  [<ffffffff8122e23a>] ext4_mb_init_cache+0x21a/0x8f0
35  [<ffffffff8113ae95>] ? lru_cache_add+0x55/0x60
36  [<ffffffff8112e16c>] ? add_to_page_cache_lru+0x6c/0x80
37  [<ffffffff8122eaa0>] ext4_mb_init_group+0x190/0x280
38  [<ffffffff8122ec51>] ext4_mb_good_group+0xc1/0x190
39  [<ffffffff8123309a>] ext4_mb_regular_allocator+0x17a/0x410
40  [<ffffffff8122c821>] ? ext4_mb_use_preallocated+0x31/0x380
41  [<ffffffff81233535>] ? ext4_mb_new_blocks+0x205/0x8e0
42  [<ffffffff8116ed5c>] ? kmem_cache_alloc+0xfc/0x180
43  [<ffffffff812335b0>] ext4_mb_new_blocks+0x280/0x8e0
44  [<ffffffff8116f2c4>] ? __kmalloc+0x144/0x1c0
45  [<ffffffff81221797>] ? ext4_find_extent+0x97/0x320
46  [<ffffffff812257f4>] ext4_ext_map_blocks+0xbc4/0x1050
47  [<ffffffff811fa387>] ? ext4_map_blocks+0x297/0x430
48  [<ffffffff811fa3ab>] ext4_map_blocks+0x2bb/0x430
49  [<ffffffff81200e43>] ? ext4_init_io_end+0x23/0x50
50  [<ffffffff811feb44>] ext4_writepages+0x564/0xaf0
51  [<ffffffff815cde3b>] ? _raw_spin_unlock+0x2b/0x40
52  [<ffffffff810ac7bd>] ? lock_release_non_nested+0x2fd/0x3c0
53  [<ffffffff811a009e>] ? writeback_sb_inodes+0x10e/0x490
54  [<ffffffff811a009e>] ? writeback_sb_inodes+0x10e/0x490
55  [<ffffffff811377e3>] do_writepages+0x23/0x40
56  [<ffffffff8119c8ce>] __writeback_single_inode+0x9e/0x280
57  [<ffffffff811a026b>] writeback_sb_inodes+0x2db/0x490
58  [<ffffffff811a0664>] wb_writeback+0x174/0x2d0
59  [<ffffffff810ac359>] ? lock_release_holdtime+0x29/0x190
60  [<ffffffff811a0863>] wb_do_writeback+0xa3/0x200
61  [<ffffffff811a0a40>] bdi_writeback_workfn+0x80/0x230
62  [<ffffffff81085618>] ? process_one_work+0x228/0x4d0
63  [<ffffffff810856cd>] process_one_work+0x2dd/0x4d0
64  [<ffffffff81085618>] ? process_one_work+0x228/0x4d0
65  [<ffffffff81085c1d>] worker_thread+0x35d/0x460
66  [<ffffffff810858c0>] ? process_one_work+0x4d0/0x4d0
67  [<ffffffff810858c0>] ? process_one_work+0x4d0/0x4d0
68  [<ffffffff8108a885>] kthread+0xf5/0x100
69  [<ffffffff810990e5>] ? local_clock+0x25/0x30
70  [<ffffffff8108a790>] ? __init_kthread_worker+0x70/0x70
71  [<ffffffff815ce2ac>] ret_from_fork+0x7c/0xb0
72  [<ffffffff8108a790>] ? __init_kthread_work
74 Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
75 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
76 ---
77  fs/ext4/balloc.c |   12 ++++++++----
78  1 files changed, 8 insertions(+), 4 deletions(-)
80 diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
81 index d70f154..83a6f49 100644
82 --- a/fs/ext4/balloc.c
83 +++ b/fs/ext4/balloc.c
84 @@ -176,7 +176,7 @@ static unsigned int num_clusters_in_group(struct super_block *sb,
85  }
87  /* Initializes an uninitialized block bitmap */
88 -static void ext4_init_block_bitmap(struct super_block *sb,
89 +static int ext4_init_block_bitmap(struct super_block *sb,
90                                    struct buffer_head *bh,
91                                    ext4_group_t block_group,
92                                    struct ext4_group_desc *gdp)
93 @@ -192,7 +192,6 @@ static void ext4_init_block_bitmap(struct super_block *sb,
94         /* If checksum is bad mark all blocks used to prevent allocation
95          * essentially implementing a per-group read-only flag. */
96         if (!ext4_group_desc_csum_verify(sb, block_group, gdp)) {
97 -               ext4_error(sb, "Checksum bad for group %u", block_group);
98                 grp = ext4_get_group_info(sb, block_group);
99                 if (!EXT4_MB_GRP_BBITMAP_CORRUPT(grp))
100                         percpu_counter_sub(&sbi->s_freeclusters_counter,
101 @@ -205,7 +204,7 @@ static void ext4_init_block_bitmap(struct super_block *sb,
102                                            count);
103                 }
104                 set_bit(EXT4_GROUP_INFO_IBITMAP_CORRUPT_BIT, &grp->bb_state);
105 -               return;
106 +               return -EIO;
107         }
108         memset(bh->b_data, 0, sb->s_blocksize);
110 @@ -243,6 +242,7 @@ static void ext4_init_block_bitmap(struct super_block *sb,
111                              sb->s_blocksize * 8, bh->b_data);
112         ext4_block_bitmap_csum_set(sb, block_group, gdp, bh);
113         ext4_group_desc_csum_set(sb, block_group, gdp);
114 +       return 0;
117  /* Return the number of free blocks in a block group.  It is used when
118 @@ -438,11 +438,15 @@ ext4_read_block_bitmap_nowait(struct super_block *sb, ext4_group_t block_group)
119         }
120         ext4_lock_group(sb, block_group);
121         if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
122 -               ext4_init_block_bitmap(sb, bh, block_group, desc);
123 +               int err;
125 +               err = ext4_init_block_bitmap(sb, bh, block_group, desc);
126                 set_bitmap_uptodate(bh);
127                 set_buffer_uptodate(bh);
128                 ext4_unlock_group(sb, block_group);
129                 unlock_buffer(bh);
130 +               if (err)
131 +                       ext4_error(sb, "Checksum bad for grp %u", block_group);
132                 return bh;
133         }
134         ext4_unlock_group(sb, block_group);
135 -- 
136 1.7.1
139 To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
140 the body of a message to majordomo@vger.kernel.org
141 More majordomo info at  http://vger.kernel.org/majordomo-info.html