[PATCH 2.4.21-pre4] JFS: Fix hang under heavy load
Dave Kleikamp <[email protected]> Tue, 11 Mar 2003 16:25:49 -0600
| Newsgroups | gmane.comp.file-systems.jfs.patches |
|---|---|
| Message-ID | <[email protected]> |
This patch fixes a hang when JFS is subjected to heavy stress. # This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.1009 -> 1.1010 # fs/jfs/jfs_txnmgr.c 1.21 -> 1.22 # fs/jfs/jfs_logmgr.c 1.16 -> 1.17 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 03/03/10 [email protected] 1.1010 # JFS: Fix hang while flushing outstanding transactions under heavy load # # During syncbarrier recovery, when JFS is waiting for all outstanding # transactions to complete before allowing new ones to start, there was a # window where a new transaction starts, but is not committed when JFS thought # it could stop flushing the journal to disk. This caused the log_SYNCBARRIER # flag to not be reset, and no new transactions are allowed to start. # # This is fixed by using the log->active field to determine when to reset the # log_FLUSH flag. # -------------------------------------------- # diff -Nru a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c --- a/fs/jfs/jfs_logmgr.c Tue Mar 11 16:17:40 2003 +++ b/fs/jfs/jfs_logmgr.c Tue Mar 11 16:17:40 2003 @@ -673,28 +673,29 @@ } jfs_info("lmGroup Commit: tblk = 0x%p, gcrtc = %d", tblk, log->gcrtc); - if (tblk->xflag & COMMIT_LAZY) { - /* - * Lazy transactions can leave now - */ + if (tblk->xflag & COMMIT_LAZY) tblk->flag |= tblkGC_LAZY; - LOGGC_UNLOCK(log); - return 0; - } - /* - * group commit pageout in progress - */ - if ((!(log->cflag & logGC_PAGEOUT)) && log->cqueue.head) { + + if ((!(log->cflag & logGC_PAGEOUT)) && log->cqueue.head && + (!(tblk->xflag & COMMIT_LAZY) || test_bit(log_FLUSH, &log->flag))) { /* - * only transaction in the commit queue: + * No pageout in progress * - * start one-transaction group commit as - * its group leader. + * start group commit as its group leader. */ log->cflag |= logGC_PAGEOUT; lmGCwrite(log, 0); } + + if (tblk->xflag & COMMIT_LAZY) { + /* + * Lazy transactions can leave now + */ + LOGGC_UNLOCK(log); + return 0; + } + /* lmGCwrite gives up LOGGC_LOCK, check again */ if (tblk->flag & tblkGC_COMMITTED) { @@ -893,10 +894,8 @@ * the first transaction entering group commit * will elect herself as new group leader. */ - else { + else log->cflag &= ~logGC_PAGEOUT; - clear_bit(log_FLUSH, &log->flag); - } //LOGGC_UNLOCK(log); spin_unlock_irqrestore(&log->gclock, flags); diff -Nru a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c --- a/fs/jfs/jfs_txnmgr.c Tue Mar 11 16:17:40 2003 +++ b/fs/jfs/jfs_txnmgr.c Tue Mar 11 16:17:40 2003 @@ -517,22 +517,24 @@ /* * mark the tblock not active */ - --log->active; + if (--log->active == 0) { + clear_bit(log_FLUSH, &log->flag); - /* - * synchronize with logsync barrier - */ - if (test_bit(log_SYNCBARRIER, &log->flag) && log->active == 0) { - /* forward log syncpt */ - /* lmSync(log); */ + /* + * synchronize with logsync barrier + */ + if (test_bit(log_SYNCBARRIER, &log->flag)) { + /* forward log syncpt */ + /* lmSync(log); */ - jfs_info(" log barrier off: 0x%x", log->lsn); + jfs_info("log barrier off: 0x%x", log->lsn); - /* enable new transactions start */ - clear_bit(log_SYNCBARRIER, &log->flag); + /* enable new transactions start */ + clear_bit(log_SYNCBARRIER, &log->flag); - /* wakeup all waitors for logsync barrier */ - TXN_WAKEUP(&log->syncwait); + /* wakeup all waitors for logsync barrier */ + TXN_WAKEUP(&log->syncwait); + } } /*