From 5c1daed2e65d96c5acf337434b88a60b667f9649 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 13 Nov 2012 15:53:34 -0800 Subject: [PATCH] 3.6-stable patches added patches: gfs2-test-bufdata-with-buffer-locked-and-gfs2_log_lock-held.patch --- ...buffer-locked-and-gfs2_log_lock-held.patch | 102 ++++++++++++++++++ queue-3.6/series | 1 + 2 files changed, 103 insertions(+) create mode 100644 queue-3.6/gfs2-test-bufdata-with-buffer-locked-and-gfs2_log_lock-held.patch diff --git a/queue-3.6/gfs2-test-bufdata-with-buffer-locked-and-gfs2_log_lock-held.patch b/queue-3.6/gfs2-test-bufdata-with-buffer-locked-and-gfs2_log_lock-held.patch new file mode 100644 index 00000000000..abe5c50c91b --- /dev/null +++ b/queue-3.6/gfs2-test-bufdata-with-buffer-locked-and-gfs2_log_lock-held.patch @@ -0,0 +1,102 @@ +From 96e5d1d3adf56f1c7eeb07258f6a1a0a7ae9c489 Mon Sep 17 00:00:00 2001 +From: Benjamin Marzinski +Date: Wed, 7 Nov 2012 00:38:06 -0600 +Subject: GFS2: Test bufdata with buffer locked and gfs2_log_lock held + +From: Benjamin Marzinski + +commit 96e5d1d3adf56f1c7eeb07258f6a1a0a7ae9c489 upstream. + +In gfs2_trans_add_bh(), gfs2 was testing if a there was a bd attached to the +buffer without having the gfs2_log_lock held. It was then assuming it would +stay attached for the rest of the function. However, without either the log +lock being held of the buffer locked, __gfs2_ail_flush() could detach bd at any +time. This patch moves the locking before the test. If there isn't a bd +already attached, gfs2 can safely allocate one and attach it before locking. +There is no way that the newly allocated bd could be on the ail list, +and thus no way for __gfs2_ail_flush() to detach it. + +Signed-off-by: Benjamin Marzinski +Signed-off-by: Steven Whitehouse +Signed-off-by: Greg Kroah-Hartman + +--- + fs/gfs2/lops.c | 14 ++------------ + fs/gfs2/trans.c | 8 ++++++++ + 2 files changed, 10 insertions(+), 12 deletions(-) + +--- a/fs/gfs2/lops.c ++++ b/fs/gfs2/lops.c +@@ -393,12 +393,10 @@ static void buf_lo_add(struct gfs2_sbd * + struct gfs2_meta_header *mh; + struct gfs2_trans *tr; + +- lock_buffer(bd->bd_bh); +- gfs2_log_lock(sdp); + tr = current->journal_info; + tr->tr_touched = 1; + if (!list_empty(&bd->bd_list)) +- goto out; ++ return; + set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); + set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); + mh = (struct gfs2_meta_header *)bd->bd_bh->b_data; +@@ -414,9 +412,6 @@ static void buf_lo_add(struct gfs2_sbd * + sdp->sd_log_num_buf++; + list_add(&bd->bd_list, &sdp->sd_log_le_buf); + tr->tr_num_buf_new++; +-out: +- gfs2_log_unlock(sdp); +- unlock_buffer(bd->bd_bh); + } + + static void gfs2_check_magic(struct buffer_head *bh) +@@ -777,12 +772,10 @@ static void databuf_lo_add(struct gfs2_s + struct address_space *mapping = bd->bd_bh->b_page->mapping; + struct gfs2_inode *ip = GFS2_I(mapping->host); + +- lock_buffer(bd->bd_bh); +- gfs2_log_lock(sdp); + if (tr) + tr->tr_touched = 1; + if (!list_empty(&bd->bd_list)) +- goto out; ++ return; + set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); + set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); + if (gfs2_is_jdata(ip)) { +@@ -793,9 +786,6 @@ static void databuf_lo_add(struct gfs2_s + } else { + list_add_tail(&bd->bd_list, &sdp->sd_log_le_ordered); + } +-out: +- gfs2_log_unlock(sdp); +- unlock_buffer(bd->bd_bh); + } + + /** +--- a/fs/gfs2/trans.c ++++ b/fs/gfs2/trans.c +@@ -155,14 +155,22 @@ void gfs2_trans_add_bh(struct gfs2_glock + struct gfs2_sbd *sdp = gl->gl_sbd; + struct gfs2_bufdata *bd; + ++ lock_buffer(bh); ++ gfs2_log_lock(sdp); + bd = bh->b_private; + if (bd) + gfs2_assert(sdp, bd->bd_gl == gl); + else { ++ gfs2_log_unlock(sdp); ++ unlock_buffer(bh); + gfs2_attach_bufdata(gl, bh, meta); + bd = bh->b_private; ++ lock_buffer(bh); ++ gfs2_log_lock(sdp); + } + lops_add(sdp, bd); ++ gfs2_log_unlock(sdp); ++ unlock_buffer(bh); + } + + void gfs2_trans_add_revoke(struct gfs2_sbd *sdp, struct gfs2_bufdata *bd) diff --git a/queue-3.6/series b/queue-3.6/series index d9d1fc5ea9f..e875195f5ec 100644 --- a/queue-3.6/series +++ b/queue-3.6/series @@ -62,3 +62,4 @@ drm-vmwgfx-fix-hibernation-device-reset.patch drm-vmwgfx-fix-a-case-where-the-code-would-bug-when-trying-to-pin-gmr-memory.patch drm-radeon-cayman-add-some-missing-regs-to-the-vm-reg-checker.patch drm-radeon-si-add-some-missing-regs-to-the-vm-reg-checker.patch +gfs2-test-bufdata-with-buffer-locked-and-gfs2_log_lock-held.patch -- 2.47.3