Lines Matching full:log
8 * jfs_logmgr.c: log manager
15 * log buffer manager:
16 * special purpose buffer manager supporting log i/o requirements.
17 * per log serial pageout of logpage
25 * log page during the pageout of previous/current log page(s) are
29 * transactions are committed asynchronously when the log page
33 * . a per log lock serialize log write.
34 * . a per log lock serialize group commit.
35 * . a per log lock serialize log open/close;
37 * TBD log integrity:
78 * log read/write serialization (per log)
80 #define LOG_LOCK_INIT(log) mutex_init(&(log)->loglock) argument
81 #define LOG_LOCK(log) mutex_lock(&((log)->loglock)) argument
82 #define LOG_UNLOCK(log) mutex_unlock(&((log)->loglock)) argument
86 * log group commit serialization (per log)
89 #define LOGGC_LOCK_INIT(log) spin_lock_init(&(log)->gclock) argument
90 #define LOGGC_LOCK(log) spin_lock_irq(&(log)->gclock) argument
91 #define LOGGC_UNLOCK(log) spin_unlock_irq(&(log)->gclock) argument
95 * log sync serialization (per log)
106 * log buffer cache synchronization
129 /* log buffer manager pageout control (cumulative, inclusive) */
149 * of log page
163 static int lmWriteRecord(struct jfs_log * log, struct tblock * tblk,
166 static int lmNextPage(struct jfs_log * log);
167 static int lmLogFileSystem(struct jfs_log * log, struct jfs_sb_info *sbi,
172 static int lbmLogInit(struct jfs_log * log);
173 static void lbmLogShutdown(struct jfs_log * log);
174 static struct lbuf *lbmAllocate(struct jfs_log * log, int);
177 static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp);
178 static void lbmWrite(struct jfs_log * log, struct lbuf * bp, int flag, int cant_block);
179 static void lbmDirectWrite(struct jfs_log * log, struct lbuf * bp, int flag);
183 static void lmGCwrite(struct jfs_log * log, int cant_block);
184 static int lmLogSync(struct jfs_log * log, int hard_sync);
201 static void write_special_inodes(struct jfs_log *log, in write_special_inodes() argument
206 list_for_each_entry(sbi, &log->sb_list, log_list) { in write_special_inodes()
216 * FUNCTION: write a log record;
220 * RETURN: lsn - offset to the next log record to write (end-of-log);
223 * note: todo: log error handler
225 int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, in lmLog() argument
233 jfs_info("lmLog: log:0x%p tblk:0x%p, lrd:0x%p tlck:0x%p", in lmLog()
234 log, tblk, lrd, tlck); in lmLog()
236 LOG_LOCK(log); in lmLog()
238 /* log by (out-of-transaction) JFS ? */ in lmLog()
242 /* log from page ? */ in lmLog()
250 lsn = log->lsn; in lmLog()
252 LOGSYNC_LOCK(log, flags); in lmLog()
255 * initialize page lsn if first log write of the page in lmLog()
258 mp->log = log; in lmLog()
260 log->count++; in lmLog()
263 list_add_tail(&mp->synclist, &log->synclist); in lmLog()
271 * log records are used to reconstruct allocation map in lmLog()
276 * commit time to allow forwarding log syncpt past log in lmLog()
287 log->count++; in lmLog()
297 logdiff(diffp, mp->lsn, log); in lmLog()
298 logdiff(difft, tblk->lsn, log); in lmLog()
308 LOGSYNC_UNLOCK(log, flags); in lmLog()
311 * write the log record in lmLog()
314 lsn = lmWriteRecord(log, tblk, lrd, tlck); in lmLog()
317 * forward log syncpt if log reached next syncpt trigger in lmLog()
319 logdiff(diffp, lsn, log); in lmLog()
320 if (diffp >= log->nextsync) in lmLog()
321 lsn = lmLogSync(log, 0); in lmLog()
323 /* update end-of-log lsn */ in lmLog()
324 log->lsn = lsn; in lmLog()
326 LOG_UNLOCK(log); in lmLog()
328 /* return end-of-log address */ in lmLog()
335 * FUNCTION: move the log record to current log page
339 * RETURN: end-of-log address
344 lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, in lmWriteRecord() argument
347 int lsn = 0; /* end-of-log address */ in lmWriteRecord()
348 struct lbuf *bp; /* dst log page buffer */ in lmWriteRecord()
349 struct logpage *lp; /* dst log page */ in lmWriteRecord()
350 caddr_t dst; /* destination address in log page */ in lmWriteRecord()
351 int dstoffset; /* end-of-log offset in log page */ in lmWriteRecord()
352 int freespace; /* free space in log page */ in lmWriteRecord()
366 /* retrieve destination log page to write */ in lmWriteRecord()
367 bp = (struct lbuf *) log->bp; in lmWriteRecord()
369 dstoffset = log->eor; in lmWriteRecord()
371 /* any log data to write ? */ in lmWriteRecord()
376 * move log record data in lmWriteRecord()
378 /* retrieve source meta-data page to log */ in lmWriteRecord()
383 /* retrieve source in-memory inode to log */ in lmWriteRecord()
408 lmNextPage(log); in lmWriteRecord()
410 bp = log->bp; in lmWriteRecord()
416 * move log vector data in lmWriteRecord()
433 lmNextPage(log); in lmWriteRecord()
435 bp = (struct lbuf *) log->bp; in lmWriteRecord()
444 * move log vector descriptor in lmWriteRecord()
461 * move log record descriptor in lmWriteRecord()
483 * end of log record descriptor in lmWriteRecord()
486 /* update last log record eor */ in lmWriteRecord()
487 log->eor = dstoffset; in lmWriteRecord()
489 lsn = (log->page << L2LOGPSIZE) + dstoffset; in lmWriteRecord()
506 LOGGC_LOCK(log); in lmWriteRecord()
510 tblk->bp = log->bp; in lmWriteRecord()
511 tblk->pn = log->page; in lmWriteRecord()
512 tblk->eor = log->eor; in lmWriteRecord()
515 list_add_tail(&tblk->cqueue, &log->cqueue); in lmWriteRecord()
517 LOGGC_UNLOCK(log); in lmWriteRecord()
521 le16_to_cpu(lrd->type), log->bp, log->page, dstoffset); in lmWriteRecord()
529 lmNextPage(log); in lmWriteRecord()
531 bp = (struct lbuf *) log->bp; in lmWriteRecord()
546 * PARAMETER: log
552 static int lmNextPage(struct jfs_log * log) in lmNextPage() argument
555 int lspn; /* log sequence page number */ in lmNextPage()
561 /* get current log page number and log sequence page number */ in lmNextPage()
562 pn = log->page; in lmNextPage()
563 bp = log->bp; in lmNextPage()
567 LOGGC_LOCK(log); in lmNextPage()
573 if (list_empty(&log->cqueue)) in lmNextPage()
576 tblk = list_entry(log->cqueue.prev, struct tblock, cqueue); in lmNextPage()
592 if (log->cflag & logGC_PAGEOUT) { in lmNextPage()
596 * of the pages since log pages will be added in lmNextPage()
600 lbmWrite(log, bp, 0, 0); in lmNextPage()
605 log->cflag |= logGC_PAGEOUT; in lmNextPage()
606 lmGCwrite(log, 0); in lmNextPage()
616 lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmFREE, 0); in lmNextPage()
618 LOGGC_UNLOCK(log); in lmNextPage()
623 /* if log wraps, the first data page of log is 2 in lmNextPage()
626 log->page = (pn == log->size - 1) ? 2 : pn + 1; in lmNextPage()
627 log->eor = LOGPHDRSIZE; /* ? valid page empty/full at logRedo() */ in lmNextPage()
629 /* allocate/initialize next log page buffer */ in lmNextPage()
630 nextbp = lbmAllocate(log, log->page); in lmNextPage()
631 nextbp->l_eor = log->eor; in lmNextPage()
632 log->bp = nextbp; in lmNextPage()
634 /* initialize next log page */ in lmNextPage()
654 * LOGGC_LOCK serializes log group commit queue, and
658 int lmGroupCommit(struct jfs_log * log, struct tblock * tblk) in lmGroupCommit() argument
662 LOGGC_LOCK(log); in lmGroupCommit()
669 LOGGC_UNLOCK(log); in lmGroupCommit()
672 jfs_info("lmGroup Commit: tblk = 0x%p, gcrtc = %d", tblk, log->gcrtc); in lmGroupCommit()
677 if ((!(log->cflag & logGC_PAGEOUT)) && (!list_empty(&log->cqueue)) && in lmGroupCommit()
678 (!(tblk->xflag & COMMIT_LAZY) || test_bit(log_FLUSH, &log->flag) in lmGroupCommit()
685 log->cflag |= logGC_PAGEOUT; in lmGroupCommit()
687 lmGCwrite(log, 0); in lmGroupCommit()
694 LOGGC_UNLOCK(log); in lmGroupCommit()
704 LOGGC_UNLOCK(log); in lmGroupCommit()
710 log->gcrtc++; in lmGroupCommit()
714 LOGGC_LOCK(log), LOGGC_UNLOCK(log)); in lmGroupCommit()
720 LOGGC_UNLOCK(log); in lmGroupCommit()
728 * initiate write of log page, building a group of all transactions
737 static void lmGCwrite(struct jfs_log * log, int cant_write) in lmGCwrite() argument
746 * build the commit group of a log page in lmGCwrite()
749 * transactions with COMMIT records on the same log page. in lmGCwrite()
752 gcpn = list_entry(log->cqueue.next, struct tblock, cqueue)->pn; in lmGCwrite()
754 list_for_each_entry(tblk, &log->cqueue, cqueue) { in lmGCwrite()
766 * pageout to commit transactions on the log page. in lmGCwrite()
777 lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmGC, in lmGCwrite()
785 lbmWrite(log, bp, lbmWRITE | lbmGC, cant_write); in lmGCwrite()
795 * to disk, redriving log I/O if necessary.
805 struct jfs_log *log = bp->l_log; in lmPostGC() local
809 //LOGGC_LOCK(log); in lmPostGC()
810 spin_lock_irqsave(&log->gclock, flags); in lmPostGC()
815 * group committed with the current log page in lmPostGC()
817 list_for_each_entry_safe(tblk, temp, &log->cqueue, cqueue) { in lmPostGC()
832 if (tblk == log->flush_tblk) { in lmPostGC()
833 /* we can stop flushing the log now */ in lmPostGC()
834 clear_bit(log_FLUSH, &log->flag); in lmPostGC()
835 log->flush_tblk = NULL; in lmPostGC()
851 log->gcrtc--; in lmPostGC()
870 lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmFREE, in lmPostGC()
877 * (whose COMMITs are after that of the last log page written. in lmPostGC()
879 * or lazy transactions are on a full (queued) log page, in lmPostGC()
883 if ((!list_empty(&log->cqueue)) && in lmPostGC()
884 ((log->gcrtc > 0) || (tblk->bp->l_wqnext != NULL) || in lmPostGC()
885 test_bit(log_FLUSH, &log->flag) || jfs_tlocks_low)) in lmPostGC()
889 lmGCwrite(log, 1); in lmPostGC()
897 log->cflag &= ~logGC_PAGEOUT; in lmPostGC()
899 //LOGGC_UNLOCK(log); in lmPostGC()
900 spin_unlock_irqrestore(&log->gclock, flags); in lmPostGC()
907 * FUNCTION: write log SYNCPT record for specified log
914 * PARAMETERS: log - log structure
921 static int lmLogSync(struct jfs_log * log, int hard_sync) in lmLogSync() argument
935 write_special_inodes(log, filemap_fdatawrite); in lmLogSync()
937 write_special_inodes(log, filemap_flush); in lmLogSync()
946 if (log->sync == log->syncpt) { in lmLogSync()
947 LOGSYNC_LOCK(log, flags); in lmLogSync()
948 if (list_empty(&log->synclist)) in lmLogSync()
949 log->sync = log->lsn; in lmLogSync()
951 lp = list_entry(log->synclist.next, in lmLogSync()
953 log->sync = lp->lsn; in lmLogSync()
955 LOGSYNC_UNLOCK(log, flags); in lmLogSync()
963 if (log->sync != log->syncpt) { in lmLogSync()
968 lrd.log.syncpt.sync = cpu_to_le32(log->sync); in lmLogSync()
969 lsn = lmWriteRecord(log, NULL, &lrd, NULL); in lmLogSync()
971 log->syncpt = log->sync; in lmLogSync()
973 lsn = log->lsn; in lmLogSync()
978 logsize = log->logsize; in lmLogSync()
980 logdiff(written, lsn, log); in lmLogSync()
985 jfs_warn("\n ... Log Wrap ... Log Wrap ... Log Wrap ...\n"); in lmLogSync()
987 * log wrapping in lmLogSync()
991 * associated with log ? in lmLogSync()
992 * option 3 - extend log ? in lmLogSync()
995 * mark log wrapped, and continue. in lmLogSync()
997 * mark log valid for recovery. in lmLogSync()
998 * if crashed during invalid state, log state in lmLogSync()
999 * implies invalid log, forcing fsck(). in lmLogSync()
1001 /* mark log state log wrap in log superblock */ in lmLogSync()
1002 /* log->state = LOGWRAP; */ in lmLogSync()
1005 log->syncpt = log->sync = lsn; in lmLogSync()
1006 log->nextsync = delta; in lmLogSync()
1009 log->nextsync = written + more; in lmLogSync()
1012 * than 1/4 of the log size, stop new transactions from in lmLogSync()
1016 if (!test_bit(log_SYNCBARRIER, &log->flag) && in lmLogSync()
1017 (written > LOGSYNC_BARRIER(logsize)) && log->active) { in lmLogSync()
1018 set_bit(log_SYNCBARRIER, &log->flag); in lmLogSync()
1019 jfs_info("log barrier on: lsn=0x%x syncpt=0x%x", lsn, in lmLogSync()
1020 log->syncpt); in lmLogSync()
1024 jfs_flush_journal(log, 0); in lmLogSync()
1033 * FUNCTION: write log SYNCPT record for specified log
1035 * PARAMETERS: log - log structure
1038 void jfs_syncpt(struct jfs_log *log, int hard_sync) in jfs_syncpt() argument
1039 { LOG_LOCK(log); in jfs_syncpt()
1040 if (!test_bit(log_QUIESCE, &log->flag)) in jfs_syncpt()
1041 lmLogSync(log, hard_sync); in jfs_syncpt()
1042 LOG_UNLOCK(log); in jfs_syncpt()
1048 * FUNCTION: open the log on first open;
1049 * insert filesystem in the active list of the log.
1052 * iplog - log inode (out)
1062 struct jfs_log *log; in lmLogOpen() local
1072 list_for_each_entry(log, &jfs_external_logs, journal_list) { in lmLogOpen()
1073 if (file_bdev(log->bdev_file)->bd_dev == sbi->logdev) { in lmLogOpen()
1074 if (!uuid_equal(&log->uuid, &sbi->loguuid)) { in lmLogOpen()
1080 * add file system to log active file system list in lmLogOpen()
1082 if ((rc = lmLogFileSystem(log, sbi, 1))) { in lmLogOpen()
1090 if (!(log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL))) { in lmLogOpen()
1094 INIT_LIST_HEAD(&log->sb_list); in lmLogOpen()
1095 init_waitqueue_head(&log->syncwait); in lmLogOpen()
1098 * external log as separate logical volume in lmLogOpen()
1100 * file systems to log may have n-to-1 relationship; in lmLogOpen()
1104 BLK_OPEN_READ | BLK_OPEN_WRITE, log, NULL); in lmLogOpen()
1110 log->bdev_file = bdev_file; in lmLogOpen()
1111 uuid_copy(&log->uuid, &sbi->loguuid); in lmLogOpen()
1114 * initialize log: in lmLogOpen()
1116 if ((rc = lmLogInit(log))) in lmLogOpen()
1119 list_add(&log->journal_list, &jfs_external_logs); in lmLogOpen()
1122 * add file system to log active file system list in lmLogOpen()
1124 if ((rc = lmLogFileSystem(log, sbi, 1))) in lmLogOpen()
1128 LOG_LOCK(log); in lmLogOpen()
1129 list_add(&sbi->log_list, &log->sb_list); in lmLogOpen()
1130 sbi->log = log; in lmLogOpen()
1131 LOG_UNLOCK(log); in lmLogOpen()
1140 list_del(&log->journal_list); in lmLogOpen()
1141 lbmLogShutdown(log); in lmLogOpen()
1143 close: /* close external log device */ in lmLogOpen()
1146 free: /* free log descriptor */ in lmLogOpen()
1148 kfree(log); in lmLogOpen()
1156 struct jfs_log *log; in open_inline_log() local
1159 if (!(log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL))) in open_inline_log()
1161 INIT_LIST_HEAD(&log->sb_list); in open_inline_log()
1162 init_waitqueue_head(&log->syncwait); in open_inline_log()
1164 set_bit(log_INLINELOG, &log->flag); in open_inline_log()
1165 log->bdev_file = sb->s_bdev_file; in open_inline_log()
1166 log->base = addressPXD(&JFS_SBI(sb)->logpxd); in open_inline_log()
1167 log->size = lengthPXD(&JFS_SBI(sb)->logpxd) >> in open_inline_log()
1169 log->l2bsize = sb->s_blocksize_bits; in open_inline_log()
1173 * initialize log. in open_inline_log()
1175 if ((rc = lmLogInit(log))) { in open_inline_log()
1176 kfree(log); in open_inline_log()
1181 list_add(&JFS_SBI(sb)->log_list, &log->sb_list); in open_inline_log()
1182 JFS_SBI(sb)->log = log; in open_inline_log()
1215 JFS_SBI(sb)->log = dummy_log; in open_dummy_log()
1225 * FUNCTION: log initialization at first log open.
1228 * initialize the log from log superblock.
1229 * set the log state in the superblock to LOGMOUNT and
1230 * write SYNCPT log record.
1232 * PARAMETER: log - log structure
1235 * -EINVAL - bad log magic number or superblock dirty
1240 int lmLogInit(struct jfs_log * log) in lmLogInit() argument
1250 jfs_info("lmLogInit: log:0x%p", log); in lmLogInit()
1253 LOGGC_LOCK_INIT(log); in lmLogInit()
1255 /* allocate/initialize the log write serialization lock */ in lmLogInit()
1256 LOG_LOCK_INIT(log); in lmLogInit()
1258 LOGSYNC_LOCK_INIT(log); in lmLogInit()
1260 INIT_LIST_HEAD(&log->synclist); in lmLogInit()
1262 INIT_LIST_HEAD(&log->cqueue); in lmLogInit()
1263 log->flush_tblk = NULL; in lmLogInit()
1265 log->count = 0; in lmLogInit()
1268 * initialize log i/o in lmLogInit()
1270 if ((rc = lbmLogInit(log))) in lmLogInit()
1273 if (!test_bit(log_INLINELOG, &log->flag)) in lmLogInit()
1274 log->l2bsize = L2LOGPSIZE; in lmLogInit()
1277 if (log->no_integrity) { in lmLogInit()
1283 bp = lbmAllocate(log , 0); in lmLogInit()
1284 log->bp = bp; in lmLogInit()
1288 * validate log superblock in lmLogInit()
1290 if ((rc = lbmRead(log, 1, &bpsuper))) in lmLogInit()
1296 jfs_warn("*** Log Format Error ! ***"); in lmLogInit()
1303 jfs_warn("*** Log Is Dirty ! ***"); in lmLogInit()
1308 /* initialize log from log superblock */ in lmLogInit()
1309 if (test_bit(log_INLINELOG,&log->flag)) { in lmLogInit()
1310 if (log->size != le32_to_cpu(logsuper->size)) { in lmLogInit()
1314 jfs_info("lmLogInit: inline log:0x%p base:0x%Lx size:0x%x", in lmLogInit()
1315 log, (unsigned long long)log->base, log->size); in lmLogInit()
1317 if (!uuid_equal(&logsuper->uuid, &log->uuid)) { in lmLogInit()
1318 jfs_warn("wrong uuid on JFS log device"); in lmLogInit()
1322 log->size = le32_to_cpu(logsuper->size); in lmLogInit()
1323 log->l2bsize = le32_to_cpu(logsuper->l2bsize); in lmLogInit()
1324 jfs_info("lmLogInit: external log:0x%p base:0x%Lx size:0x%x", in lmLogInit()
1325 log, (unsigned long long)log->base, log->size); in lmLogInit()
1328 log->page = le32_to_cpu(logsuper->end) / LOGPSIZE; in lmLogInit()
1329 log->eor = le32_to_cpu(logsuper->end) - (LOGPSIZE * log->page); in lmLogInit()
1332 * initialize for log append write mode in lmLogInit()
1334 /* establish current/end-of-log page/buffer */ in lmLogInit()
1335 if ((rc = lbmRead(log, log->page, &bp))) in lmLogInit()
1341 le32_to_cpu(logsuper->end), log->page, log->eor, in lmLogInit()
1344 log->bp = bp; in lmLogInit()
1345 bp->l_pn = log->page; in lmLogInit()
1346 bp->l_eor = log->eor; in lmLogInit()
1349 if (log->eor >= LOGPSIZE - LOGPTLRSIZE) in lmLogInit()
1350 lmNextPage(log); in lmLogInit()
1353 * initialize log syncpoint in lmLogInit()
1357 * (i.e., log redo up to HERE !); in lmLogInit()
1359 * (to write log superblock update), but do not release to in lmLogInit()
1366 lrd.log.syncpt.sync = 0; in lmLogInit()
1367 lsn = lmWriteRecord(log, NULL, &lrd, NULL); in lmLogInit()
1368 bp = log->bp; in lmLogInit()
1372 lbmWrite(log, bp, lbmWRITE | lbmSYNC, 0); in lmLogInit()
1380 log->serial = le32_to_cpu(logsuper->serial) + 1; in lmLogInit()
1381 logsuper->serial = cpu_to_le32(log->serial); in lmLogInit()
1382 lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC); in lmLogInit()
1388 log->logsize = (log->size - 2) << L2LOGPSIZE; in lmLogInit()
1389 log->lsn = lsn; in lmLogInit()
1390 log->syncpt = lsn; in lmLogInit()
1391 log->sync = log->syncpt; in lmLogInit()
1392 log->nextsync = LOGSYNC_DELTA(log->logsize); in lmLogInit()
1395 log->lsn, log->syncpt, log->sync); in lmLogInit()
1400 log->clsn = lsn; in lmLogInit()
1407 errout30: /* release log page */ in lmLogInit()
1408 log->wqueue = NULL; in lmLogInit()
1412 errout20: /* release log superblock */ in lmLogInit()
1416 lbmLogShutdown(log); in lmLogInit()
1426 * FUNCTION: remove file system <ipmnt> from active list of log <iplog>
1438 struct jfs_log *log = sbi->log; in lmLogClose() local
1442 jfs_info("lmLogClose: log:0x%p", log); in lmLogClose()
1445 LOG_LOCK(log); in lmLogClose()
1447 LOG_UNLOCK(log); in lmLogClose()
1448 sbi->log = NULL; in lmLogClose()
1456 if (test_bit(log_INLINELOG, &log->flag)) { in lmLogClose()
1458 * in-line log in host file system in lmLogClose()
1460 rc = lmLogShutdown(log); in lmLogClose()
1461 kfree(log); in lmLogClose()
1465 if (!log->no_integrity) in lmLogClose()
1466 lmLogFileSystem(log, sbi, 0); in lmLogClose()
1468 if (!list_empty(&log->sb_list)) in lmLogClose()
1478 if (log->no_integrity) in lmLogClose()
1482 * external log as separate logical volume in lmLogClose()
1484 list_del(&log->journal_list); in lmLogClose()
1485 bdev_file = log->bdev_file; in lmLogClose()
1486 rc = lmLogShutdown(log); in lmLogClose()
1490 kfree(log); in lmLogClose()
1509 void jfs_flush_journal(struct jfs_log *log, int wait) in jfs_flush_journal() argument
1515 if (!log) in jfs_flush_journal()
1518 jfs_info("jfs_flush_journal: log:0x%p wait=%d", log, wait); in jfs_flush_journal()
1520 LOGGC_LOCK(log); in jfs_flush_journal()
1522 if (!list_empty(&log->cqueue)) { in jfs_flush_journal()
1527 target = list_entry(log->cqueue.prev, struct tblock, cqueue); in jfs_flush_journal()
1529 if (test_bit(log_FLUSH, &log->flag)) { in jfs_flush_journal()
1536 if (log->flush_tblk) in jfs_flush_journal()
1537 log->flush_tblk = target; in jfs_flush_journal()
1540 log->flush_tblk = target; in jfs_flush_journal()
1541 set_bit(log_FLUSH, &log->flag); in jfs_flush_journal()
1546 if (!(log->cflag & logGC_PAGEOUT)) { in jfs_flush_journal()
1547 log->cflag |= logGC_PAGEOUT; in jfs_flush_journal()
1548 lmGCwrite(log, 0); in jfs_flush_journal()
1552 if ((wait > 1) || test_bit(log_SYNCBARRIER, &log->flag)) { in jfs_flush_journal()
1554 set_bit(log_FLUSH, &log->flag); in jfs_flush_journal()
1555 log->flush_tblk = NULL; in jfs_flush_journal()
1563 LOGGC_UNLOCK(log); in jfs_flush_journal()
1565 LOGGC_LOCK(log); in jfs_flush_journal()
1568 LOGGC_UNLOCK(log); in jfs_flush_journal()
1573 write_special_inodes(log, filemap_fdatawrite); in jfs_flush_journal()
1579 if ((!list_empty(&log->cqueue)) || !list_empty(&log->synclist)) { in jfs_flush_journal()
1582 write_special_inodes(log, filemap_fdatawrite); in jfs_flush_journal()
1583 if (list_empty(&log->cqueue) && in jfs_flush_journal()
1584 list_empty(&log->synclist)) in jfs_flush_journal()
1588 assert(list_empty(&log->cqueue)); in jfs_flush_journal()
1591 if (!list_empty(&log->synclist)) { in jfs_flush_journal()
1595 list_for_each_entry(lp, &log->synclist, synclist) { in jfs_flush_journal()
1612 WARN_ON(!list_empty(&log->synclist)); in jfs_flush_journal()
1614 clear_bit(log_FLUSH, &log->flag); in jfs_flush_journal()
1620 * FUNCTION: log shutdown at last LogClose().
1622 * write log syncpt record.
1625 * PARAMETER: log - log inode
1631 int lmLogShutdown(struct jfs_log * log) in lmLogShutdown() argument
1641 jfs_info("lmLogShutdown: log:0x%p", log); in lmLogShutdown()
1643 jfs_flush_journal(log, 2); in lmLogShutdown()
1647 * (i.e., log redo up to HERE !) in lmLogShutdown()
1653 lrd.log.syncpt.sync = 0; in lmLogShutdown()
1655 lsn = lmWriteRecord(log, NULL, &lrd, NULL); in lmLogShutdown()
1656 bp = log->bp; in lmLogShutdown()
1659 lbmWrite(log, log->bp, lbmWRITE | lbmRELEASE | lbmSYNC, 0); in lmLogShutdown()
1660 lbmIOWait(log->bp, lbmFREE); in lmLogShutdown()
1661 log->bp = NULL; in lmLogShutdown()
1664 * synchronous update log superblock in lmLogShutdown()
1665 * mark log state as shutdown cleanly in lmLogShutdown()
1666 * (i.e., Log does not need to be replayed). in lmLogShutdown()
1668 if ((rc = lbmRead(log, 1, &bpsuper))) in lmLogShutdown()
1674 lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC); in lmLogShutdown()
1678 lsn, log->page, log->eor); in lmLogShutdown()
1682 * shutdown per log i/o in lmLogShutdown()
1684 lbmLogShutdown(log); in lmLogShutdown()
1697 * file system into/from log active file system list.
1699 * PARAMETE: log - pointer to logs inode.
1701 * serial - pointer to returned log serial number
1707 static int lmLogFileSystem(struct jfs_log * log, struct jfs_sb_info *sbi, in lmLogFileSystem() argument
1717 * insert/remove file system device to log active file system list. in lmLogFileSystem()
1719 if ((rc = lbmRead(log, 1, &bpsuper))) in lmLogFileSystem()
1751 * synchronous write log superblock: in lmLogFileSystem()
1754 * at file system mount, log super block is updated for in lmLogFileSystem()
1755 * activation of the file system before any log record in lmLogFileSystem()
1758 * flushed before log super block is updated for deactivation in lmLogFileSystem()
1761 lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC); in lmLogFileSystem()
1768 * log buffer manager (lbm)
1771 * special purpose buffer manager supporting log i/o requirements.
1773 * per log write queue:
1774 * log pageout occurs in serial order by fifo write queue and
1777 * (log->wrqueue points to the tail, and buffers are linked via
1779 * maintains log page in pageout ot waiting for pageout in serial pageout.
1785 * initialize per log I/O setup at lmLogInit()
1787 static int lbmLogInit(struct jfs_log * log) in lbmLogInit() argument
1788 { /* log inode */ in lbmLogInit()
1792 jfs_info("lbmLogInit: log:0x%p", log); in lbmLogInit()
1795 log->bp = NULL; in lbmLogInit()
1797 /* initialize log device write queue */ in lbmLogInit()
1798 log->wqueue = NULL; in lbmLogInit()
1801 * Each log has its own buffer pages allocated to it. These are in lbmLogInit()
1803 * writing to the log does not block trying to allocate a page from in lbmLogInit()
1804 * the page cache (for the log). This would be bad, since page in lbmLogInit()
1806 * which would cause log activity. Was that clear? I'm trying to in lbmLogInit()
1809 init_waitqueue_head(&log->free_wait); in lbmLogInit()
1811 log->lbuf_free = NULL; in lbmLogInit()
1833 lbuf->l_log = log; in lbmLogInit()
1836 lbuf->l_freelist = log->lbuf_free; in lbmLogInit()
1837 log->lbuf_free = lbuf; in lbmLogInit()
1845 lbmLogShutdown(log); in lbmLogInit()
1853 * finalize per log I/O setup at lmLogShutdown()
1855 static void lbmLogShutdown(struct jfs_log * log) in lbmLogShutdown() argument
1859 jfs_info("lbmLogShutdown: log:0x%p", log); in lbmLogShutdown()
1861 lbuf = log->lbuf_free; in lbmLogShutdown()
1874 * allocate an empty log buffer
1876 static struct lbuf *lbmAllocate(struct jfs_log * log, int pn) in lbmAllocate() argument
1882 * recycle from log buffer freelist if any in lbmAllocate()
1885 LCACHE_SLEEP_COND(log->free_wait, (bp = log->lbuf_free), flags); in lbmAllocate()
1886 log->lbuf_free = bp->l_freelist; in lbmAllocate()
1895 bp->l_blkno = log->base + (pn << (L2LOGPSIZE - log->l2bsize)); in lbmAllocate()
1905 * release a log buffer to freelist
1920 struct jfs_log *log = bp->l_log; in lbmfree() local
1927 bp->l_freelist = log->lbuf_free; in lbmfree()
1928 log->lbuf_free = bp; in lbmfree()
1930 wake_up(&log->free_wait); in lbmfree()
1938 * FUNCTION: add a log buffer to the log redrive list
1941 * bp - log buffer
1962 static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp) in lbmRead() argument
1968 * allocate a log buffer in lbmRead()
1970 *bpp = bp = lbmAllocate(log, pn); in lbmRead()
1975 bio = bio_alloc(file_bdev(log->bdev_file), 1, REQ_OP_READ, GFP_NOFS); in lbmRead()
1976 bio->bi_iter.bi_sector = bp->l_blkno << (log->l2bsize - 9); in lbmRead()
1983 if (log->no_integrity) { in lbmRead()
2011 static void lbmWrite(struct jfs_log * log, struct lbuf * bp, int flag, in lbmWrite() argument
2021 log->base + (bp->l_pn << (L2LOGPSIZE - log->l2bsize)); in lbmWrite()
2031 * insert bp at tail of write queue associated with log in lbmWrite()
2036 tail = log->wqueue; in lbmWrite()
2042 log->wqueue = bp; in lbmWrite()
2045 log->wqueue = bp; in lbmWrite()
2066 LOGGC_UNLOCK(log); in lbmWrite()
2068 LOGGC_LOCK(log); in lbmWrite()
2077 * (e.g., log superblock) write;
2079 static void lbmDirectWrite(struct jfs_log * log, struct lbuf * bp, int flag) in lbmDirectWrite() argument
2091 log->base + (bp->l_pn << (L2LOGPSIZE - log->l2bsize)); in lbmDirectWrite()
2107 * serialization: LCACHE_LOCK() is NOT held during log i/o;
2112 struct jfs_log *log = bp->l_log; in lbmStartIO() local
2117 if (!log->no_integrity) in lbmStartIO()
2118 bdev = file_bdev(log->bdev_file); in lbmStartIO()
2122 bio->bi_iter.bi_sector = bp->l_blkno << (log->l2bsize - 9); in lbmStartIO()
2130 if (log->no_integrity) { in lbmStartIO()
2174 struct jfs_log *log; in lbmIODone() local
2189 jfs_err("lbmIODone: I/O error in JFS log"); in lbmIODone()
2224 log = bp->l_log; in lbmIODone()
2225 log->clsn = (bp->l_pn << L2LOGPSIZE) + bp->l_ceor; in lbmIODone()
2233 tail = log->wqueue; in lbmIODone()
2238 * from log device write queue in lbmIODone()
2241 log->wqueue = NULL; in lbmIODone()
2248 * from log device write queue in lbmIODone()
2342 * FUNCTION: format file system log
2345 * log - volume log
2346 * logAddress - start address of log space in FS block
2347 * logSize - length of log space in FS block;
2355 int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize) in lmLogFormat() argument
2361 int lspn; /* log sequence page number */ in lmLogFormat()
2369 sbi = list_entry(log->sb_list.next, struct jfs_sb_info, log_list); in lmLogFormat()
2371 /* allocate a log buffer */ in lmLogFormat()
2372 bp = lbmAllocate(log, 1); in lmLogFormat()
2377 * log space: in lmLogFormat()
2380 * page 1 - log superblock; in lmLogFormat()
2381 * page 2 - log data page: A SYNC log record is written in lmLogFormat()
2383 * pages 3-N - log data page: set to empty log data pages; in lmLogFormat()
2386 * init log superblock: log page 1 in lmLogFormat()
2406 * init pages 2 to npages-1 as log data pages: in lmLogFormat()
2408 * log page sequence number (lpsn) initialization: in lmLogFormat()
2415 * the N (= npages-2) data pages of the log is maintained as in lmLogFormat()
2416 * a circular file for the log records; in lmLogFormat()
2417 * lpsn grows by 1 monotonically as each log page is written in lmLogFormat()
2418 * to the circular file of the log; in lmLogFormat()
2421 * still work in find log end process, we have to simulate the in lmLogFormat()
2422 * log wrap situation at the log format time. in lmLogFormat()
2423 * The 1st log page written will have the highest lpsn. Then in lmLogFormat()
2424 * the succeeding log pages will have ascending order of in lmLogFormat()
2429 * initialize 1st log page to be written: lpsn = N - 1, in lmLogFormat()
2430 * write a SYNCPT log record is written to this page in lmLogFormat()
2440 lrd_ptr->log.syncpt.sync = 0; in lmLogFormat()
2449 * initialize succeeding log pages: lpsn = 0, 1, ..., (N-2) in lmLogFormat()
2465 * finalize log in lmLogFormat()