diff options
author | jiangyiwen <jiangyiwen@huawei.com> | 2016-03-15 17:53:01 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-15 19:55:16 -0400 |
commit | bfd97a0320d338b2fce422adeddd512466ef2390 (patch) | |
tree | 713049fa5cc725af82d5738bfae132a2685316f5 /fs | |
parent | 4d548f61d61fcaa5b5e14b8d250de9604bdb61bf (diff) |
ocfs2: use spinlock_irqsave() to downconvert lock in ocfs2_osb_dump()
Commit a75e9ccabd92 ("ocfs2: use spinlock irqsave for downconvert lock")
missed an unmodified place in ocfs2_osb_dump(), so it still exists a
deadlock scenario.
ocfs2_wake_downconvert_thread
ocfs2_rw_unlock
ocfs2_dio_end_io
dio_complete
.....
bio_endio
req_bio_endio
....
scsi_io_completion
blk_done_softirq
__do_softirq
do_softirq
irq_exit
do_IRQ
ocfs2_osb_dump
cat /sys/kernel/debug/ocfs2/${uuid}/fs_state
This patch still uses spin_lock_irqsave() - replace spin_lock() to solve
this situation.
Signed-off-by: Yiwen Jiang <jiangyiwen@huawei.com>
Reviewed-by: Joseph Qi <joseph.qi@huawei.com>
Cc: Mark Fasheh <mfasheh@suse.de>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ocfs2/super.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index faa1365097bc..302854ee0985 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -236,6 +236,7 @@ static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len) | |||
236 | struct ocfs2_recovery_map *rm = osb->recovery_map; | 236 | struct ocfs2_recovery_map *rm = osb->recovery_map; |
237 | struct ocfs2_orphan_scan *os = &osb->osb_orphan_scan; | 237 | struct ocfs2_orphan_scan *os = &osb->osb_orphan_scan; |
238 | int i, out = 0; | 238 | int i, out = 0; |
239 | unsigned long flags; | ||
239 | 240 | ||
240 | out += snprintf(buf + out, len - out, | 241 | out += snprintf(buf + out, len - out, |
241 | "%10s => Id: %-s Uuid: %-s Gen: 0x%X Label: %-s\n", | 242 | "%10s => Id: %-s Uuid: %-s Gen: 0x%X Label: %-s\n", |
@@ -271,14 +272,14 @@ static int ocfs2_osb_dump(struct ocfs2_super *osb, char *buf, int len) | |||
271 | cconn->cc_version.pv_minor); | 272 | cconn->cc_version.pv_minor); |
272 | } | 273 | } |
273 | 274 | ||
274 | spin_lock(&osb->dc_task_lock); | 275 | spin_lock_irqsave(&osb->dc_task_lock, flags); |
275 | out += snprintf(buf + out, len - out, | 276 | out += snprintf(buf + out, len - out, |
276 | "%10s => Pid: %d Count: %lu WakeSeq: %lu " | 277 | "%10s => Pid: %d Count: %lu WakeSeq: %lu " |
277 | "WorkSeq: %lu\n", "DownCnvt", | 278 | "WorkSeq: %lu\n", "DownCnvt", |
278 | (osb->dc_task ? task_pid_nr(osb->dc_task) : -1), | 279 | (osb->dc_task ? task_pid_nr(osb->dc_task) : -1), |
279 | osb->blocked_lock_count, osb->dc_wake_sequence, | 280 | osb->blocked_lock_count, osb->dc_wake_sequence, |
280 | osb->dc_work_sequence); | 281 | osb->dc_work_sequence); |
281 | spin_unlock(&osb->dc_task_lock); | 282 | spin_unlock_irqrestore(&osb->dc_task_lock, flags); |
282 | 283 | ||
283 | spin_lock(&osb->osb_lock); | 284 | spin_lock(&osb->osb_lock); |
284 | out += snprintf(buf + out, len - out, "%10s => Pid: %d Nodes:", | 285 | out += snprintf(buf + out, len - out, "%10s => Pid: %d Nodes:", |