Commit cbc3d65ebcb0c494183d45cf202a53352cbf3871
1 parent
de8fd087b2
Exists in
master
and in
7 other branches
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: Dave Kleikamp <shaggy@austin.ibm.com>
Showing 4 changed files with 26 additions and 24 deletions Side-by-side Diff
fs/jfs/jfs_logmgr.c
... | ... | @@ -191,7 +191,7 @@ |
191 | 191 | static bio_end_io_t lbmIODone; |
192 | 192 | static void lbmStartIO(struct lbuf * bp); |
193 | 193 | static void lmGCwrite(struct jfs_log * log, int cant_block); |
194 | -static int lmLogSync(struct jfs_log * log, int nosyncwait); | |
194 | +static int lmLogSync(struct jfs_log * log, int hard_sync); | |
195 | 195 | |
196 | 196 | |
197 | 197 | |
198 | 198 | |
199 | 199 | |
... | ... | @@ -915,19 +915,17 @@ |
915 | 915 | * if new sync address is available |
916 | 916 | * (normally the case if sync() is executed by back-ground |
917 | 917 | * process). |
918 | - * if not, explicitly run jfs_blogsync() to initiate | |
919 | - * getting of new sync address. | |
920 | 918 | * calculate new value of i_nextsync which determines when |
921 | 919 | * this code is called again. |
922 | 920 | * |
923 | 921 | * PARAMETERS: log - log structure |
924 | - * nosyncwait - 1 if called asynchronously | |
922 | + * hard_sync - 1 to force all metadata to be written | |
925 | 923 | * |
926 | 924 | * RETURN: 0 |
927 | 925 | * |
928 | 926 | * serialization: LOG_LOCK() held on entry/exit |
929 | 927 | */ |
930 | -static int lmLogSync(struct jfs_log * log, int nosyncwait) | |
928 | +static int lmLogSync(struct jfs_log * log, int hard_sync) | |
931 | 929 | { |
932 | 930 | int logsize; |
933 | 931 | int written; /* written since last syncpt */ |
... | ... | @@ -941,11 +939,18 @@ |
941 | 939 | unsigned long flags; |
942 | 940 | |
943 | 941 | /* push dirty metapages out to disk */ |
944 | - list_for_each_entry(sbi, &log->sb_list, log_list) { | |
945 | - filemap_flush(sbi->ipbmap->i_mapping); | |
946 | - filemap_flush(sbi->ipimap->i_mapping); | |
947 | - filemap_flush(sbi->direct_inode->i_mapping); | |
948 | - } | |
942 | + if (hard_sync) | |
943 | + list_for_each_entry(sbi, &log->sb_list, log_list) { | |
944 | + filemap_fdatawrite(sbi->ipbmap->i_mapping); | |
945 | + filemap_fdatawrite(sbi->ipimap->i_mapping); | |
946 | + filemap_fdatawrite(sbi->direct_inode->i_mapping); | |
947 | + } | |
948 | + else | |
949 | + list_for_each_entry(sbi, &log->sb_list, log_list) { | |
950 | + filemap_flush(sbi->ipbmap->i_mapping); | |
951 | + filemap_flush(sbi->ipimap->i_mapping); | |
952 | + filemap_flush(sbi->direct_inode->i_mapping); | |
953 | + } | |
949 | 954 | |
950 | 955 | /* |
951 | 956 | * forward syncpt |
... | ... | @@ -1021,10 +1026,6 @@ |
1021 | 1026 | /* next syncpt trigger = written + more */ |
1022 | 1027 | log->nextsync = written + more; |
1023 | 1028 | |
1024 | - /* return if lmLogSync() from outside of transaction, e.g., sync() */ | |
1025 | - if (nosyncwait) | |
1026 | - return lsn; | |
1027 | - | |
1028 | 1029 | /* if number of bytes written from last sync point is more |
1029 | 1030 | * than 1/4 of the log size, stop new transactions from |
1030 | 1031 | * starting until all current transactions are completed |
1031 | 1032 | |
1032 | 1033 | |
... | ... | @@ -1049,11 +1050,12 @@ |
1049 | 1050 | * |
1050 | 1051 | * FUNCTION: write log SYNCPT record for specified log |
1051 | 1052 | * |
1052 | - * PARAMETERS: log - log structure | |
1053 | + * PARAMETERS: log - log structure | |
1054 | + * hard_sync - set to 1 to force metadata to be written | |
1053 | 1055 | */ |
1054 | -void jfs_syncpt(struct jfs_log *log) | |
1056 | +void jfs_syncpt(struct jfs_log *log, int hard_sync) | |
1055 | 1057 | { LOG_LOCK(log); |
1056 | - lmLogSync(log, 1); | |
1058 | + lmLogSync(log, hard_sync); | |
1057 | 1059 | LOG_UNLOCK(log); |
1058 | 1060 | } |
1059 | 1061 |
fs/jfs/jfs_logmgr.h
... | ... | @@ -510,7 +510,7 @@ |
510 | 510 | extern int lmGroupCommit(struct jfs_log *, struct tblock *); |
511 | 511 | extern int jfsIOWait(void *); |
512 | 512 | extern void jfs_flush_journal(struct jfs_log * log, int wait); |
513 | -extern void jfs_syncpt(struct jfs_log *log); | |
513 | +extern void jfs_syncpt(struct jfs_log *log, int hard_sync); | |
514 | 514 | |
515 | 515 | #endif /* _H_JFS_LOGMGR */ |
fs/jfs/jfs_txnmgr.c
... | ... | @@ -552,6 +552,11 @@ |
552 | 552 | * synchronize with logsync barrier |
553 | 553 | */ |
554 | 554 | if (test_bit(log_SYNCBARRIER, &log->flag)) { |
555 | + TXN_UNLOCK(); | |
556 | + | |
557 | + /* write dirty metadata & forward log syncpt */ | |
558 | + jfs_syncpt(log, 1); | |
559 | + | |
555 | 560 | jfs_info("log barrier off: 0x%x", log->lsn); |
556 | 561 | |
557 | 562 | /* enable new transactions start */ |
... | ... | @@ -559,11 +564,6 @@ |
559 | 564 | |
560 | 565 | /* wakeup all waitors for logsync barrier */ |
561 | 566 | TXN_WAKEUP(&log->syncwait); |
562 | - | |
563 | - TXN_UNLOCK(); | |
564 | - | |
565 | - /* forward log syncpt */ | |
566 | - jfs_syncpt(log); | |
567 | 567 | |
568 | 568 | goto wakeup; |
569 | 569 | } |