^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) International Business Machines Corp., 2000-2004
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Portions Copyright (C) Christoph Hellwig, 2001-2002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * jfs_logmgr.c: log manager
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * for related information, see transaction manager (jfs_txnmgr.c), and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * recovery manager (jfs_logredo.c).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * note: for detail, RTFS.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * log buffer manager:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * special purpose buffer manager supporting log i/o requirements.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * per log serial pageout of logpage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * queuing i/o requests and redrive i/o at iodone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * maintain current logpage buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * no caching since append only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * appropriate jfs buffer cache buffers as needed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * group commit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * transactions which wrote COMMIT records in the same in-memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * log page during the pageout of previous/current log page(s) are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * committed together by the pageout of the page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * TBD lazy commit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * transactions are committed asynchronously when the log page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * containing it COMMIT is paged out when it becomes full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * serialization:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * . a per log lock serialize log write.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * . a per log lock serialize group commit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * . a per log lock serialize log open/close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * TBD log integrity:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * careful-write (ping-pong) of last logpage to recover from crash
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * in overwrite.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * detection of split (out-of-order) write of physical sectors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * of last logpage via timestamp at end of each sector
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * with its mirror data array at trailer).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * alternatives:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * lsn - 64-bit monotonically increasing integer vs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * 32-bit lspn and page eor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/blkdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <linux/completion.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <linux/buffer_head.h> /* for sync_blockdev() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #include <linux/bio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <linux/freezer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #include "jfs_incore.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #include "jfs_filsys.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #include "jfs_metapage.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #include "jfs_superblock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #include "jfs_txnmgr.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #include "jfs_debug.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * lbuf's ready to be redriven. Protected by log_redrive_lock (jfsIO thread)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static struct lbuf *log_redrive_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static DEFINE_SPINLOCK(log_redrive_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * log read/write serialization (per log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define LOG_LOCK_INIT(log) mutex_init(&(log)->loglock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define LOG_LOCK(log) mutex_lock(&((log)->loglock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define LOG_UNLOCK(log) mutex_unlock(&((log)->loglock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * log group commit serialization (per log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define LOGGC_LOCK_INIT(log) spin_lock_init(&(log)->gclock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define LOGGC_LOCK(log) spin_lock_irq(&(log)->gclock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define LOGGC_UNLOCK(log) spin_unlock_irq(&(log)->gclock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define LOGGC_WAKEUP(tblk) wake_up_all(&(tblk)->gcwait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * log sync serialization (per log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define LOGSYNC_DELTA(logsize) min((logsize)/8, 128*LOGPSIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define LOGSYNC_BARRIER(logsize) ((logsize)/4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define LOGSYNC_DELTA(logsize) min((logsize)/4, 256*LOGPSIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define LOGSYNC_BARRIER(logsize) ((logsize)/2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * log buffer cache synchronization
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) static DEFINE_SPINLOCK(jfsLCacheLock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) #define LCACHE_LOCK(flags) spin_lock_irqsave(&jfsLCacheLock, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define LCACHE_UNLOCK(flags) spin_unlock_irqrestore(&jfsLCacheLock, flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * See __SLEEP_COND in jfs_locks.h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define LCACHE_SLEEP_COND(wq, cond, flags) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) do { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (cond) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) break; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) __SLEEP_COND(wq, cond, LCACHE_LOCK(flags), LCACHE_UNLOCK(flags)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define LCACHE_WAKEUP(event) wake_up(event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * lbuf buffer cache (lCache) control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) /* log buffer manager pageout control (cumulative, inclusive) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) #define lbmREAD 0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define lbmWRITE 0x0002 /* enqueue at tail of write queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * init pageout if at head of queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #define lbmRELEASE 0x0004 /* remove from write queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * at completion of pageout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * do not free/recycle it yet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * caller will free it;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) #define lbmSYNC 0x0008 /* do not return to freelist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) * when removed from write queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) #define lbmFREE 0x0010 /* return to freelist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * at completion of pageout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * the buffer may be recycled;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define lbmDONE 0x0020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) #define lbmERROR 0x0040
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define lbmGC 0x0080 /* lbmIODone to perform post-GC processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * of log page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) #define lbmDIRECT 0x0100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * Global list of active external journals
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static LIST_HEAD(jfs_external_logs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static struct jfs_log *dummy_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static DEFINE_MUTEX(jfs_log_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * forward references
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static int lmWriteRecord(struct jfs_log * log, struct tblock * tblk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) struct lrd * lrd, struct tlock * tlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static int lmNextPage(struct jfs_log * log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static int lmLogFileSystem(struct jfs_log * log, struct jfs_sb_info *sbi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int activate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static int open_inline_log(struct super_block *sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static int open_dummy_log(struct super_block *sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static int lbmLogInit(struct jfs_log * log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static void lbmLogShutdown(struct jfs_log * log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static struct lbuf *lbmAllocate(struct jfs_log * log, int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static void lbmFree(struct lbuf * bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static void lbmfree(struct lbuf * bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static void lbmWrite(struct jfs_log * log, struct lbuf * bp, int flag, int cant_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static void lbmDirectWrite(struct jfs_log * log, struct lbuf * bp, int flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static int lbmIOWait(struct lbuf * bp, int flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static bio_end_io_t lbmIODone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static void lbmStartIO(struct lbuf * bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static void lmGCwrite(struct jfs_log * log, int cant_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static int lmLogSync(struct jfs_log * log, int hard_sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * statistics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #ifdef CONFIG_JFS_STATISTICS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static struct lmStat {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) uint commit; /* # of commit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) uint pagedone; /* # of page written */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) uint submitted; /* # of pages submitted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) uint full_page; /* # of full pages submitted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) uint partial_page; /* # of partial pages submitted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) } lmStat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static void write_special_inodes(struct jfs_log *log,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) int (*writer)(struct address_space *))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct jfs_sb_info *sbi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) list_for_each_entry(sbi, &log->sb_list, log_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) writer(sbi->ipbmap->i_mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) writer(sbi->ipimap->i_mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) writer(sbi->direct_inode->i_mapping);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * NAME: lmLog()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * FUNCTION: write a log record;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) * PARAMETER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) * RETURN: lsn - offset to the next log record to write (end-of-log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * -1 - error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * note: todo: log error handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) struct tlock * tlck)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) int lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) int diffp, difft;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) struct metapage *mp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) jfs_info("lmLog: log:0x%p tblk:0x%p, lrd:0x%p tlck:0x%p",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) log, tblk, lrd, tlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) LOG_LOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* log by (out-of-transaction) JFS ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) if (tblk == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) goto writeRecord;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* log from page ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (tlck == NULL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) tlck->type & tlckBTROOT || (mp = tlck->mp) == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) goto writeRecord;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * initialize/update page/transaction recovery lsn
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) lsn = log->lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) LOGSYNC_LOCK(log, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * initialize page lsn if first log write of the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (mp->lsn == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) mp->log = log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) mp->lsn = lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) log->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* insert page at tail of logsynclist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) list_add_tail(&mp->synclist, &log->synclist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * initialize/update lsn of tblock of the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * transaction inherits oldest lsn of pages associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * with allocation/deallocation of resources (their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * log records are used to reconstruct allocation map
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * at recovery time: inode for inode allocation map,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * B+-tree index of extent descriptors for block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * allocation map);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * allocation map pages inherit transaction lsn at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * commit time to allow forwarding log syncpt past log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * records associated with allocation/deallocation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * resources only after persistent map of these map pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * have been updated and propagated to home.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * initialize transaction lsn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (tblk->lsn == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) /* inherit lsn of its first page logged */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) tblk->lsn = mp->lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) log->count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) /* insert tblock after the page on logsynclist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) list_add(&tblk->synclist, &mp->synclist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * update transaction lsn:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* inherit oldest/smallest lsn of page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) logdiff(diffp, mp->lsn, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) logdiff(difft, tblk->lsn, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) if (diffp < difft) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) /* update tblock lsn with page lsn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) tblk->lsn = mp->lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) /* move tblock after page on logsynclist */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) list_move(&tblk->synclist, &mp->synclist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) LOGSYNC_UNLOCK(log, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * write the log record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) writeRecord:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) lsn = lmWriteRecord(log, tblk, lrd, tlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * forward log syncpt if log reached next syncpt trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) logdiff(diffp, lsn, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (diffp >= log->nextsync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) lsn = lmLogSync(log, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) /* update end-of-log lsn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) log->lsn = lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) LOG_UNLOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /* return end-of-log address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * NAME: lmWriteRecord()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * FUNCTION: move the log record to current log page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * PARAMETER: cd - commit descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * RETURN: end-of-log address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) * serialization: LOG_LOCK() held on entry/exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) lmWriteRecord(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) struct tlock * tlck)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) int lsn = 0; /* end-of-log address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) struct lbuf *bp; /* dst log page buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) struct logpage *lp; /* dst log page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) caddr_t dst; /* destination address in log page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) int dstoffset; /* end-of-log offset in log page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) int freespace; /* free space in log page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) caddr_t p; /* src meta-data page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) caddr_t src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int srclen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int nbytes; /* number of bytes to move */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) struct linelock *linelock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct lv *lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct lvd *lvd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) int l2linesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) /* retrieve destination log page to write */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) bp = (struct lbuf *) log->bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) lp = (struct logpage *) bp->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) dstoffset = log->eor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* any log data to write ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (tlck == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) goto moveLrd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * move log record data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* retrieve source meta-data page to log */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) if (tlck->flag & tlckPAGELOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) p = (caddr_t) (tlck->mp->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) linelock = (struct linelock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) /* retrieve source in-memory inode to log */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) else if (tlck->flag & tlckINODELOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) if (tlck->type & tlckDTREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) p = (caddr_t) &JFS_IP(tlck->ip)->i_dtroot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) p = (caddr_t) &JFS_IP(tlck->ip)->i_xtroot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) linelock = (struct linelock *) & tlck->lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) #ifdef _JFS_WIP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) else if (tlck->flag & tlckINLINELOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) inlinelock = (struct inlinelock *) & tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) p = (caddr_t) & inlinelock->pxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) linelock = (struct linelock *) & tlck;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) #endif /* _JFS_WIP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) jfs_err("lmWriteRecord: UFO tlck:0x%p", tlck);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return 0; /* Probably should trap */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) l2linesize = linelock->l2linesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) moveData:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) ASSERT(linelock->index <= linelock->maxcnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) lv = linelock->lv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) for (i = 0; i < linelock->index; i++, lv++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) if (lv->length == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) /* is page full ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (dstoffset >= LOGPSIZE - LOGPTLRSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* page become full: move on to next page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) lmNextPage(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) bp = log->bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) lp = (struct logpage *) bp->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) dstoffset = LOGPHDRSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * move log vector data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) src = (u8 *) p + (lv->offset << l2linesize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) srclen = lv->length << l2linesize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) len += srclen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) while (srclen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) freespace = (LOGPSIZE - LOGPTLRSIZE) - dstoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) nbytes = min(freespace, srclen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) dst = (caddr_t) lp + dstoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) memcpy(dst, src, nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) dstoffset += nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /* is page not full ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) if (dstoffset < LOGPSIZE - LOGPTLRSIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* page become full: move on to next page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) lmNextPage(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) bp = (struct lbuf *) log->bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) lp = (struct logpage *) bp->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) dstoffset = LOGPHDRSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) srclen -= nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) src += nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) * move log vector descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) len += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) lvd = (struct lvd *) ((caddr_t) lp + dstoffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) lvd->offset = cpu_to_le16(lv->offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) lvd->length = cpu_to_le16(lv->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) dstoffset += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) jfs_info("lmWriteRecord: lv offset:%d length:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) lv->offset, lv->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) if ((i = linelock->next)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) linelock = (struct linelock *) lid_to_tlock(i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) goto moveData;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) * move log record descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) moveLrd:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) lrd->length = cpu_to_le16(len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) src = (caddr_t) lrd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) srclen = LOGRDSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) while (srclen > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) freespace = (LOGPSIZE - LOGPTLRSIZE) - dstoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) nbytes = min(freespace, srclen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) dst = (caddr_t) lp + dstoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) memcpy(dst, src, nbytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) dstoffset += nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) srclen -= nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* are there more to move than freespace of page ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (srclen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) goto pageFull;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * end of log record descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) /* update last log record eor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) log->eor = dstoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) bp->l_eor = dstoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) lsn = (log->page << L2LOGPSIZE) + dstoffset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (lrd->type & cpu_to_le16(LOG_COMMIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) tblk->clsn = lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) jfs_info("wr: tclsn:0x%x, beor:0x%x", tblk->clsn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) bp->l_eor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) INCREMENT(lmStat.commit); /* # of commit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * enqueue tblock for group commit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * enqueue tblock of non-trivial/synchronous COMMIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * at tail of group commit queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) * (trivial/asynchronous COMMITs are ignored by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * group commit.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) LOGGC_LOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /* init tblock gc state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) tblk->flag = tblkGC_QUEUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) tblk->bp = log->bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) tblk->pn = log->page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) tblk->eor = log->eor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) /* enqueue transaction to commit queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) list_add_tail(&tblk->cqueue, &log->cqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) LOGGC_UNLOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) jfs_info("lmWriteRecord: lrd:0x%04x bp:0x%p pn:%d eor:0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) le16_to_cpu(lrd->type), log->bp, log->page, dstoffset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /* page not full ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (dstoffset < LOGPSIZE - LOGPTLRSIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) return lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) pageFull:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /* page become full: move on to next page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) lmNextPage(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) bp = (struct lbuf *) log->bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) lp = (struct logpage *) bp->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) dstoffset = LOGPHDRSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) src += nbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * NAME: lmNextPage()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) * FUNCTION: write current page and allocate next page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) * PARAMETER: log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) * RETURN: 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * serialization: LOG_LOCK() held on entry/exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) static int lmNextPage(struct jfs_log * log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) struct logpage *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) int lspn; /* log sequence page number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) int pn; /* current page number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) struct lbuf *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct lbuf *nextbp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct tblock *tblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* get current log page number and log sequence page number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) pn = log->page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) bp = log->bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) lp = (struct logpage *) bp->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) lspn = le32_to_cpu(lp->h.page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) LOGGC_LOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * write or queue the full page at the tail of write queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) /* get the tail tblk on commit queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (list_empty(&log->cqueue))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) tblk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) tblk = list_entry(log->cqueue.prev, struct tblock, cqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) /* every tblk who has COMMIT record on the current page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * and has not been committed, must be on commit queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * since tblk is queued at commit queueu at the time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * of writing its COMMIT record on the page before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * page becomes full (even though the tblk thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * who wrote COMMIT record may have been suspended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * currently);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) /* is page bound with outstanding tail tblk ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) if (tblk && tblk->pn == pn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* mark tblk for end-of-page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) tblk->flag |= tblkGC_EOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) if (log->cflag & logGC_PAGEOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /* if page is not already on write queue,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * just enqueue (no lbmWRITE to prevent redrive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * buffer to wqueue to ensure correct serial order
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) * of the pages since log pages will be added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) * continuously
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) if (bp->l_wqnext == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) lbmWrite(log, bp, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) * No current GC leader, initiate group commit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) log->cflag |= logGC_PAGEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) lmGCwrite(log, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) /* page is not bound with outstanding tblk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * init write or mark it to be redriven (lbmWRITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) /* finalize the page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) bp->l_ceor = bp->l_eor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_ceor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmFREE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) LOGGC_UNLOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * allocate/initialize next page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /* if log wraps, the first data page of log is 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * (0 never used, 1 is superblock).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) log->page = (pn == log->size - 1) ? 2 : pn + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) log->eor = LOGPHDRSIZE; /* ? valid page empty/full at logRedo() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* allocate/initialize next log page buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) nextbp = lbmAllocate(log, log->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) nextbp->l_eor = log->eor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) log->bp = nextbp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /* initialize next log page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) lp = (struct logpage *) nextbp->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) lp->h.page = lp->t.page = cpu_to_le32(lspn + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) lp->h.eor = lp->t.eor = cpu_to_le16(LOGPHDRSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * NAME: lmGroupCommit()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * FUNCTION: group commit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) * initiate pageout of the pages with COMMIT in the order of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * page number - redrive pageout of the page at the head of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * pageout queue until full page has been written.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * RETURN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * NOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * LOGGC_LOCK serializes log group commit queue, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * transaction blocks on the commit queue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) * N.B. LOG_LOCK is NOT held during lmGroupCommit().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) int lmGroupCommit(struct jfs_log * log, struct tblock * tblk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) LOGGC_LOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) /* group committed already ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (tblk->flag & tblkGC_COMMITTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) if (tblk->flag & tblkGC_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) LOGGC_UNLOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) jfs_info("lmGroup Commit: tblk = 0x%p, gcrtc = %d", tblk, log->gcrtc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (tblk->xflag & COMMIT_LAZY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) tblk->flag |= tblkGC_LAZY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if ((!(log->cflag & logGC_PAGEOUT)) && (!list_empty(&log->cqueue)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) (!(tblk->xflag & COMMIT_LAZY) || test_bit(log_FLUSH, &log->flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) || jfs_tlocks_low)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) * No pageout in progress
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * start group commit as its group leader.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) log->cflag |= logGC_PAGEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) lmGCwrite(log, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) if (tblk->xflag & COMMIT_LAZY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) * Lazy transactions can leave now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) LOGGC_UNLOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /* lmGCwrite gives up LOGGC_LOCK, check again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (tblk->flag & tblkGC_COMMITTED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (tblk->flag & tblkGC_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) LOGGC_UNLOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) /* upcount transaction waiting for completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) log->gcrtc++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) tblk->flag |= tblkGC_READY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) __SLEEP_COND(tblk->gcwait, (tblk->flag & tblkGC_COMMITTED),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) LOGGC_LOCK(log), LOGGC_UNLOCK(log));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) /* removed from commit queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (tblk->flag & tblkGC_ERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) LOGGC_UNLOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) * NAME: lmGCwrite()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) * FUNCTION: group commit write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) * initiate write of log page, building a group of all transactions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) * with commit records on that page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * RETURN: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) * NOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * LOGGC_LOCK must be held by caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * N.B. LOG_LOCK is NOT held during lmGroupCommit().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) static void lmGCwrite(struct jfs_log * log, int cant_write)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) struct lbuf *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) struct logpage *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) int gcpn; /* group commit page number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) struct tblock *tblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) struct tblock *xtblk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) * build the commit group of a log page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) * scan commit queue and make a commit group of all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) * transactions with COMMIT records on the same log page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) /* get the head tblk on the commit queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) gcpn = list_entry(log->cqueue.next, struct tblock, cqueue)->pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) list_for_each_entry(tblk, &log->cqueue, cqueue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) if (tblk->pn != gcpn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) xtblk = tblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) /* state transition: (QUEUE, READY) -> COMMIT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) tblk->flag |= tblkGC_COMMIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) tblk = xtblk; /* last tblk of the page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * pageout to commit transactions on the log page.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) bp = (struct lbuf *) tblk->bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) lp = (struct logpage *) bp->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) /* is page already full ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (tblk->flag & tblkGC_EOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* mark page to free at end of group commit of the page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) tblk->flag &= ~tblkGC_EOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) tblk->flag |= tblkGC_FREE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) bp->l_ceor = bp->l_eor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_ceor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmGC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) cant_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) INCREMENT(lmStat.full_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) /* page is not yet full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) bp->l_ceor = tblk->eor; /* ? bp->l_ceor = bp->l_eor; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_ceor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) lbmWrite(log, bp, lbmWRITE | lbmGC, cant_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) INCREMENT(lmStat.partial_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * NAME: lmPostGC()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) * FUNCTION: group commit post-processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) * Processes transactions after their commit records have been written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) * to disk, redriving log I/O if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) * RETURN: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * NOTE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * This routine is called a interrupt time by lbmIODone
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static void lmPostGC(struct lbuf * bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) struct jfs_log *log = bp->l_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) struct logpage *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) struct tblock *tblk, *temp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) //LOGGC_LOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) spin_lock_irqsave(&log->gclock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * current pageout of group commit completed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) * remove/wakeup transactions from commit queue who were
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * group committed with the current log page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) list_for_each_entry_safe(tblk, temp, &log->cqueue, cqueue) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (!(tblk->flag & tblkGC_COMMIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) /* if transaction was marked GC_COMMIT then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) * it has been shipped in the current pageout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) * and made it to disk - it is committed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (bp->l_flag & lbmERROR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) tblk->flag |= tblkGC_ERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) /* remove it from the commit queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) list_del(&tblk->cqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) tblk->flag &= ~tblkGC_QUEUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (tblk == log->flush_tblk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /* we can stop flushing the log now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) clear_bit(log_FLUSH, &log->flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) log->flush_tblk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) jfs_info("lmPostGC: tblk = 0x%p, flag = 0x%x", tblk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) tblk->flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (!(tblk->xflag & COMMIT_FORCE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) * Hand tblk over to lazy commit thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) txLazyUnlock(tblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) /* state transition: COMMIT -> COMMITTED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) tblk->flag |= tblkGC_COMMITTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (tblk->flag & tblkGC_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) log->gcrtc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) LOGGC_WAKEUP(tblk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) /* was page full before pageout ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) * (and this is the last tblk bound with the page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (tblk->flag & tblkGC_FREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) lbmFree(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) /* did page become full after pageout ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) * (and this is the last tblk bound with the page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) else if (tblk->flag & tblkGC_EOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /* finalize the page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) lp = (struct logpage *) bp->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) bp->l_ceor = bp->l_eor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) jfs_info("lmPostGC: calling lbmWrite");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) lbmWrite(log, bp, lbmWRITE | lbmRELEASE | lbmFREE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) /* are there any transactions who have entered lnGroupCommit()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) * (whose COMMITs are after that of the last log page written.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) * They are waiting for new group commit (above at (SLEEP 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * or lazy transactions are on a full (queued) log page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * select the latest ready transaction as new group leader and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * wake her up to lead her group.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if ((!list_empty(&log->cqueue)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) ((log->gcrtc > 0) || (tblk->bp->l_wqnext != NULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) test_bit(log_FLUSH, &log->flag) || jfs_tlocks_low))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * Call lmGCwrite with new group leader
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) lmGCwrite(log, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) /* no transaction are ready yet (transactions are only just
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) * queued (GC_QUEUE) and not entered for group commit yet).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) * the first transaction entering group commit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) * will elect herself as new group leader.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) log->cflag &= ~logGC_PAGEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) //LOGGC_UNLOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) spin_unlock_irqrestore(&log->gclock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) * NAME: lmLogSync()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) * FUNCTION: write log SYNCPT record for specified log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) * if new sync address is available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) * (normally the case if sync() is executed by back-ground
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * process).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * calculate new value of i_nextsync which determines when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) * this code is called again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * PARAMETERS: log - log structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) * hard_sync - 1 to force all metadata to be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * RETURN: 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) * serialization: LOG_LOCK() held on entry/exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) static int lmLogSync(struct jfs_log * log, int hard_sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) int logsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) int written; /* written since last syncpt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) int free; /* free space left available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) int delta; /* additional delta to write normally */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) int more; /* additional write granted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) struct lrd lrd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) int lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) struct logsyncblk *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) /* push dirty metapages out to disk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (hard_sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) write_special_inodes(log, filemap_fdatawrite);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) write_special_inodes(log, filemap_flush);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) * forward syncpt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) /* if last sync is same as last syncpt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) * invoke sync point forward processing to update sync.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (log->sync == log->syncpt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) LOGSYNC_LOCK(log, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (list_empty(&log->synclist))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) log->sync = log->lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) lp = list_entry(log->synclist.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) struct logsyncblk, synclist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) log->sync = lp->lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) LOGSYNC_UNLOCK(log, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) /* if sync is different from last syncpt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) * write a SYNCPT record with syncpt = sync.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) * reset syncpt = sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (log->sync != log->syncpt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) lrd.logtid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) lrd.backchain = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) lrd.type = cpu_to_le16(LOG_SYNCPT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) lrd.length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) lrd.log.syncpt.sync = cpu_to_le32(log->sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) lsn = lmWriteRecord(log, NULL, &lrd, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) log->syncpt = log->sync;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) lsn = log->lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) * setup next syncpt trigger (SWAG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) logsize = log->logsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) logdiff(written, lsn, log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) free = logsize - written;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) delta = LOGSYNC_DELTA(logsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) more = min(free / 2, delta);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (more < 2 * LOGPSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) jfs_warn("\n ... Log Wrap ... Log Wrap ... Log Wrap ...\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * log wrapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) * option 1 - panic ? No.!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) * option 2 - shutdown file systems
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) * associated with log ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) * option 3 - extend log ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) * option 4 - second chance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) * mark log wrapped, and continue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) * when all active transactions are completed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) * mark log valid for recovery.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) * if crashed during invalid state, log state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) * implies invalid log, forcing fsck().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) /* mark log state log wrap in log superblock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) /* log->state = LOGWRAP; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /* reset sync point computation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) log->syncpt = log->sync = lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) log->nextsync = delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) /* next syncpt trigger = written + more */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) log->nextsync = written + more;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) /* if number of bytes written from last sync point is more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) * than 1/4 of the log size, stop new transactions from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) * starting until all current transactions are completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) * by setting syncbarrier flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (!test_bit(log_SYNCBARRIER, &log->flag) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) (written > LOGSYNC_BARRIER(logsize)) && log->active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) set_bit(log_SYNCBARRIER, &log->flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) jfs_info("log barrier on: lsn=0x%x syncpt=0x%x", lsn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) log->syncpt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) * We may have to initiate group commit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) jfs_flush_journal(log, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) * NAME: jfs_syncpt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) * FUNCTION: write log SYNCPT record for specified log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) * PARAMETERS: log - log structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) * hard_sync - set to 1 to force metadata to be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) void jfs_syncpt(struct jfs_log *log, int hard_sync)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) { LOG_LOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) if (!test_bit(log_QUIESCE, &log->flag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) lmLogSync(log, hard_sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) LOG_UNLOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) * NAME: lmLogOpen()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) * FUNCTION: open the log on first open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) * insert filesystem in the active list of the log.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) * PARAMETER: ipmnt - file system mount inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) * iplog - log inode (out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) * RETURN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) * serialization:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) int lmLogOpen(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) struct block_device *bdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) struct jfs_log *log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) struct jfs_sb_info *sbi = JFS_SBI(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (sbi->flag & JFS_NOINTEGRITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) return open_dummy_log(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (sbi->mntflag & JFS_INLINELOG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return open_inline_log(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) mutex_lock(&jfs_log_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) list_for_each_entry(log, &jfs_external_logs, journal_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) if (log->bdev->bd_dev == sbi->logdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) if (!uuid_equal(&log->uuid, &sbi->loguuid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) jfs_warn("wrong uuid on JFS journal");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) mutex_unlock(&jfs_log_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) * add file system to log active file system list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) if ((rc = lmLogFileSystem(log, sbi, 1))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) mutex_unlock(&jfs_log_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) goto journal_found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) if (!(log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) mutex_unlock(&jfs_log_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) INIT_LIST_HEAD(&log->sb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) init_waitqueue_head(&log->syncwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) * external log as separate logical volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) * file systems to log may have n-to-1 relationship;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) bdev = blkdev_get_by_dev(sbi->logdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) if (IS_ERR(bdev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) rc = PTR_ERR(bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) goto free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) log->bdev = bdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) uuid_copy(&log->uuid, &sbi->loguuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) * initialize log:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if ((rc = lmLogInit(log)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) goto close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) list_add(&log->journal_list, &jfs_external_logs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) * add file system to log active file system list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) if ((rc = lmLogFileSystem(log, sbi, 1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) goto shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) journal_found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) LOG_LOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) list_add(&sbi->log_list, &log->sb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) sbi->log = log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) LOG_UNLOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) mutex_unlock(&jfs_log_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) * unwind on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) shutdown: /* unwind lbmLogInit() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) list_del(&log->journal_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) lbmLogShutdown(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) close: /* close external log device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) free: /* free log descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) mutex_unlock(&jfs_log_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) kfree(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) jfs_warn("lmLogOpen: exit(%d)", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) static int open_inline_log(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) struct jfs_log *log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (!(log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) INIT_LIST_HEAD(&log->sb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) init_waitqueue_head(&log->syncwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) set_bit(log_INLINELOG, &log->flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) log->bdev = sb->s_bdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) log->base = addressPXD(&JFS_SBI(sb)->logpxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) log->size = lengthPXD(&JFS_SBI(sb)->logpxd) >>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) (L2LOGPSIZE - sb->s_blocksize_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) log->l2bsize = sb->s_blocksize_bits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) ASSERT(L2LOGPSIZE >= sb->s_blocksize_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) * initialize log.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) if ((rc = lmLogInit(log))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) kfree(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) jfs_warn("lmLogOpen: exit(%d)", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) list_add(&JFS_SBI(sb)->log_list, &log->sb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) JFS_SBI(sb)->log = log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) static int open_dummy_log(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) mutex_lock(&jfs_log_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (!dummy_log) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) dummy_log = kzalloc(sizeof(struct jfs_log), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) if (!dummy_log) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) mutex_unlock(&jfs_log_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) INIT_LIST_HEAD(&dummy_log->sb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) init_waitqueue_head(&dummy_log->syncwait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) dummy_log->no_integrity = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) /* Make up some stuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) dummy_log->base = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) dummy_log->size = 1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) rc = lmLogInit(dummy_log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) kfree(dummy_log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) dummy_log = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) mutex_unlock(&jfs_log_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) LOG_LOCK(dummy_log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) list_add(&JFS_SBI(sb)->log_list, &dummy_log->sb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) JFS_SBI(sb)->log = dummy_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) LOG_UNLOCK(dummy_log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) mutex_unlock(&jfs_log_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) * NAME: lmLogInit()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) * FUNCTION: log initialization at first log open.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) * logredo() (or logformat()) should have been run previously.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) * initialize the log from log superblock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) * set the log state in the superblock to LOGMOUNT and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) * write SYNCPT log record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) * PARAMETER: log - log structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) * RETURN: 0 - if ok
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) * -EINVAL - bad log magic number or superblock dirty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) * error returned from logwait()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) * serialization: single first open thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) int lmLogInit(struct jfs_log * log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) struct lrd lrd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) struct logsuper *logsuper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) struct lbuf *bpsuper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) struct lbuf *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) struct logpage *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) int lsn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) jfs_info("lmLogInit: log:0x%p", log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) /* initialize the group commit serialization lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) LOGGC_LOCK_INIT(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) /* allocate/initialize the log write serialization lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) LOG_LOCK_INIT(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) LOGSYNC_LOCK_INIT(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) INIT_LIST_HEAD(&log->synclist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) INIT_LIST_HEAD(&log->cqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) log->flush_tblk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) log->count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) * initialize log i/o
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if ((rc = lbmLogInit(log)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) if (!test_bit(log_INLINELOG, &log->flag))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) log->l2bsize = L2LOGPSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) /* check for disabled journaling to disk */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) if (log->no_integrity) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) * Journal pages will still be filled. When the time comes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) * to actually do the I/O, the write is not done, and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) * endio routine is called directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) bp = lbmAllocate(log , 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) log->bp = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) bp->l_pn = bp->l_eor = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) * validate log superblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) if ((rc = lbmRead(log, 1, &bpsuper)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) goto errout10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) logsuper = (struct logsuper *) bpsuper->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) if (logsuper->magic != cpu_to_le32(LOGMAGIC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) jfs_warn("*** Log Format Error ! ***");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) goto errout20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) /* logredo() should have been run successfully. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) if (logsuper->state != cpu_to_le32(LOGREDONE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) jfs_warn("*** Log Is Dirty ! ***");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) goto errout20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) /* initialize log from log superblock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) if (test_bit(log_INLINELOG,&log->flag)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) if (log->size != le32_to_cpu(logsuper->size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) goto errout20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) jfs_info("lmLogInit: inline log:0x%p base:0x%Lx size:0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) log, (unsigned long long)log->base, log->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (!uuid_equal(&logsuper->uuid, &log->uuid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) jfs_warn("wrong uuid on JFS log device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) goto errout20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) log->size = le32_to_cpu(logsuper->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) log->l2bsize = le32_to_cpu(logsuper->l2bsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) jfs_info("lmLogInit: external log:0x%p base:0x%Lx size:0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) log, (unsigned long long)log->base, log->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) log->page = le32_to_cpu(logsuper->end) / LOGPSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) log->eor = le32_to_cpu(logsuper->end) - (LOGPSIZE * log->page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) * initialize for log append write mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) /* establish current/end-of-log page/buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) if ((rc = lbmRead(log, log->page, &bp)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) goto errout20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) lp = (struct logpage *) bp->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) jfs_info("lmLogInit: lsn:0x%x page:%d eor:%d:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) le32_to_cpu(logsuper->end), log->page, log->eor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) le16_to_cpu(lp->h.eor));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) log->bp = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) bp->l_pn = log->page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) bp->l_eor = log->eor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) /* if current page is full, move on to next page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) if (log->eor >= LOGPSIZE - LOGPTLRSIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) lmNextPage(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) * initialize log syncpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) * write the first SYNCPT record with syncpoint = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) * (i.e., log redo up to HERE !);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) * remove current page from lbm write queue at end of pageout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) * (to write log superblock update), but do not release to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) * freelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) lrd.logtid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) lrd.backchain = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) lrd.type = cpu_to_le16(LOG_SYNCPT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) lrd.length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) lrd.log.syncpt.sync = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) lsn = lmWriteRecord(log, NULL, &lrd, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) bp = log->bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) bp->l_ceor = bp->l_eor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) lp = (struct logpage *) bp->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) lbmWrite(log, bp, lbmWRITE | lbmSYNC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) if ((rc = lbmIOWait(bp, 0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) goto errout30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) * update/write superblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) logsuper->state = cpu_to_le32(LOGMOUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) log->serial = le32_to_cpu(logsuper->serial) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) logsuper->serial = cpu_to_le32(log->serial);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) if ((rc = lbmIOWait(bpsuper, lbmFREE)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) goto errout30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) /* initialize logsync parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) log->logsize = (log->size - 2) << L2LOGPSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) log->lsn = lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) log->syncpt = lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) log->sync = log->syncpt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) log->nextsync = LOGSYNC_DELTA(log->logsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) jfs_info("lmLogInit: lsn:0x%x syncpt:0x%x sync:0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) log->lsn, log->syncpt, log->sync);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) * initialize for lazy/group commit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) log->clsn = lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) * unwind on error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) errout30: /* release log page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) log->wqueue = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) bp->l_wqnext = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) lbmFree(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) errout20: /* release log superblock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) lbmFree(bpsuper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) errout10: /* unwind lbmLogInit() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) lbmLogShutdown(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) jfs_warn("lmLogInit: exit(%d)", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) * NAME: lmLogClose()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) * FUNCTION: remove file system <ipmnt> from active list of log <iplog>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) * and close it on last close.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) * PARAMETER: sb - superblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) * RETURN: errors from subroutines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) * serialization:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) int lmLogClose(struct super_block *sb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) struct jfs_sb_info *sbi = JFS_SBI(sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) struct jfs_log *log = sbi->log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) struct block_device *bdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) jfs_info("lmLogClose: log:0x%p", log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) mutex_lock(&jfs_log_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) LOG_LOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) list_del(&sbi->log_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) LOG_UNLOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) sbi->log = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) * We need to make sure all of the "written" metapages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) * actually make it to disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) sync_blockdev(sb->s_bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) if (test_bit(log_INLINELOG, &log->flag)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) * in-line log in host file system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) rc = lmLogShutdown(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) kfree(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) if (!log->no_integrity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) lmLogFileSystem(log, sbi, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) if (!list_empty(&log->sb_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) * TODO: ensure that the dummy_log is in a state to allow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) * lbmLogShutdown to deallocate all the buffers and call
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) * kfree against dummy_log. For now, leave dummy_log & its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) * buffers in memory, and resuse if another no-integrity mount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) * is requested.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (log->no_integrity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) * external log as separate logical volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) list_del(&log->journal_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) bdev = log->bdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) rc = lmLogShutdown(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) kfree(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) mutex_unlock(&jfs_log_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) jfs_info("lmLogClose: exit(%d)", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) * NAME: jfs_flush_journal()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) * FUNCTION: initiate write of any outstanding transactions to the journal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) * and optionally wait until they are all written to disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) * wait == 0 flush until latest txn is committed, don't wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) * wait == 1 flush until latest txn is committed, wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) * wait > 1 flush until all txn's are complete, wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) void jfs_flush_journal(struct jfs_log *log, int wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) struct tblock *target = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) /* jfs_write_inode may call us during read-only mount */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) if (!log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) jfs_info("jfs_flush_journal: log:0x%p wait=%d", log, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) LOGGC_LOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) if (!list_empty(&log->cqueue)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) * This ensures that we will keep writing to the journal as long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) * as there are unwritten commit records
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) target = list_entry(log->cqueue.prev, struct tblock, cqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) if (test_bit(log_FLUSH, &log->flag)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) * We're already flushing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) * if flush_tblk is NULL, we are flushing everything,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) * so leave it that way. Otherwise, update it to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) * latest transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) if (log->flush_tblk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) log->flush_tblk = target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) /* Only flush until latest transaction is committed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) log->flush_tblk = target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) set_bit(log_FLUSH, &log->flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) * Initiate I/O on outstanding transactions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) if (!(log->cflag & logGC_PAGEOUT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) log->cflag |= logGC_PAGEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) lmGCwrite(log, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) if ((wait > 1) || test_bit(log_SYNCBARRIER, &log->flag)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) /* Flush until all activity complete */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) set_bit(log_FLUSH, &log->flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) log->flush_tblk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) if (wait && target && !(target->flag & tblkGC_COMMITTED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) DECLARE_WAITQUEUE(__wait, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) add_wait_queue(&target->gcwait, &__wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) set_current_state(TASK_UNINTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) LOGGC_UNLOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) LOGGC_LOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) remove_wait_queue(&target->gcwait, &__wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) LOGGC_UNLOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) if (wait < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) write_special_inodes(log, filemap_fdatawrite);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) * If there was recent activity, we may need to wait
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) * for the lazycommit thread to catch up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) if ((!list_empty(&log->cqueue)) || !list_empty(&log->synclist)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) for (i = 0; i < 200; i++) { /* Too much? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) msleep(250);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) write_special_inodes(log, filemap_fdatawrite);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) if (list_empty(&log->cqueue) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) list_empty(&log->synclist))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) assert(list_empty(&log->cqueue));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) #ifdef CONFIG_JFS_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if (!list_empty(&log->synclist)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) struct logsyncblk *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) printk(KERN_ERR "jfs_flush_journal: synclist not empty\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) list_for_each_entry(lp, &log->synclist, synclist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (lp->xflag & COMMIT_PAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) struct metapage *mp = (struct metapage *)lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) print_hex_dump(KERN_ERR, "metapage: ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) DUMP_PREFIX_ADDRESS, 16, 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) mp, sizeof(struct metapage), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) print_hex_dump(KERN_ERR, "page: ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) DUMP_PREFIX_ADDRESS, 16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) sizeof(long), mp->page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) sizeof(struct page), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) print_hex_dump(KERN_ERR, "tblock:",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) DUMP_PREFIX_ADDRESS, 16, 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) lp, sizeof(struct tblock), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) WARN_ON(!list_empty(&log->synclist));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) clear_bit(log_FLUSH, &log->flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) * NAME: lmLogShutdown()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) * FUNCTION: log shutdown at last LogClose().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) * write log syncpt record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) * update super block to set redone flag to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) * PARAMETER: log - log inode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) * RETURN: 0 - success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) * serialization: single last close thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) int lmLogShutdown(struct jfs_log * log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) struct lrd lrd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) int lsn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) struct logsuper *logsuper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) struct lbuf *bpsuper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) struct lbuf *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) struct logpage *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) jfs_info("lmLogShutdown: log:0x%p", log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) jfs_flush_journal(log, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) * write the last SYNCPT record with syncpoint = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) * (i.e., log redo up to HERE !)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) lrd.logtid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) lrd.backchain = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) lrd.type = cpu_to_le16(LOG_SYNCPT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) lrd.length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) lrd.log.syncpt.sync = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) lsn = lmWriteRecord(log, NULL, &lrd, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) bp = log->bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) lp = (struct logpage *) bp->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) lbmWrite(log, log->bp, lbmWRITE | lbmRELEASE | lbmSYNC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) lbmIOWait(log->bp, lbmFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) log->bp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) * synchronous update log superblock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) * mark log state as shutdown cleanly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) * (i.e., Log does not need to be replayed).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) if ((rc = lbmRead(log, 1, &bpsuper)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) logsuper = (struct logsuper *) bpsuper->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) logsuper->state = cpu_to_le32(LOGREDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) logsuper->end = cpu_to_le32(lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) rc = lbmIOWait(bpsuper, lbmFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) jfs_info("lmLogShutdown: lsn:0x%x page:%d eor:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) lsn, log->page, log->eor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) * shutdown per log i/o
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) lbmLogShutdown(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) jfs_warn("lmLogShutdown: exit(%d)", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) * NAME: lmLogFileSystem()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) * FUNCTION: insert (<activate> = true)/remove (<activate> = false)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) * file system into/from log active file system list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) * PARAMETE: log - pointer to logs inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) * fsdev - kdev_t of filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) * serial - pointer to returned log serial number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) * activate - insert/remove device from active list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) * RETURN: 0 - success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) * errors returned by vms_iowait().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) static int lmLogFileSystem(struct jfs_log * log, struct jfs_sb_info *sbi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) int activate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) struct logsuper *logsuper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) struct lbuf *bpsuper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) uuid_t *uuid = &sbi->uuid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) * insert/remove file system device to log active file system list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) if ((rc = lbmRead(log, 1, &bpsuper)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) logsuper = (struct logsuper *) bpsuper->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) if (activate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) for (i = 0; i < MAX_ACTIVE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) if (uuid_is_null(&logsuper->active[i].uuid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) uuid_copy(&logsuper->active[i].uuid, uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) sbi->aggregate = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) if (i == MAX_ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) jfs_warn("Too many file systems sharing journal!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) lbmFree(bpsuper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) return -EMFILE; /* Is there a better rc? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) for (i = 0; i < MAX_ACTIVE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) if (uuid_equal(&logsuper->active[i].uuid, uuid)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) uuid_copy(&logsuper->active[i].uuid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) &uuid_null);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) if (i == MAX_ACTIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) jfs_warn("Somebody stomped on the journal!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) lbmFree(bpsuper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) * synchronous write log superblock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) * write sidestream bypassing write queue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) * at file system mount, log super block is updated for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) * activation of the file system before any log record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) * (MOUNT record) of the file system, and at file system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) * unmount, all meta data for the file system has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) * flushed before log super block is updated for deactivation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) * of the file system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) rc = lbmIOWait(bpsuper, lbmFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) * log buffer manager (lbm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) * ------------------------
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) * special purpose buffer manager supporting log i/o requirements.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) * per log write queue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) * log pageout occurs in serial order by fifo write queue and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) * restricting to a single i/o in pregress at any one time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) * a circular singly-linked list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) * (log->wrqueue points to the tail, and buffers are linked via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) * bp->wrqueue field), and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) * maintains log page in pageout ot waiting for pageout in serial pageout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) * lbmLogInit()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) * initialize per log I/O setup at lmLogInit()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) static int lbmLogInit(struct jfs_log * log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) { /* log inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) struct lbuf *lbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) jfs_info("lbmLogInit: log:0x%p", log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) /* initialize current buffer cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) log->bp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) /* initialize log device write queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) log->wqueue = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) * Each log has its own buffer pages allocated to it. These are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) * not managed by the page cache. This ensures that a transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) * writing to the log does not block trying to allocate a page from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) * the page cache (for the log). This would be bad, since page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) * allocation waits on the kswapd thread that may be committing inodes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) * which would cause log activity. Was that clear? I'm trying to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) * avoid deadlock here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) init_waitqueue_head(&log->free_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) log->lbuf_free = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) for (i = 0; i < LOGPAGES;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) char *buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) uint offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) struct page *page = alloc_page(GFP_KERNEL | __GFP_ZERO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) if (!page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) buffer = page_address(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) for (offset = 0; offset < PAGE_SIZE; offset += LOGPSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) lbuf = kmalloc(sizeof(struct lbuf), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) if (lbuf == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) if (offset == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) __free_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) if (offset) /* we already have one reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) get_page(page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) lbuf->l_offset = offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) lbuf->l_ldata = buffer + offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) lbuf->l_page = page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) lbuf->l_log = log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) init_waitqueue_head(&lbuf->l_ioevent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) lbuf->l_freelist = log->lbuf_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) log->lbuf_free = lbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) i++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) return (0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) lbmLogShutdown(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) * lbmLogShutdown()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) * finalize per log I/O setup at lmLogShutdown()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) static void lbmLogShutdown(struct jfs_log * log)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) struct lbuf *lbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) jfs_info("lbmLogShutdown: log:0x%p", log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) lbuf = log->lbuf_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) while (lbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) struct lbuf *next = lbuf->l_freelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) __free_page(lbuf->l_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) kfree(lbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) lbuf = next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) * lbmAllocate()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) * allocate an empty log buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) static struct lbuf *lbmAllocate(struct jfs_log * log, int pn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) struct lbuf *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) * recycle from log buffer freelist if any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) LCACHE_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) LCACHE_SLEEP_COND(log->free_wait, (bp = log->lbuf_free), flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) log->lbuf_free = bp->l_freelist;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) LCACHE_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) bp->l_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) bp->l_wqnext = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) bp->l_freelist = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) bp->l_pn = pn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) bp->l_blkno = log->base + (pn << (L2LOGPSIZE - log->l2bsize));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) bp->l_ceor = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) return bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) * lbmFree()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) * release a log buffer to freelist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) static void lbmFree(struct lbuf * bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) LCACHE_LOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) lbmfree(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) LCACHE_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) static void lbmfree(struct lbuf * bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) struct jfs_log *log = bp->l_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) assert(bp->l_wqnext == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) * return the buffer to head of freelist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) bp->l_freelist = log->lbuf_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) log->lbuf_free = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) wake_up(&log->free_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) * NAME: lbmRedrive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) * FUNCTION: add a log buffer to the log redrive list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) * PARAMETER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) * bp - log buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) * NOTES:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) * Takes log_redrive_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) static inline void lbmRedrive(struct lbuf *bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) spin_lock_irqsave(&log_redrive_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) bp->l_redrive_next = log_redrive_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) log_redrive_list = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) spin_unlock_irqrestore(&log_redrive_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) wake_up_process(jfsIOthread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) * lbmRead()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) struct bio *bio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) struct lbuf *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) * allocate a log buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) *bpp = bp = lbmAllocate(log, pn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) jfs_info("lbmRead: bp:0x%p pn:0x%x", bp, pn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) bp->l_flag |= lbmREAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) bio = bio_alloc(GFP_NOFS, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) bio->bi_iter.bi_sector = bp->l_blkno << (log->l2bsize - 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) bio_set_dev(bio, log->bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) bio_add_page(bio, bp->l_page, LOGPSIZE, bp->l_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) BUG_ON(bio->bi_iter.bi_size != LOGPSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) bio->bi_end_io = lbmIODone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) bio->bi_private = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) bio->bi_opf = REQ_OP_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) /*check if journaling to disk has been disabled*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) if (log->no_integrity) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) bio->bi_iter.bi_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) lbmIODone(bio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) submit_bio(bio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) wait_event(bp->l_ioevent, (bp->l_flag != lbmREAD));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) * lbmWrite()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) * buffer at head of pageout queue stays after completion of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) * partial-page pageout and redriven by explicit initiation of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) * pageout by caller until full-page pageout is completed and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) * released.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) * device driver i/o done redrives pageout of new buffer at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) * head of pageout queue when current buffer at head of pageout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) * queue is released at the completion of its full-page pageout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) * LOGGC_LOCK() serializes lbmWrite() by lmNextPage() and lmGroupCommit().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) * LCACHE_LOCK() serializes xflag between lbmWrite() and lbmIODone()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) static void lbmWrite(struct jfs_log * log, struct lbuf * bp, int flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) int cant_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) struct lbuf *tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) jfs_info("lbmWrite: bp:0x%p flag:0x%x pn:0x%x", bp, flag, bp->l_pn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) /* map the logical block address to physical block address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) bp->l_blkno =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) log->base + (bp->l_pn << (L2LOGPSIZE - log->l2bsize));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) LCACHE_LOCK(flags); /* disable+lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) * initialize buffer for device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) bp->l_flag = flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) * insert bp at tail of write queue associated with log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) * (request is either for bp already/currently at head of queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) * or new bp to be inserted at tail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) tail = log->wqueue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) /* is buffer not already on write queue ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) if (bp->l_wqnext == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) /* insert at tail of wqueue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) if (tail == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) log->wqueue = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) bp->l_wqnext = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) log->wqueue = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) bp->l_wqnext = tail->l_wqnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) tail->l_wqnext = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) tail = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) /* is buffer at head of wqueue and for write ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) if ((bp != tail->l_wqnext) || !(flag & lbmWRITE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) LCACHE_UNLOCK(flags); /* unlock+enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) LCACHE_UNLOCK(flags); /* unlock+enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) if (cant_block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) lbmRedrive(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) else if (flag & lbmSYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) lbmStartIO(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) LOGGC_UNLOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) lbmStartIO(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) LOGGC_LOCK(log);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) * lbmDirectWrite()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) * initiate pageout bypassing write queue for sidestream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) * (e.g., log superblock) write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) static void lbmDirectWrite(struct jfs_log * log, struct lbuf * bp, int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) jfs_info("lbmDirectWrite: bp:0x%p flag:0x%x pn:0x%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) bp, flag, bp->l_pn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) * initialize buffer for device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) bp->l_flag = flag | lbmDIRECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) /* map the logical block address to physical block address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) bp->l_blkno =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) log->base + (bp->l_pn << (L2LOGPSIZE - log->l2bsize));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) * initiate pageout of the page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) lbmStartIO(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) * NAME: lbmStartIO()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) * FUNCTION: Interface to DD strategy routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) * RETURN: none
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) * serialization: LCACHE_LOCK() is NOT held during log i/o;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) static void lbmStartIO(struct lbuf * bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) struct bio *bio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) struct jfs_log *log = bp->l_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) jfs_info("lbmStartIO");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) bio = bio_alloc(GFP_NOFS, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) bio->bi_iter.bi_sector = bp->l_blkno << (log->l2bsize - 9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) bio_set_dev(bio, log->bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) bio_add_page(bio, bp->l_page, LOGPSIZE, bp->l_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) BUG_ON(bio->bi_iter.bi_size != LOGPSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) bio->bi_end_io = lbmIODone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) bio->bi_private = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) bio->bi_opf = REQ_OP_WRITE | REQ_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) /* check if journaling to disk has been disabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) if (log->no_integrity) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) bio->bi_iter.bi_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) lbmIODone(bio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) submit_bio(bio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) INCREMENT(lmStat.submitted);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) * lbmIOWait()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) static int lbmIOWait(struct lbuf * bp, int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) jfs_info("lbmIOWait1: bp:0x%p flag:0x%x:0x%x", bp, bp->l_flag, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) LCACHE_LOCK(flags); /* disable+lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) LCACHE_SLEEP_COND(bp->l_ioevent, (bp->l_flag & lbmDONE), flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) rc = (bp->l_flag & lbmERROR) ? -EIO : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) if (flag & lbmFREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) lbmfree(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) LCACHE_UNLOCK(flags); /* unlock+enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) jfs_info("lbmIOWait2: bp:0x%p flag:0x%x:0x%x", bp, bp->l_flag, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) * lbmIODone()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) * executed at INTIODONE level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) static void lbmIODone(struct bio *bio)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) struct lbuf *bp = bio->bi_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) struct lbuf *nextbp, *tail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) struct jfs_log *log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) * get back jfs buffer bound to the i/o buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) jfs_info("lbmIODone: bp:0x%p flag:0x%x", bp, bp->l_flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) LCACHE_LOCK(flags); /* disable+lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) bp->l_flag |= lbmDONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) if (bio->bi_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) bp->l_flag |= lbmERROR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) jfs_err("lbmIODone: I/O error in JFS log");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) bio_put(bio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) * pagein completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) if (bp->l_flag & lbmREAD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) bp->l_flag &= ~lbmREAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) LCACHE_UNLOCK(flags); /* unlock+enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) /* wakeup I/O initiator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) LCACHE_WAKEUP(&bp->l_ioevent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) * pageout completion
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) * the bp at the head of write queue has completed pageout.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) * if single-commit/full-page pageout, remove the current buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) * from head of pageout queue, and redrive pageout with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) * the new buffer at head of pageout queue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) * otherwise, the partial-page pageout buffer stays at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) * the head of pageout queue to be redriven for pageout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) * by lmGroupCommit() until full-page pageout is completed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) bp->l_flag &= ~lbmWRITE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) INCREMENT(lmStat.pagedone);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) /* update committed lsn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) log = bp->l_log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) log->clsn = (bp->l_pn << L2LOGPSIZE) + bp->l_ceor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) if (bp->l_flag & lbmDIRECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) LCACHE_WAKEUP(&bp->l_ioevent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) LCACHE_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) tail = log->wqueue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) /* single element queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) if (bp == tail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) /* remove head buffer of full-page pageout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) * from log device write queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) if (bp->l_flag & lbmRELEASE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) log->wqueue = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) bp->l_wqnext = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) /* multi element queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) /* remove head buffer of full-page pageout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) * from log device write queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) if (bp->l_flag & lbmRELEASE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) nextbp = tail->l_wqnext = bp->l_wqnext;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) bp->l_wqnext = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) * redrive pageout of next page at head of write queue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) * redrive next page without any bound tblk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) * (i.e., page w/o any COMMIT records), or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) * first page of new group commit which has been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) * queued after current page (subsequent pageout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) * is performed synchronously, except page without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) * any COMMITs) by lmGroupCommit() as indicated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) * by lbmWRITE flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) if (nextbp->l_flag & lbmWRITE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) * We can't do the I/O at interrupt time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) * The jfsIO thread can do it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) lbmRedrive(nextbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) * synchronous pageout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) * buffer has not necessarily been removed from write queue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) * (e.g., synchronous write of partial-page with COMMIT):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) * leave buffer for i/o initiator to dispose
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) if (bp->l_flag & lbmSYNC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) LCACHE_UNLOCK(flags); /* unlock+enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) /* wakeup I/O initiator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) LCACHE_WAKEUP(&bp->l_ioevent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) * Group Commit pageout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) else if (bp->l_flag & lbmGC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) LCACHE_UNLOCK(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) lmPostGC(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) * asynchronous pageout:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) * buffer must have been removed from write queue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) * insert buffer at head of freelist where it can be recycled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) assert(bp->l_flag & lbmRELEASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) assert(bp->l_flag & lbmFREE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) lbmfree(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) LCACHE_UNLOCK(flags); /* unlock+enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) int jfsIOWait(void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) struct lbuf *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) spin_lock_irq(&log_redrive_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) while ((bp = log_redrive_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) log_redrive_list = bp->l_redrive_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) bp->l_redrive_next = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) spin_unlock_irq(&log_redrive_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) lbmStartIO(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) spin_lock_irq(&log_redrive_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) if (freezing(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) spin_unlock_irq(&log_redrive_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) try_to_freeze();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) spin_unlock_irq(&log_redrive_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) } while (!kthread_should_stop());
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) jfs_info("jfsIOWait being killed!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) * NAME: lmLogFormat()/jfs_logform()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) * FUNCTION: format file system log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) * PARAMETERS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) * log - volume log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) * logAddress - start address of log space in FS block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) * logSize - length of log space in FS block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) * RETURN: 0 - success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) * -EIO - i/o error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) * XXX: We're synchronously writing one page at a time. This needs to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) * be improved by writing multiple pages at once.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) int rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) struct jfs_sb_info *sbi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) struct logsuper *logsuper;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) struct logpage *lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) int lspn; /* log sequence page number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) struct lrd *lrd_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) int npages = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) struct lbuf *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) jfs_info("lmLogFormat: logAddress:%Ld logSize:%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) (long long)logAddress, logSize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) sbi = list_entry(log->sb_list.next, struct jfs_sb_info, log_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) /* allocate a log buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) bp = lbmAllocate(log, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) npages = logSize >> sbi->l2nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) * log space:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) * page 0 - reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) * page 1 - log superblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) * page 2 - log data page: A SYNC log record is written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) * into this page at logform time;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) * pages 3-N - log data page: set to empty log data pages;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) * init log superblock: log page 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) logsuper = (struct logsuper *) bp->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) logsuper->magic = cpu_to_le32(LOGMAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) logsuper->version = cpu_to_le32(LOGVERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) logsuper->state = cpu_to_le32(LOGREDONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) logsuper->flag = cpu_to_le32(sbi->mntflag); /* ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) logsuper->size = cpu_to_le32(npages);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) logsuper->bsize = cpu_to_le32(sbi->bsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) logsuper->l2bsize = cpu_to_le32(sbi->l2bsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) logsuper->end = cpu_to_le32(2 * LOGPSIZE + LOGPHDRSIZE + LOGRDSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) bp->l_flag = lbmWRITE | lbmSYNC | lbmDIRECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) bp->l_blkno = logAddress + sbi->nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) lbmStartIO(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) if ((rc = lbmIOWait(bp, 0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) * init pages 2 to npages-1 as log data pages:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) * log page sequence number (lpsn) initialization:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) * pn: 0 1 2 3 n-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) * +-----+-----+=====+=====+===.....===+=====+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) * lspn: N-1 0 1 N-2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) * <--- N page circular file ---->
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) * the N (= npages-2) data pages of the log is maintained as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) * a circular file for the log records;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) * lpsn grows by 1 monotonically as each log page is written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) * to the circular file of the log;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) * and setLogpage() will not reset the page number even if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) * the eor is equal to LOGPHDRSIZE. In order for binary search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) * still work in find log end process, we have to simulate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) * log wrap situation at the log format time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) * The 1st log page written will have the highest lpsn. Then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) * the succeeding log pages will have ascending order of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) * the lspn starting from 0, ... (N-2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) lp = (struct logpage *) bp->l_ldata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) * initialize 1st log page to be written: lpsn = N - 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) * write a SYNCPT log record is written to this page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) lp->h.page = lp->t.page = cpu_to_le32(npages - 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) lp->h.eor = lp->t.eor = cpu_to_le16(LOGPHDRSIZE + LOGRDSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) lrd_ptr = (struct lrd *) &lp->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) lrd_ptr->logtid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) lrd_ptr->backchain = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) lrd_ptr->type = cpu_to_le16(LOG_SYNCPT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) lrd_ptr->length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) lrd_ptr->log.syncpt.sync = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) bp->l_blkno += sbi->nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) bp->l_flag = lbmWRITE | lbmSYNC | lbmDIRECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) lbmStartIO(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) if ((rc = lbmIOWait(bp, 0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) * initialize succeeding log pages: lpsn = 0, 1, ..., (N-2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) for (lspn = 0; lspn < npages - 3; lspn++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) lp->h.page = lp->t.page = cpu_to_le32(lspn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) lp->h.eor = lp->t.eor = cpu_to_le16(LOGPHDRSIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) bp->l_blkno += sbi->nbperpage;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) bp->l_flag = lbmWRITE | lbmSYNC | lbmDIRECT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) lbmStartIO(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) if ((rc = lbmIOWait(bp, 0)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) * finalize log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) /* release the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) lbmFree(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) #ifdef CONFIG_JFS_STATISTICS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) int jfs_lmstats_proc_show(struct seq_file *m, void *v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) seq_printf(m,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) "JFS Logmgr stats\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) "================\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) "commits = %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) "writes submitted = %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) "writes completed = %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) "full pages submitted = %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) "partial pages submitted = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) lmStat.commit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) lmStat.submitted,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) lmStat.pagedone,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) lmStat.full_page,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) lmStat.partial_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) #endif /* CONFIG_JFS_STATISTICS */