diff options
| author | Wu Fengguang <fengguang.wu@intel.com> | 2012-02-04 21:54:03 -0500 |
|---|---|---|
| committer | Wu Fengguang <fengguang.wu@intel.com> | 2012-02-05 22:17:25 -0500 |
| commit | 977b7e3a52a7421ad33a393a38ece59f3d41c2fa (patch) | |
| tree | 8ad7bb97c2385c3407c4fb647cc932978057559d /include | |
| parent | 3310225dfc71a35a2cc9340c15c0e08b14b3c754 (diff) | |
writeback: fix dereferencing NULL bdi->dev on trace_writeback_queue
When a SD card is hot removed without umount, del_gendisk() will call
bdi_unregister() without destroying/freeing it. This leaves the bdi in
the bdi->dev = NULL, bdi->wb.task = NULL, bdi->bdi_list removed state.
When sync(2) gets the bdi before bdi_unregister() and calls
bdi_queue_work() after the unregister, trace_writeback_queue will be
dereferencing the NULL bdi->dev. Fix it with a simple test for NULL.
LKML-reference: http://lkml.org/lkml/2012/1/18/346
Cc: stable@kernel.org
Reported-by: Rabin Vincent <rabin@rab.in>
Tested-by: Namjae Jeon <linkinjeon@gmail.com>
Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
Diffstat (limited to 'include')
| -rw-r--r-- | include/trace/events/writeback.h | 5 |
1 files changed, 4 insertions, 1 deletions
diff --git a/include/trace/events/writeback.h b/include/trace/events/writeback.h index 06d302ebcb72..5973410e8f8c 100644 --- a/include/trace/events/writeback.h +++ b/include/trace/events/writeback.h | |||
| @@ -47,7 +47,10 @@ DECLARE_EVENT_CLASS(writeback_work_class, | |||
| 47 | __field(int, reason) | 47 | __field(int, reason) |
| 48 | ), | 48 | ), |
| 49 | TP_fast_assign( | 49 | TP_fast_assign( |
| 50 | strncpy(__entry->name, dev_name(bdi->dev), 32); | 50 | struct device *dev = bdi->dev; |
| 51 | if (!dev) | ||
| 52 | dev = default_backing_dev_info.dev; | ||
| 53 | strncpy(__entry->name, dev_name(dev), 32); | ||
| 51 | __entry->nr_pages = work->nr_pages; | 54 | __entry->nr_pages = work->nr_pages; |
| 52 | __entry->sb_dev = work->sb ? work->sb->s_dev : 0; | 55 | __entry->sb_dev = work->sb ? work->sb->s_dev : 0; |
| 53 | __entry->sync_mode = work->sync_mode; | 56 | __entry->sync_mode = work->sync_mode; |
