Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6883562588bc6c70776ecc396ee7eda36c2c8da9
Commit:     6883562588bc6c70776ecc396ee7eda36c2c8da9
Parent:     f35ac346bc48b2086aa94f031baf1f6237a89de6
Author:     Benjamin Marzinski <[EMAIL PROTECTED]>
AuthorDate: Fri Mar 23 09:05:12 2007 +0000
Committer:  Steven Whitehouse <[EMAIL PROTECTED]>
CommitDate: Tue May 1 09:10:50 2007 +0100

    [GFS2] Fix log entry list corruption
    
    When glock_lo_add and rg_lo_add attempt to add an element to the log, they
    check to see if has already been added before locking the log. If another
    process adds that element to the log in this window between the check and
    locking the log, the element will be added to the list twice. This causes
    the log element list to become corrupted in such a way that the log element
    can never be successfully removed from the list. This patch pulls the
    list_empty() check inside the log lock, to remove this window.
    
    Signed-off-by: Benjamin E. Marzinski <[EMAIL PROTECTED]>
    Signed-off-by: Steven Whitehouse <[EMAIL PROTECTED]>
---
 fs/gfs2/lops.c |   20 +++++++++++---------
 1 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 16bb4b4..f82d84d 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -33,16 +33,17 @@ static void glock_lo_add(struct gfs2_sbd *sdp, struct 
gfs2_log_element *le)
 
        tr->tr_touched = 1;
 
-       if (!list_empty(&le->le_list))
-               return;
-
        gl = container_of(le, struct gfs2_glock, gl_le);
        if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(gl)))
                return;
-       gfs2_glock_hold(gl);
-       set_bit(GLF_DIRTY, &gl->gl_flags);
 
        gfs2_log_lock(sdp);
+       if (!list_empty(&le->le_list)){
+               gfs2_log_unlock(sdp);
+               return;
+       }
+       gfs2_glock_hold(gl);
+       set_bit(GLF_DIRTY, &gl->gl_flags);
        sdp->sd_log_num_gl++;
        list_add(&le->le_list, &sdp->sd_log_le_gl);
        gfs2_log_unlock(sdp);
@@ -415,13 +416,14 @@ static void rg_lo_add(struct gfs2_sbd *sdp, struct 
gfs2_log_element *le)
 
        tr->tr_touched = 1;
 
-       if (!list_empty(&le->le_list))
-               return;
-
        rgd = container_of(le, struct gfs2_rgrpd, rd_le);
-       gfs2_rgrp_bh_hold(rgd);
 
        gfs2_log_lock(sdp);
+       if (!list_empty(&le->le_list)){
+               gfs2_log_unlock(sdp);
+               return;
+       }
+       gfs2_rgrp_bh_hold(rgd);
        sdp->sd_log_num_rg++;
        list_add(&le->le_list, &sdp->sd_log_le_rg);
        gfs2_log_unlock(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