Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=8bd9572769767c6fd164cff4e1202df12cb34b4a
Commit:     8bd9572769767c6fd164cff4e1202df12cb34b4a
Parent:     d7c103d0bd29c94f78155a4538faf314e49d9713
Author:     Steven Whitehouse <[EMAIL PROTECTED]>
AuthorDate: Thu Jan 25 10:04:20 2007 +0000
Committer:  Steven Whitehouse <[EMAIL PROTECTED]>
CommitDate: Mon Feb 5 13:37:56 2007 -0500

    [GFS2] Fix list corruption in lops.c
    
    The patch below appears to fix the list corruption that we are seeing on
    occasion. Although the transaction structure is private to a single
    thread, when the queued structures are dismantled during an in-core
    commit, its possible for a different thread to be trying to add the same
    structure to another, new, transaction at the same time.
    
    To avoid this, this patch takes the log spinlock during this operation.
    
    Signed-off-by: Steven Whitehouse <[EMAIL PROTECTED]>
---
 fs/gfs2/lops.c |   14 +++++++++++---
 1 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 4d7f94d..16bb4b4 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -69,13 +69,16 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct 
gfs2_log_element *le)
        struct gfs2_bufdata *bd = container_of(le, struct gfs2_bufdata, bd_le);
        struct gfs2_trans *tr;
 
-       if (!list_empty(&bd->bd_list_tr))
+       gfs2_log_lock(sdp);
+       if (!list_empty(&bd->bd_list_tr)) {
+               gfs2_log_unlock(sdp);
                return;
-
+       }
        tr = current->journal_info;
        tr->tr_touched = 1;
        tr->tr_num_buf++;
        list_add(&bd->bd_list_tr, &tr->tr_list_buf);
+       gfs2_log_unlock(sdp);
 
        if (!list_empty(&le->le_list))
                return;
@@ -84,7 +87,6 @@ static void buf_lo_add(struct gfs2_sbd *sdp, struct 
gfs2_log_element *le)
 
        gfs2_meta_check(sdp, bd->bd_bh);
        gfs2_pin(sdp, bd->bd_bh);
-
        gfs2_log_lock(sdp);
        sdp->sd_log_num_buf++;
        list_add(&le->le_list, &sdp->sd_log_le_buf);
@@ -98,11 +100,13 @@ static void buf_lo_incore_commit(struct gfs2_sbd *sdp, 
struct gfs2_trans *tr)
        struct list_head *head = &tr->tr_list_buf;
        struct gfs2_bufdata *bd;
 
+       gfs2_log_lock(sdp);
        while (!list_empty(head)) {
                bd = list_entry(head->next, struct gfs2_bufdata, bd_list_tr);
                list_del_init(&bd->bd_list_tr);
                tr->tr_num_buf--;
        }
+       gfs2_log_unlock(sdp);
        gfs2_assert_warn(sdp, !tr->tr_num_buf);
 }
 
@@ -462,13 +466,17 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct 
gfs2_log_element *le)
        struct address_space *mapping = bd->bd_bh->b_page->mapping;
        struct gfs2_inode *ip = GFS2_I(mapping->host);
 
+       gfs2_log_lock(sdp);
        tr->tr_touched = 1;
        if (list_empty(&bd->bd_list_tr) &&
            (ip->i_di.di_flags & GFS2_DIF_JDATA)) {
                tr->tr_num_buf++;
                list_add(&bd->bd_list_tr, &tr->tr_list_buf);
+               gfs2_log_unlock(sdp);
                gfs2_pin(sdp, bd->bd_bh);
                tr->tr_num_buf_new++;
+       } else {
+               gfs2_log_unlock(sdp);
        }
        gfs2_trans_add_gl(bd->bd_gl);
        gfs2_log_lock(sdp);
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to