GIT da28c12089dfcfb8695b6b555cdb8e03dda2b690 master.kernel.org:/pub/scm/linux/kernel/git/shaggy/jfs-2.6.git#for-mm --- diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -191,7 +191,7 @@ static int lbmIOWait(struct lbuf * bp, i static bio_end_io_t lbmIODone; static void lbmStartIO(struct lbuf * bp); static void lmGCwrite(struct jfs_log * log, int cant_block); -static int lmLogSync(struct jfs_log * log, int nosyncwait); +static int lmLogSync(struct jfs_log * log, int hard_sync); @@ -915,19 +915,17 @@ static void lmPostGC(struct lbuf * bp) * if new sync address is available * (normally the case if sync() is executed by back-ground * process). - * if not, explicitly run jfs_blogsync() to initiate - * getting of new sync address. * calculate new value of i_nextsync which determines when * this code is called again. * * PARAMETERS: log - log structure - * nosyncwait - 1 if called asynchronously + * hard_sync - 1 to force all metadata to be written * * RETURN: 0 * * serialization: LOG_LOCK() held on entry/exit */ -static int lmLogSync(struct jfs_log * log, int nosyncwait) +static int lmLogSync(struct jfs_log * log, int hard_sync) { int logsize; int written; /* written since last syncpt */ @@ -941,11 +939,18 @@ static int lmLogSync(struct jfs_log * lo unsigned long flags; /* push dirty metapages out to disk */ - list_for_each_entry(sbi, &log->sb_list, log_list) { - filemap_flush(sbi->ipbmap->i_mapping); - filemap_flush(sbi->ipimap->i_mapping); - filemap_flush(sbi->direct_inode->i_mapping); - } + if (hard_sync) + list_for_each_entry(sbi, &log->sb_list, log_list) { + filemap_fdatawrite(sbi->ipbmap->i_mapping); + filemap_fdatawrite(sbi->ipimap->i_mapping); + filemap_fdatawrite(sbi->direct_inode->i_mapping); + } + else + list_for_each_entry(sbi, &log->sb_list, log_list) { + filemap_flush(sbi->ipbmap->i_mapping); + filemap_flush(sbi->ipimap->i_mapping); + filemap_flush(sbi->direct_inode->i_mapping); + } /* * forward syncpt @@ -1021,10 +1026,6 @@ static int lmLogSync(struct jfs_log * lo /* next syncpt trigger = written + more */ log->nextsync = written + more; - /* return if lmLogSync() from outside of transaction, e.g., sync() */ - if (nosyncwait) - return lsn; - /* if number of bytes written from last sync point is more * than 1/4 of the log size, stop new transactions from * starting until all current transactions are completed @@ -1049,11 +1050,12 @@ static int lmLogSync(struct jfs_log * lo * * FUNCTION: write log SYNCPT record for specified log * - * PARAMETERS: log - log structure + * PARAMETERS: log - log structure + * hard_sync - set to 1 to force metadata to be written */ -void jfs_syncpt(struct jfs_log *log) +void jfs_syncpt(struct jfs_log *log, int hard_sync) { LOG_LOCK(log); - lmLogSync(log, 1); + lmLogSync(log, hard_sync); LOG_UNLOCK(log); } diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h --- a/fs/jfs/jfs_logmgr.h +++ b/fs/jfs/jfs_logmgr.h @@ -510,6 +510,6 @@ extern int lmLogFormat(struct jfs_log *l extern int lmGroupCommit(struct jfs_log *, struct tblock *); extern int jfsIOWait(void *); extern void jfs_flush_journal(struct jfs_log * log, int wait); -extern void jfs_syncpt(struct jfs_log *log); +extern void jfs_syncpt(struct jfs_log *log, int hard_sync); #endif /* _H_JFS_LOGMGR */ diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c --- a/fs/jfs/jfs_txnmgr.c +++ b/fs/jfs/jfs_txnmgr.c @@ -552,6 +552,11 @@ void txEnd(tid_t tid) * synchronize with logsync barrier */ if (test_bit(log_SYNCBARRIER, &log->flag)) { + TXN_UNLOCK(); + + /* write dirty metadata & forward log syncpt */ + jfs_syncpt(log, 1); + jfs_info("log barrier off: 0x%x", log->lsn); /* enable new transactions start */ @@ -560,11 +565,6 @@ void txEnd(tid_t tid) /* wakeup all waitors for logsync barrier */ TXN_WAKEUP(&log->syncwait); - TXN_UNLOCK(); - - /* forward log syncpt */ - jfs_syncpt(log); - goto wakeup; } } diff --git a/fs/jfs/super.c b/fs/jfs/super.c --- a/fs/jfs/super.c +++ b/fs/jfs/super.c @@ -531,7 +531,7 @@ static int jfs_sync_fs(struct super_bloc /* log == NULL indicates read-only mount */ if (log) { jfs_flush_journal(log, wait); - jfs_syncpt(log); + jfs_syncpt(log, 0); } return 0;