1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) International Business Machines Corp., 2000-2004 4*4882a593Smuzhiyun * Portions Copyright (C) Christoph Hellwig, 2001-2002 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun #ifndef _H_JFS_LOGMGR 7*4882a593Smuzhiyun #define _H_JFS_LOGMGR 8*4882a593Smuzhiyun 9*4882a593Smuzhiyun #include <linux/uuid.h> 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun #include "jfs_filsys.h" 12*4882a593Smuzhiyun #include "jfs_lock.h" 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun /* 15*4882a593Smuzhiyun * log manager configuration parameters 16*4882a593Smuzhiyun */ 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun /* log page size */ 19*4882a593Smuzhiyun #define LOGPSIZE 4096 20*4882a593Smuzhiyun #define L2LOGPSIZE 12 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun #define LOGPAGES 16 /* Log pages per mounted file system */ 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun /* 25*4882a593Smuzhiyun * log logical volume 26*4882a593Smuzhiyun * 27*4882a593Smuzhiyun * a log is used to make the commit operation on journalled 28*4882a593Smuzhiyun * files within the same logical volume group atomic. 29*4882a593Smuzhiyun * a log is implemented with a logical volume. 30*4882a593Smuzhiyun * there is one log per logical volume group. 31*4882a593Smuzhiyun * 32*4882a593Smuzhiyun * block 0 of the log logical volume is not used (ipl etc). 33*4882a593Smuzhiyun * block 1 contains a log "superblock" and is used by logFormat(), 34*4882a593Smuzhiyun * lmLogInit(), lmLogShutdown(), and logRedo() to record status 35*4882a593Smuzhiyun * of the log but is not otherwise used during normal processing. 36*4882a593Smuzhiyun * blocks 2 - (N-1) are used to contain log records. 37*4882a593Smuzhiyun * 38*4882a593Smuzhiyun * when a volume group is varied-on-line, logRedo() must have 39*4882a593Smuzhiyun * been executed before the file systems (logical volumes) in 40*4882a593Smuzhiyun * the volume group can be mounted. 41*4882a593Smuzhiyun */ 42*4882a593Smuzhiyun /* 43*4882a593Smuzhiyun * log superblock (block 1 of logical volume) 44*4882a593Smuzhiyun */ 45*4882a593Smuzhiyun #define LOGSUPER_B 1 46*4882a593Smuzhiyun #define LOGSTART_B 2 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun #define LOGMAGIC 0x87654321 49*4882a593Smuzhiyun #define LOGVERSION 1 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun #define MAX_ACTIVE 128 /* Max active file systems sharing log */ 52*4882a593Smuzhiyun 53*4882a593Smuzhiyun struct logsuper { 54*4882a593Smuzhiyun __le32 magic; /* 4: log lv identifier */ 55*4882a593Smuzhiyun __le32 version; /* 4: version number */ 56*4882a593Smuzhiyun __le32 serial; /* 4: log open/mount counter */ 57*4882a593Smuzhiyun __le32 size; /* 4: size in number of LOGPSIZE blocks */ 58*4882a593Smuzhiyun __le32 bsize; /* 4: logical block size in byte */ 59*4882a593Smuzhiyun __le32 l2bsize; /* 4: log2 of bsize */ 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun __le32 flag; /* 4: option */ 62*4882a593Smuzhiyun __le32 state; /* 4: state - see below */ 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun __le32 end; /* 4: addr of last log record set by logredo */ 65*4882a593Smuzhiyun uuid_t uuid; /* 16: 128-bit journal uuid */ 66*4882a593Smuzhiyun char label[16]; /* 16: journal label */ 67*4882a593Smuzhiyun struct { 68*4882a593Smuzhiyun uuid_t uuid; 69*4882a593Smuzhiyun } active[MAX_ACTIVE]; /* 2048: active file systems list */ 70*4882a593Smuzhiyun }; 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun /* log flag: commit option (see jfs_filsys.h) */ 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun /* log state */ 75*4882a593Smuzhiyun #define LOGMOUNT 0 /* log mounted by lmLogInit() */ 76*4882a593Smuzhiyun #define LOGREDONE 1 /* log shutdown by lmLogShutdown(). 77*4882a593Smuzhiyun * log redo completed by logredo(). 78*4882a593Smuzhiyun */ 79*4882a593Smuzhiyun #define LOGWRAP 2 /* log wrapped */ 80*4882a593Smuzhiyun #define LOGREADERR 3 /* log read error detected in logredo() */ 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun 83*4882a593Smuzhiyun /* 84*4882a593Smuzhiyun * log logical page 85*4882a593Smuzhiyun * 86*4882a593Smuzhiyun * (this comment should be rewritten !) 87*4882a593Smuzhiyun * the header and trailer structures (h,t) will normally have 88*4882a593Smuzhiyun * the same page and eor value. 89*4882a593Smuzhiyun * An exception to this occurs when a complete page write is not 90*4882a593Smuzhiyun * accomplished on a power failure. Since the hardware may "split write" 91*4882a593Smuzhiyun * sectors in the page, any out of order sequence may occur during powerfail 92*4882a593Smuzhiyun * and needs to be recognized during log replay. The xor value is 93*4882a593Smuzhiyun * an "exclusive or" of all log words in the page up to eor. This 94*4882a593Smuzhiyun * 32 bit eor is stored with the top 16 bits in the header and the 95*4882a593Smuzhiyun * bottom 16 bits in the trailer. logredo can easily recognize pages 96*4882a593Smuzhiyun * that were not completed by reconstructing this eor and checking 97*4882a593Smuzhiyun * the log page. 98*4882a593Smuzhiyun * 99*4882a593Smuzhiyun * Previous versions of the operating system did not allow split 100*4882a593Smuzhiyun * writes and detected partially written records in logredo by 101*4882a593Smuzhiyun * ordering the updates to the header, trailer, and the move of data 102*4882a593Smuzhiyun * into the logdata area. The order: (1) data is moved (2) header 103*4882a593Smuzhiyun * is updated (3) trailer is updated. In logredo, when the header 104*4882a593Smuzhiyun * differed from the trailer, the header and trailer were reconciled 105*4882a593Smuzhiyun * as follows: if h.page != t.page they were set to the smaller of 106*4882a593Smuzhiyun * the two and h.eor and t.eor set to 8 (i.e. empty page). if (only) 107*4882a593Smuzhiyun * h.eor != t.eor they were set to the smaller of their two values. 108*4882a593Smuzhiyun */ 109*4882a593Smuzhiyun struct logpage { 110*4882a593Smuzhiyun struct { /* header */ 111*4882a593Smuzhiyun __le32 page; /* 4: log sequence page number */ 112*4882a593Smuzhiyun __le16 rsrvd; /* 2: */ 113*4882a593Smuzhiyun __le16 eor; /* 2: end-of-log offset of lasrt record write */ 114*4882a593Smuzhiyun } h; 115*4882a593Smuzhiyun 116*4882a593Smuzhiyun __le32 data[LOGPSIZE / 4 - 4]; /* log record area */ 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun struct { /* trailer */ 119*4882a593Smuzhiyun __le32 page; /* 4: normally the same as h.page */ 120*4882a593Smuzhiyun __le16 rsrvd; /* 2: */ 121*4882a593Smuzhiyun __le16 eor; /* 2: normally the same as h.eor */ 122*4882a593Smuzhiyun } t; 123*4882a593Smuzhiyun }; 124*4882a593Smuzhiyun 125*4882a593Smuzhiyun #define LOGPHDRSIZE 8 /* log page header size */ 126*4882a593Smuzhiyun #define LOGPTLRSIZE 8 /* log page trailer size */ 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun /* 130*4882a593Smuzhiyun * log record 131*4882a593Smuzhiyun * 132*4882a593Smuzhiyun * (this comment should be rewritten !) 133*4882a593Smuzhiyun * jfs uses only "after" log records (only a single writer is allowed 134*4882a593Smuzhiyun * in a page, pages are written to temporary paging space if 135*4882a593Smuzhiyun * if they must be written to disk before commit, and i/o is 136*4882a593Smuzhiyun * scheduled for modified pages to their home location after 137*4882a593Smuzhiyun * the log records containing the after values and the commit 138*4882a593Smuzhiyun * record is written to the log on disk, undo discards the copy 139*4882a593Smuzhiyun * in main-memory.) 140*4882a593Smuzhiyun * 141*4882a593Smuzhiyun * a log record consists of a data area of variable length followed by 142*4882a593Smuzhiyun * a descriptor of fixed size LOGRDSIZE bytes. 143*4882a593Smuzhiyun * the data area is rounded up to an integral number of 4-bytes and 144*4882a593Smuzhiyun * must be no longer than LOGPSIZE. 145*4882a593Smuzhiyun * the descriptor is of size of multiple of 4-bytes and aligned on a 146*4882a593Smuzhiyun * 4-byte boundary. 147*4882a593Smuzhiyun * records are packed one after the other in the data area of log pages. 148*4882a593Smuzhiyun * (sometimes a DUMMY record is inserted so that at least one record ends 149*4882a593Smuzhiyun * on every page or the longest record is placed on at most two pages). 150*4882a593Smuzhiyun * the field eor in page header/trailer points to the byte following 151*4882a593Smuzhiyun * the last record on a page. 152*4882a593Smuzhiyun */ 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun /* log record types */ 155*4882a593Smuzhiyun #define LOG_COMMIT 0x8000 156*4882a593Smuzhiyun #define LOG_SYNCPT 0x4000 157*4882a593Smuzhiyun #define LOG_MOUNT 0x2000 158*4882a593Smuzhiyun #define LOG_REDOPAGE 0x0800 159*4882a593Smuzhiyun #define LOG_NOREDOPAGE 0x0080 160*4882a593Smuzhiyun #define LOG_NOREDOINOEXT 0x0040 161*4882a593Smuzhiyun #define LOG_UPDATEMAP 0x0008 162*4882a593Smuzhiyun #define LOG_NOREDOFILE 0x0001 163*4882a593Smuzhiyun 164*4882a593Smuzhiyun /* REDOPAGE/NOREDOPAGE log record data type */ 165*4882a593Smuzhiyun #define LOG_INODE 0x0001 166*4882a593Smuzhiyun #define LOG_XTREE 0x0002 167*4882a593Smuzhiyun #define LOG_DTREE 0x0004 168*4882a593Smuzhiyun #define LOG_BTROOT 0x0010 169*4882a593Smuzhiyun #define LOG_EA 0x0020 170*4882a593Smuzhiyun #define LOG_ACL 0x0040 171*4882a593Smuzhiyun #define LOG_DATA 0x0080 172*4882a593Smuzhiyun #define LOG_NEW 0x0100 173*4882a593Smuzhiyun #define LOG_EXTEND 0x0200 174*4882a593Smuzhiyun #define LOG_RELOCATE 0x0400 175*4882a593Smuzhiyun #define LOG_DIR_XTREE 0x0800 /* Xtree is in directory inode */ 176*4882a593Smuzhiyun 177*4882a593Smuzhiyun /* UPDATEMAP log record descriptor type */ 178*4882a593Smuzhiyun #define LOG_ALLOCXADLIST 0x0080 179*4882a593Smuzhiyun #define LOG_ALLOCPXDLIST 0x0040 180*4882a593Smuzhiyun #define LOG_ALLOCXAD 0x0020 181*4882a593Smuzhiyun #define LOG_ALLOCPXD 0x0010 182*4882a593Smuzhiyun #define LOG_FREEXADLIST 0x0008 183*4882a593Smuzhiyun #define LOG_FREEPXDLIST 0x0004 184*4882a593Smuzhiyun #define LOG_FREEXAD 0x0002 185*4882a593Smuzhiyun #define LOG_FREEPXD 0x0001 186*4882a593Smuzhiyun 187*4882a593Smuzhiyun 188*4882a593Smuzhiyun struct lrd { 189*4882a593Smuzhiyun /* 190*4882a593Smuzhiyun * type independent area 191*4882a593Smuzhiyun */ 192*4882a593Smuzhiyun __le32 logtid; /* 4: log transaction identifier */ 193*4882a593Smuzhiyun __le32 backchain; /* 4: ptr to prev record of same transaction */ 194*4882a593Smuzhiyun __le16 type; /* 2: record type */ 195*4882a593Smuzhiyun __le16 length; /* 2: length of data in record (in byte) */ 196*4882a593Smuzhiyun __le32 aggregate; /* 4: file system lv/aggregate */ 197*4882a593Smuzhiyun /* (16) */ 198*4882a593Smuzhiyun 199*4882a593Smuzhiyun /* 200*4882a593Smuzhiyun * type dependent area (20) 201*4882a593Smuzhiyun */ 202*4882a593Smuzhiyun union { 203*4882a593Smuzhiyun 204*4882a593Smuzhiyun /* 205*4882a593Smuzhiyun * COMMIT: commit 206*4882a593Smuzhiyun * 207*4882a593Smuzhiyun * transaction commit: no type-dependent information; 208*4882a593Smuzhiyun */ 209*4882a593Smuzhiyun 210*4882a593Smuzhiyun /* 211*4882a593Smuzhiyun * REDOPAGE: after-image 212*4882a593Smuzhiyun * 213*4882a593Smuzhiyun * apply after-image; 214*4882a593Smuzhiyun * 215*4882a593Smuzhiyun * N.B. REDOPAGE, NOREDOPAGE, and UPDATEMAP must be same format; 216*4882a593Smuzhiyun */ 217*4882a593Smuzhiyun struct { 218*4882a593Smuzhiyun __le32 fileset; /* 4: fileset number */ 219*4882a593Smuzhiyun __le32 inode; /* 4: inode number */ 220*4882a593Smuzhiyun __le16 type; /* 2: REDOPAGE record type */ 221*4882a593Smuzhiyun __le16 l2linesize; /* 2: log2 of line size */ 222*4882a593Smuzhiyun pxd_t pxd; /* 8: on-disk page pxd */ 223*4882a593Smuzhiyun } redopage; /* (20) */ 224*4882a593Smuzhiyun 225*4882a593Smuzhiyun /* 226*4882a593Smuzhiyun * NOREDOPAGE: the page is freed 227*4882a593Smuzhiyun * 228*4882a593Smuzhiyun * do not apply after-image records which precede this record 229*4882a593Smuzhiyun * in the log with the same page block number to this page. 230*4882a593Smuzhiyun * 231*4882a593Smuzhiyun * N.B. REDOPAGE, NOREDOPAGE, and UPDATEMAP must be same format; 232*4882a593Smuzhiyun */ 233*4882a593Smuzhiyun struct { 234*4882a593Smuzhiyun __le32 fileset; /* 4: fileset number */ 235*4882a593Smuzhiyun __le32 inode; /* 4: inode number */ 236*4882a593Smuzhiyun __le16 type; /* 2: NOREDOPAGE record type */ 237*4882a593Smuzhiyun __le16 rsrvd; /* 2: reserved */ 238*4882a593Smuzhiyun pxd_t pxd; /* 8: on-disk page pxd */ 239*4882a593Smuzhiyun } noredopage; /* (20) */ 240*4882a593Smuzhiyun 241*4882a593Smuzhiyun /* 242*4882a593Smuzhiyun * UPDATEMAP: update block allocation map 243*4882a593Smuzhiyun * 244*4882a593Smuzhiyun * either in-line PXD, 245*4882a593Smuzhiyun * or out-of-line XADLIST; 246*4882a593Smuzhiyun * 247*4882a593Smuzhiyun * N.B. REDOPAGE, NOREDOPAGE, and UPDATEMAP must be same format; 248*4882a593Smuzhiyun */ 249*4882a593Smuzhiyun struct { 250*4882a593Smuzhiyun __le32 fileset; /* 4: fileset number */ 251*4882a593Smuzhiyun __le32 inode; /* 4: inode number */ 252*4882a593Smuzhiyun __le16 type; /* 2: UPDATEMAP record type */ 253*4882a593Smuzhiyun __le16 nxd; /* 2: number of extents */ 254*4882a593Smuzhiyun pxd_t pxd; /* 8: pxd */ 255*4882a593Smuzhiyun } updatemap; /* (20) */ 256*4882a593Smuzhiyun 257*4882a593Smuzhiyun /* 258*4882a593Smuzhiyun * NOREDOINOEXT: the inode extent is freed 259*4882a593Smuzhiyun * 260*4882a593Smuzhiyun * do not apply after-image records which precede this 261*4882a593Smuzhiyun * record in the log with the any of the 4 page block 262*4882a593Smuzhiyun * numbers in this inode extent. 263*4882a593Smuzhiyun * 264*4882a593Smuzhiyun * NOTE: The fileset and pxd fields MUST remain in 265*4882a593Smuzhiyun * the same fields in the REDOPAGE record format. 266*4882a593Smuzhiyun * 267*4882a593Smuzhiyun */ 268*4882a593Smuzhiyun struct { 269*4882a593Smuzhiyun __le32 fileset; /* 4: fileset number */ 270*4882a593Smuzhiyun __le32 iagnum; /* 4: IAG number */ 271*4882a593Smuzhiyun __le32 inoext_idx; /* 4: inode extent index */ 272*4882a593Smuzhiyun pxd_t pxd; /* 8: on-disk page pxd */ 273*4882a593Smuzhiyun } noredoinoext; /* (20) */ 274*4882a593Smuzhiyun 275*4882a593Smuzhiyun /* 276*4882a593Smuzhiyun * SYNCPT: log sync point 277*4882a593Smuzhiyun * 278*4882a593Smuzhiyun * replay log up to syncpt address specified; 279*4882a593Smuzhiyun */ 280*4882a593Smuzhiyun struct { 281*4882a593Smuzhiyun __le32 sync; /* 4: syncpt address (0 = here) */ 282*4882a593Smuzhiyun } syncpt; 283*4882a593Smuzhiyun 284*4882a593Smuzhiyun /* 285*4882a593Smuzhiyun * MOUNT: file system mount 286*4882a593Smuzhiyun * 287*4882a593Smuzhiyun * file system mount: no type-dependent information; 288*4882a593Smuzhiyun */ 289*4882a593Smuzhiyun 290*4882a593Smuzhiyun /* 291*4882a593Smuzhiyun * ? FREEXTENT: free specified extent(s) 292*4882a593Smuzhiyun * 293*4882a593Smuzhiyun * free specified extent(s) from block allocation map 294*4882a593Smuzhiyun * N.B.: nextents should be length of data/sizeof(xad_t) 295*4882a593Smuzhiyun */ 296*4882a593Smuzhiyun struct { 297*4882a593Smuzhiyun __le32 type; /* 4: FREEXTENT record type */ 298*4882a593Smuzhiyun __le32 nextent; /* 4: number of extents */ 299*4882a593Smuzhiyun 300*4882a593Smuzhiyun /* data: PXD or XAD list */ 301*4882a593Smuzhiyun } freextent; 302*4882a593Smuzhiyun 303*4882a593Smuzhiyun /* 304*4882a593Smuzhiyun * ? NOREDOFILE: this file is freed 305*4882a593Smuzhiyun * 306*4882a593Smuzhiyun * do not apply records which precede this record in the log 307*4882a593Smuzhiyun * with the same inode number. 308*4882a593Smuzhiyun * 309*4882a593Smuzhiyun * NOREDOFILE must be the first to be written at commit 310*4882a593Smuzhiyun * (last to be read in logredo()) - it prevents 311*4882a593Smuzhiyun * replay of preceding updates of all preceding generations 312*4882a593Smuzhiyun * of the inumber esp. the on-disk inode itself. 313*4882a593Smuzhiyun */ 314*4882a593Smuzhiyun struct { 315*4882a593Smuzhiyun __le32 fileset; /* 4: fileset number */ 316*4882a593Smuzhiyun __le32 inode; /* 4: inode number */ 317*4882a593Smuzhiyun } noredofile; 318*4882a593Smuzhiyun 319*4882a593Smuzhiyun /* 320*4882a593Smuzhiyun * ? NEWPAGE: 321*4882a593Smuzhiyun * 322*4882a593Smuzhiyun * metadata type dependent 323*4882a593Smuzhiyun */ 324*4882a593Smuzhiyun struct { 325*4882a593Smuzhiyun __le32 fileset; /* 4: fileset number */ 326*4882a593Smuzhiyun __le32 inode; /* 4: inode number */ 327*4882a593Smuzhiyun __le32 type; /* 4: NEWPAGE record type */ 328*4882a593Smuzhiyun pxd_t pxd; /* 8: on-disk page pxd */ 329*4882a593Smuzhiyun } newpage; 330*4882a593Smuzhiyun 331*4882a593Smuzhiyun /* 332*4882a593Smuzhiyun * ? DUMMY: filler 333*4882a593Smuzhiyun * 334*4882a593Smuzhiyun * no type-dependent information 335*4882a593Smuzhiyun */ 336*4882a593Smuzhiyun } log; 337*4882a593Smuzhiyun }; /* (36) */ 338*4882a593Smuzhiyun 339*4882a593Smuzhiyun #define LOGRDSIZE (sizeof(struct lrd)) 340*4882a593Smuzhiyun 341*4882a593Smuzhiyun /* 342*4882a593Smuzhiyun * line vector descriptor 343*4882a593Smuzhiyun */ 344*4882a593Smuzhiyun struct lvd { 345*4882a593Smuzhiyun __le16 offset; 346*4882a593Smuzhiyun __le16 length; 347*4882a593Smuzhiyun }; 348*4882a593Smuzhiyun 349*4882a593Smuzhiyun 350*4882a593Smuzhiyun /* 351*4882a593Smuzhiyun * log logical volume 352*4882a593Smuzhiyun */ 353*4882a593Smuzhiyun struct jfs_log { 354*4882a593Smuzhiyun 355*4882a593Smuzhiyun struct list_head sb_list;/* This is used to sync metadata 356*4882a593Smuzhiyun * before writing syncpt. 357*4882a593Smuzhiyun */ 358*4882a593Smuzhiyun struct list_head journal_list; /* Global list */ 359*4882a593Smuzhiyun struct block_device *bdev; /* 4: log lv pointer */ 360*4882a593Smuzhiyun int serial; /* 4: log mount serial number */ 361*4882a593Smuzhiyun 362*4882a593Smuzhiyun s64 base; /* @8: log extent address (inline log ) */ 363*4882a593Smuzhiyun int size; /* 4: log size in log page (in page) */ 364*4882a593Smuzhiyun int l2bsize; /* 4: log2 of bsize */ 365*4882a593Smuzhiyun 366*4882a593Smuzhiyun unsigned long flag; /* 4: flag */ 367*4882a593Smuzhiyun 368*4882a593Smuzhiyun struct lbuf *lbuf_free; /* 4: free lbufs */ 369*4882a593Smuzhiyun wait_queue_head_t free_wait; /* 4: */ 370*4882a593Smuzhiyun 371*4882a593Smuzhiyun /* log write */ 372*4882a593Smuzhiyun int logtid; /* 4: log tid */ 373*4882a593Smuzhiyun int page; /* 4: page number of eol page */ 374*4882a593Smuzhiyun int eor; /* 4: eor of last record in eol page */ 375*4882a593Smuzhiyun struct lbuf *bp; /* 4: current log page buffer */ 376*4882a593Smuzhiyun 377*4882a593Smuzhiyun struct mutex loglock; /* 4: log write serialization lock */ 378*4882a593Smuzhiyun 379*4882a593Smuzhiyun /* syncpt */ 380*4882a593Smuzhiyun int nextsync; /* 4: bytes to write before next syncpt */ 381*4882a593Smuzhiyun int active; /* 4: */ 382*4882a593Smuzhiyun wait_queue_head_t syncwait; /* 4: */ 383*4882a593Smuzhiyun 384*4882a593Smuzhiyun /* commit */ 385*4882a593Smuzhiyun uint cflag; /* 4: */ 386*4882a593Smuzhiyun struct list_head cqueue; /* FIFO commit queue */ 387*4882a593Smuzhiyun struct tblock *flush_tblk; /* tblk we're waiting on for flush */ 388*4882a593Smuzhiyun int gcrtc; /* 4: GC_READY transaction count */ 389*4882a593Smuzhiyun struct tblock *gclrt; /* 4: latest GC_READY transaction */ 390*4882a593Smuzhiyun spinlock_t gclock; /* 4: group commit lock */ 391*4882a593Smuzhiyun int logsize; /* 4: log data area size in byte */ 392*4882a593Smuzhiyun int lsn; /* 4: end-of-log */ 393*4882a593Smuzhiyun int clsn; /* 4: clsn */ 394*4882a593Smuzhiyun int syncpt; /* 4: addr of last syncpt record */ 395*4882a593Smuzhiyun int sync; /* 4: addr from last logsync() */ 396*4882a593Smuzhiyun struct list_head synclist; /* 8: logsynclist anchor */ 397*4882a593Smuzhiyun spinlock_t synclock; /* 4: synclist lock */ 398*4882a593Smuzhiyun struct lbuf *wqueue; /* 4: log pageout queue */ 399*4882a593Smuzhiyun int count; /* 4: count */ 400*4882a593Smuzhiyun uuid_t uuid; /* 16: 128-bit uuid of log device */ 401*4882a593Smuzhiyun 402*4882a593Smuzhiyun int no_integrity; /* 3: flag to disable journaling to disk */ 403*4882a593Smuzhiyun }; 404*4882a593Smuzhiyun 405*4882a593Smuzhiyun /* 406*4882a593Smuzhiyun * Log flag 407*4882a593Smuzhiyun */ 408*4882a593Smuzhiyun #define log_INLINELOG 1 409*4882a593Smuzhiyun #define log_SYNCBARRIER 2 410*4882a593Smuzhiyun #define log_QUIESCE 3 411*4882a593Smuzhiyun #define log_FLUSH 4 412*4882a593Smuzhiyun 413*4882a593Smuzhiyun /* 414*4882a593Smuzhiyun * group commit flag 415*4882a593Smuzhiyun */ 416*4882a593Smuzhiyun /* jfs_log */ 417*4882a593Smuzhiyun #define logGC_PAGEOUT 0x00000001 418*4882a593Smuzhiyun 419*4882a593Smuzhiyun /* tblock/lbuf */ 420*4882a593Smuzhiyun #define tblkGC_QUEUE 0x0001 421*4882a593Smuzhiyun #define tblkGC_READY 0x0002 422*4882a593Smuzhiyun #define tblkGC_COMMIT 0x0004 423*4882a593Smuzhiyun #define tblkGC_COMMITTED 0x0008 424*4882a593Smuzhiyun #define tblkGC_EOP 0x0010 425*4882a593Smuzhiyun #define tblkGC_FREE 0x0020 426*4882a593Smuzhiyun #define tblkGC_LEADER 0x0040 427*4882a593Smuzhiyun #define tblkGC_ERROR 0x0080 428*4882a593Smuzhiyun #define tblkGC_LAZY 0x0100 // D230860 429*4882a593Smuzhiyun #define tblkGC_UNLOCKED 0x0200 // D230860 430*4882a593Smuzhiyun 431*4882a593Smuzhiyun /* 432*4882a593Smuzhiyun * log cache buffer header 433*4882a593Smuzhiyun */ 434*4882a593Smuzhiyun struct lbuf { 435*4882a593Smuzhiyun struct jfs_log *l_log; /* 4: log associated with buffer */ 436*4882a593Smuzhiyun 437*4882a593Smuzhiyun /* 438*4882a593Smuzhiyun * data buffer base area 439*4882a593Smuzhiyun */ 440*4882a593Smuzhiyun uint l_flag; /* 4: pageout control flags */ 441*4882a593Smuzhiyun 442*4882a593Smuzhiyun struct lbuf *l_wqnext; /* 4: write queue link */ 443*4882a593Smuzhiyun struct lbuf *l_freelist; /* 4: freelistlink */ 444*4882a593Smuzhiyun 445*4882a593Smuzhiyun int l_pn; /* 4: log page number */ 446*4882a593Smuzhiyun int l_eor; /* 4: log record eor */ 447*4882a593Smuzhiyun int l_ceor; /* 4: committed log record eor */ 448*4882a593Smuzhiyun 449*4882a593Smuzhiyun s64 l_blkno; /* 8: log page block number */ 450*4882a593Smuzhiyun caddr_t l_ldata; /* 4: data page */ 451*4882a593Smuzhiyun struct page *l_page; /* The page itself */ 452*4882a593Smuzhiyun uint l_offset; /* Offset of l_ldata within the page */ 453*4882a593Smuzhiyun 454*4882a593Smuzhiyun wait_queue_head_t l_ioevent; /* 4: i/o done event */ 455*4882a593Smuzhiyun }; 456*4882a593Smuzhiyun 457*4882a593Smuzhiyun /* Reuse l_freelist for redrive list */ 458*4882a593Smuzhiyun #define l_redrive_next l_freelist 459*4882a593Smuzhiyun 460*4882a593Smuzhiyun /* 461*4882a593Smuzhiyun * logsynclist block 462*4882a593Smuzhiyun * 463*4882a593Smuzhiyun * common logsyncblk prefix for jbuf_t and tblock 464*4882a593Smuzhiyun */ 465*4882a593Smuzhiyun struct logsyncblk { 466*4882a593Smuzhiyun u16 xflag; /* flags */ 467*4882a593Smuzhiyun u16 flag; /* only meaninful in tblock */ 468*4882a593Smuzhiyun lid_t lid; /* lock id */ 469*4882a593Smuzhiyun s32 lsn; /* log sequence number */ 470*4882a593Smuzhiyun struct list_head synclist; /* log sync list link */ 471*4882a593Smuzhiyun }; 472*4882a593Smuzhiyun 473*4882a593Smuzhiyun /* 474*4882a593Smuzhiyun * logsynclist serialization (per log) 475*4882a593Smuzhiyun */ 476*4882a593Smuzhiyun 477*4882a593Smuzhiyun #define LOGSYNC_LOCK_INIT(log) spin_lock_init(&(log)->synclock) 478*4882a593Smuzhiyun #define LOGSYNC_LOCK(log, flags) spin_lock_irqsave(&(log)->synclock, flags) 479*4882a593Smuzhiyun #define LOGSYNC_UNLOCK(log, flags) \ 480*4882a593Smuzhiyun spin_unlock_irqrestore(&(log)->synclock, flags) 481*4882a593Smuzhiyun 482*4882a593Smuzhiyun /* compute the difference in bytes of lsn from sync point */ 483*4882a593Smuzhiyun #define logdiff(diff, lsn, log)\ 484*4882a593Smuzhiyun {\ 485*4882a593Smuzhiyun diff = (lsn) - (log)->syncpt;\ 486*4882a593Smuzhiyun if (diff < 0)\ 487*4882a593Smuzhiyun diff += (log)->logsize;\ 488*4882a593Smuzhiyun } 489*4882a593Smuzhiyun 490*4882a593Smuzhiyun extern int lmLogOpen(struct super_block *sb); 491*4882a593Smuzhiyun extern int lmLogClose(struct super_block *sb); 492*4882a593Smuzhiyun extern int lmLogShutdown(struct jfs_log * log); 493*4882a593Smuzhiyun extern int lmLogInit(struct jfs_log * log); 494*4882a593Smuzhiyun extern int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize); 495*4882a593Smuzhiyun extern int lmGroupCommit(struct jfs_log *, struct tblock *); 496*4882a593Smuzhiyun extern int jfsIOWait(void *); 497*4882a593Smuzhiyun extern void jfs_flush_journal(struct jfs_log * log, int wait); 498*4882a593Smuzhiyun extern void jfs_syncpt(struct jfs_log *log, int hard_sync); 499*4882a593Smuzhiyun 500*4882a593Smuzhiyun #endif /* _H_JFS_LOGMGR */ 501