jfs_txnmgr.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:74k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *   Copyright (c) International Business Machines Corp., 2000-2002
  3.  *   Portions Copyright (c) Christoph Hellwig, 2001-2002
  4.  *
  5.  *   This program is free software;  you can redistribute it and/or modify
  6.  *   it under the terms of the GNU General Public License as published by
  7.  *   the Free Software Foundation; either version 2 of the License, or 
  8.  *   (at your option) any later version.
  9.  * 
  10.  *   This program is distributed in the hope that it will be useful,
  11.  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
  12.  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  13.  *   the GNU General Public License for more details.
  14.  *
  15.  *   You should have received a copy of the GNU General Public License
  16.  *   along with this program;  if not, write to the Free Software 
  17.  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18.  */
  19. /*
  20.  *      jfs_txnmgr.c: transaction manager
  21.  *
  22.  * notes:
  23.  * transaction starts with txBegin() and ends with txCommit()
  24.  * or txAbort().
  25.  *
  26.  * tlock is acquired at the time of update;
  27.  * (obviate scan at commit time for xtree and dtree)
  28.  * tlock and mp points to each other;
  29.  * (no hashlist for mp -> tlock).
  30.  *
  31.  * special cases:
  32.  * tlock on in-memory inode:
  33.  * in-place tlock in the in-memory inode itself;
  34.  * converted to page lock by iWrite() at commit time.
  35.  *
  36.  * tlock during write()/mmap() under anonymous transaction (tid = 0):
  37.  * transferred (?) to transaction at commit time.
  38.  *
  39.  * use the page itself to update allocation maps
  40.  * (obviate intermediate replication of allocation/deallocation data)
  41.  * hold on to mp+lock thru update of maps
  42.  */
  43. #include <linux/fs.h>
  44. #include <linux/vmalloc.h>
  45. #include <linux/smp_lock.h>
  46. #include <linux/completion.h>
  47. #include "jfs_incore.h"
  48. #include "jfs_filsys.h"
  49. #include "jfs_metapage.h"
  50. #include "jfs_dinode.h"
  51. #include "jfs_imap.h"
  52. #include "jfs_dmap.h"
  53. #include "jfs_superblock.h"
  54. #include "jfs_debug.h"
  55. /*
  56.  *      transaction management structures
  57.  */
  58. static struct {
  59. /* tblock */
  60. int freetid; /* index of a free tid structure */
  61. wait_queue_head_t freewait; /* eventlist of free tblock */
  62. /* tlock */
  63. int freelock; /* index first free lock word */
  64. wait_queue_head_t freelockwait; /* eventlist of free tlock */
  65. wait_queue_head_t lowlockwait; /* eventlist of ample tlocks */
  66. int tlocksInUse; /* Number of tlocks in use */
  67. spinlock_t LazyLock; /* synchronize sync_queue & unlock_queue */
  68. /* struct tblock *sync_queue; * Transactions waiting for data sync */
  69. struct tblock *unlock_queue; /* Txns waiting to be released */
  70. struct tblock *unlock_tail; /* Tail of unlock_queue */
  71. struct list_head anon_list; /* inodes having anonymous txns */
  72. struct list_head anon_list2; /* inodes having anonymous txns
  73.    that couldn't be sync'ed */
  74. } TxAnchor;
  75. static int nTxBlock = 512; /* number of transaction blocks */
  76. struct tblock *TxBlock;         /* transaction block table */
  77. static int nTxLock = 4096; /* number of transaction locks */
  78. static int TxLockLWM = 4096*.4; /* Low water mark for number of txLocks used */
  79. static int TxLockHWM = 4096*.8; /* High water mark for number of txLocks used */
  80. struct tlock *TxLock;           /* transaction lock table */
  81. static int TlocksLow = 0; /* Indicates low number of available tlocks */
  82. /*
  83.  *      transaction management lock
  84.  */
  85. static spinlock_t jfsTxnLock = SPIN_LOCK_UNLOCKED;
  86. #define TXN_LOCK()              spin_lock(&jfsTxnLock)
  87. #define TXN_UNLOCK()            spin_unlock(&jfsTxnLock)
  88. #define LAZY_LOCK_INIT() spin_lock_init(&TxAnchor.LazyLock);
  89. #define LAZY_LOCK(flags) spin_lock_irqsave(&TxAnchor.LazyLock, flags)
  90. #define LAZY_UNLOCK(flags) spin_unlock_irqrestore(&TxAnchor.LazyLock, flags)
  91. DECLARE_WAIT_QUEUE_HEAD(jfs_sync_thread_wait);
  92. DECLARE_WAIT_QUEUE_HEAD(jfs_commit_thread_wait);
  93. /*
  94.  * Retry logic exist outside these macros to protect from spurrious wakeups.
  95.  */
  96. static inline void TXN_SLEEP_DROP_LOCK(wait_queue_head_t * event)
  97. {
  98. DECLARE_WAITQUEUE(wait, current);
  99. add_wait_queue(event, &wait);
  100. set_current_state(TASK_UNINTERRUPTIBLE);
  101. TXN_UNLOCK();
  102. schedule();
  103. current->state = TASK_RUNNING;
  104. remove_wait_queue(event, &wait);
  105. }
  106. #define TXN_SLEEP(event)
  107. {
  108. TXN_SLEEP_DROP_LOCK(event);
  109. TXN_LOCK();
  110. }
  111. #define TXN_WAKEUP(event) wake_up_all(event)
  112. /*
  113.  *      statistics
  114.  */
  115. struct {
  116. tid_t maxtid; /* 4: biggest tid ever used */
  117. lid_t maxlid; /* 4: biggest lid ever used */
  118. int ntid; /* 4: # of transactions performed */
  119. int nlid; /* 4: # of tlocks acquired */
  120. int waitlock; /* 4: # of tlock wait */
  121. } stattx;
  122. /*
  123.  * external references
  124.  */
  125. extern int lmGroupCommit(struct jfs_log * log, struct tblock * tblk);
  126. extern void lmSync(struct jfs_log *);
  127. extern int jfs_commit_inode(struct inode *, int);
  128. extern int jfs_stop_threads;
  129. struct task_struct *jfsCommitTask;
  130. extern struct completion jfsIOwait;
  131. /*
  132.  * forward references
  133.  */
  134. int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
  135.   struct tlock * tlck, struct commit * cd);
  136. int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
  137.     struct tlock * tlck);
  138. void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
  139.    struct tlock * tlck);
  140. void inlineLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
  141.        struct tlock * tlck);
  142. void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
  143.     struct tlock * tlck);
  144. void txAbortCommit(struct commit * cd, int exval);
  145. static void txAllocPMap(struct inode *ip, struct maplock * maplock,
  146. struct tblock * tblk);
  147. void txForce(struct tblock * tblk);
  148. static int txLog(struct jfs_log * log, struct tblock * tblk, struct commit * cd);
  149. int txMoreLock(void);
  150. static void txUpdateMap(struct tblock * tblk);
  151. static void txRelease(struct tblock * tblk);
  152. void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
  153.    struct tlock * tlck);
  154. static void LogSyncRelease(struct metapage * mp);
  155. /*
  156.  *              transaction block/lock management
  157.  *              ---------------------------------
  158.  */
  159. /*
  160.  * Get a transaction lock from the free list.  If the number in use is
  161.  * greater than the high water mark, wake up the sync daemon.  This should
  162.  * free some anonymous transaction locks.  (TXN_LOCK must be held.)
  163.  */
  164. static lid_t txLockAlloc(void)
  165. {
  166. lid_t lid;
  167. while (!(lid = TxAnchor.freelock))
  168. TXN_SLEEP(&TxAnchor.freelockwait);
  169. TxAnchor.freelock = TxLock[lid].next;
  170. HIGHWATERMARK(stattx.maxlid, lid);
  171. if ((++TxAnchor.tlocksInUse > TxLockHWM) && (TlocksLow == 0)) {
  172. jEVENT(0,("txLockAlloc TlocksLown"));
  173. TlocksLow = 1;
  174. wake_up(&jfs_sync_thread_wait);
  175. }
  176. return lid;
  177. }
  178. static void txLockFree(lid_t lid)
  179. {
  180. TxLock[lid].next = TxAnchor.freelock;
  181. TxAnchor.freelock = lid;
  182. TxAnchor.tlocksInUse--;
  183. if (TlocksLow && (TxAnchor.tlocksInUse < TxLockLWM)) {
  184. jEVENT(0,("txLockFree TlocksLow no moren"));
  185. TlocksLow = 0;
  186. TXN_WAKEUP(&TxAnchor.lowlockwait);
  187. }
  188. TXN_WAKEUP(&TxAnchor.freelockwait);
  189. }
  190. /*
  191.  * NAME:        txInit()
  192.  *
  193.  * FUNCTION:    initialize transaction management structures
  194.  *
  195.  * RETURN:
  196.  *
  197.  * serialization: single thread at jfs_init()
  198.  */
  199. int txInit(void)
  200. {
  201. int k, size;
  202. /*
  203.  * initialize transaction block (tblock) table
  204.  *
  205.  * transaction id (tid) = tblock index
  206.  * tid = 0 is reserved.
  207.  */
  208. size = sizeof(struct tblock) * nTxBlock;
  209. TxBlock = (struct tblock *) vmalloc(size);
  210. if (TxBlock == NULL)
  211. return ENOMEM;
  212. for (k = 1; k < nTxBlock - 1; k++) {
  213. TxBlock[k].next = k + 1;
  214. init_waitqueue_head(&TxBlock[k].gcwait);
  215. init_waitqueue_head(&TxBlock[k].waitor);
  216. }
  217. TxBlock[k].next = 0;
  218. init_waitqueue_head(&TxBlock[k].gcwait);
  219. init_waitqueue_head(&TxBlock[k].waitor);
  220. TxAnchor.freetid = 1;
  221. init_waitqueue_head(&TxAnchor.freewait);
  222. stattx.maxtid = 1; /* statistics */
  223. /*
  224.  * initialize transaction lock (tlock) table
  225.  *
  226.  * transaction lock id = tlock index
  227.  * tlock id = 0 is reserved.
  228.  */
  229. size = sizeof(struct tlock) * nTxLock;
  230. TxLock = (struct tlock *) vmalloc(size);
  231. if (TxLock == NULL) {
  232. vfree(TxBlock);
  233. return ENOMEM;
  234. }
  235. /* initialize tlock table */
  236. for (k = 1; k < nTxLock - 1; k++)
  237. TxLock[k].next = k + 1;
  238. TxLock[k].next = 0;
  239. init_waitqueue_head(&TxAnchor.freelockwait);
  240. init_waitqueue_head(&TxAnchor.lowlockwait);
  241. TxAnchor.freelock = 1;
  242. TxAnchor.tlocksInUse = 0;
  243. INIT_LIST_HEAD(&TxAnchor.anon_list);
  244. INIT_LIST_HEAD(&TxAnchor.anon_list2);
  245. stattx.maxlid = 1; /* statistics */
  246. return 0;
  247. }
  248. /*
  249.  * NAME:        txExit()
  250.  *
  251.  * FUNCTION:    clean up when module is unloaded
  252.  */
  253. void txExit(void)
  254. {
  255. vfree(TxLock);
  256. TxLock = 0;
  257. vfree(TxBlock);
  258. TxBlock = 0;
  259. }
  260. /*
  261.  * NAME:        txBegin()
  262.  *
  263.  * FUNCTION:    start a transaction.
  264.  *
  265.  * PARAMETER:   sb - superblock
  266.  *              flag - force for nested tx;
  267.  *
  268.  * RETURN: tid - transaction id
  269.  *
  270.  * note: flag force allows to start tx for nested tx
  271.  * to prevent deadlock on logsync barrier;
  272.  */
  273. tid_t txBegin(struct super_block *sb, int flag)
  274. {
  275. tid_t t;
  276. struct tblock *tblk;
  277. struct jfs_log *log;
  278. jFYI(1, ("txBegin: flag = 0x%xn", flag));
  279. log = JFS_SBI(sb)->log;
  280. TXN_LOCK();
  281.       retry:
  282. if (!(flag & COMMIT_FORCE)) {
  283. /*
  284.  * synchronize with logsync barrier
  285.  */
  286. if (test_bit(log_SYNCBARRIER, &log->flag) ||
  287.     test_bit(log_QUIESCE, &log->flag)) {
  288. TXN_SLEEP(&log->syncwait);
  289. goto retry;
  290. }
  291. }
  292. if (flag == 0) {
  293. /*
  294.  * Don't begin transaction if we're getting starved for tlocks
  295.  * unless COMMIT_FORCE or COMMIT_INODE (which may ultimately
  296.  * free tlocks)
  297.  */
  298. if (TlocksLow) {
  299. TXN_SLEEP(&TxAnchor.lowlockwait);
  300. goto retry;
  301. }
  302. }
  303. /*
  304.  * allocate transaction id/block
  305.  */
  306. if ((t = TxAnchor.freetid) == 0) {
  307. jFYI(1, ("txBegin: waiting for free tidn"));
  308. TXN_SLEEP(&TxAnchor.freewait);
  309. goto retry;
  310. }
  311. tblk = tid_to_tblock(t);
  312. if ((tblk->next == 0) && (current != jfsCommitTask)) {
  313. /* Save one tblk for jfsCommit thread */
  314. jFYI(1, ("txBegin: waiting for free tidn"));
  315. TXN_SLEEP(&TxAnchor.freewait);
  316. goto retry;
  317. }
  318. TxAnchor.freetid = tblk->next;
  319. /*
  320.  * initialize transaction
  321.  */
  322. /*
  323.  * We can't zero the whole thing or we screw up another thread being
  324.  * awakened after sleeping on tblk->waitor
  325.  *
  326.  * memset(tblk, 0, sizeof(struct tblock));
  327.  */
  328. tblk->next = tblk->last = tblk->xflag = tblk->flag = tblk->lsn = 0;
  329. tblk->sb = sb;
  330. ++log->logtid;
  331. tblk->logtid = log->logtid;
  332. ++log->active;
  333. HIGHWATERMARK(stattx.maxtid, t); /* statistics */
  334. INCREMENT(stattx.ntid); /* statistics */
  335. TXN_UNLOCK();
  336. jFYI(1, ("txBegin: returning tid = %dn", t));
  337. return t;
  338. }
  339. /*
  340.  * NAME:        txBeginAnon()
  341.  *
  342.  * FUNCTION:    start an anonymous transaction.
  343.  * Blocks if logsync or available tlocks are low to prevent
  344.  * anonymous tlocks from depleting supply.
  345.  *
  346.  * PARAMETER:   sb - superblock
  347.  *
  348.  * RETURN: none
  349.  */
  350. void txBeginAnon(struct super_block *sb)
  351. {
  352. struct jfs_log *log;
  353. log = JFS_SBI(sb)->log;
  354. TXN_LOCK();
  355.       retry:
  356. /*
  357.  * synchronize with logsync barrier
  358.  */
  359. if (test_bit(log_SYNCBARRIER, &log->flag) ||
  360.     test_bit(log_QUIESCE, &log->flag)) {
  361. TXN_SLEEP(&log->syncwait);
  362. goto retry;
  363. }
  364. /*
  365.  * Don't begin transaction if we're getting starved for tlocks
  366.  */
  367. if (TlocksLow) {
  368. TXN_SLEEP(&TxAnchor.lowlockwait);
  369. goto retry;
  370. }
  371. TXN_UNLOCK();
  372. }
  373. /*
  374.  *      txEnd()
  375.  *
  376.  * function: free specified transaction block.
  377.  *
  378.  *      logsync barrier processing:
  379.  *
  380.  * serialization:
  381.  */
  382. void txEnd(tid_t tid)
  383. {
  384. struct tblock *tblk = tid_to_tblock(tid);
  385. struct jfs_log *log;
  386. jFYI(1, ("txEnd: tid = %dn", tid));
  387. TXN_LOCK();
  388. /*
  389.  * wakeup transactions waiting on the page locked
  390.  * by the current transaction
  391.  */
  392. TXN_WAKEUP(&tblk->waitor);
  393. log = JFS_SBI(tblk->sb)->log;
  394. /*
  395.  * Lazy commit thread can't free this guy until we mark it UNLOCKED,
  396.  * otherwise, we would be left with a transaction that may have been
  397.  * reused.
  398.  *
  399.  * Lazy commit thread will turn off tblkGC_LAZY before calling this
  400.  * routine.
  401.  */
  402. if (tblk->flag & tblkGC_LAZY) {
  403. jFYI(1,
  404.      ("txEnd called w/lazy tid: %d, tblk = 0x%pn",
  405.       tid, tblk));
  406. TXN_UNLOCK();
  407. spin_lock_irq(&log->gclock); // LOGGC_LOCK
  408. tblk->flag |= tblkGC_UNLOCKED;
  409. spin_unlock_irq(&log->gclock); // LOGGC_UNLOCK
  410. return;
  411. }
  412. jFYI(1, ("txEnd: tid: %d, tblk = 0x%pn", tid, tblk));
  413. assert(tblk->next == 0);
  414. /*
  415.  * insert tblock back on freelist
  416.  */
  417. tblk->next = TxAnchor.freetid;
  418. TxAnchor.freetid = tid;
  419. /*
  420.  * mark the tblock not active
  421.  */
  422. --log->active;
  423. /*
  424.  * synchronize with logsync barrier
  425.  */
  426. if (test_bit(log_SYNCBARRIER, &log->flag) && log->active == 0) {
  427. /* forward log syncpt */
  428. /* lmSync(log); */
  429. jFYI(1, ("     log barrier off: 0x%xn", log->lsn));
  430. /* enable new transactions start */
  431. clear_bit(log_SYNCBARRIER, &log->flag);
  432. /* wakeup all waitors for logsync barrier */
  433. TXN_WAKEUP(&log->syncwait);
  434. }
  435. /*
  436.  * wakeup all waitors for a free tblock
  437.  */
  438. TXN_WAKEUP(&TxAnchor.freewait);
  439. TXN_UNLOCK();
  440. jFYI(1, ("txEnd: exittingn"));
  441. }
  442. /*
  443.  *      txLock()
  444.  *
  445.  * function: acquire a transaction lock on the specified <mp>
  446.  *
  447.  * parameter:
  448.  *
  449.  * return:      transaction lock id
  450.  *
  451.  * serialization:
  452.  */
  453. struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
  454.      int type)
  455. {
  456. struct jfs_inode_info *jfs_ip = JFS_IP(ip);
  457. int dir_xtree = 0;
  458. lid_t lid;
  459. tid_t xtid;
  460. struct tlock *tlck;
  461. struct xtlock *xtlck;
  462. struct linelock *linelock;
  463. xtpage_t *p;
  464. struct tblock *tblk;
  465. assert(!test_cflag(COMMIT_Nolink, ip));
  466. TXN_LOCK();
  467. if (S_ISDIR(ip->i_mode) && (type & tlckXTREE) &&
  468.     !(mp->xflag & COMMIT_PAGE)) {
  469. /*
  470.  * Directory inode is special.  It can have both an xtree tlock
  471.  * and a dtree tlock associated with it.
  472.  */
  473. dir_xtree = 1;
  474. lid = jfs_ip->xtlid;
  475. } else
  476. lid = mp->lid;
  477. /* is page not locked by a transaction ? */
  478. if (lid == 0)
  479. goto allocateLock;
  480. jFYI(1, ("txLock: tid:%d ip:0x%p mp:0x%p lid:%dn",
  481.  tid, ip, mp, lid));
  482. /* is page locked by the requester transaction ? */
  483. tlck = lid_to_tlock(lid);
  484. if ((xtid = tlck->tid) == tid)
  485. goto grantLock;
  486. /*
  487.  * is page locked by anonymous transaction/lock ?
  488.  *
  489.  * (page update without transaction (i.e., file write) is
  490.  * locked under anonymous transaction tid = 0:
  491.  * anonymous tlocks maintained on anonymous tlock list of
  492.  * the inode of the page and available to all anonymous
  493.  * transactions until txCommit() time at which point
  494.  * they are transferred to the transaction tlock list of
  495.  * the commiting transaction of the inode)
  496.  */
  497. if (xtid == 0) {
  498. tlck->tid = tid;
  499. tblk = tid_to_tblock(tid);
  500. /*
  501.  * The order of the tlocks in the transaction is important
  502.  * (during truncate, child xtree pages must be freed before
  503.  * parent's tlocks change the working map).
  504.  * Take tlock off anonymous list and add to tail of
  505.  * transaction list
  506.  *
  507.  * Note:  We really need to get rid of the tid & lid and
  508.  * use list_head's.  This code is getting UGLY!
  509.  */
  510. if (jfs_ip->atlhead == lid) {
  511. if (jfs_ip->atltail == lid) {
  512. /* only anonymous txn.
  513.  * Remove from anon_list
  514.  */
  515. list_del_init(&jfs_ip->anon_inode_list);
  516. }
  517. jfs_ip->atlhead = tlck->next;
  518. } else {
  519. lid_t last;
  520. for (last = jfs_ip->atlhead;
  521.      lid_to_tlock(last)->next != lid;
  522.      last = lid_to_tlock(last)->next) {
  523. assert(last);
  524. }
  525. lid_to_tlock(last)->next = tlck->next;
  526. if (jfs_ip->atltail == lid)
  527. jfs_ip->atltail = last;
  528. }
  529. /* insert the tlock at tail of transaction tlock list */
  530. if (tblk->next)
  531. lid_to_tlock(tblk->last)->next = lid;
  532. else
  533. tblk->next = lid;
  534. tlck->next = 0;
  535. tblk->last = lid;
  536. goto grantLock;
  537. }
  538. goto waitLock;
  539. /*
  540.  * allocate a tlock
  541.  */
  542.       allocateLock:
  543. lid = txLockAlloc();
  544. tlck = lid_to_tlock(lid);
  545. /*
  546.  * initialize tlock
  547.  */
  548. tlck->tid = tid;
  549. /* mark tlock for meta-data page */
  550. if (mp->xflag & COMMIT_PAGE) {
  551. tlck->flag = tlckPAGELOCK;
  552. /* mark the page dirty and nohomeok */
  553. mark_metapage_dirty(mp);
  554. atomic_inc(&mp->nohomeok);
  555. jFYI(1,
  556.      ("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%pn",
  557.       mp, atomic_read(&mp->nohomeok), tid, tlck));
  558. /* if anonymous transaction, and buffer is on the group
  559.  * commit synclist, mark inode to show this.  This will
  560.  * prevent the buffer from being marked nohomeok for too
  561.  * long a time.
  562.  */
  563. if ((tid == 0) && mp->lsn)
  564. set_cflag(COMMIT_Synclist, ip);
  565. }
  566. /* mark tlock for in-memory inode */
  567. else
  568. tlck->flag = tlckINODELOCK;
  569. tlck->type = 0;
  570. /* bind the tlock and the page */
  571. tlck->ip = ip;
  572. tlck->mp = mp;
  573. if (dir_xtree)
  574. jfs_ip->xtlid = lid;
  575. else
  576. mp->lid = lid;
  577. /*
  578.  * enqueue transaction lock to transaction/inode
  579.  */
  580. /* insert the tlock at tail of transaction tlock list */
  581. if (tid) {
  582. tblk = tid_to_tblock(tid);
  583. if (tblk->next)
  584. lid_to_tlock(tblk->last)->next = lid;
  585. else
  586. tblk->next = lid;
  587. tlck->next = 0;
  588. tblk->last = lid;
  589. }
  590. /* anonymous transaction:
  591.  * insert the tlock at head of inode anonymous tlock list
  592.  */
  593. else {
  594. tlck->next = jfs_ip->atlhead;
  595. jfs_ip->atlhead = lid;
  596. if (tlck->next == 0) {
  597. /* This inode's first anonymous transaction */
  598. jfs_ip->atltail = lid;
  599. list_add_tail(&jfs_ip->anon_inode_list,
  600.       &TxAnchor.anon_list);
  601. }
  602. }
  603. /* initialize type dependent area for linelock */
  604. linelock = (struct linelock *) & tlck->lock;
  605. linelock->next = 0;
  606. linelock->flag = tlckLINELOCK;
  607. linelock->maxcnt = TLOCKSHORT;
  608. linelock->index = 0;
  609. switch (type & tlckTYPE) {
  610. case tlckDTREE:
  611. linelock->l2linesize = L2DTSLOTSIZE;
  612. break;
  613. case tlckXTREE:
  614. linelock->l2linesize = L2XTSLOTSIZE;
  615. xtlck = (struct xtlock *) linelock;
  616. xtlck->header.offset = 0;
  617. xtlck->header.length = 2;
  618. if (type & tlckNEW) {
  619. xtlck->lwm.offset = XTENTRYSTART;
  620. } else {
  621. if (mp->xflag & COMMIT_PAGE)
  622. p = (xtpage_t *) mp->data;
  623. else
  624. p = &jfs_ip->i_xtroot;
  625. xtlck->lwm.offset =
  626.     le16_to_cpu(p->header.nextindex);
  627. }
  628. xtlck->lwm.length = 0; /* ! */
  629. xtlck->twm.offset = 0;
  630. xtlck->hwm.offset = 0;
  631. xtlck->index = 2;
  632. break;
  633. case tlckINODE:
  634. linelock->l2linesize = L2INODESLOTSIZE;
  635. break;
  636. case tlckDATA:
  637. linelock->l2linesize = L2DATASLOTSIZE;
  638. break;
  639. default:
  640. jERROR(1, ("UFO tlock:0x%pn", tlck));
  641. }
  642. /*
  643.  * update tlock vector
  644.  */
  645.       grantLock:
  646. tlck->type |= type;
  647. TXN_UNLOCK();
  648. return tlck;
  649. /*
  650.  * page is being locked by another transaction:
  651.  */
  652.       waitLock:
  653. /* Only locks on ipimap or ipaimap should reach here */
  654. /* assert(jfs_ip->fileset == AGGREGATE_I); */
  655. if (jfs_ip->fileset != AGGREGATE_I) {
  656. jERROR(1, ("txLock: trying to lock locked page!n"));
  657. dump_mem("ip", ip, sizeof(struct inode));
  658. dump_mem("mp", mp, sizeof(struct metapage));
  659. dump_mem("Locker's tblk", tid_to_tblock(tid),
  660.  sizeof(struct tblock));
  661. dump_mem("Tlock", tlck, sizeof(struct tlock));
  662. BUG();
  663. }
  664. INCREMENT(stattx.waitlock); /* statistics */
  665. release_metapage(mp);
  666. jEVENT(0, ("txLock: in waitLock, tid = %d, xtid = %d, lid = %dn",
  667.    tid, xtid, lid));
  668. TXN_SLEEP_DROP_LOCK(&tid_to_tblock(xtid)->waitor);
  669. jEVENT(0, ("txLock: awakened     tid = %d, lid = %dn", tid, lid));
  670. return NULL;
  671. }
  672. /*
  673.  * NAME:        txRelease()
  674.  *
  675.  * FUNCTION:    Release buffers associated with transaction locks, but don't
  676.  * mark homeok yet.  The allows other transactions to modify
  677.  * buffers, but won't let them go to disk until commit record
  678.  * actually gets written.
  679.  *
  680.  * PARAMETER:
  681.  *              tblk    -
  682.  *
  683.  * RETURN:      Errors from subroutines.
  684.  */
  685. static void txRelease(struct tblock * tblk)
  686. {
  687. struct metapage *mp;
  688. lid_t lid;
  689. struct tlock *tlck;
  690. TXN_LOCK();
  691. for (lid = tblk->next; lid; lid = tlck->next) {
  692. tlck = lid_to_tlock(lid);
  693. if ((mp = tlck->mp) != NULL &&
  694.     (tlck->type & tlckBTROOT) == 0) {
  695. assert(mp->xflag & COMMIT_PAGE);
  696. mp->lid = 0;
  697. }
  698. }
  699. /*
  700.  * wakeup transactions waiting on a page locked
  701.  * by the current transaction
  702.  */
  703. TXN_WAKEUP(&tblk->waitor);
  704. TXN_UNLOCK();
  705. }
  706. /*
  707.  * NAME:        txUnlock()
  708.  *
  709.  * FUNCTION:    Initiates pageout of pages modified by tid in journalled
  710.  *              objects and frees their lockwords.
  711.  */
  712. static void txUnlock(struct tblock * tblk)
  713. {
  714. struct tlock *tlck;
  715. struct linelock *linelock;
  716. lid_t lid, next, llid, k;
  717. struct metapage *mp;
  718. struct jfs_log *log;
  719. int difft, diffp;
  720. jFYI(1, ("txUnlock: tblk = 0x%pn", tblk));
  721. log = JFS_SBI(tblk->sb)->log;
  722. /*
  723.  * mark page under tlock homeok (its log has been written):
  724.  */
  725. for (lid = tblk->next; lid; lid = next) {
  726. tlck = lid_to_tlock(lid);
  727. next = tlck->next;
  728. jFYI(1, ("unlocking lid = %d, tlck = 0x%pn", lid, tlck));
  729. /* unbind page from tlock */
  730. if ((mp = tlck->mp) != NULL &&
  731.     (tlck->type & tlckBTROOT) == 0) {
  732. assert(mp->xflag & COMMIT_PAGE);
  733. /* hold buffer
  734.  *
  735.  * It's possible that someone else has the metapage.
  736.  * The only things were changing are nohomeok, which
  737.  * is handled atomically, and clsn which is protected
  738.  * by the LOGSYNC_LOCK.
  739.  */
  740. hold_metapage(mp, 1);
  741. assert(atomic_read(&mp->nohomeok) > 0);
  742. atomic_dec(&mp->nohomeok);
  743. /* inherit younger/larger clsn */
  744. LOGSYNC_LOCK(log);
  745. if (mp->clsn) {
  746. logdiff(difft, tblk->clsn, log);
  747. logdiff(diffp, mp->clsn, log);
  748. if (difft > diffp)
  749. mp->clsn = tblk->clsn;
  750. } else
  751. mp->clsn = tblk->clsn;
  752. LOGSYNC_UNLOCK(log);
  753. assert(!(tlck->flag & tlckFREEPAGE));
  754. if (tlck->flag & tlckWRITEPAGE) {
  755. write_metapage(mp);
  756. } else {
  757. /* release page which has been forced */
  758. release_metapage(mp);
  759. }
  760. }
  761. /* insert tlock, and linelock(s) of the tlock if any,
  762.  * at head of freelist
  763.  */
  764. TXN_LOCK();
  765. llid = ((struct linelock *) & tlck->lock)->next;
  766. while (llid) {
  767. linelock = (struct linelock *) lid_to_tlock(llid);
  768. k = linelock->next;
  769. txLockFree(llid);
  770. llid = k;
  771. }
  772. txLockFree(lid);
  773. TXN_UNLOCK();
  774. }
  775. tblk->next = tblk->last = 0;
  776. /*
  777.  * remove tblock from logsynclist
  778.  * (allocation map pages inherited lsn of tblk and
  779.  * has been inserted in logsync list at txUpdateMap())
  780.  */
  781. if (tblk->lsn) {
  782. LOGSYNC_LOCK(log);
  783. log->count--;
  784. list_del(&tblk->synclist);
  785. LOGSYNC_UNLOCK(log);
  786. }
  787. }
  788. /*
  789.  *      txMaplock()
  790.  *
  791.  * function: allocate a transaction lock for freed page/entry;
  792.  *      for freed page, maplock is used as xtlock/dtlock type;
  793.  */
  794. struct tlock *txMaplock(tid_t tid, struct inode *ip, int type)
  795. {
  796. struct jfs_inode_info *jfs_ip = JFS_IP(ip);
  797. lid_t lid;
  798. struct tblock *tblk;
  799. struct tlock *tlck;
  800. struct maplock *maplock;
  801. TXN_LOCK();
  802. /*
  803.  * allocate a tlock
  804.  */
  805. lid = txLockAlloc();
  806. tlck = lid_to_tlock(lid);
  807. /*
  808.  * initialize tlock
  809.  */
  810. tlck->tid = tid;
  811. /* bind the tlock and the object */
  812. tlck->flag = tlckINODELOCK;
  813. tlck->ip = ip;
  814. tlck->mp = NULL;
  815. tlck->type = type;
  816. /*
  817.  * enqueue transaction lock to transaction/inode
  818.  */
  819. /* insert the tlock at tail of transaction tlock list */
  820. if (tid) {
  821. tblk = tid_to_tblock(tid);
  822. if (tblk->next)
  823. lid_to_tlock(tblk->last)->next = lid;
  824. else
  825. tblk->next = lid;
  826. tlck->next = 0;
  827. tblk->last = lid;
  828. }
  829. /* anonymous transaction:
  830.  * insert the tlock at head of inode anonymous tlock list
  831.  */
  832. else {
  833. tlck->next = jfs_ip->atlhead;
  834. jfs_ip->atlhead = lid;
  835. if (tlck->next == 0) {
  836. /* This inode's first anonymous transaction */
  837. jfs_ip->atltail = lid;
  838. list_add_tail(&jfs_ip->anon_inode_list,
  839.       &TxAnchor.anon_list);
  840. }
  841. }
  842. TXN_UNLOCK();
  843. /* initialize type dependent area for maplock */
  844. maplock = (struct maplock *) & tlck->lock;
  845. maplock->next = 0;
  846. maplock->maxcnt = 0;
  847. maplock->index = 0;
  848. return tlck;
  849. }
  850. /*
  851.  *      txLinelock()
  852.  *
  853.  * function: allocate a transaction lock for log vector list
  854.  */
  855. struct linelock *txLinelock(struct linelock * tlock)
  856. {
  857. lid_t lid;
  858. struct tlock *tlck;
  859. struct linelock *linelock;
  860. TXN_LOCK();
  861. /* allocate a TxLock structure */
  862. lid = txLockAlloc();
  863. tlck = lid_to_tlock(lid);
  864. TXN_UNLOCK();
  865. /* initialize linelock */
  866. linelock = (struct linelock *) tlck;
  867. linelock->next = 0;
  868. linelock->flag = tlckLINELOCK;
  869. linelock->maxcnt = TLOCKLONG;
  870. linelock->index = 0;
  871. /* append linelock after tlock */
  872. linelock->next = tlock->next;
  873. tlock->next = lid;
  874. return linelock;
  875. }
  876. /*
  877.  *              transaction commit management
  878.  *              -----------------------------
  879.  */
  880. /*
  881.  * NAME:        txCommit()
  882.  *
  883.  * FUNCTION:    commit the changes to the objects specified in
  884.  *              clist.  For journalled segments only the
  885.  *              changes of the caller are committed, ie by tid.
  886.  *              for non-journalled segments the data are flushed to
  887.  *              disk and then the change to the disk inode and indirect
  888.  *              blocks committed (so blocks newly allocated to the
  889.  *              segment will be made a part of the segment atomically).
  890.  *
  891.  *              all of the segments specified in clist must be in
  892.  *              one file system. no more than 6 segments are needed
  893.  *              to handle all unix svcs.
  894.  *
  895.  *              if the i_nlink field (i.e. disk inode link count)
  896.  *              is zero, and the type of inode is a regular file or
  897.  *              directory, or symbolic link , the inode is truncated
  898.  *              to zero length. the truncation is committed but the
  899.  *              VM resources are unaffected until it is closed (see
  900.  *              iput and iclose).
  901.  *
  902.  * PARAMETER:
  903.  *
  904.  * RETURN:
  905.  *
  906.  * serialization:
  907.  *              on entry the inode lock on each segment is assumed
  908.  *              to be held.
  909.  *
  910.  * i/o error:
  911.  */
  912. int txCommit(tid_t tid, /* transaction identifier */
  913.      int nip, /* number of inodes to commit */
  914.      struct inode **iplist, /* list of inode to commit */
  915.      int flag)
  916. {
  917. int rc = 0, rc1 = 0;
  918. struct commit cd;
  919. struct jfs_log *log;
  920. struct tblock *tblk;
  921. struct lrd *lrd;
  922. int lsn;
  923. struct inode *ip;
  924. struct jfs_inode_info *jfs_ip;
  925. int k, n;
  926. ino_t top;
  927. struct super_block *sb;
  928. jFYI(1, ("txCommit, tid = %d, flag = %dn", tid, flag));
  929. /* is read-only file system ? */
  930. if (isReadOnly(iplist[0])) {
  931. rc = EROFS;
  932. goto TheEnd;
  933. }
  934. sb = cd.sb = iplist[0]->i_sb;
  935. cd.tid = tid;
  936. if (tid == 0)
  937. tid = txBegin(sb, 0);
  938. tblk = tid_to_tblock(tid);
  939. /*
  940.  * initialize commit structure
  941.  */
  942. log = JFS_SBI(sb)->log;
  943. cd.log = log;
  944. /* initialize log record descriptor in commit */
  945. lrd = &cd.lrd;
  946. lrd->logtid = cpu_to_le32(tblk->logtid);
  947. lrd->backchain = 0;
  948. tblk->xflag |= flag;
  949. if ((flag & (COMMIT_FORCE | COMMIT_SYNC)) == 0)
  950. tblk->xflag |= COMMIT_LAZY;
  951. /*
  952.  *      prepare non-journaled objects for commit
  953.  *
  954.  * flush data pages of non-journaled file
  955.  * to prevent the file getting non-initialized disk blocks
  956.  * in case of crash.
  957.  * (new blocks - )
  958.  */
  959. cd.iplist = iplist;
  960. cd.nip = nip;
  961. /*
  962.  *      acquire transaction lock on (on-disk) inodes
  963.  *
  964.  * update on-disk inode from in-memory inode
  965.  * acquiring transaction locks for AFTER records
  966.  * on the on-disk inode of file object
  967.  *
  968.  * sort the inodes array by inode number in descending order
  969.  * to prevent deadlock when acquiring transaction lock
  970.  * of on-disk inodes on multiple on-disk inode pages by
  971.  * multiple concurrent transactions
  972.  */
  973. for (k = 0; k < cd.nip; k++) {
  974. top = (cd.iplist[k])->i_ino;
  975. for (n = k + 1; n < cd.nip; n++) {
  976. ip = cd.iplist[n];
  977. if (ip->i_ino > top) {
  978. top = ip->i_ino;
  979. cd.iplist[n] = cd.iplist[k];
  980. cd.iplist[k] = ip;
  981. }
  982. }
  983. ip = cd.iplist[k];
  984. jfs_ip = JFS_IP(ip);
  985. /*
  986.  * BUGBUG - Should we call filemap_fdatasync here instead
  987.  * of fsync_inode_data?
  988.  * If we do, we have a deadlock condition since we may end
  989.  * up recursively calling jfs_get_block with the IWRITELOCK
  990.  * held.  We may be able to do away with IWRITELOCK while
  991.  * committing transactions and use i_sem instead.
  992.  */
  993. if ((!S_ISDIR(ip->i_mode))
  994.     && (tblk->flag & COMMIT_DELETE) == 0)
  995. fsync_inode_data_buffers(ip);
  996. /*
  997.  * Mark inode as not dirty.  It will still be on the dirty
  998.  * inode list, but we'll know not to commit it again unless
  999.  * it gets marked dirty again
  1000.  */
  1001. clear_cflag(COMMIT_Dirty, ip);
  1002. /* inherit anonymous tlock(s) of inode */
  1003. if (jfs_ip->atlhead) {
  1004. lid_to_tlock(jfs_ip->atltail)->next = tblk->next;
  1005. tblk->next = jfs_ip->atlhead;
  1006. if (!tblk->last)
  1007. tblk->last = jfs_ip->atltail;
  1008. jfs_ip->atlhead = jfs_ip->atltail = 0;
  1009. TXN_LOCK();
  1010. list_del_init(&jfs_ip->anon_inode_list);
  1011. TXN_UNLOCK();
  1012. }
  1013. /*
  1014.  * acquire transaction lock on on-disk inode page
  1015.  * (become first tlock of the tblk's tlock list)
  1016.  */
  1017. if (((rc = diWrite(tid, ip))))
  1018. goto out;
  1019. }
  1020. /*
  1021.  *      write log records from transaction locks
  1022.  *
  1023.  * txUpdateMap() resets XAD_NEW in XAD.
  1024.  */
  1025. if ((rc = txLog(log, tblk, &cd)))
  1026. goto TheEnd;
  1027. /*
  1028.  * Ensure that inode isn't reused before
  1029.  * lazy commit thread finishes processing
  1030.  */
  1031. if (tblk->xflag & (COMMIT_CREATE | COMMIT_DELETE))
  1032. atomic_inc(&tblk->ip->i_count);
  1033. ASSERT((!(tblk->xflag & COMMIT_DELETE)) ||
  1034.        ((tblk->ip->i_nlink == 0) &&
  1035. !test_cflag(COMMIT_Nolink, tblk->ip)));
  1036. /*
  1037.  *      write COMMIT log record
  1038.  */
  1039. lrd->type = cpu_to_le16(LOG_COMMIT);
  1040. lrd->length = 0;
  1041. lsn = lmLog(log, tblk, lrd, NULL);
  1042. lmGroupCommit(log, tblk);
  1043. /*
  1044.  *      - transaction is now committed -
  1045.  */
  1046. /*
  1047.  * force pages in careful update
  1048.  * (imap addressing structure update)
  1049.  */
  1050. if (flag & COMMIT_FORCE)
  1051. txForce(tblk);
  1052. /*
  1053.  *      update allocation map.
  1054.  *
  1055.  * update inode allocation map and inode:
  1056.  * free pager lock on memory object of inode if any.
  1057.  * update  block allocation map.
  1058.  *
  1059.  * txUpdateMap() resets XAD_NEW in XAD.
  1060.  */
  1061. if (tblk->xflag & COMMIT_FORCE)
  1062. txUpdateMap(tblk);
  1063. /*
  1064.  *      free transaction locks and pageout/free pages
  1065.  */
  1066. txRelease(tblk);
  1067. if ((tblk->flag & tblkGC_LAZY) == 0)
  1068. txUnlock(tblk);
  1069. /*
  1070.  *      reset in-memory object state
  1071.  */
  1072. for (k = 0; k < cd.nip; k++) {
  1073. ip = cd.iplist[k];
  1074. jfs_ip = JFS_IP(ip);
  1075. /*
  1076.  * reset in-memory inode state
  1077.  */
  1078. jfs_ip->bxflag = 0;
  1079. jfs_ip->blid = 0;
  1080. }
  1081.       out:
  1082. if (rc != 0)
  1083. txAbortCommit(&cd, rc);
  1084. else
  1085. rc = rc1;
  1086.       TheEnd:
  1087. jFYI(1, ("txCommit: tid = %d, returning %dn", tid, rc));
  1088. return rc;
  1089. }
  1090. /*
  1091.  * NAME:        txLog()
  1092.  *
  1093.  * FUNCTION:    Writes AFTER log records for all lines modified
  1094.  *              by tid for segments specified by inodes in comdata.
  1095.  *              Code assumes only WRITELOCKS are recorded in lockwords.
  1096.  *
  1097.  * PARAMETERS:
  1098.  *
  1099.  * RETURN :
  1100.  */
  1101. static int txLog(struct jfs_log * log, struct tblock * tblk, struct commit * cd)
  1102. {
  1103. int rc = 0;
  1104. struct inode *ip;
  1105. lid_t lid;
  1106. struct tlock *tlck;
  1107. struct lrd *lrd = &cd->lrd;
  1108. /*
  1109.  * write log record(s) for each tlock of transaction,
  1110.  */
  1111. for (lid = tblk->next; lid; lid = tlck->next) {
  1112. tlck = lid_to_tlock(lid);
  1113. tlck->flag |= tlckLOG;
  1114. /* initialize lrd common */
  1115. ip = tlck->ip;
  1116. lrd->aggregate = cpu_to_le32(kdev_t_to_nr(ip->i_dev));
  1117. lrd->log.redopage.fileset = cpu_to_le32(JFS_IP(ip)->fileset);
  1118. lrd->log.redopage.inode = cpu_to_le32(ip->i_ino);
  1119. if (tlck->mp)
  1120. hold_metapage(tlck->mp, 0);
  1121. /* write log record of page from the tlock */
  1122. switch (tlck->type & tlckTYPE) {
  1123. case tlckXTREE:
  1124. xtLog(log, tblk, lrd, tlck);
  1125. break;
  1126. case tlckDTREE:
  1127. dtLog(log, tblk, lrd, tlck);
  1128. break;
  1129. case tlckINODE:
  1130. diLog(log, tblk, lrd, tlck, cd);
  1131. break;
  1132. case tlckMAP:
  1133. mapLog(log, tblk, lrd, tlck);
  1134. break;
  1135. case tlckDATA:
  1136. dataLog(log, tblk, lrd, tlck);
  1137. break;
  1138. default:
  1139. jERROR(1, ("UFO tlock:0x%pn", tlck));
  1140. }
  1141. if (tlck->mp)
  1142. release_metapage(tlck->mp);
  1143. }
  1144. return rc;
  1145. }
  1146. /*
  1147.  *      diLog()
  1148.  *
  1149.  * function:    log inode tlock and format maplock to update bmap;
  1150.  */
  1151. int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
  1152.   struct tlock * tlck, struct commit * cd)
  1153. {
  1154. int rc = 0;
  1155. struct metapage *mp;
  1156. pxd_t *pxd;
  1157. struct pxd_lock *pxdlock;
  1158. mp = tlck->mp;
  1159. /* initialize as REDOPAGE record format */
  1160. lrd->log.redopage.type = cpu_to_le16(LOG_INODE);
  1161. lrd->log.redopage.l2linesize = cpu_to_le16(L2INODESLOTSIZE);
  1162. pxd = &lrd->log.redopage.pxd;
  1163. /*
  1164.  *      inode after image
  1165.  */
  1166. if (tlck->type & tlckENTRY) {
  1167. /* log after-image for logredo(): */
  1168. lrd->type = cpu_to_le16(LOG_REDOPAGE);
  1169. //              *pxd = mp->cm_pxd;
  1170. PXDaddress(pxd, mp->index);
  1171. PXDlength(pxd,
  1172.   mp->logical_size >> tblk->sb->s_blocksize_bits);
  1173. lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
  1174. /* mark page as homeward bound */
  1175. tlck->flag |= tlckWRITEPAGE;
  1176. } else if (tlck->type & tlckFREE) {
  1177. /*
  1178.  *      free inode extent
  1179.  *
  1180.  * (pages of the freed inode extent have been invalidated and
  1181.  * a maplock for free of the extent has been formatted at
  1182.  * txLock() time);
  1183.  *
  1184.  * the tlock had been acquired on the inode allocation map page
  1185.  * (iag) that specifies the freed extent, even though the map
  1186.  * page is not itself logged, to prevent pageout of the map
  1187.  * page before the log;
  1188.  */
  1189. assert(tlck->type & tlckFREE);
  1190. /* log LOG_NOREDOINOEXT of the freed inode extent for
  1191.  * logredo() to start NoRedoPage filters, and to update
  1192.  * imap and bmap for free of the extent;
  1193.  */
  1194. lrd->type = cpu_to_le16(LOG_NOREDOINOEXT);
  1195. /*
  1196.  * For the LOG_NOREDOINOEXT record, we need
  1197.  * to pass the IAG number and inode extent
  1198.  * index (within that IAG) from which the
  1199.  * the extent being released.  These have been
  1200.  * passed to us in the iplist[1] and iplist[2].
  1201.  */
  1202. lrd->log.noredoinoext.iagnum =
  1203.     cpu_to_le32((u32) (size_t) cd->iplist[1]);
  1204. lrd->log.noredoinoext.inoext_idx =
  1205.     cpu_to_le32((u32) (size_t) cd->iplist[2]);
  1206. pxdlock = (struct pxd_lock *) & tlck->lock;
  1207. *pxd = pxdlock->pxd;
  1208. lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL));
  1209. /* update bmap */
  1210. tlck->flag |= tlckUPDATEMAP;
  1211. /* mark page as homeward bound */
  1212. tlck->flag |= tlckWRITEPAGE;
  1213. } else {
  1214. jERROR(2, ("diLog: UFO type tlck:0x%pn", tlck));
  1215. }
  1216. #ifdef  _JFS_WIP
  1217. /*
  1218.  *      alloc/free external EA extent
  1219.  *
  1220.  * a maplock for txUpdateMap() to update bPWMAP for alloc/free
  1221.  * of the extent has been formatted at txLock() time;
  1222.  */
  1223. else {
  1224. assert(tlck->type & tlckEA);
  1225. /* log LOG_UPDATEMAP for logredo() to update bmap for
  1226.  * alloc of new (and free of old) external EA extent;
  1227.  */
  1228. lrd->type = cpu_to_le16(LOG_UPDATEMAP);
  1229. pxdlock = (struct pxd_lock *) & tlck->lock;
  1230. nlock = pxdlock->index;
  1231. for (i = 0; i < nlock; i++, pxdlock++) {
  1232. if (pxdlock->flag & mlckALLOCPXD)
  1233. lrd->log.updatemap.type =
  1234.     cpu_to_le16(LOG_ALLOCPXD);
  1235. else
  1236. lrd->log.updatemap.type =
  1237.     cpu_to_le16(LOG_FREEPXD);
  1238. lrd->log.updatemap.nxd = cpu_to_le16(1);
  1239. lrd->log.updatemap.pxd = pxdlock->pxd;
  1240. lrd->backchain =
  1241.     cpu_to_le32(lmLog(log, tblk, lrd, NULL));
  1242. }
  1243. /* update bmap */
  1244. tlck->flag |= tlckUPDATEMAP;
  1245. }
  1246. #endif /* _JFS_WIP */
  1247. return rc;
  1248. }
  1249. /*
  1250.  *      dataLog()
  1251.  *
  1252.  * function:    log data tlock
  1253.  */
  1254. int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
  1255.     struct tlock * tlck)
  1256. {
  1257. struct metapage *mp;
  1258. pxd_t *pxd;
  1259. int rc;
  1260. s64 xaddr;
  1261. int xflag;
  1262. s32 xlen;
  1263. mp = tlck->mp;
  1264. /* initialize as REDOPAGE record format */
  1265. lrd->log.redopage.type = cpu_to_le16(LOG_DATA);
  1266. lrd->log.redopage.l2linesize = cpu_to_le16(L2DATASLOTSIZE);
  1267. pxd = &lrd->log.redopage.pxd;
  1268. /* log after-image for logredo(): */
  1269. lrd->type = cpu_to_le16(LOG_REDOPAGE);
  1270. if (JFS_IP(tlck->ip)->next_index < MAX_INLINE_DIRTABLE_ENTRY) {
  1271. /*
  1272.  * The table has been truncated, we've must have deleted
  1273.  * the last entry, so don't bother logging this
  1274.  */
  1275. mp->lid = 0;
  1276. atomic_dec(&mp->nohomeok);
  1277. discard_metapage(mp);
  1278. tlck->mp = 0;
  1279. return 0;
  1280. }
  1281. rc = xtLookup(tlck->ip, mp->index, 1, &xflag, &xaddr, &xlen, 1);
  1282. if (rc || (xlen == 0)) {
  1283. jERROR(1, ("dataLog: can't find physical addressn"));
  1284. return 0;
  1285. }
  1286. PXDaddress(pxd, xaddr);
  1287. PXDlength(pxd, mp->logical_size >> tblk->sb->s_blocksize_bits);
  1288. lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
  1289. /* mark page as homeward bound */
  1290. tlck->flag |= tlckWRITEPAGE;
  1291. return 0;
  1292. }
  1293. /*
  1294.  *      dtLog()
  1295.  *
  1296.  * function:    log dtree tlock and format maplock to update bmap;
  1297.  */
  1298. void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
  1299.    struct tlock * tlck)
  1300. {
  1301. struct inode *ip;
  1302. struct metapage *mp;
  1303. struct pxd_lock *pxdlock;
  1304. pxd_t *pxd;
  1305. ip = tlck->ip;
  1306. mp = tlck->mp;
  1307. /* initialize as REDOPAGE/NOREDOPAGE record format */
  1308. lrd->log.redopage.type = cpu_to_le16(LOG_DTREE);
  1309. lrd->log.redopage.l2linesize = cpu_to_le16(L2DTSLOTSIZE);
  1310. pxd = &lrd->log.redopage.pxd;
  1311. if (tlck->type & tlckBTROOT)
  1312. lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT);
  1313. /*
  1314.  *      page extension via relocation: entry insertion;
  1315.  *      page extension in-place: entry insertion;
  1316.  *      new right page from page split, reinitialized in-line
  1317.  *      root from root page split: entry insertion;
  1318.  */
  1319. if (tlck->type & (tlckNEW | tlckEXTEND)) {
  1320. /* log after-image of the new page for logredo():
  1321.  * mark log (LOG_NEW) for logredo() to initialize
  1322.  * freelist and update bmap for alloc of the new page;
  1323.  */
  1324. lrd->type = cpu_to_le16(LOG_REDOPAGE);
  1325. if (tlck->type & tlckEXTEND)
  1326. lrd->log.redopage.type |= cpu_to_le16(LOG_EXTEND);
  1327. else
  1328. lrd->log.redopage.type |= cpu_to_le16(LOG_NEW);
  1329. //              *pxd = mp->cm_pxd;
  1330. PXDaddress(pxd, mp->index);
  1331. PXDlength(pxd,
  1332.   mp->logical_size >> tblk->sb->s_blocksize_bits);
  1333. lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
  1334. /* format a maplock for txUpdateMap() to update bPMAP for
  1335.  * alloc of the new page;
  1336.  */
  1337. if (tlck->type & tlckBTROOT)
  1338. return;
  1339. tlck->flag |= tlckUPDATEMAP;
  1340. pxdlock = (struct pxd_lock *) & tlck->lock;
  1341. pxdlock->flag = mlckALLOCPXD;
  1342. pxdlock->pxd = *pxd;
  1343. pxdlock->index = 1;
  1344. /* mark page as homeward bound */
  1345. tlck->flag |= tlckWRITEPAGE;
  1346. return;
  1347. }
  1348. /*
  1349.  *      entry insertion/deletion,
  1350.  *      sibling page link update (old right page before split);
  1351.  */
  1352. if (tlck->type & (tlckENTRY | tlckRELINK)) {
  1353. /* log after-image for logredo(): */
  1354. lrd->type = cpu_to_le16(LOG_REDOPAGE);
  1355. PXDaddress(pxd, mp->index);
  1356. PXDlength(pxd,
  1357.   mp->logical_size >> tblk->sb->s_blocksize_bits);
  1358. lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
  1359. /* mark page as homeward bound */
  1360. tlck->flag |= tlckWRITEPAGE;
  1361. return;
  1362. }
  1363. /*
  1364.  *      page deletion: page has been invalidated
  1365.  *      page relocation: source extent
  1366.  *
  1367.  *      a maplock for free of the page has been formatted
  1368.  *      at txLock() time);
  1369.  */
  1370. if (tlck->type & (tlckFREE | tlckRELOCATE)) {
  1371. /* log LOG_NOREDOPAGE of the deleted page for logredo()
  1372.  * to start NoRedoPage filter and to update bmap for free
  1373.  * of the deletd page
  1374.  */
  1375. lrd->type = cpu_to_le16(LOG_NOREDOPAGE);
  1376. pxdlock = (struct pxd_lock *) & tlck->lock;
  1377. *pxd = pxdlock->pxd;
  1378. lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL));
  1379. /* a maplock for txUpdateMap() for free of the page
  1380.  * has been formatted at txLock() time;
  1381.  */
  1382. tlck->flag |= tlckUPDATEMAP;
  1383. }
  1384. return;
  1385. }
  1386. /*
  1387.  *      xtLog()
  1388.  *
  1389.  * function:    log xtree tlock and format maplock to update bmap;
  1390.  */
  1391. void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
  1392.    struct tlock * tlck)
  1393. {
  1394. struct inode *ip;
  1395. struct metapage *mp;
  1396. xtpage_t *p;
  1397. struct xtlock *xtlck;
  1398. struct maplock *maplock;
  1399. struct xdlistlock *xadlock;
  1400. struct pxd_lock *pxdlock;
  1401. pxd_t *pxd;
  1402. int next, lwm, hwm;
  1403. ip = tlck->ip;
  1404. mp = tlck->mp;
  1405. /* initialize as REDOPAGE/NOREDOPAGE record format */
  1406. lrd->log.redopage.type = cpu_to_le16(LOG_XTREE);
  1407. lrd->log.redopage.l2linesize = cpu_to_le16(L2XTSLOTSIZE);
  1408. pxd = &lrd->log.redopage.pxd;
  1409. if (tlck->type & tlckBTROOT) {
  1410. lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT);
  1411. p = &JFS_IP(ip)->i_xtroot;
  1412. if (S_ISDIR(ip->i_mode))
  1413. lrd->log.redopage.type |=
  1414.     cpu_to_le16(LOG_DIR_XTREE);
  1415. } else
  1416. p = (xtpage_t *) mp->data;
  1417. next = le16_to_cpu(p->header.nextindex);
  1418. xtlck = (struct xtlock *) & tlck->lock;
  1419. maplock = (struct maplock *) & tlck->lock;
  1420. xadlock = (struct xdlistlock *) maplock;
  1421. /*
  1422.  *      entry insertion/extension;
  1423.  *      sibling page link update (old right page before split);
  1424.  */
  1425. if (tlck->type & (tlckNEW | tlckGROW | tlckRELINK)) {
  1426. /* log after-image for logredo():
  1427.  * logredo() will update bmap for alloc of new/extended
  1428.  * extents (XAD_NEW|XAD_EXTEND) of XAD[lwm:next) from
  1429.  * after-image of XADlist;
  1430.  * logredo() resets (XAD_NEW|XAD_EXTEND) flag when
  1431.  * applying the after-image to the meta-data page.
  1432.  */
  1433. lrd->type = cpu_to_le16(LOG_REDOPAGE);
  1434. //              *pxd = mp->cm_pxd;
  1435. PXDaddress(pxd, mp->index);
  1436. PXDlength(pxd,
  1437.   mp->logical_size >> tblk->sb->s_blocksize_bits);
  1438. lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
  1439. /* format a maplock for txUpdateMap() to update bPMAP
  1440.  * for alloc of new/extended extents of XAD[lwm:next)
  1441.  * from the page itself;
  1442.  * txUpdateMap() resets (XAD_NEW|XAD_EXTEND) flag.
  1443.  */
  1444. lwm = xtlck->lwm.offset;
  1445. if (lwm == 0)
  1446. lwm = XTPAGEMAXSLOT;
  1447. if (lwm == next)
  1448. goto out;
  1449. assert(lwm < next);
  1450. tlck->flag |= tlckUPDATEMAP;
  1451. xadlock->flag = mlckALLOCXADLIST;
  1452. xadlock->count = next - lwm;
  1453. if ((xadlock->count <= 2) && (tblk->xflag & COMMIT_LAZY)) {
  1454. int i;
  1455. /*
  1456.  * Lazy commit may allow xtree to be modified before
  1457.  * txUpdateMap runs.  Copy xad into linelock to
  1458.  * preserve correct data.
  1459.  */
  1460. xadlock->xdlist = &xtlck->pxdlock;
  1461. memcpy(xadlock->xdlist, &p->xad[lwm],
  1462.        sizeof(xad_t) * xadlock->count);
  1463. for (i = 0; i < xadlock->count; i++)
  1464. p->xad[lwm + i].flag &=
  1465.     ~(XAD_NEW | XAD_EXTENDED);
  1466. } else {
  1467. /*
  1468.  * xdlist will point to into inode's xtree, ensure
  1469.  * that transaction is not committed lazily.
  1470.  */
  1471. xadlock->xdlist = &p->xad[lwm];
  1472. tblk->xflag &= ~COMMIT_LAZY;
  1473. }
  1474. jFYI(1,
  1475.      ("xtLog: alloc ip:0x%p mp:0x%p tlck:0x%p lwm:%d count:%dn",
  1476.       tlck->ip, mp, tlck, lwm, xadlock->count));
  1477. maplock->index = 1;
  1478.       out:
  1479. /* mark page as homeward bound */
  1480. tlck->flag |= tlckWRITEPAGE;
  1481. return;
  1482. }
  1483. /*
  1484.  *      page deletion: file deletion/truncation (ref. xtTruncate())
  1485.  *
  1486.  * (page will be invalidated after log is written and bmap
  1487.  * is updated from the page);
  1488.  */
  1489. if (tlck->type & tlckFREE) {
  1490. /* LOG_NOREDOPAGE log for NoRedoPage filter:
  1491.  * if page free from file delete, NoRedoFile filter from
  1492.  * inode image of zero link count will subsume NoRedoPage
  1493.  * filters for each page;
  1494.  * if page free from file truncattion, write NoRedoPage
  1495.  * filter;
  1496.  *
  1497.  * upadte of block allocation map for the page itself:
  1498.  * if page free from deletion and truncation, LOG_UPDATEMAP
  1499.  * log for the page itself is generated from processing
  1500.  * its parent page xad entries;
  1501.  */
  1502. /* if page free from file truncation, log LOG_NOREDOPAGE
  1503.  * of the deleted page for logredo() to start NoRedoPage
  1504.  * filter for the page;
  1505.  */
  1506. if (tblk->xflag & COMMIT_TRUNCATE) {
  1507. /* write NOREDOPAGE for the page */
  1508. lrd->type = cpu_to_le16(LOG_NOREDOPAGE);
  1509. PXDaddress(pxd, mp->index);
  1510. PXDlength(pxd,
  1511.   mp->logical_size >> tblk->sb->
  1512.   s_blocksize_bits);
  1513. lrd->backchain =
  1514.     cpu_to_le32(lmLog(log, tblk, lrd, NULL));
  1515. if (tlck->type & tlckBTROOT) {
  1516. /* Empty xtree must be logged */
  1517. lrd->type = cpu_to_le16(LOG_REDOPAGE);
  1518. lrd->backchain =
  1519.     cpu_to_le32(lmLog(log, tblk, lrd, tlck));
  1520. }
  1521. }
  1522. /* init LOG_UPDATEMAP of the freed extents
  1523.  * XAD[XTENTRYSTART:hwm) from the deleted page itself
  1524.  * for logredo() to update bmap;
  1525.  */
  1526. lrd->type = cpu_to_le16(LOG_UPDATEMAP);
  1527. lrd->log.updatemap.type = cpu_to_le16(LOG_FREEXADLIST);
  1528. xtlck = (struct xtlock *) & tlck->lock;
  1529. hwm = xtlck->hwm.offset;
  1530. lrd->log.updatemap.nxd =
  1531.     cpu_to_le16(hwm - XTENTRYSTART + 1);
  1532. /* reformat linelock for lmLog() */
  1533. xtlck->header.offset = XTENTRYSTART;
  1534. xtlck->header.length = hwm - XTENTRYSTART + 1;
  1535. xtlck->index = 1;
  1536. lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
  1537. /* format a maplock for txUpdateMap() to update bmap
  1538.  * to free extents of XAD[XTENTRYSTART:hwm) from the
  1539.  * deleted page itself;
  1540.  */
  1541. tlck->flag |= tlckUPDATEMAP;
  1542. xadlock->flag = mlckFREEXADLIST;
  1543. xadlock->count = hwm - XTENTRYSTART + 1;
  1544. if ((xadlock->count <= 2) && (tblk->xflag & COMMIT_LAZY)) {
  1545. /*
  1546.  * Lazy commit may allow xtree to be modified before
  1547.  * txUpdateMap runs.  Copy xad into linelock to
  1548.  * preserve correct data.
  1549.  */
  1550. xadlock->xdlist = &xtlck->pxdlock;
  1551. memcpy(xadlock->xdlist, &p->xad[XTENTRYSTART],
  1552.        sizeof(xad_t) * xadlock->count);
  1553. } else {
  1554. /*
  1555.  * xdlist will point to into inode's xtree, ensure
  1556.  * that transaction is not committed lazily unless
  1557.  * we're deleting the inode (unlink).  In that case
  1558.  * we have special logic for the inode to be
  1559.  * unlocked by the lazy commit thread.
  1560.  */
  1561. xadlock->xdlist = &p->xad[XTENTRYSTART];
  1562. if ((tblk->xflag & COMMIT_LAZY) &&
  1563.     (tblk->xflag & COMMIT_DELETE) &&
  1564.     (tblk->ip == ip))
  1565. set_cflag(COMMIT_Holdlock, ip);
  1566. else
  1567. tblk->xflag &= ~COMMIT_LAZY;
  1568. }
  1569. jFYI(1,
  1570.      ("xtLog: free ip:0x%p mp:0x%p count:%d lwm:2n",
  1571.       tlck->ip, mp, xadlock->count));
  1572. maplock->index = 1;
  1573. /* mark page as invalid */
  1574. if (((tblk->xflag & COMMIT_PWMAP) || S_ISDIR(ip->i_mode))
  1575.     && !(tlck->type & tlckBTROOT))
  1576. tlck->flag |= tlckFREEPAGE;
  1577. /*
  1578.    else (tblk->xflag & COMMIT_PMAP)
  1579.    ? release the page;
  1580.  */
  1581. return;
  1582. }
  1583. /*
  1584.  *      page/entry truncation: file truncation (ref. xtTruncate())
  1585.  *
  1586.  *     |----------+------+------+---------------|
  1587.  *                |      |      |
  1588.  *                |      |     hwm - hwm before truncation
  1589.  *                |     next - truncation point
  1590.  *               lwm - lwm before truncation
  1591.  * header ?
  1592.  */
  1593. if (tlck->type & tlckTRUNCATE) {
  1594. pxd_t tpxd; /* truncated extent of xad */
  1595. int twm;
  1596. /*
  1597.  * For truncation the entire linelock may be used, so it would
  1598.  * be difficult to store xad list in linelock itself.
  1599.  * Therefore, we'll just force transaction to be committed
  1600.  * synchronously, so that xtree pages won't be changed before
  1601.  * txUpdateMap runs.
  1602.  */
  1603. tblk->xflag &= ~COMMIT_LAZY;
  1604. lwm = xtlck->lwm.offset;
  1605. if (lwm == 0)
  1606. lwm = XTPAGEMAXSLOT;
  1607. hwm = xtlck->hwm.offset;
  1608. twm = xtlck->twm.offset;
  1609. /*
  1610.  *      write log records
  1611.  */
  1612. /*
  1613.  * allocate entries XAD[lwm:next]:
  1614.  */
  1615. if (lwm < next) {
  1616. /* log after-image for logredo():
  1617.  * logredo() will update bmap for alloc of new/extended
  1618.  * extents (XAD_NEW|XAD_EXTEND) of XAD[lwm:next) from
  1619.  * after-image of XADlist;
  1620.  * logredo() resets (XAD_NEW|XAD_EXTEND) flag when
  1621.  * applying the after-image to the meta-data page.
  1622.  */
  1623. lrd->type = cpu_to_le16(LOG_REDOPAGE);
  1624. PXDaddress(pxd, mp->index);
  1625. PXDlength(pxd,
  1626.   mp->logical_size >> tblk->sb->
  1627.   s_blocksize_bits);
  1628. lrd->backchain =
  1629.     cpu_to_le32(lmLog(log, tblk, lrd, tlck));
  1630. }
  1631. /*
  1632.  * truncate entry XAD[twm == next - 1]:
  1633.  */
  1634. if (twm == next - 1) {
  1635. /* init LOG_UPDATEMAP for logredo() to update bmap for
  1636.  * free of truncated delta extent of the truncated
  1637.  * entry XAD[next - 1]:
  1638.  * (xtlck->pxdlock = truncated delta extent);
  1639.  */
  1640. pxdlock = (struct pxd_lock *) & xtlck->pxdlock;
  1641. /* assert(pxdlock->type & tlckTRUNCATE); */
  1642. lrd->type = cpu_to_le16(LOG_UPDATEMAP);
  1643. lrd->log.updatemap.type = cpu_to_le16(LOG_FREEPXD);
  1644. lrd->log.updatemap.nxd = cpu_to_le16(1);
  1645. lrd->log.updatemap.pxd = pxdlock->pxd;
  1646. tpxd = pxdlock->pxd; /* save to format maplock */
  1647. lrd->backchain =
  1648.     cpu_to_le32(lmLog(log, tblk, lrd, NULL));
  1649. }
  1650. /*
  1651.  * free entries XAD[next:hwm]:
  1652.  */
  1653. if (hwm >= next) {
  1654. /* init LOG_UPDATEMAP of the freed extents
  1655.  * XAD[next:hwm] from the deleted page itself
  1656.  * for logredo() to update bmap;
  1657.  */
  1658. lrd->type = cpu_to_le16(LOG_UPDATEMAP);
  1659. lrd->log.updatemap.type =
  1660.     cpu_to_le16(LOG_FREEXADLIST);
  1661. xtlck = (struct xtlock *) & tlck->lock;
  1662. hwm = xtlck->hwm.offset;
  1663. lrd->log.updatemap.nxd =
  1664.     cpu_to_le16(hwm - next + 1);
  1665. /* reformat linelock for lmLog() */
  1666. xtlck->header.offset = next;
  1667. xtlck->header.length = hwm - next + 1;
  1668. xtlck->index = 1;
  1669. lrd->backchain =
  1670.     cpu_to_le32(lmLog(log, tblk, lrd, tlck));
  1671. }
  1672. /*
  1673.  *      format maplock(s) for txUpdateMap() to update bmap
  1674.  */
  1675. maplock->index = 0;
  1676. /*
  1677.  * allocate entries XAD[lwm:next):
  1678.  */
  1679. if (lwm < next) {
  1680. /* format a maplock for txUpdateMap() to update bPMAP
  1681.  * for alloc of new/extended extents of XAD[lwm:next)
  1682.  * from the page itself;
  1683.  * txUpdateMap() resets (XAD_NEW|XAD_EXTEND) flag.
  1684.  */
  1685. tlck->flag |= tlckUPDATEMAP;
  1686. xadlock->flag = mlckALLOCXADLIST;
  1687. xadlock->count = next - lwm;
  1688. xadlock->xdlist = &p->xad[lwm];
  1689. jFYI(1,
  1690.      ("xtLog: alloc ip:0x%p mp:0x%p count:%d lwm:%d next:%dn",
  1691.       tlck->ip, mp, xadlock->count, lwm, next));
  1692. maplock->index++;
  1693. xadlock++;
  1694. }
  1695. /*
  1696.  * truncate entry XAD[twm == next - 1]:
  1697.  */
  1698. if (twm == next - 1) {
  1699. struct pxd_lock *pxdlock;
  1700. /* format a maplock for txUpdateMap() to update bmap
  1701.  * to free truncated delta extent of the truncated
  1702.  * entry XAD[next - 1];
  1703.  * (xtlck->pxdlock = truncated delta extent);
  1704.  */
  1705. tlck->flag |= tlckUPDATEMAP;
  1706. pxdlock = (struct pxd_lock *) xadlock;
  1707. pxdlock->flag = mlckFREEPXD;
  1708. pxdlock->count = 1;
  1709. pxdlock->pxd = tpxd;
  1710. jFYI(1,
  1711.      ("xtLog: truncate ip:0x%p mp:0x%p count:%d hwm:%dn",
  1712.       ip, mp, pxdlock->count, hwm));
  1713. maplock->index++;
  1714. xadlock++;
  1715. }
  1716. /*
  1717.  * free entries XAD[next:hwm]:
  1718.  */
  1719. if (hwm >= next) {
  1720. /* format a maplock for txUpdateMap() to update bmap
  1721.  * to free extents of XAD[next:hwm] from thedeleted
  1722.  * page itself;
  1723.  */
  1724. tlck->flag |= tlckUPDATEMAP;
  1725. xadlock->flag = mlckFREEXADLIST;
  1726. xadlock->count = hwm - next + 1;
  1727. xadlock->xdlist = &p->xad[next];
  1728. jFYI(1,
  1729.      ("xtLog: free ip:0x%p mp:0x%p count:%d next:%d hwm:%dn",
  1730.       tlck->ip, mp, xadlock->count, next, hwm));
  1731. maplock->index++;
  1732. }
  1733. /* mark page as homeward bound */
  1734. tlck->flag |= tlckWRITEPAGE;
  1735. }
  1736. return;
  1737. }
  1738. /*
  1739.  *      mapLog()
  1740.  *
  1741.  * function:    log from maplock of freed data extents;
  1742.  */
  1743. void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
  1744.     struct tlock * tlck)
  1745. {
  1746. struct pxd_lock *pxdlock;
  1747. int i, nlock;
  1748. pxd_t *pxd;
  1749. /*
  1750.  *      page relocation: free the source page extent
  1751.  *
  1752.  * a maplock for txUpdateMap() for free of the page
  1753.  * has been formatted at txLock() time saving the src
  1754.  * relocated page address;
  1755.  */
  1756. if (tlck->type & tlckRELOCATE) {
  1757. /* log LOG_NOREDOPAGE of the old relocated page
  1758.  * for logredo() to start NoRedoPage filter;
  1759.  */
  1760. lrd->type = cpu_to_le16(LOG_NOREDOPAGE);
  1761. pxdlock = (struct pxd_lock *) & tlck->lock;
  1762. pxd = &lrd->log.redopage.pxd;
  1763. *pxd = pxdlock->pxd;
  1764. lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL));
  1765. /* (N.B. currently, logredo() does NOT update bmap
  1766.  * for free of the page itself for (LOG_XTREE|LOG_NOREDOPAGE);
  1767.  * if page free from relocation, LOG_UPDATEMAP log is
  1768.  * specifically generated now for logredo()
  1769.  * to update bmap for free of src relocated page;
  1770.  * (new flag LOG_RELOCATE may be introduced which will
  1771.  * inform logredo() to start NORedoPage filter and also
  1772.  * update block allocation map at the same time, thus
  1773.  * avoiding an extra log write);
  1774.  */
  1775. lrd->type = cpu_to_le16(LOG_UPDATEMAP);
  1776. lrd->log.updatemap.type = cpu_to_le16(LOG_FREEPXD);
  1777. lrd->log.updatemap.nxd = cpu_to_le16(1);
  1778. lrd->log.updatemap.pxd = pxdlock->pxd;
  1779. lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, NULL));
  1780. /* a maplock for txUpdateMap() for free of the page
  1781.  * has been formatted at txLock() time;
  1782.  */
  1783. tlck->flag |= tlckUPDATEMAP;
  1784. return;
  1785. }
  1786. /*
  1787.  * Otherwise it's not a relocate request
  1788.  *
  1789.  */
  1790. else {
  1791. /* log LOG_UPDATEMAP for logredo() to update bmap for
  1792.  * free of truncated/relocated delta extent of the data;
  1793.  * e.g.: external EA extent, relocated/truncated extent
  1794.  * from xtTailgate();
  1795.  */
  1796. lrd->type = cpu_to_le16(LOG_UPDATEMAP);
  1797. pxdlock = (struct pxd_lock *) & tlck->lock;
  1798. nlock = pxdlock->index;
  1799. for (i = 0; i < nlock; i++, pxdlock++) {
  1800. if (pxdlock->flag & mlckALLOCPXD)
  1801. lrd->log.updatemap.type =
  1802.     cpu_to_le16(LOG_ALLOCPXD);
  1803. else
  1804. lrd->log.updatemap.type =
  1805.     cpu_to_le16(LOG_FREEPXD);
  1806. lrd->log.updatemap.nxd = cpu_to_le16(1);
  1807. lrd->log.updatemap.pxd = pxdlock->pxd;
  1808. lrd->backchain =
  1809.     cpu_to_le32(lmLog(log, tblk, lrd, NULL));
  1810. jFYI(1, ("mapLog: xaddr:0x%lx xlen:0x%xn",
  1811.  (ulong) addressPXD(&pxdlock->pxd),
  1812.  lengthPXD(&pxdlock->pxd)));
  1813. }
  1814. /* update bmap */
  1815. tlck->flag |= tlckUPDATEMAP;
  1816. }
  1817. }
  1818. /*
  1819.  *      txEA()
  1820.  *
  1821.  * function:    acquire maplock for EA/ACL extents or
  1822.  *              set COMMIT_INLINE flag;
  1823.  */
  1824. void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea)
  1825. {
  1826. struct tlock *tlck = NULL;
  1827. struct pxd_lock *maplock = NULL, *pxdlock = NULL;
  1828. /*
  1829.  * format maplock for alloc of new EA extent
  1830.  */
  1831. if (newea) {
  1832. /* Since the newea could be a completely zeroed entry we need to
  1833.  * check for the two flags which indicate we should actually
  1834.  * commit new EA data
  1835.  */
  1836. if (newea->flag & DXD_EXTENT) {
  1837. tlck = txMaplock(tid, ip, tlckMAP);
  1838. maplock = (struct pxd_lock *) & tlck->lock;
  1839. pxdlock = (struct pxd_lock *) maplock;
  1840. pxdlock->flag = mlckALLOCPXD;
  1841. PXDaddress(&pxdlock->pxd, addressDXD(newea));
  1842. PXDlength(&pxdlock->pxd, lengthDXD(newea));
  1843. pxdlock++;
  1844. maplock->index = 1;
  1845. } else if (newea->flag & DXD_INLINE) {
  1846. tlck = NULL;
  1847. set_cflag(COMMIT_Inlineea, ip);
  1848. }
  1849. }
  1850. /*
  1851.  * format maplock for free of old EA extent
  1852.  */
  1853. if (!test_cflag(COMMIT_Nolink, ip) && oldea->flag & DXD_EXTENT) {
  1854. if (tlck == NULL) {
  1855. tlck = txMaplock(tid, ip, tlckMAP);
  1856. maplock = (struct pxd_lock *) & tlck->lock;
  1857. pxdlock = (struct pxd_lock *) maplock;
  1858. maplock->index = 0;
  1859. }
  1860. pxdlock->flag = mlckFREEPXD;
  1861. PXDaddress(&pxdlock->pxd, addressDXD(oldea));
  1862. PXDlength(&pxdlock->pxd, lengthDXD(oldea));
  1863. maplock->index++;
  1864. }
  1865. }
  1866. /*
  1867.  *      txForce()
  1868.  *
  1869.  * function: synchronously write pages locked by transaction
  1870.  *              after txLog() but before txUpdateMap();
  1871.  */
  1872. void txForce(struct tblock * tblk)
  1873. {
  1874. struct tlock *tlck;
  1875. lid_t lid, next;
  1876. struct metapage *mp;
  1877. /*
  1878.  * reverse the order of transaction tlocks in
  1879.  * careful update order of address index pages
  1880.  * (right to left, bottom up)
  1881.  */
  1882. tlck = lid_to_tlock(tblk->next);
  1883. lid = tlck->next;
  1884. tlck->next = 0;
  1885. while (lid) {
  1886. tlck = lid_to_tlock(lid);
  1887. next = tlck->next;
  1888. tlck->next = tblk->next;
  1889. tblk->next = lid;
  1890. lid = next;
  1891. }
  1892. /*
  1893.  * synchronously write the page, and
  1894.  * hold the page for txUpdateMap();
  1895.  */
  1896. for (lid = tblk->next; lid; lid = next) {
  1897. tlck = lid_to_tlock(lid);
  1898. next = tlck->next;
  1899. if ((mp = tlck->mp) != NULL &&
  1900.     (tlck->type & tlckBTROOT) == 0) {
  1901. assert(mp->xflag & COMMIT_PAGE);
  1902. if (tlck->flag & tlckWRITEPAGE) {
  1903. tlck->flag &= ~tlckWRITEPAGE;
  1904. /* do not release page to freelist */
  1905. assert(atomic_read(&mp->nohomeok));
  1906. hold_metapage(mp, 0);
  1907. write_metapage(mp);
  1908. }
  1909. }
  1910. }
  1911. }
  1912. /*
  1913.  *      txUpdateMap()
  1914.  *
  1915.  * function:    update persistent allocation map (and working map
  1916.  *              if appropriate);
  1917.  *
  1918.  * parameter:
  1919.  */
  1920. static void txUpdateMap(struct tblock * tblk)
  1921. {
  1922. struct inode *ip;
  1923. struct inode *ipimap;
  1924. lid_t lid;
  1925. struct tlock *tlck;
  1926. struct maplock *maplock;
  1927. struct pxd_lock pxdlock;
  1928. int maptype;
  1929. int k, nlock;
  1930. struct metapage *mp = 0;
  1931. ipimap = JFS_SBI(tblk->sb)->ipimap;
  1932. maptype = (tblk->xflag & COMMIT_PMAP) ? COMMIT_PMAP : COMMIT_PWMAP;
  1933. /*
  1934.  *      update block allocation map
  1935.  *
  1936.  * update allocation state in pmap (and wmap) and
  1937.  * update lsn of the pmap page;
  1938.  */
  1939. /*
  1940.  * scan each tlock/page of transaction for block allocation/free:
  1941.  *
  1942.  * for each tlock/page of transaction, update map.
  1943.  *  ? are there tlock for pmap and pwmap at the same time ?
  1944.  */
  1945. for (lid = tblk->next; lid; lid = tlck->next) {
  1946. tlck = lid_to_tlock(lid);
  1947. if ((tlck->flag & tlckUPDATEMAP) == 0)
  1948. continue;
  1949. if (tlck->flag & tlckFREEPAGE) {
  1950. /*
  1951.  * Another thread may attempt to reuse freed space
  1952.  * immediately, so we want to get rid of the metapage
  1953.  * before anyone else has a chance to get it.
  1954.  * Lock metapage, update maps, then invalidate
  1955.  * the metapage.
  1956.  */
  1957. mp = tlck->mp;
  1958. ASSERT(mp->xflag & COMMIT_PAGE);
  1959. hold_metapage(mp, 0);
  1960. }
  1961. /*
  1962.  * extent list:
  1963.  * . in-line PXD list:
  1964.  * . out-of-line XAD list:
  1965.  */
  1966. maplock = (struct maplock *) & tlck->lock;
  1967. nlock = maplock->index;
  1968. for (k = 0; k < nlock; k++, maplock++) {
  1969. /*
  1970.  * allocate blocks in persistent map:
  1971.  *
  1972.  * blocks have been allocated from wmap at alloc time;
  1973.  */
  1974. if (maplock->flag & mlckALLOC) {
  1975. txAllocPMap(ipimap, maplock, tblk);
  1976. }
  1977. /*
  1978.  * free blocks in persistent and working map:
  1979.  * blocks will be freed in pmap and then in wmap;
  1980.  *
  1981.  * ? tblock specifies the PMAP/PWMAP based upon
  1982.  * transaction
  1983.  *
  1984.  * free blocks in persistent map:
  1985.  * blocks will be freed from wmap at last reference
  1986.  * release of the object for regular files;
  1987.  *
  1988.  * Alway free blocks from both persistent & working
  1989.  * maps for directories
  1990.  */
  1991. else { /* (maplock->flag & mlckFREE) */
  1992. if (S_ISDIR(tlck->ip->i_mode))
  1993. txFreeMap(ipimap, maplock,
  1994.   tblk, COMMIT_PWMAP);
  1995. else
  1996. txFreeMap(ipimap, maplock,
  1997.   tblk, maptype);
  1998. }
  1999. }
  2000. if (tlck->flag & tlckFREEPAGE) {
  2001. if (!(tblk->flag & tblkGC_LAZY)) {
  2002. /* This is equivalent to txRelease */
  2003. ASSERT(mp->lid == lid);
  2004. tlck->mp->lid = 0;
  2005. }
  2006. assert(atomic_read(&mp->nohomeok) == 1);
  2007. atomic_dec(&mp->nohomeok);
  2008. discard_metapage(mp);
  2009. tlck->mp = 0;
  2010. }
  2011. }
  2012. /*
  2013.  *      update inode allocation map
  2014.  *
  2015.  * update allocation state in pmap and
  2016.  * update lsn of the pmap page;
  2017.  * update in-memory inode flag/state
  2018.  *
  2019.  * unlock mapper/write lock
  2020.  */
  2021. if (tblk->xflag & COMMIT_CREATE) {
  2022. ip = tblk->ip;
  2023. ASSERT(test_cflag(COMMIT_New, ip));
  2024. clear_cflag(COMMIT_New, ip);
  2025. diUpdatePMap(ipimap, ip->i_ino, FALSE, tblk);
  2026. ipimap->i_state |= I_DIRTY;
  2027. /* update persistent block allocation map
  2028.  * for the allocation of inode extent;
  2029.  */
  2030. pxdlock.flag = mlckALLOCPXD;
  2031. pxdlock.pxd = JFS_IP(ip)->ixpxd;
  2032. pxdlock.index = 1;
  2033. txAllocPMap(ip, (struct maplock *) & pxdlock, tblk);
  2034. iput(ip);
  2035. } else if (tblk->xflag & COMMIT_DELETE) {
  2036. ip = tblk->ip;
  2037. diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk);
  2038. ipimap->i_state |= I_DIRTY;
  2039. if (test_and_clear_cflag(COMMIT_Holdlock, ip)) {
  2040. if (tblk->flag & tblkGC_LAZY)
  2041. IWRITE_UNLOCK(ip);
  2042. }
  2043. iput(ip);
  2044. }
  2045. }
  2046. /*
  2047.  *      txAllocPMap()
  2048.  *
  2049.  * function: allocate from persistent map;
  2050.  *
  2051.  * parameter:
  2052.  *      ipbmap  -
  2053.  *      malock -
  2054.  *              xad list:
  2055.  *              pxd:
  2056.  *
  2057.  *      maptype -
  2058.  *              allocate from persistent map;
  2059.  *              free from persistent map;
  2060.  *              (e.g., tmp file - free from working map at releae
  2061.  *               of last reference);
  2062.  *              free from persistent and working map;
  2063.  *
  2064.  *      lsn     - log sequence number;
  2065.  */
  2066. static void txAllocPMap(struct inode *ip, struct maplock * maplock,
  2067. struct tblock * tblk)
  2068. {
  2069. struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
  2070. struct xdlistlock *xadlistlock;
  2071. xad_t *xad;
  2072. s64 xaddr;
  2073. int xlen;
  2074. struct pxd_lock *pxdlock;
  2075. struct xdlistlock *pxdlistlock;
  2076. pxd_t *pxd;
  2077. int n;
  2078. /*
  2079.  * allocate from persistent map;
  2080.  */
  2081. if (maplock->flag & mlckALLOCXADLIST) {
  2082. xadlistlock = (struct xdlistlock *) maplock;
  2083. xad = xadlistlock->xdlist;
  2084. for (n = 0; n < xadlistlock->count; n++, xad++) {
  2085. if (xad->flag & (XAD_NEW | XAD_EXTENDED)) {
  2086. xaddr = addressXAD(xad);
  2087. xlen = lengthXAD(xad);
  2088. dbUpdatePMap(ipbmap, FALSE, xaddr,
  2089.      (s64) xlen, tblk);
  2090. xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
  2091. jFYI(1,
  2092.      ("allocPMap: xaddr:0x%lx xlen:%dn",
  2093.       (ulong) xaddr, xlen));
  2094. }
  2095. }
  2096. } else if (maplock->flag & mlckALLOCPXD) {
  2097. pxdlock = (struct pxd_lock *) maplock;
  2098. xaddr = addressPXD(&pxdlock->pxd);
  2099. xlen = lengthPXD(&pxdlock->pxd);
  2100. dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, tblk);
  2101. jFYI(1,
  2102.      ("allocPMap: xaddr:0x%lx xlen:%dn", (ulong) xaddr,
  2103.       xlen));
  2104. } else { /* (maplock->flag & mlckALLOCPXDLIST) */
  2105. pxdlistlock = (struct xdlistlock *) maplock;
  2106. pxd = pxdlistlock->xdlist;
  2107. for (n = 0; n < pxdlistlock->count; n++, pxd++) {
  2108. xaddr = addressPXD(pxd);
  2109. xlen = lengthPXD(pxd);
  2110. dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen,
  2111.      tblk);
  2112. jFYI(1,
  2113.      ("allocPMap: xaddr:0x%lx xlen:%dn",
  2114.       (ulong) xaddr, xlen));
  2115. }
  2116. }
  2117. }
  2118. /*
  2119.  *      txFreeMap()
  2120.  *
  2121.  * function:    free from persistent and/or working map;
  2122.  *
  2123.  * todo: optimization
  2124.  */
  2125. void txFreeMap(struct inode *ip,
  2126.        struct maplock * maplock, struct tblock * tblk, int maptype)
  2127. {
  2128. struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
  2129. struct xdlistlock *xadlistlock;
  2130. xad_t *xad;
  2131. s64 xaddr;
  2132. int xlen;
  2133. struct pxd_lock *pxdlock;
  2134. struct xdlistlock *pxdlistlock;
  2135. pxd_t *pxd;
  2136. int n;
  2137. jFYI(1,
  2138.      ("txFreeMap: tblk:0x%p maplock:0x%p maptype:0x%xn",
  2139.       tblk, maplock, maptype));
  2140. /*
  2141.  * free from persistent map;
  2142.  */
  2143. if (maptype == COMMIT_PMAP || maptype == COMMIT_PWMAP) {
  2144. if (maplock->flag & mlckFREEXADLIST) {
  2145. xadlistlock = (struct xdlistlock *) maplock;
  2146. xad = xadlistlock->xdlist;
  2147. for (n = 0; n < xadlistlock->count; n++, xad++) {
  2148. if (!(xad->flag & XAD_NEW)) {
  2149. xaddr = addressXAD(xad);
  2150. xlen = lengthXAD(xad);
  2151. dbUpdatePMap(ipbmap, TRUE, xaddr,
  2152.      (s64) xlen, tblk);
  2153. jFYI(1,
  2154.      ("freePMap: xaddr:0x%lx xlen:%dn",
  2155.       (ulong) xaddr, xlen));
  2156. }
  2157. }
  2158. } else if (maplock->flag & mlckFREEPXD) {
  2159. pxdlock = (struct pxd_lock *) maplock;
  2160. xaddr = addressPXD(&pxdlock->pxd);
  2161. xlen = lengthPXD(&pxdlock->pxd);
  2162. dbUpdatePMap(ipbmap, TRUE, xaddr, (s64) xlen,
  2163.      tblk);
  2164. jFYI(1,
  2165.      ("freePMap: xaddr:0x%lx xlen:%dn",
  2166.       (ulong) xaddr, xlen));
  2167. } else { /* (maplock->flag & mlckALLOCPXDLIST) */
  2168. pxdlistlock = (struct xdlistlock *) maplock;
  2169. pxd = pxdlistlock->xdlist;
  2170. for (n = 0; n < pxdlistlock->count; n++, pxd++) {
  2171. xaddr = addressPXD(pxd);
  2172. xlen = lengthPXD(pxd);
  2173. dbUpdatePMap(ipbmap, TRUE, xaddr,
  2174.      (s64) xlen, tblk);
  2175. jFYI(1,
  2176.      ("freePMap: xaddr:0x%lx xlen:%dn",
  2177.       (ulong) xaddr, xlen));
  2178. }
  2179. }
  2180. }
  2181. /*
  2182.  * free from working map;
  2183.  */
  2184. if (maptype == COMMIT_PWMAP || maptype == COMMIT_WMAP) {
  2185. if (maplock->flag & mlckFREEXADLIST) {
  2186. xadlistlock = (struct xdlistlock *) maplock;
  2187. xad = xadlistlock->xdlist;
  2188. for (n = 0; n < xadlistlock->count; n++, xad++) {
  2189. xaddr = addressXAD(xad);
  2190. xlen = lengthXAD(xad);
  2191. dbFree(ip, xaddr, (s64) xlen);
  2192. xad->flag = 0;
  2193. jFYI(1,
  2194.      ("freeWMap: xaddr:0x%lx xlen:%dn",
  2195.       (ulong) xaddr, xlen));
  2196. }
  2197. } else if (maplock->flag & mlckFREEPXD) {
  2198. pxdlock = (struct pxd_lock *) maplock;
  2199. xaddr = addressPXD(&pxdlock->pxd);
  2200. xlen = lengthPXD(&pxdlock->pxd);
  2201. dbFree(ip, xaddr, (s64) xlen);
  2202. jFYI(1,
  2203.      ("freeWMap: xaddr:0x%lx xlen:%dn",
  2204.       (ulong) xaddr, xlen));
  2205. } else { /* (maplock->flag & mlckFREEPXDLIST) */
  2206. pxdlistlock = (struct xdlistlock *) maplock;
  2207. pxd = pxdlistlock->xdlist;
  2208. for (n = 0; n < pxdlistlock->count; n++, pxd++) {
  2209. xaddr = addressPXD(pxd);
  2210. xlen = lengthPXD(pxd);
  2211. dbFree(ip, xaddr, (s64) xlen);
  2212. jFYI(1,
  2213.      ("freeWMap: xaddr:0x%lx xlen:%dn",
  2214.       (ulong) xaddr, xlen));
  2215. }
  2216. }
  2217. }
  2218. }
  2219. /*
  2220.  *      txFreelock()
  2221.  *
  2222.  * function:    remove tlock from inode anonymous locklist
  2223.  */
  2224. void txFreelock(struct inode *ip)
  2225. {
  2226. struct jfs_inode_info *jfs_ip = JFS_IP(ip);
  2227. struct tlock *xtlck, *tlck;
  2228. lid_t xlid = 0, lid;
  2229. if (!jfs_ip->atlhead)
  2230. return;
  2231. xtlck = (struct tlock *) &jfs_ip->atlhead;
  2232. while ((lid = xtlck->next)) {
  2233. tlck = lid_to_tlock(lid);
  2234. if (tlck->flag & tlckFREELOCK) {
  2235. xtlck->next = tlck->next;
  2236. txLockFree(lid);
  2237. } else {
  2238. xtlck = tlck;
  2239. xlid = lid;
  2240. }
  2241. }
  2242. if (jfs_ip->atlhead)
  2243. jfs_ip->atltail = xlid;
  2244. else {
  2245. jfs_ip->atltail = 0;
  2246. /*
  2247.  * If inode was on anon_list, remove it
  2248.  */
  2249. TXN_LOCK();
  2250. list_del_init(&jfs_ip->anon_inode_list);
  2251. TXN_UNLOCK();
  2252. }
  2253. }
  2254. /*
  2255.  *      txAbort()
  2256.  *
  2257.  * function: abort tx before commit;
  2258.  *
  2259.  * frees line-locks and segment locks for all
  2260.  * segments in comdata structure.
  2261.  * Optionally sets state of file-system to FM_DIRTY in super-block.
  2262.  * log age of page-frames in memory for which caller has
  2263.  * are reset to 0 (to avoid logwarap).
  2264.  */
  2265. void txAbort(tid_t tid, int dirty)
  2266. {
  2267. lid_t lid, next;
  2268. struct metapage *mp;
  2269. struct tblock *tblk = tid_to_tblock(tid);
  2270. jEVENT(1, ("txAbort: tid:%d dirty:0x%xn", tid, dirty));
  2271. /*
  2272.  * free tlocks of the transaction
  2273.  */
  2274. for (lid = tblk->next; lid; lid = next) {
  2275. next = lid_to_tlock(lid)->next;
  2276. mp = lid_to_tlock(lid)->mp;
  2277. if (mp) {
  2278. mp->lid = 0;
  2279. /*
  2280.  * reset lsn of page to avoid logwarap:
  2281.  *
  2282.  * (page may have been previously committed by another
  2283.  * transaction(s) but has not been paged, i.e.,
  2284.  * it may be on logsync list even though it has not
  2285.  * been logged for the current tx.)
  2286.  */
  2287. if (mp->xflag & COMMIT_PAGE && mp->lsn)
  2288. LogSyncRelease(mp);
  2289. }
  2290. /* insert tlock at head of freelist */
  2291. TXN_LOCK();
  2292. txLockFree(lid);
  2293. TXN_UNLOCK();
  2294. }
  2295. /* caller will free the transaction block */
  2296. tblk->next = tblk->last = 0;
  2297. /*
  2298.  * mark filesystem dirty
  2299.  */
  2300. if (dirty)
  2301. updateSuper(tblk->sb, FM_DIRTY);
  2302. return;
  2303. }
  2304. /*
  2305.  *      txAbortCommit()
  2306.  *
  2307.  * function: abort commit.
  2308.  *
  2309.  * frees tlocks of transaction; line-locks and segment locks for all
  2310.  * segments in comdata structure. frees malloc storage
  2311.  * sets state of file-system to FM_MDIRTY in super-block.
  2312.  * log age of page-frames in memory for which caller has
  2313.  * are reset to 0 (to avoid logwarap).
  2314.  */
  2315. void txAbortCommit(struct commit * cd, int exval)
  2316. {
  2317. struct tblock *tblk;
  2318. tid_t tid;
  2319. lid_t lid, next;
  2320. struct metapage *mp;
  2321. assert(exval == EIO || exval == ENOMEM);
  2322. jEVENT(1, ("txAbortCommit: cd:0x%pn", cd));
  2323. /*
  2324.  * free tlocks of the transaction
  2325.  */
  2326. tid = cd->tid;
  2327. tblk = tid_to_tblock(tid);
  2328. for (lid = tblk->next; lid; lid = next) {
  2329. next = lid_to_tlock(lid)->next;
  2330. mp = lid_to_tlock(lid)->mp;
  2331. if (mp) {
  2332. mp->lid = 0;
  2333. /*
  2334.  * reset lsn of page to avoid logwarap;
  2335.  */
  2336. if (mp->xflag & COMMIT_PAGE)
  2337. LogSyncRelease(mp);
  2338. }
  2339. /* insert tlock at head of freelist */
  2340. TXN_LOCK();
  2341. txLockFree(lid);
  2342. TXN_UNLOCK();
  2343. }
  2344. tblk->next = tblk->last = 0;
  2345. /* free the transaction block */
  2346. txEnd(tid);
  2347. /*
  2348.  * mark filesystem dirty
  2349.  */
  2350. updateSuper(cd->sb, FM_DIRTY);
  2351. }
  2352. /*
  2353.  *      txLazyCommit(void)
  2354.  *
  2355.  * All transactions except those changing ipimap (COMMIT_FORCE) are
  2356.  * processed by this routine.  This insures that the inode and block
  2357.  * allocation maps are updated in order.  For synchronous transactions,
  2358.  * let the user thread finish processing after txUpdateMap() is called.
  2359.  */
  2360. void txLazyCommit(struct tblock * tblk)
  2361. {
  2362. struct jfs_log *log;
  2363. while (((tblk->flag & tblkGC_READY) == 0) &&
  2364.        ((tblk->flag & tblkGC_UNLOCKED) == 0)) {
  2365. /* We must have gotten ahead of the user thread
  2366.  */
  2367. jFYI(1, ("txLazyCommit: tblk 0x%p not unlockedn", tblk));
  2368. schedule();
  2369. }
  2370. jFYI(1, ("txLazyCommit: processing tblk 0x%pn", tblk));
  2371. txUpdateMap(tblk);
  2372. log = (struct jfs_log *) JFS_SBI(tblk->sb)->log;
  2373. spin_lock_irq(&log->gclock); // LOGGC_LOCK
  2374. tblk->flag |= tblkGC_COMMITTED;
  2375. if ((tblk->flag & tblkGC_READY) || (tblk->flag & tblkGC_LAZY))
  2376. log->gcrtc--;
  2377. if (tblk->flag & tblkGC_READY)
  2378. wake_up(&tblk->gcwait); // LOGGC_WAKEUP
  2379. /*
  2380.  * Can't release log->gclock until we've tested tblk->flag
  2381.  */
  2382. if (tblk->flag & tblkGC_LAZY) {
  2383. spin_unlock_irq(&log->gclock); // LOGGC_UNLOCK
  2384. txUnlock(tblk);
  2385. tblk->flag &= ~tblkGC_LAZY;
  2386. txEnd(tblk - TxBlock); /* Convert back to tid */
  2387. } else
  2388. spin_unlock_irq(&log->gclock); // LOGGC_UNLOCK
  2389. jFYI(1, ("txLazyCommit: done: tblk = 0x%pn", tblk));
  2390. }
  2391. /*
  2392.  *      jfs_lazycommit(void)
  2393.  *
  2394.  * To be run as a kernel daemon.  If lbmIODone is called in an interrupt
  2395.  * context, or where blocking is not wanted, this routine will process
  2396.  * committed transactions from the unlock queue.
  2397.  */
  2398. int jfs_lazycommit(void *arg)
  2399. {
  2400. int WorkDone;
  2401. struct tblock *tblk;
  2402. unsigned long flags;
  2403. lock_kernel();
  2404. daemonize();
  2405. current->tty = NULL;
  2406. strcpy(current->comm, "jfsCommit");
  2407. unlock_kernel();
  2408. jfsCommitTask = current;
  2409. spin_lock_irq(&current->sigmask_lock);
  2410. sigfillset(&current->blocked);
  2411. recalc_sigpending(current);
  2412. spin_unlock_irq(&current->sigmask_lock);
  2413. LAZY_LOCK_INIT();
  2414. TxAnchor.unlock_queue = TxAnchor.unlock_tail = 0;
  2415. complete(&jfsIOwait);
  2416. do {
  2417. DECLARE_WAITQUEUE(wq, current);
  2418. LAZY_LOCK(flags);
  2419. restart:
  2420. WorkDone = 0;
  2421. while ((tblk = TxAnchor.unlock_queue)) {
  2422. /*
  2423.  * We can't get ahead of user thread.  Spinning is
  2424.  * simpler than blocking/waking.  We shouldn't spin
  2425.  * very long, since user thread shouldn't be blocking
  2426.  * between lmGroupCommit & txEnd.
  2427.  */
  2428. WorkDone = 1;
  2429. /*
  2430.  * Remove first transaction from queue
  2431.  */
  2432. TxAnchor.unlock_queue = tblk->cqnext;
  2433. tblk->cqnext = 0;
  2434. if (TxAnchor.unlock_tail == tblk)
  2435. TxAnchor.unlock_tail = 0;
  2436. LAZY_UNLOCK(flags);
  2437. txLazyCommit(tblk);
  2438. /*
  2439.  * We can be running indefinately if other processors
  2440.  * are adding transactions to this list
  2441.  */
  2442. cond_resched();
  2443. LAZY_LOCK(flags);
  2444. }
  2445. if (WorkDone)
  2446. goto restart;
  2447. add_wait_queue(&jfs_commit_thread_wait, &wq);
  2448. set_current_state(TASK_INTERRUPTIBLE);
  2449. LAZY_UNLOCK(flags);
  2450. schedule();
  2451. current->state = TASK_RUNNING;
  2452. remove_wait_queue(&jfs_commit_thread_wait, &wq);
  2453. } while (!jfs_stop_threads);
  2454. if (TxAnchor.unlock_queue)
  2455. jERROR(1, ("jfs_lazycommit being killed with pending transactions!n"));
  2456. else
  2457. jFYI(1, ("jfs_lazycommit being killedn"));
  2458. complete(&jfsIOwait);
  2459. return 0;
  2460. }
  2461. void txLazyUnlock(struct tblock * tblk)
  2462. {
  2463. unsigned long flags;
  2464. LAZY_LOCK(flags);
  2465. if (TxAnchor.unlock_tail)
  2466. TxAnchor.unlock_tail->cqnext = tblk;
  2467. else
  2468. TxAnchor.unlock_queue = tblk;
  2469. TxAnchor.unlock_tail = tblk;
  2470. tblk->cqnext = 0;
  2471. LAZY_UNLOCK(flags);
  2472. wake_up(&jfs_commit_thread_wait);
  2473. }
  2474. static void LogSyncRelease(struct metapage * mp)
  2475. {
  2476. struct jfs_log *log = mp->log;
  2477. assert(atomic_read(&mp->nohomeok));
  2478. assert(log);
  2479. atomic_dec(&mp->nohomeok);
  2480. if (atomic_read(&mp->nohomeok))
  2481. return;
  2482. hold_metapage(mp, 0);
  2483. LOGSYNC_LOCK(log);
  2484. mp->log = NULL;
  2485. mp->lsn = 0;
  2486. mp->clsn = 0;
  2487. log->count--;
  2488. list_del_init(&mp->synclist);
  2489. LOGSYNC_UNLOCK(log);
  2490. release_metapage(mp);
  2491. }
  2492. /*
  2493.  * txQuiesce
  2494.  *
  2495.  * Block all new transactions and push anonymous transactions to
  2496.  * completion
  2497.  *
  2498.  * This does almost the same thing as jfs_sync below.  We don't
  2499.  * worry about deadlocking when TlocksLow is set, since we would
  2500.  * expect jfs_sync to get us out of that jam.
  2501.  */
  2502. void txQuiesce(struct super_block *sb)
  2503. {
  2504. struct inode *ip;
  2505. struct jfs_inode_info *jfs_ip;
  2506. struct jfs_log *log = JFS_SBI(sb)->log;
  2507. int rc;
  2508. tid_t tid;
  2509. set_bit(log_QUIESCE, &log->flag);
  2510. TXN_LOCK();
  2511. restart:
  2512. while (!list_empty(&TxAnchor.anon_list)) {
  2513. jfs_ip = list_entry(TxAnchor.anon_list.next,
  2514.     struct jfs_inode_info,
  2515.     anon_inode_list);
  2516. ip = jfs_ip->inode;
  2517. /*
  2518.  * inode will be removed from anonymous list
  2519.  * when it is committed
  2520.  */
  2521. TXN_UNLOCK();
  2522. tid = txBegin(ip->i_sb, COMMIT_INODE | COMMIT_FORCE);
  2523. down(&jfs_ip->commit_sem);
  2524. rc = txCommit(tid, 1, &ip, 0);
  2525. txEnd(tid);
  2526. up(&jfs_ip->commit_sem);
  2527. /*
  2528.  * Just to be safe.  I don't know how
  2529.  * long we can run without blocking
  2530.  */
  2531. cond_resched();
  2532. TXN_LOCK();
  2533. }
  2534. /*
  2535.  * If jfs_sync is running in parallel, there could be some inodes
  2536.  * on anon_list2.  Let's check.
  2537.  */
  2538. if (!list_empty(&TxAnchor.anon_list2)) {
  2539. list_splice(&TxAnchor.anon_list2, &TxAnchor.anon_list);
  2540. INIT_LIST_HEAD(&TxAnchor.anon_list2);
  2541. goto restart;
  2542. }
  2543. TXN_UNLOCK();
  2544. }
  2545. /*
  2546.  * txResume()
  2547.  *
  2548.  * Allows transactions to start again following txQuiesce
  2549.  */
  2550. void txResume(struct super_block *sb)
  2551. {
  2552. struct jfs_log *log = JFS_SBI(sb)->log;
  2553. clear_bit(log_QUIESCE, &log->flag);
  2554. TXN_WAKEUP(&log->syncwait);
  2555. }
  2556. /*
  2557.  *      jfs_sync(void)
  2558.  *
  2559.  * To be run as a kernel daemon.  This is awakened when tlocks run low.
  2560.  * We write any inodes that have anonymous tlocks so they will become
  2561.  * available.
  2562.  */
  2563. int jfs_sync(void *arg)
  2564. {
  2565. struct inode *ip;
  2566. struct jfs_inode_info *jfs_ip;
  2567. int rc;
  2568. tid_t tid;
  2569. lock_kernel();
  2570. daemonize();
  2571. current->tty = NULL;
  2572. strcpy(current->comm, "jfsSync");
  2573. unlock_kernel();
  2574. spin_lock_irq(&current->sigmask_lock);
  2575. sigfillset(&current->blocked);
  2576. recalc_sigpending(current);
  2577. spin_unlock_irq(&current->sigmask_lock);
  2578. complete(&jfsIOwait);
  2579. do {
  2580. DECLARE_WAITQUEUE(wq, current);
  2581. /*
  2582.  * write each inode on the anonymous inode list
  2583.  */
  2584. TXN_LOCK();
  2585. while (TlocksLow && !list_empty(&TxAnchor.anon_list)) {
  2586. jfs_ip = list_entry(TxAnchor.anon_list.next,
  2587.     struct jfs_inode_info,
  2588.     anon_inode_list);
  2589. ip = jfs_ip->inode;
  2590. /*
  2591.  * down_trylock returns 0 on success.  This is
  2592.  * inconsistent with spin_trylock.
  2593.  */
  2594. if (! down_trylock(&jfs_ip->commit_sem)) {
  2595. /*
  2596.  * inode will be removed from anonymous list
  2597.  * when it is committed
  2598.  */
  2599. TXN_UNLOCK();
  2600. tid = txBegin(ip->i_sb,
  2601.       COMMIT_INODE | COMMIT_FORCE);
  2602. rc = txCommit(tid, 1, &ip, 0);
  2603. txEnd(tid);
  2604. up(&jfs_ip->commit_sem);
  2605. /*
  2606.  * Just to be safe.  I don't know how
  2607.  * long we can run without blocking
  2608.  */
  2609. cond_resched();
  2610. TXN_LOCK();
  2611. } else {
  2612. /* We can't get the commit semaphore.  It may
  2613.  * be held by a thread waiting for tlock's
  2614.  * so let's not block here.  Save it to
  2615.  * put back on the anon_list.
  2616.  */
  2617. /* Take off anon_list */
  2618. list_del(&jfs_ip->anon_inode_list);
  2619. /* Put on anon_list2 */
  2620. list_add(&jfs_ip->anon_inode_list,
  2621.  &TxAnchor.anon_list2);
  2622. }
  2623. }
  2624. /* Add anon_list2 back to anon_list */
  2625. if (!list_empty(&TxAnchor.anon_list2)) {
  2626. list_splice(&TxAnchor.anon_list2, &TxAnchor.anon_list);
  2627. INIT_LIST_HEAD(&TxAnchor.anon_list2);
  2628. }
  2629. add_wait_queue(&jfs_sync_thread_wait, &wq);
  2630. set_current_state(TASK_INTERRUPTIBLE);
  2631. TXN_UNLOCK();
  2632. schedule();
  2633. current->state = TASK_RUNNING;
  2634. remove_wait_queue(&jfs_sync_thread_wait, &wq);
  2635. } while (!jfs_stop_threads);
  2636. jFYI(1, ("jfs_sync being killedn"));
  2637. complete(&jfsIOwait);
  2638. return 0;
  2639. }
  2640. #if defined(CONFIG_PROC_FS) && defined(CONFIG_JFS_DEBUG)
  2641. int jfs_txanchor_read(char *buffer, char **start, off_t offset, int length,
  2642.       int *eof, void *data)
  2643. {
  2644. int len = 0;
  2645. off_t begin;
  2646. char *freewait;
  2647. char *freelockwait;
  2648. char *lowlockwait;
  2649. freewait =
  2650.     waitqueue_active(&TxAnchor.freewait) ? "active" : "empty";
  2651. freelockwait =
  2652.     waitqueue_active(&TxAnchor.freelockwait) ? "active" : "empty";
  2653. lowlockwait =
  2654.     waitqueue_active(&TxAnchor.lowlockwait) ? "active" : "empty";
  2655. len += sprintf(buffer,
  2656.        "JFS TxAnchorn"
  2657.        "============n"
  2658.        "freetid = %dn"
  2659.        "freewait = %sn"
  2660.        "freelock = %dn"
  2661.        "freelockwait = %sn"
  2662.        "lowlockwait = %sn"
  2663.        "tlocksInUse = %dn"
  2664.        "unlock_queue = 0x%pn"
  2665.        "unlock_tail = 0x%pn",
  2666.        TxAnchor.freetid,
  2667.        freewait,
  2668.        TxAnchor.freelock,
  2669.        freelockwait,
  2670.        lowlockwait,
  2671.        TxAnchor.tlocksInUse,
  2672.        TxAnchor.unlock_queue,
  2673.        TxAnchor.unlock_tail);
  2674. begin = offset;
  2675. *start = buffer + begin;
  2676. len -= begin;
  2677. if (len > length)
  2678. len = length;
  2679. else
  2680. *eof = 1;
  2681. if (len < 0)
  2682. len = 0;
  2683. return len;
  2684. }
  2685. #endif