From: Greg Kroah-Hartman Date: Tue, 15 Jan 2013 13:33:07 +0000 (-0800) Subject: 3.4-stable patches X-Git-Tag: v3.7.3~27 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=98ee1db912b868ed2d238fbba1c847a62e3aa173;p=thirdparty%2Fkernel%2Fstable-queue.git 3.4-stable patches added patches: gfs2-test-bufdata-with-buffer-locked-and-gfs2_log_lock-held.patch --- diff --git a/queue-3.4/gfs2-test-bufdata-with-buffer-locked-and-gfs2_log_lock-held.patch b/queue-3.4/gfs2-test-bufdata-with-buffer-locked-and-gfs2_log_lock-held.patch new file mode 100644 index 00000000000..a77a0ea50f8 --- /dev/null +++ b/queue-3.4/gfs2-test-bufdata-with-buffer-locked-and-gfs2_log_lock-held.patch @@ -0,0 +1,115 @@ +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 +[bwh: Backported to 3.2: adjust context] +Signed-off-by: Ben Hutchings +Signed-off-by: Greg Kroah-Hartman +--- + fs/gfs2/lops.c | 18 ++++-------------- + fs/gfs2/trans.c | 8 ++++++++ + 2 files changed, 12 insertions(+), 14 deletions(-) + +--- a/fs/gfs2/lops.c ++++ b/fs/gfs2/lops.c +@@ -258,16 +258,14 @@ 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); + if (!list_empty(&bd->bd_list_tr)) +- goto out; ++ return; + tr = current->journal_info; + tr->tr_touched = 1; + tr->tr_num_buf++; + list_add(&bd->bd_list_tr, &tr->tr_list_buf); + if (!list_empty(&le->le_list)) +- goto out; ++ return; + set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); + set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); + gfs2_meta_check(sdp, bd->bd_bh); +@@ -278,9 +276,6 @@ static void buf_lo_add(struct gfs2_sbd * + sdp->sd_log_num_buf++; + list_add(&le->le_list, &sdp->sd_log_le_buf); + tr->tr_num_buf_new++; +-out: +- gfs2_log_unlock(sdp); +- unlock_buffer(bd->bd_bh); + } + + static void buf_lo_before_commit(struct gfs2_sbd *sdp) +@@ -611,11 +606,9 @@ 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) { + if (!list_empty(&bd->bd_list_tr)) +- goto out; ++ return; + tr->tr_touched = 1; + if (gfs2_is_jdata(ip)) { + tr->tr_num_buf++; +@@ -623,7 +616,7 @@ static void databuf_lo_add(struct gfs2_s + } + } + if (!list_empty(&le->le_list)) +- goto out; ++ return; + + set_bit(GLF_LFLUSH, &bd->bd_gl->gl_flags); + set_bit(GLF_DIRTY, &bd->bd_gl->gl_flags); +@@ -635,9 +628,6 @@ static void databuf_lo_add(struct gfs2_s + } else { + list_add_tail(&le->le_list, &sdp->sd_log_le_ordered); + } +-out: +- gfs2_log_unlock(sdp); +- unlock_buffer(bd->bd_bh); + } + + static void gfs2_check_magic(struct buffer_head *bh) +--- a/fs/gfs2/trans.c ++++ b/fs/gfs2/trans.c +@@ -145,14 +145,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->bd_le); ++ 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.4/series b/queue-3.4/series index a0d5f6fa3fa..6ba87a87ef5 100644 --- a/queue-3.4/series +++ b/queue-3.4/series @@ -106,3 +106,4 @@ usb-handle-warm-reset-failure-on-empty-port.patch xhci-avoid-dead-ports-add-roothub-port-polling.patch usb-hub-handle-claim-of-enabled-remote-wakeup-after-reset.patch xhci-handle-hs-bulk-ctrl-endpoints-that-don-t-nak.patch +gfs2-test-bufdata-with-buffer-locked-and-gfs2_log_lock-held.patch