Add cc: stable to revert-remove-block_device_ejected
[ext4-patch-queue.git] / revert-remove-block_device_ejected
blobd40ab452640d20b5f9d3ced5461e139b9dc74d5f
1 Revert "ext4: remove block_device_ejected"
3 From: Theodore Ts'o <tytso@mit.edu>
5 This reverts commit 08439fec266c3cc5702953b4f54bdf5649357de0.
7 Unfortunately we still need to test for bdi->dev to avoid a crash when a
8 USB stick is yanked out while a file system is mounted:
10    usb 2-2: USB disconnect, device number 2
11    Buffer I/O error on dev sdb1, logical block 15237120, lost sync page write
12    JBD2: Error -5 detected when updating journal superblock for sdb1-8.
13    BUG: unable to handle kernel paging request at 34beb000
14    IP: [<c136ce88>] __percpu_counter_add+0x18/0xc0
15    *pdpt = 0000000023db9001 *pde = 0000000000000000 
16    Oops: 0000 [#1] SMP 
17    CPU: 0 PID: 4083 Comm: umount Tainted: G     U     OE   4.1.1-040101-generic #201507011435
18    Hardware name: LENOVO 7675CTO/7675CTO, BIOS 7NETC2WW (2.22 ) 03/22/2011
19    task: ebf06b50 ti: ebebc000 task.ti: ebebc000
20    EIP: 0060:[<c136ce88>] EFLAGS: 00010082 CPU: 0
21    EIP is at __percpu_counter_add+0x18/0xc0
22    EAX: f21c8e88 EBX: f21c8e88 ECX: 00000000 EDX: 00000001
23    ESI: 00000001 EDI: 00000000 EBP: ebebde60 ESP: ebebde40
24     DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
25    CR0: 8005003b CR2: 34beb000 CR3: 33354200 CR4: 000007f0
26    Stack:
27     c1abe100 edcb0098 edcb00ec ffffffff f21c8e68 ffffffff f21c8e68 f286d160
28     ebebde84 c1160454 00000010 00000282 f72a77f8 00000984 f72a77f8 f286d160
29     f286d170 ebebdea0 c11e613f 00000000 00000282 f72a77f8 edd7f4d0 00000000
30    Call Trace:
31     [<c1160454>] account_page_dirtied+0x74/0x110
32     [<c11e613f>] __set_page_dirty+0x3f/0xb0
33     [<c11e6203>] mark_buffer_dirty+0x53/0xc0
34     [<c124a0cb>] ext4_commit_super+0x17b/0x250
35     [<c124ac71>] ext4_put_super+0xc1/0x320
36     [<c11f04ba>] ? fsnotify_unmount_inodes+0x1aa/0x1c0
37     [<c11cfeda>] ? evict_inodes+0xca/0xe0
38     [<c11b925a>] generic_shutdown_super+0x6a/0xe0
39     [<c10a1df0>] ? prepare_to_wait_event+0xd0/0xd0
40     [<c1165a50>] ? unregister_shrinker+0x40/0x50
41     [<c11b92f6>] kill_block_super+0x26/0x70
42     [<c11b94f5>] deactivate_locked_super+0x45/0x80
43     [<c11ba007>] deactivate_super+0x47/0x60
44     [<c11d2b39>] cleanup_mnt+0x39/0x80
45     [<c11d2bc0>] __cleanup_mnt+0x10/0x20
46     [<c1080b51>] task_work_run+0x91/0xd0
47     [<c1011e3c>] do_notify_resume+0x7c/0x90
48     [<c1720da5>] work_notify
49    Code: 8b 55 e8 e9 f4 fe ff ff 90 90 90 90 90 90 90 90 90 90 90 55 89 e5 83 ec 20 89 5d f4 89 c3 89 75 f8 89 d6 89 7d fc 89 cf 8b 48 14 <64> 8b 01 89 45 ec 89 c2 8b 45 08 c1 fa 1f 01 75 ec 89 55 f0 89
50    EIP: [<c136ce88>] __percpu_counter_add+0x18/0xc0 SS:ESP 0068:ebebde40
51    CR2: 0000000034beb000
52    ---[ end trace dd564a7bea834ecd ]---
54 Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=101011
56 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
57 Cc: stable@vger.kernel.org
59 ---
60  fs/ext4/super.c | 18 +++++++++++++++++-
61  1 file changed, 17 insertions(+), 1 deletion(-)
63 diff --git a/fs/ext4/super.c b/fs/ext4/super.c
64 index 45658c1..bd3ff92 100644
65 --- a/fs/ext4/super.c
66 +++ b/fs/ext4/super.c
67 @@ -326,6 +326,22 @@ static void save_error_info(struct super_block *sb, const char *func,
68         ext4_commit_super(sb, 1);
69  }
71 +/*
72 + * The del_gendisk() function uninitializes the disk-specific data
73 + * structures, including the bdi structure, without telling anyone
74 + * else.  Once this happens, any attempt to call mark_buffer_dirty()
75 + * (for example, by ext4_commit_super), will cause a kernel OOPS.
76 + * This is a kludge to prevent these oops until we can put in a proper
77 + * hook in del_gendisk() to inform the VFS and file system layers.
78 + */
79 +static int block_device_ejected(struct super_block *sb)
81 +       struct inode *bd_inode = sb->s_bdev->bd_inode;
82 +       struct backing_dev_info *bdi = inode_to_bdi(bd_inode);
84 +       return bdi->dev == NULL;
87  static void ext4_journal_commit_callback(journal_t *journal, transaction_t *txn)
88  {
89         struct super_block              *sb = journal->j_private;
90 @@ -4621,7 +4637,7 @@ static int ext4_commit_super(struct super_block *sb, int sync)
91         struct buffer_head *sbh = EXT4_SB(sb)->s_sbh;
92         int error = 0;
94 -       if (!sbh)
95 +       if (!sbh || block_device_ejected(sb))
96                 return error;
97         if (buffer_write_io_error(sbh)) {
98                 /*
99 -- 
100 2.5.0