1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (C) International Business Machines Corp., 2000-2004 4*4882a593Smuzhiyun */ 5*4882a593Smuzhiyun #ifndef _H_JFS_TXNMGR 6*4882a593Smuzhiyun #define _H_JFS_TXNMGR 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun #include "jfs_logmgr.h" 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun /* 11*4882a593Smuzhiyun * Hide implementation of TxBlock and TxLock 12*4882a593Smuzhiyun */ 13*4882a593Smuzhiyun #define tid_to_tblock(tid) (&TxBlock[tid]) 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun #define lid_to_tlock(lid) (&TxLock[lid]) 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun /* 18*4882a593Smuzhiyun * transaction block 19*4882a593Smuzhiyun */ 20*4882a593Smuzhiyun struct tblock { 21*4882a593Smuzhiyun /* 22*4882a593Smuzhiyun * tblock and jbuf_t common area: struct logsyncblk 23*4882a593Smuzhiyun * 24*4882a593Smuzhiyun * the following 5 fields are the same as struct logsyncblk 25*4882a593Smuzhiyun * which is common to tblock and jbuf to form logsynclist 26*4882a593Smuzhiyun */ 27*4882a593Smuzhiyun u16 xflag; /* tx commit type */ 28*4882a593Smuzhiyun u16 flag; /* tx commit state */ 29*4882a593Smuzhiyun lid_t dummy; /* Must keep structures common */ 30*4882a593Smuzhiyun s32 lsn; /* recovery lsn */ 31*4882a593Smuzhiyun struct list_head synclist; /* logsynclist link */ 32*4882a593Smuzhiyun 33*4882a593Smuzhiyun /* lock management */ 34*4882a593Smuzhiyun struct super_block *sb; /* super block */ 35*4882a593Smuzhiyun lid_t next; /* index of first tlock of tid */ 36*4882a593Smuzhiyun lid_t last; /* index of last tlock of tid */ 37*4882a593Smuzhiyun wait_queue_head_t waitor; /* tids waiting on this tid */ 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun /* log management */ 40*4882a593Smuzhiyun u32 logtid; /* log transaction id */ 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun /* commit management */ 43*4882a593Smuzhiyun struct list_head cqueue; /* commit queue list */ 44*4882a593Smuzhiyun s32 clsn; /* commit lsn */ 45*4882a593Smuzhiyun struct lbuf *bp; 46*4882a593Smuzhiyun s32 pn; /* commit record log page number */ 47*4882a593Smuzhiyun s32 eor; /* commit record eor */ 48*4882a593Smuzhiyun wait_queue_head_t gcwait; /* group commit event list: 49*4882a593Smuzhiyun * ready transactions wait on this 50*4882a593Smuzhiyun * event for group commit completion. 51*4882a593Smuzhiyun */ 52*4882a593Smuzhiyun union { 53*4882a593Smuzhiyun struct inode *ip; /* inode being deleted */ 54*4882a593Smuzhiyun pxd_t ixpxd; /* pxd of inode extent for created inode */ 55*4882a593Smuzhiyun } u; 56*4882a593Smuzhiyun u32 ino; /* inode number being created */ 57*4882a593Smuzhiyun }; 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun extern struct tblock *TxBlock; /* transaction block table */ 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun /* commit flags: tblk->xflag */ 62*4882a593Smuzhiyun #define COMMIT_SYNC 0x0001 /* synchronous commit */ 63*4882a593Smuzhiyun #define COMMIT_FORCE 0x0002 /* force pageout at end of commit */ 64*4882a593Smuzhiyun #define COMMIT_FLUSH 0x0004 /* init flush at end of commit */ 65*4882a593Smuzhiyun #define COMMIT_MAP 0x00f0 66*4882a593Smuzhiyun #define COMMIT_PMAP 0x0010 /* update pmap */ 67*4882a593Smuzhiyun #define COMMIT_WMAP 0x0020 /* update wmap */ 68*4882a593Smuzhiyun #define COMMIT_PWMAP 0x0040 /* update pwmap */ 69*4882a593Smuzhiyun #define COMMIT_FREE 0x0f00 70*4882a593Smuzhiyun #define COMMIT_DELETE 0x0100 /* inode delete */ 71*4882a593Smuzhiyun #define COMMIT_TRUNCATE 0x0200 /* file truncation */ 72*4882a593Smuzhiyun #define COMMIT_CREATE 0x0400 /* inode create */ 73*4882a593Smuzhiyun #define COMMIT_LAZY 0x0800 /* lazy commit */ 74*4882a593Smuzhiyun #define COMMIT_PAGE 0x1000 /* Identifies element as metapage */ 75*4882a593Smuzhiyun #define COMMIT_INODE 0x2000 /* Identifies element as inode */ 76*4882a593Smuzhiyun 77*4882a593Smuzhiyun /* group commit flags tblk->flag: see jfs_logmgr.h */ 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun /* 80*4882a593Smuzhiyun * transaction lock 81*4882a593Smuzhiyun */ 82*4882a593Smuzhiyun struct tlock { 83*4882a593Smuzhiyun lid_t next; /* 2: index next lockword on tid locklist 84*4882a593Smuzhiyun * next lockword on freelist 85*4882a593Smuzhiyun */ 86*4882a593Smuzhiyun tid_t tid; /* 2: transaction id holding lock */ 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun u16 flag; /* 2: lock control */ 89*4882a593Smuzhiyun u16 type; /* 2: log type */ 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun struct metapage *mp; /* 4/8: object page buffer locked */ 92*4882a593Smuzhiyun struct inode *ip; /* 4/8: object */ 93*4882a593Smuzhiyun /* (16) */ 94*4882a593Smuzhiyun 95*4882a593Smuzhiyun s16 lock[24]; /* 48: overlay area */ 96*4882a593Smuzhiyun }; /* (64) */ 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun extern struct tlock *TxLock; /* transaction lock table */ 99*4882a593Smuzhiyun 100*4882a593Smuzhiyun /* 101*4882a593Smuzhiyun * tlock flag 102*4882a593Smuzhiyun */ 103*4882a593Smuzhiyun /* txLock state */ 104*4882a593Smuzhiyun #define tlckPAGELOCK 0x8000 105*4882a593Smuzhiyun #define tlckINODELOCK 0x4000 106*4882a593Smuzhiyun #define tlckLINELOCK 0x2000 107*4882a593Smuzhiyun #define tlckINLINELOCK 0x1000 108*4882a593Smuzhiyun /* lmLog state */ 109*4882a593Smuzhiyun #define tlckLOG 0x0800 110*4882a593Smuzhiyun /* updateMap state */ 111*4882a593Smuzhiyun #define tlckUPDATEMAP 0x0080 112*4882a593Smuzhiyun #define tlckDIRECTORY 0x0040 113*4882a593Smuzhiyun /* freeLock state */ 114*4882a593Smuzhiyun #define tlckFREELOCK 0x0008 115*4882a593Smuzhiyun #define tlckWRITEPAGE 0x0004 116*4882a593Smuzhiyun #define tlckFREEPAGE 0x0002 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun /* 119*4882a593Smuzhiyun * tlock type 120*4882a593Smuzhiyun */ 121*4882a593Smuzhiyun #define tlckTYPE 0xfe00 122*4882a593Smuzhiyun #define tlckINODE 0x8000 123*4882a593Smuzhiyun #define tlckXTREE 0x4000 124*4882a593Smuzhiyun #define tlckDTREE 0x2000 125*4882a593Smuzhiyun #define tlckMAP 0x1000 126*4882a593Smuzhiyun #define tlckEA 0x0800 127*4882a593Smuzhiyun #define tlckACL 0x0400 128*4882a593Smuzhiyun #define tlckDATA 0x0200 129*4882a593Smuzhiyun #define tlckBTROOT 0x0100 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun #define tlckOPERATION 0x00ff 132*4882a593Smuzhiyun #define tlckGROW 0x0001 /* file grow */ 133*4882a593Smuzhiyun #define tlckREMOVE 0x0002 /* file delete */ 134*4882a593Smuzhiyun #define tlckTRUNCATE 0x0004 /* file truncate */ 135*4882a593Smuzhiyun #define tlckRELOCATE 0x0008 /* file/directory relocate */ 136*4882a593Smuzhiyun #define tlckENTRY 0x0001 /* directory insert/delete */ 137*4882a593Smuzhiyun #define tlckEXTEND 0x0002 /* directory extend in-line */ 138*4882a593Smuzhiyun #define tlckSPLIT 0x0010 /* splited page */ 139*4882a593Smuzhiyun #define tlckNEW 0x0020 /* new page from split */ 140*4882a593Smuzhiyun #define tlckFREE 0x0040 /* free page */ 141*4882a593Smuzhiyun #define tlckRELINK 0x0080 /* update sibling pointer */ 142*4882a593Smuzhiyun 143*4882a593Smuzhiyun /* 144*4882a593Smuzhiyun * linelock for lmLog() 145*4882a593Smuzhiyun * 146*4882a593Smuzhiyun * note: linelock and its variations are overlaid 147*4882a593Smuzhiyun * at tlock.lock: watch for alignment; 148*4882a593Smuzhiyun */ 149*4882a593Smuzhiyun struct lv { 150*4882a593Smuzhiyun u8 offset; /* 1: */ 151*4882a593Smuzhiyun u8 length; /* 1: */ 152*4882a593Smuzhiyun }; /* (2) */ 153*4882a593Smuzhiyun 154*4882a593Smuzhiyun #define TLOCKSHORT 20 155*4882a593Smuzhiyun #define TLOCKLONG 28 156*4882a593Smuzhiyun 157*4882a593Smuzhiyun struct linelock { 158*4882a593Smuzhiyun lid_t next; /* 2: next linelock */ 159*4882a593Smuzhiyun 160*4882a593Smuzhiyun s8 maxcnt; /* 1: */ 161*4882a593Smuzhiyun s8 index; /* 1: */ 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun u16 flag; /* 2: */ 164*4882a593Smuzhiyun u8 type; /* 1: */ 165*4882a593Smuzhiyun u8 l2linesize; /* 1: log2 of linesize */ 166*4882a593Smuzhiyun /* (8) */ 167*4882a593Smuzhiyun 168*4882a593Smuzhiyun struct lv lv[20]; /* 40: */ 169*4882a593Smuzhiyun }; /* (48) */ 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun #define dt_lock linelock 172*4882a593Smuzhiyun 173*4882a593Smuzhiyun struct xtlock { 174*4882a593Smuzhiyun lid_t next; /* 2: */ 175*4882a593Smuzhiyun 176*4882a593Smuzhiyun s8 maxcnt; /* 1: */ 177*4882a593Smuzhiyun s8 index; /* 1: */ 178*4882a593Smuzhiyun 179*4882a593Smuzhiyun u16 flag; /* 2: */ 180*4882a593Smuzhiyun u8 type; /* 1: */ 181*4882a593Smuzhiyun u8 l2linesize; /* 1: log2 of linesize */ 182*4882a593Smuzhiyun /* (8) */ 183*4882a593Smuzhiyun 184*4882a593Smuzhiyun struct lv header; /* 2: */ 185*4882a593Smuzhiyun struct lv lwm; /* 2: low water mark */ 186*4882a593Smuzhiyun struct lv hwm; /* 2: high water mark */ 187*4882a593Smuzhiyun struct lv twm; /* 2: */ 188*4882a593Smuzhiyun /* (16) */ 189*4882a593Smuzhiyun 190*4882a593Smuzhiyun s32 pxdlock[8]; /* 32: */ 191*4882a593Smuzhiyun }; /* (48) */ 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun 194*4882a593Smuzhiyun /* 195*4882a593Smuzhiyun * maplock for txUpdateMap() 196*4882a593Smuzhiyun * 197*4882a593Smuzhiyun * note: maplock and its variations are overlaid 198*4882a593Smuzhiyun * at tlock.lock/linelock: watch for alignment; 199*4882a593Smuzhiyun * N.B. next field may be set by linelock, and should not 200*4882a593Smuzhiyun * be modified by maplock; 201*4882a593Smuzhiyun * N.B. index of the first pxdlock specifies index of next 202*4882a593Smuzhiyun * free maplock (i.e., number of maplock) in the tlock; 203*4882a593Smuzhiyun */ 204*4882a593Smuzhiyun struct maplock { 205*4882a593Smuzhiyun lid_t next; /* 2: */ 206*4882a593Smuzhiyun 207*4882a593Smuzhiyun u8 maxcnt; /* 2: */ 208*4882a593Smuzhiyun u8 index; /* 2: next free maplock index */ 209*4882a593Smuzhiyun 210*4882a593Smuzhiyun u16 flag; /* 2: */ 211*4882a593Smuzhiyun u8 type; /* 1: */ 212*4882a593Smuzhiyun u8 count; /* 1: number of pxd/xad */ 213*4882a593Smuzhiyun /* (8) */ 214*4882a593Smuzhiyun 215*4882a593Smuzhiyun pxd_t pxd; /* 8: */ 216*4882a593Smuzhiyun }; /* (16): */ 217*4882a593Smuzhiyun 218*4882a593Smuzhiyun /* maplock flag */ 219*4882a593Smuzhiyun #define mlckALLOC 0x00f0 220*4882a593Smuzhiyun #define mlckALLOCXADLIST 0x0080 221*4882a593Smuzhiyun #define mlckALLOCPXDLIST 0x0040 222*4882a593Smuzhiyun #define mlckALLOCXAD 0x0020 223*4882a593Smuzhiyun #define mlckALLOCPXD 0x0010 224*4882a593Smuzhiyun #define mlckFREE 0x000f 225*4882a593Smuzhiyun #define mlckFREEXADLIST 0x0008 226*4882a593Smuzhiyun #define mlckFREEPXDLIST 0x0004 227*4882a593Smuzhiyun #define mlckFREEXAD 0x0002 228*4882a593Smuzhiyun #define mlckFREEPXD 0x0001 229*4882a593Smuzhiyun 230*4882a593Smuzhiyun #define pxd_lock maplock 231*4882a593Smuzhiyun 232*4882a593Smuzhiyun struct xdlistlock { 233*4882a593Smuzhiyun lid_t next; /* 2: */ 234*4882a593Smuzhiyun 235*4882a593Smuzhiyun u8 maxcnt; /* 2: */ 236*4882a593Smuzhiyun u8 index; /* 2: */ 237*4882a593Smuzhiyun 238*4882a593Smuzhiyun u16 flag; /* 2: */ 239*4882a593Smuzhiyun u8 type; /* 1: */ 240*4882a593Smuzhiyun u8 count; /* 1: number of pxd/xad */ 241*4882a593Smuzhiyun /* (8) */ 242*4882a593Smuzhiyun 243*4882a593Smuzhiyun /* 244*4882a593Smuzhiyun * We need xdlist to be 64 bits (8 bytes), regardless of 245*4882a593Smuzhiyun * whether void * is 32 or 64 bits 246*4882a593Smuzhiyun */ 247*4882a593Smuzhiyun union { 248*4882a593Smuzhiyun void *_xdlist; /* pxd/xad list */ 249*4882a593Smuzhiyun s64 pad; /* 8: Force 64-bit xdlist size */ 250*4882a593Smuzhiyun } union64; 251*4882a593Smuzhiyun }; /* (16): */ 252*4882a593Smuzhiyun 253*4882a593Smuzhiyun #define xdlist union64._xdlist 254*4882a593Smuzhiyun 255*4882a593Smuzhiyun /* 256*4882a593Smuzhiyun * commit 257*4882a593Smuzhiyun * 258*4882a593Smuzhiyun * parameter to the commit manager routines 259*4882a593Smuzhiyun */ 260*4882a593Smuzhiyun struct commit { 261*4882a593Smuzhiyun tid_t tid; /* tid = index of tblock */ 262*4882a593Smuzhiyun int flag; /* flags */ 263*4882a593Smuzhiyun struct jfs_log *log; /* log */ 264*4882a593Smuzhiyun struct super_block *sb; /* superblock */ 265*4882a593Smuzhiyun 266*4882a593Smuzhiyun int nip; /* number of entries in iplist */ 267*4882a593Smuzhiyun struct inode **iplist; /* list of pointers to inodes */ 268*4882a593Smuzhiyun 269*4882a593Smuzhiyun /* log record descriptor on 64-bit boundary */ 270*4882a593Smuzhiyun struct lrd lrd; /* : log record descriptor */ 271*4882a593Smuzhiyun }; 272*4882a593Smuzhiyun 273*4882a593Smuzhiyun /* 274*4882a593Smuzhiyun * external declarations 275*4882a593Smuzhiyun */ 276*4882a593Smuzhiyun extern int jfs_tlocks_low; 277*4882a593Smuzhiyun 278*4882a593Smuzhiyun extern int txInit(void); 279*4882a593Smuzhiyun extern void txExit(void); 280*4882a593Smuzhiyun extern struct tlock *txLock(tid_t, struct inode *, struct metapage *, int); 281*4882a593Smuzhiyun extern struct tlock *txMaplock(tid_t, struct inode *, int); 282*4882a593Smuzhiyun extern int txCommit(tid_t, int, struct inode **, int); 283*4882a593Smuzhiyun extern tid_t txBegin(struct super_block *, int); 284*4882a593Smuzhiyun extern void txBeginAnon(struct super_block *); 285*4882a593Smuzhiyun extern void txEnd(tid_t); 286*4882a593Smuzhiyun extern void txAbort(tid_t, int); 287*4882a593Smuzhiyun extern struct linelock *txLinelock(struct linelock *); 288*4882a593Smuzhiyun extern void txFreeMap(struct inode *, struct maplock *, struct tblock *, int); 289*4882a593Smuzhiyun extern void txEA(tid_t, struct inode *, dxd_t *, dxd_t *); 290*4882a593Smuzhiyun extern void txFreelock(struct inode *); 291*4882a593Smuzhiyun extern int lmLog(struct jfs_log *, struct tblock *, struct lrd *, 292*4882a593Smuzhiyun struct tlock *); 293*4882a593Smuzhiyun extern void txQuiesce(struct super_block *); 294*4882a593Smuzhiyun extern void txResume(struct super_block *); 295*4882a593Smuzhiyun extern void txLazyUnlock(struct tblock *); 296*4882a593Smuzhiyun extern int jfs_lazycommit(void *); 297*4882a593Smuzhiyun extern int jfs_sync(void *); 298*4882a593Smuzhiyun #endif /* _H_JFS_TXNMGR */ 299