Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cbc3d65e authored by Dave Kleikamp's avatar Dave Kleikamp
Browse files

JFS: Improve sync barrier processing



Under heavy load, hot metadata pages are often locked by non-committed
transactions, making them difficult to flush to disk.  This prevents
the sync point from advancing past a transaction that had modified the
page.

There is a point during the sync barrier processing where all
outstanding transactions have been committed to disk, but no new
transaction have been allowed to proceed.  This is the best time
to write the metadata.

Signed-off-by: default avatarDave Kleikamp <shaggy@austin.ibm.com>
parent de8fd087
Loading
Loading
Loading
Loading
+19 −17
Original line number Original line Diff line number Diff line
@@ -191,7 +191,7 @@ static int lbmIOWait(struct lbuf * bp, int flag);
static bio_end_io_t lbmIODone;
static bio_end_io_t lbmIODone;
static void lbmStartIO(struct lbuf * bp);
static void lbmStartIO(struct lbuf * bp);
static void lmGCwrite(struct jfs_log * log, int cant_block);
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
 *	if new sync address is available
 *	(normally the case if sync() is executed by back-ground
 *	(normally the case if sync() is executed by back-ground
 *	process).
 *	process).
 *	if not, explicitly run jfs_blogsync() to initiate
 *	getting of new sync address.
 *	calculate new value of i_nextsync which determines when
 *	calculate new value of i_nextsync which determines when
 *	this code is called again.
 *	this code is called again.
 *
 *
 * PARAMETERS:	log	- log structure
 * PARAMETERS:	log	- log structure
 * 		nosyncwait - 1 if called asynchronously
 * 		hard_sync - 1 to force all metadata to be written
 *
 *
 * RETURN:	0
 * RETURN:	0
 *			
 *			
 * serialization: LOG_LOCK() held on entry/exit
 * 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 logsize;
	int written;		/* written since last syncpt */
	int written;		/* written since last syncpt */
@@ -941,6 +939,13 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait)
	unsigned long flags;
	unsigned long flags;


	/* push dirty metapages out to disk */
	/* push dirty metapages out to disk */
	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) {
		list_for_each_entry(sbi, &log->sb_list, log_list) {
			filemap_flush(sbi->ipbmap->i_mapping);
			filemap_flush(sbi->ipbmap->i_mapping);
			filemap_flush(sbi->ipimap->i_mapping);
			filemap_flush(sbi->ipimap->i_mapping);
@@ -1021,10 +1026,6 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait)
		/* next syncpt trigger = written + more */
		/* next syncpt trigger = written + more */
		log->nextsync = 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
	/* if number of bytes written from last sync point is more
	 * than 1/4 of the log size, stop new transactions from
	 * than 1/4 of the log size, stop new transactions from
	 * starting until all current transactions are completed
	 * starting until all current transactions are completed
@@ -1050,10 +1051,11 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait)
 * FUNCTION:	write log SYNCPT record for specified log
 * 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);
{	LOG_LOCK(log);
	lmLogSync(log, 1);
	lmLogSync(log, hard_sync);
	LOG_UNLOCK(log);
	LOG_UNLOCK(log);
}
}


+1 −1
Original line number Original line Diff line number Diff line
@@ -510,6 +510,6 @@ extern int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize);
extern int lmGroupCommit(struct jfs_log *, struct tblock *);
extern int lmGroupCommit(struct jfs_log *, struct tblock *);
extern int jfsIOWait(void *);
extern int jfsIOWait(void *);
extern void jfs_flush_journal(struct jfs_log * log, int wait);
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 */
#endif				/* _H_JFS_LOGMGR */
+5 −5
Original line number Original line Diff line number Diff line
@@ -552,6 +552,11 @@ void txEnd(tid_t tid)
		 * synchronize with logsync barrier
		 * synchronize with logsync barrier
		 */
		 */
		if (test_bit(log_SYNCBARRIER, &log->flag)) {
		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);
			jfs_info("log barrier off: 0x%x", log->lsn);


			/* enable new transactions start */
			/* enable new transactions start */
@@ -560,11 +565,6 @@ void txEnd(tid_t tid)
			/* wakeup all waitors for logsync barrier */
			/* wakeup all waitors for logsync barrier */
			TXN_WAKEUP(&log->syncwait);
			TXN_WAKEUP(&log->syncwait);


			TXN_UNLOCK();

			/* forward log syncpt */
			jfs_syncpt(log);

			goto wakeup;
			goto wakeup;
		}
		}
	}
	}
+1 −1
Original line number Original line Diff line number Diff line
@@ -531,7 +531,7 @@ static int jfs_sync_fs(struct super_block *sb, int wait)
	/* log == NULL indicates read-only mount */
	/* log == NULL indicates read-only mount */
	if (log) {
	if (log) {
		jfs_flush_journal(log, wait);
		jfs_flush_journal(log, wait);
		jfs_syncpt(log);
		jfs_syncpt(log, 0);
	}
	}


	return 0;
	return 0;