diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index 306165e61438c..855d58210b12a 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -1806,6 +1806,7 @@ static int lbmLogInit(struct jfs_log * log) init_waitqueue_head(&log->free_wait); log->lbuf_free = NULL; + atomic_set(&log->pending_io, 0); for (i = 0; i < LOGPAGES;) { char *buffer; @@ -1855,6 +1856,8 @@ static void lbmLogShutdown(struct jfs_log * log) jfs_info("lbmLogShutdown: log:0x%p", log); + wait_event(log->free_wait, atomic_read(&log->pending_io) == 0); + lbuf = log->lbuf_free; while (lbuf) { struct lbuf *next = lbuf->l_freelist; @@ -1976,6 +1979,7 @@ static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp) bio->bi_end_io = lbmIODone; bio->bi_private = bp; + atomic_inc(&log->pending_io); /*check if journaling to disk has been disabled*/ if (log->no_integrity) { bio->bi_iter.bi_size = 0; @@ -2122,6 +2126,7 @@ static void lbmStartIO(struct lbuf * bp) bio->bi_end_io = lbmIODone; bio->bi_private = bp; + atomic_inc(&log->pending_io); /* check if journaling to disk has been disabled */ if (log->no_integrity) { @@ -2186,6 +2191,8 @@ static void lbmIODone(struct bio *bio) bio_put(bio); + log = bp->l_log; + /* * pagein completion */ @@ -2214,7 +2221,6 @@ static void lbmIODone(struct bio *bio) INCREMENT(lmStat.pagedone); /* update committed lsn */ - log = bp->l_log; log->clsn = (bp->l_pn << L2LOGPSIZE) + bp->l_ceor; if (bp->l_flag & lbmDIRECT) { @@ -2297,6 +2303,8 @@ static void lbmIODone(struct bio *bio) } out: + if (atomic_dec_and_test(&log->pending_io)) + wake_up(&log->free_wait); bp->l_flag |= lbmDONE; LCACHE_UNLOCK(flags); } diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h index 09e0ef6aeccef..df0375ce572f8 100644 --- a/fs/jfs/jfs_logmgr.h +++ b/fs/jfs/jfs_logmgr.h @@ -400,6 +400,7 @@ struct jfs_log { uuid_t uuid; /* 16: 128-bit uuid of log device */ int no_integrity; /* 3: flag to disable journaling to disk */ + atomic_t pending_io; /* count of in-flight log I/Os */ }; /*