kill I_LOCK
[safe/jmp/linux-2.6] / fs / jfs / jfs_txnmgr.c
index b660c93..d945ea7 100644 (file)
@@ -4,21 +4,21 @@
  *
  *   This program is free software;  you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
- *   the Free Software Foundation; either version 2 of the License, or 
+ *   the Free Software Foundation; either version 2 of the License, or
  *   (at your option) any later version.
- * 
+ *
  *   This program is distributed in the hope that it will be useful,
  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  *   the GNU General Public License for more details.
  *
  *   You should have received a copy of the GNU General Public License
- *   along with this program;  if not, write to the Free Software 
+ *   along with this program;  if not, write to the Free Software
  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  */
 
 /*
- *      jfs_txnmgr.c: transaction manager
+ *     jfs_txnmgr.c: transaction manager
  *
  * notes:
  * transaction starts with txBegin() and ends with txCommit()
 
 #include <linux/fs.h>
 #include <linux/vmalloc.h>
-#include <linux/smp_lock.h>
 #include <linux/completion.h>
-#include <linux/suspend.h>
+#include <linux/freezer.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
+#include <linux/kthread.h>
+#include <linux/seq_file.h>
 #include "jfs_incore.h"
 #include "jfs_inode.h"
 #include "jfs_filsys.h"
@@ -60,7 +61,7 @@
 #include "jfs_debug.h"
 
 /*
- *      transaction management structures
+ *     transaction management structures
  */
 static struct {
        int freetid;            /* index of a free tid structure */
@@ -103,26 +104,25 @@ module_param(nTxLock, int, 0);
 MODULE_PARM_DESC(nTxLock,
                 "Number of transaction locks (max:65536)");
 
-struct tblock *TxBlock;                /* transaction block table */
-static int TxLockLWM;          /* Low water mark for number of txLocks used */
-static int TxLockHWM;          /* High water mark for number of txLocks used */
-static int TxLockVHWM;         /* Very High water mark */
-struct tlock *TxLock;           /* transaction lock table */
+struct tblock *TxBlock;        /* transaction block table */
+static int TxLockLWM;  /* Low water mark for number of txLocks used */
+static int TxLockHWM;  /* High water mark for number of txLocks used */
+static int TxLockVHWM; /* Very High water mark */
+struct tlock *TxLock;  /* transaction lock table */
 
 /*
- *      transaction management lock
+ *     transaction management lock
  */
 static DEFINE_SPINLOCK(jfsTxnLock);
 
-#define TXN_LOCK()              spin_lock(&jfsTxnLock)
-#define TXN_UNLOCK()            spin_unlock(&jfsTxnLock)
+#define TXN_LOCK()             spin_lock(&jfsTxnLock)
+#define TXN_UNLOCK()           spin_unlock(&jfsTxnLock)
 
 #define LAZY_LOCK_INIT()       spin_lock_init(&TxAnchor.LazyLock);
 #define LAZY_LOCK(flags)       spin_lock_irqsave(&TxAnchor.LazyLock, flags)
 #define LAZY_UNLOCK(flags) spin_unlock_irqrestore(&TxAnchor.LazyLock, flags)
 
-DECLARE_WAIT_QUEUE_HEAD(jfs_sync_thread_wait);
-DECLARE_WAIT_QUEUE_HEAD(jfs_commit_thread_wait);
+static DECLARE_WAIT_QUEUE_HEAD(jfs_commit_thread_wait);
 static int jfs_commit_thread_waking;
 
 /*
@@ -135,8 +135,8 @@ static inline void TXN_SLEEP_DROP_LOCK(wait_queue_head_t * event)
        add_wait_queue(event, &wait);
        set_current_state(TASK_UNINTERRUPTIBLE);
        TXN_UNLOCK();
-       schedule();
-       current->state = TASK_RUNNING;
+       io_schedule();
+       __set_current_state(TASK_RUNNING);
        remove_wait_queue(event, &wait);
 }
 
@@ -149,7 +149,7 @@ static inline void TXN_SLEEP_DROP_LOCK(wait_queue_head_t * event)
 #define TXN_WAKEUP(event) wake_up_all(event)
 
 /*
- *      statistics
+ *     statistics
  */
 static struct {
        tid_t maxtid;           /* 4: biggest tid ever used */
@@ -182,8 +182,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
 static void LogSyncRelease(struct metapage * mp);
 
 /*
- *              transaction block/lock management
- *              ---------------------------------
+ *             transaction block/lock management
+ *             ---------------------------------
  */
 
 /*
@@ -207,7 +207,7 @@ static lid_t txLockAlloc(void)
        if ((++TxAnchor.tlocksInUse > TxLockHWM) && (jfs_tlocks_low == 0)) {
                jfs_info("txLockAlloc tlocks low");
                jfs_tlocks_low = 1;
-               wake_up(&jfs_sync_thread_wait);
+               wake_up_process(jfsSyncThread);
        }
 
        return lid;
@@ -228,9 +228,9 @@ static void txLockFree(lid_t lid)
 }
 
 /*
- * NAME:        txInit()
+ * NAME:       txInit()
  *
- * FUNCTION:    initialize transaction management structures
+ * FUNCTION:   initialize transaction management structures
  *
  * RETURN:
  *
@@ -282,7 +282,7 @@ int txInit(void)
        TxLockVHWM = (nTxLock * 8) / 10;
 
        size = sizeof(struct tblock) * nTxBlock;
-       TxBlock = (struct tblock *) vmalloc(size);
+       TxBlock = vmalloc(size);
        if (TxBlock == NULL)
                return -ENOMEM;
 
@@ -307,7 +307,7 @@ int txInit(void)
         * tlock id = 0 is reserved.
         */
        size = sizeof(struct tlock) * nTxLock;
-       TxLock = (struct tlock *) vmalloc(size);
+       TxLock = vmalloc(size);
        if (TxLock == NULL) {
                vfree(TxBlock);
                return -ENOMEM;
@@ -334,9 +334,9 @@ int txInit(void)
 }
 
 /*
- * NAME:        txExit()
+ * NAME:       txExit()
  *
- * FUNCTION:    clean up when module is unloaded
+ * FUNCTION:   clean up when module is unloaded
  */
 void txExit(void)
 {
@@ -347,12 +347,12 @@ void txExit(void)
 }
 
 /*
- * NAME:        txBegin()
+ * NAME:       txBegin()
  *
- * FUNCTION:    start a transaction.
+ * FUNCTION:   start a transaction.
  *
- * PARAMETER:   sb     - superblock
- *              flag   - force for nested tx;
+ * PARAMETER:  sb      - superblock
+ *             flag    - force for nested tx;
  *
  * RETURN:     tid     - transaction id
  *
@@ -448,13 +448,13 @@ tid_t txBegin(struct super_block *sb, int flag)
 }
 
 /*
- * NAME:        txBeginAnon()
+ * NAME:       txBeginAnon()
  *
- * FUNCTION:    start an anonymous transaction.
+ * FUNCTION:   start an anonymous transaction.
  *             Blocks if logsync or available tlocks are low to prevent
  *             anonymous tlocks from depleting supply.
  *
- * PARAMETER:   sb     - superblock
+ * PARAMETER:  sb      - superblock
  *
  * RETURN:     none
  */
@@ -490,11 +490,11 @@ void txBeginAnon(struct super_block *sb)
 }
 
 /*
- *      txEnd()
+ *     txEnd()
  *
  * function: free specified transaction block.
  *
- *      logsync barrier processing:
+ *     logsync barrier processing:
  *
  * serialization:
  */
@@ -578,13 +578,13 @@ wakeup:
 }
 
 /*
- *      txLock()
+ *     txLock()
  *
  * function: acquire a transaction lock on the specified <mp>
  *
  * parameter:
  *
- * return:      transaction lock id
+ * return:     transaction lock id
  *
  * serialization:
  */
@@ -830,19 +830,23 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
        /* Only locks on ipimap or ipaimap should reach here */
        /* assert(jfs_ip->fileset == AGGREGATE_I); */
        if (jfs_ip->fileset != AGGREGATE_I) {
-               jfs_err("txLock: trying to lock locked page!");
-               dump_mem("ip", ip, sizeof(struct inode));
-               dump_mem("mp", mp, sizeof(struct metapage));
-               dump_mem("Locker's tblk", tid_to_tblock(tid),
-                        sizeof(struct tblock));
-               dump_mem("Tlock", tlck, sizeof(struct tlock));
+               printk(KERN_ERR "txLock: trying to lock locked page!");
+               print_hex_dump(KERN_ERR, "ip: ", DUMP_PREFIX_ADDRESS, 16, 4,
+                              ip, sizeof(*ip), 0);
+               print_hex_dump(KERN_ERR, "mp: ", DUMP_PREFIX_ADDRESS, 16, 4,
+                              mp, sizeof(*mp), 0);
+               print_hex_dump(KERN_ERR, "Locker's tblock: ",
+                              DUMP_PREFIX_ADDRESS, 16, 4, tid_to_tblock(tid),
+                              sizeof(struct tblock), 0);
+               print_hex_dump(KERN_ERR, "Tlock: ", DUMP_PREFIX_ADDRESS, 16, 4,
+                              tlck, sizeof(*tlck), 0);
                BUG();
        }
        INCREMENT(stattx.waitlock);     /* statistics */
        TXN_UNLOCK();
        release_metapage(mp);
        TXN_LOCK();
-       xtid = tlck->tid;       /* reaquire after dropping TXN_LOCK */
+       xtid = tlck->tid;       /* reacquire after dropping TXN_LOCK */
 
        jfs_info("txLock: in waitLock, tid = %d, xtid = %d, lid = %d",
                 tid, xtid, lid);
@@ -858,17 +862,17 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
 }
 
 /*
- * NAME:        txRelease()
+ * NAME:       txRelease()
  *
- * FUNCTION:    Release buffers associated with transaction locks, but don't
+ * FUNCTION:   Release buffers associated with transaction locks, but don't
  *             mark homeok yet.  The allows other transactions to modify
  *             buffers, but won't let them go to disk until commit record
  *             actually gets written.
  *
  * PARAMETER:
- *              tblk    -
+ *             tblk    -
  *
- * RETURN:      Errors from subroutines.
+ * RETURN:     Errors from subroutines.
  */
 static void txRelease(struct tblock * tblk)
 {
@@ -897,10 +901,10 @@ static void txRelease(struct tblock * tblk)
 }
 
 /*
- * NAME:        txUnlock()
+ * NAME:       txUnlock()
  *
- * FUNCTION:    Initiates pageout of pages modified by tid in journalled
- *              objects and frees their lockwords.
+ * FUNCTION:   Initiates pageout of pages modified by tid in journalled
+ *             objects and frees their lockwords.
  */
 static void txUnlock(struct tblock * tblk)
 {
@@ -984,10 +988,10 @@ static void txUnlock(struct tblock * tblk)
 }
 
 /*
- *      txMaplock()
+ *     txMaplock()
  *
  * function: allocate a transaction lock for freed page/entry;
- *      for freed page, maplock is used as xtlock/dtlock type;
+ *     for freed page, maplock is used as xtlock/dtlock type;
  */
 struct tlock *txMaplock(tid_t tid, struct inode *ip, int type)
 {
@@ -1058,7 +1062,7 @@ struct tlock *txMaplock(tid_t tid, struct inode *ip, int type)
 }
 
 /*
- *      txLinelock()
+ *     txLinelock()
  *
  * function: allocate a transaction lock for log vector list
  */
@@ -1093,39 +1097,39 @@ struct linelock *txLinelock(struct linelock * tlock)
 }
 
 /*
- *              transaction commit management
- *              -----------------------------
+ *             transaction commit management
+ *             -----------------------------
  */
 
 /*
- * NAME:        txCommit()
- *
- * FUNCTION:    commit the changes to the objects specified in
- *              clist.  For journalled segments only the
- *              changes of the caller are committed, ie by tid.
- *              for non-journalled segments the data are flushed to
- *              disk and then the change to the disk inode and indirect
- *              blocks committed (so blocks newly allocated to the
- *              segment will be made a part of the segment atomically).
- *
- *              all of the segments specified in clist must be in
- *              one file system. no more than 6 segments are needed
- *              to handle all unix svcs.
- *
- *              if the i_nlink field (i.e. disk inode link count)
- *              is zero, and the type of inode is a regular file or
- *              directory, or symbolic link , the inode is truncated
- *              to zero length. the truncation is committed but the
- *              VM resources are unaffected until it is closed (see
- *              iput and iclose).
+ * NAME:       txCommit()
+ *
+ * FUNCTION:   commit the changes to the objects specified in
+ *             clist.  For journalled segments only the
+ *             changes of the caller are committed, ie by tid.
+ *             for non-journalled segments the data are flushed to
+ *             disk and then the change to the disk inode and indirect
+ *             blocks committed (so blocks newly allocated to the
+ *             segment will be made a part of the segment atomically).
+ *
+ *             all of the segments specified in clist must be in
+ *             one file system. no more than 6 segments are needed
+ *             to handle all unix svcs.
+ *
+ *             if the i_nlink field (i.e. disk inode link count)
+ *             is zero, and the type of inode is a regular file or
+ *             directory, or symbolic link , the inode is truncated
+ *             to zero length. the truncation is committed but the
+ *             VM resources are unaffected until it is closed (see
+ *             iput and iclose).
  *
  * PARAMETER:
  *
  * RETURN:
  *
  * serialization:
- *              on entry the inode lock on each segment is assumed
- *              to be held.
+ *             on entry the inode lock on each segment is assumed
+ *             to be held.
  *
  * i/o error:
  */
@@ -1176,7 +1180,7 @@ int txCommit(tid_t tid,           /* transaction identifier */
        if ((flag & (COMMIT_FORCE | COMMIT_SYNC)) == 0)
                tblk->xflag |= COMMIT_LAZY;
        /*
-        *      prepare non-journaled objects for commit
+        *      prepare non-journaled objects for commit
         *
         * flush data pages of non-journaled file
         * to prevent the file getting non-initialized disk blocks
@@ -1187,7 +1191,7 @@ int txCommit(tid_t tid,           /* transaction identifier */
        cd.nip = nip;
 
        /*
-        *      acquire transaction lock on (on-disk) inodes
+        *      acquire transaction lock on (on-disk) inodes
         *
         * update on-disk inode from in-memory inode
         * acquiring transaction locks for AFTER records
@@ -1231,10 +1235,8 @@ int txCommit(tid_t tid,          /* transaction identifier */
                 * when we don't need to worry about it at all.
                 *
                 * if ((!S_ISDIR(ip->i_mode))
-                *    && (tblk->flag & COMMIT_DELETE) == 0) {
-                *      filemap_fdatawrite(ip->i_mapping);
-                *      filemap_fdatawait(ip->i_mapping);
-                * }
+                *    && (tblk->flag & COMMIT_DELETE) == 0)
+                *      filemap_write_and_wait(ip->i_mapping);
                 */
 
                /*
@@ -1265,7 +1267,7 @@ int txCommit(tid_t tid,           /* transaction identifier */
        }
 
        /*
-        *      write log records from transaction locks
+        *      write log records from transaction locks
         *
         * txUpdateMap() resets XAD_NEW in XAD.
         */
@@ -1288,7 +1290,14 @@ int txCommit(tid_t tid,          /* transaction identifier */
                 * commit the transaction synchronously, so the last iput
                 * will be done by the calling thread (or later)
                 */
-               if (tblk->u.ip->i_state & I_LOCK)
+               /*
+                * I believe this code is no longer needed.  Splitting I_LOCK
+                * into two bits, I_NEW and I_SYNC should prevent this
+                * deadlock as well.  But since I don't have a JFS testload
+                * to verify this, only a trivial s/I_LOCK/I_SYNC/ was done.
+                * Joern
+                */
+               if (tblk->u.ip->i_state & I_SYNC)
                        tblk->xflag &= ~COMMIT_LAZY;
        }
 
@@ -1297,7 +1306,7 @@ int txCommit(tid_t tid,           /* transaction identifier */
                !test_cflag(COMMIT_Nolink, tblk->u.ip)));
 
        /*
-        *      write COMMIT log record
+        *      write COMMIT log record
         */
        lrd->type = cpu_to_le16(LOG_COMMIT);
        lrd->length = 0;
@@ -1306,7 +1315,7 @@ int txCommit(tid_t tid,           /* transaction identifier */
        lmGroupCommit(log, tblk);
 
        /*
-        *      - transaction is now committed -
+        *      - transaction is now committed -
         */
 
        /*
@@ -1317,11 +1326,11 @@ int txCommit(tid_t tid,         /* transaction identifier */
                txForce(tblk);
 
        /*
-        *      update allocation map.
+        *      update allocation map.
         *
         * update inode allocation map and inode:
         * free pager lock on memory object of inode if any.
-        * update  block allocation map.
+        * update block allocation map.
         *
         * txUpdateMap() resets XAD_NEW in XAD.
         */
@@ -1329,7 +1338,7 @@ int txCommit(tid_t tid,           /* transaction identifier */
                txUpdateMap(tblk);
 
        /*
-        *      free transaction locks and pageout/free pages
+        *      free transaction locks and pageout/free pages
         */
        txRelease(tblk);
 
@@ -1338,7 +1347,7 @@ int txCommit(tid_t tid,           /* transaction identifier */
 
 
        /*
-        *      reset in-memory object state
+        *      reset in-memory object state
         */
        for (k = 0; k < cd.nip; k++) {
                ip = cd.iplist[k];
@@ -1361,11 +1370,11 @@ int txCommit(tid_t tid,         /* transaction identifier */
 }
 
 /*
- * NAME:        txLog()
+ * NAME:       txLog()
  *
- * FUNCTION:    Writes AFTER log records for all lines modified
- *              by tid for segments specified by inodes in comdata.
- *              Code assumes only WRITELOCKS are recorded in lockwords.
+ * FUNCTION:   Writes AFTER log records for all lines modified
+ *             by tid for segments specified by inodes in comdata.
+ *             Code assumes only WRITELOCKS are recorded in lockwords.
  *
  * PARAMETERS:
  *
@@ -1424,12 +1433,12 @@ static int txLog(struct jfs_log * log, struct tblock * tblk, struct commit * cd)
 }
 
 /*
- *      diLog()
+ *     diLog()
  *
- * function:    log inode tlock and format maplock to update bmap;
+ * function:   log inode tlock and format maplock to update bmap;
  */
 static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
-         struct tlock * tlck, struct commit * cd)
+                struct tlock * tlck, struct commit * cd)
 {
        int rc = 0;
        struct metapage *mp;
@@ -1445,7 +1454,7 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        pxd = &lrd->log.redopage.pxd;
 
        /*
-        *      inode after image
+        *      inode after image
         */
        if (tlck->type & tlckENTRY) {
                /* log after-image for logredo(): */
@@ -1459,7 +1468,7 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                tlck->flag |= tlckWRITEPAGE;
        } else if (tlck->type & tlckFREE) {
                /*
-                *      free inode extent
+                *      free inode extent
                 *
                 * (pages of the freed inode extent have been invalidated and
                 * a maplock for free of the extent has been formatted at
@@ -1501,7 +1510,7 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                jfs_err("diLog: UFO type tlck:0x%p", tlck);
 #ifdef  _JFS_WIP
        /*
-        *      alloc/free external EA extent
+        *      alloc/free external EA extent
         *
         * a maplock for txUpdateMap() to update bPWMAP for alloc/free
         * of the extent has been formatted at txLock() time;
@@ -1537,9 +1546,9 @@ static int diLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
 }
 
 /*
- *      dataLog()
+ *     dataLog()
  *
- * function:    log data tlock
+ * function:   log data tlock
  */
 static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
            struct tlock * tlck)
@@ -1583,9 +1592,9 @@ static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
 }
 
 /*
- *      dtLog()
+ *     dtLog()
  *
- * function:    log dtree tlock and format maplock to update bmap;
+ * function:   log dtree tlock and format maplock to update bmap;
  */
 static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
           struct tlock * tlck)
@@ -1606,10 +1615,10 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT);
 
        /*
-        *      page extension via relocation: entry insertion;
-        *      page extension in-place: entry insertion;
-        *      new right page from page split, reinitialized in-line
-        *      root from root page split: entry insertion;
+        *      page extension via relocation: entry insertion;
+        *      page extension in-place: entry insertion;
+        *      new right page from page split, reinitialized in-line
+        *      root from root page split: entry insertion;
         */
        if (tlck->type & (tlckNEW | tlckEXTEND)) {
                /* log after-image of the new page for logredo():
@@ -1644,8 +1653,8 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        }
 
        /*
-        *      entry insertion/deletion,
-        *      sibling page link update (old right page before split);
+        *      entry insertion/deletion,
+        *      sibling page link update (old right page before split);
         */
        if (tlck->type & (tlckENTRY | tlckRELINK)) {
                /* log after-image for logredo(): */
@@ -1661,11 +1670,11 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        }
 
        /*
-        *      page deletion: page has been invalidated
-        *      page relocation: source extent
+        *      page deletion: page has been invalidated
+        *      page relocation: source extent
         *
-        *      a maplock for free of the page has been formatted
-        *      at txLock() time);
+        *      a maplock for free of the page has been formatted
+        *      at txLock() time);
         */
        if (tlck->type & (tlckFREE | tlckRELOCATE)) {
                /* log LOG_NOREDOPAGE of the deleted page for logredo()
@@ -1686,9 +1695,9 @@ static void dtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
 }
 
 /*
- *      xtLog()
+ *     xtLog()
  *
- * function:    log xtree tlock and format maplock to update bmap;
+ * function:   log xtree tlock and format maplock to update bmap;
  */
 static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
           struct tlock * tlck)
@@ -1728,8 +1737,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        xadlock = (struct xdlistlock *) maplock;
 
        /*
-        *      entry insertion/extension;
-        *      sibling page link update (old right page before split);
+        *      entry insertion/extension;
+        *      sibling page link update (old right page before split);
         */
        if (tlck->type & (tlckNEW | tlckGROW | tlckRELINK)) {
                /* log after-image for logredo():
@@ -1804,7 +1813,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        }
 
        /*
-        *      page deletion: file deletion/truncation (ref. xtTruncate())
+        *      page deletion: file deletion/truncation (ref. xtTruncate())
         *
         * (page will be invalidated after log is written and bmap
         * is updated from the page);
@@ -1911,17 +1920,18 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        }
 
        /*
-        *      page/entry truncation: file truncation (ref. xtTruncate())
+        *      page/entry truncation: file truncation (ref. xtTruncate())
         *
-        *     |----------+------+------+---------------|
-        *                |      |      |
-        *                |      |     hwm - hwm before truncation
-        *                |     next - truncation point
-        *               lwm - lwm before truncation
+        *      |----------+------+------+---------------|
+        *                 |      |      |
+        *                 |      |     hwm - hwm before truncation
+        *                 |     next - truncation point
+        *                lwm - lwm before truncation
         * header ?
         */
        if (tlck->type & tlckTRUNCATE) {
-               pxd_t pxd;      /* truncated extent of xad */
+               /* This odd declaration suppresses a bogus gcc warning */
+               pxd_t pxd = pxd;        /* truncated extent of xad */
                int twm;
 
                /*
@@ -1939,7 +1949,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                twm = xtlck->twm.offset;
 
                /*
-                *      write log records
+                *      write log records
                 */
                /* log after-image for logredo():
                 *
@@ -1999,7 +2009,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                }
 
                /*
-                *      format maplock(s) for txUpdateMap() to update bmap
+                *      format maplock(s) for txUpdateMap() to update bmap
                 */
                maplock->index = 0;
 
@@ -2028,8 +2038,6 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                 * truncate entry XAD[twm == next - 1]:
                 */
                if (twm == next - 1) {
-                       struct pxd_lock *pxdlock;
-
                        /* format a maplock for txUpdateMap() to update bmap
                         * to free truncated delta extent of the truncated
                         * entry XAD[next - 1];
@@ -2073,9 +2081,9 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
 }
 
 /*
- *      mapLog()
+ *     mapLog()
  *
- * function:    log from maplock of freed data extents;
+ * function:   log from maplock of freed data extents;
  */
 static void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
                   struct tlock * tlck)
@@ -2085,7 +2093,7 @@ static void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
        pxd_t *pxd;
 
        /*
-        *      page relocation: free the source page extent
+        *      page relocation: free the source page extent
         *
         * a maplock for txUpdateMap() for free of the page
         * has been formatted at txLock() time saving the src
@@ -2159,10 +2167,10 @@ static void mapLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
 }
 
 /*
- *      txEA()
+ *     txEA()
  *
- * function:    acquire maplock for EA/ACL extents or
- *              set COMMIT_INLINE flag;
+ * function:   acquire maplock for EA/ACL extents or
+ *             set COMMIT_INLINE flag;
  */
 void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea)
 {
@@ -2211,10 +2219,10 @@ void txEA(tid_t tid, struct inode *ip, dxd_t * oldea, dxd_t * newea)
 }
 
 /*
- *      txForce()
+ *     txForce()
  *
  * function: synchronously write pages locked by transaction
- *              after txLog() but before txUpdateMap();
+ *          after txLog() but before txUpdateMap();
  */
 static void txForce(struct tblock * tblk)
 {
@@ -2277,10 +2285,10 @@ static void txForce(struct tblock * tblk)
 }
 
 /*
- *      txUpdateMap()
+ *     txUpdateMap()
  *
- * function:    update persistent allocation map (and working map
- *              if appropriate);
+ * function:   update persistent allocation map (and working map
+ *             if appropriate);
  *
  * parameter:
  */
@@ -2302,7 +2310,7 @@ static void txUpdateMap(struct tblock * tblk)
 
 
        /*
-        *      update block allocation map
+        *      update block allocation map
         *
         * update allocation state in pmap (and wmap) and
         * update lsn of the pmap page;
@@ -2386,7 +2394,7 @@ static void txUpdateMap(struct tblock * tblk)
                }
        }
        /*
-        *      update inode allocation map
+        *      update inode allocation map
         *
         * update allocation state in pmap and
         * update lsn of the pmap page;
@@ -2395,7 +2403,7 @@ static void txUpdateMap(struct tblock * tblk)
         * unlock mapper/write lock
         */
        if (tblk->xflag & COMMIT_CREATE) {
-               diUpdatePMap(ipimap, tblk->ino, FALSE, tblk);
+               diUpdatePMap(ipimap, tblk->ino, false, tblk);
                /* update persistent block allocation map
                 * for the allocation of inode extent;
                 */
@@ -2405,30 +2413,30 @@ static void txUpdateMap(struct tblock * tblk)
                txAllocPMap(ipimap, (struct maplock *) & pxdlock, tblk);
        } else if (tblk->xflag & COMMIT_DELETE) {
                ip = tblk->u.ip;
-               diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk);
+               diUpdatePMap(ipimap, ip->i_ino, true, tblk);
                iput(ip);
        }
 }
 
 /*
- *      txAllocPMap()
+ *     txAllocPMap()
  *
  * function: allocate from persistent map;
  *
  * parameter:
- *      ipbmap  -
- *      malock -
- *              xad list:
- *              pxd:
- *
- *      maptype -
- *              allocate from persistent map;
- *              free from persistent map;
- *              (e.g., tmp file - free from working map at releae
- *               of last reference);
- *              free from persistent and working map;
- *
- *      lsn     - log sequence number;
+ *     ipbmap  -
+ *     malock  -
+ *             xad list:
+ *             pxd:
+ *
+ *     maptype -
+ *             allocate from persistent map;
+ *             free from persistent map;
+ *             (e.g., tmp file - free from working map at releae
+ *              of last reference);
+ *             free from persistent and working map;
+ *
+ *     lsn     - log sequence number;
  */
 static void txAllocPMap(struct inode *ip, struct maplock * maplock,
                        struct tblock * tblk)
@@ -2453,7 +2461,7 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock,
                        if (xad->flag & (XAD_NEW | XAD_EXTENDED)) {
                                xaddr = addressXAD(xad);
                                xlen = lengthXAD(xad);
-                               dbUpdatePMap(ipbmap, FALSE, xaddr,
+                               dbUpdatePMap(ipbmap, false, xaddr,
                                             (s64) xlen, tblk);
                                xad->flag &= ~(XAD_NEW | XAD_EXTENDED);
                                jfs_info("allocPMap: xaddr:0x%lx xlen:%d",
@@ -2464,7 +2472,7 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock,
                pxdlock = (struct pxd_lock *) maplock;
                xaddr = addressPXD(&pxdlock->pxd);
                xlen = lengthPXD(&pxdlock->pxd);
-               dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen, tblk);
+               dbUpdatePMap(ipbmap, false, xaddr, (s64) xlen, tblk);
                jfs_info("allocPMap: xaddr:0x%lx xlen:%d", (ulong) xaddr, xlen);
        } else {                /* (maplock->flag & mlckALLOCPXDLIST) */
 
@@ -2473,7 +2481,7 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock,
                for (n = 0; n < pxdlistlock->count; n++, pxd++) {
                        xaddr = addressPXD(pxd);
                        xlen = lengthPXD(pxd);
-                       dbUpdatePMap(ipbmap, FALSE, xaddr, (s64) xlen,
+                       dbUpdatePMap(ipbmap, false, xaddr, (s64) xlen,
                                     tblk);
                        jfs_info("allocPMap: xaddr:0x%lx xlen:%d",
                                 (ulong) xaddr, xlen);
@@ -2482,9 +2490,9 @@ static void txAllocPMap(struct inode *ip, struct maplock * maplock,
 }
 
 /*
- *      txFreeMap()
+ *     txFreeMap()
  *
- * function:    free from persistent and/or working map;
+ * function:   free from persistent and/or working map;
  *
  * todo: optimization
  */
@@ -2515,7 +2523,7 @@ void txFreeMap(struct inode *ip,
                                if (!(xad->flag & XAD_NEW)) {
                                        xaddr = addressXAD(xad);
                                        xlen = lengthXAD(xad);
-                                       dbUpdatePMap(ipbmap, TRUE, xaddr,
+                                       dbUpdatePMap(ipbmap, true, xaddr,
                                                     (s64) xlen, tblk);
                                        jfs_info("freePMap: xaddr:0x%lx "
                                                 "xlen:%d",
@@ -2526,7 +2534,7 @@ void txFreeMap(struct inode *ip,
                        pxdlock = (struct pxd_lock *) maplock;
                        xaddr = addressPXD(&pxdlock->pxd);
                        xlen = lengthPXD(&pxdlock->pxd);
-                       dbUpdatePMap(ipbmap, TRUE, xaddr, (s64) xlen,
+                       dbUpdatePMap(ipbmap, true, xaddr, (s64) xlen,
                                     tblk);
                        jfs_info("freePMap: xaddr:0x%lx xlen:%d",
                                 (ulong) xaddr, xlen);
@@ -2537,7 +2545,7 @@ void txFreeMap(struct inode *ip,
                        for (n = 0; n < pxdlistlock->count; n++, pxd++) {
                                xaddr = addressPXD(pxd);
                                xlen = lengthPXD(pxd);
-                               dbUpdatePMap(ipbmap, TRUE, xaddr,
+                               dbUpdatePMap(ipbmap, true, xaddr,
                                             (s64) xlen, tblk);
                                jfs_info("freePMap: xaddr:0x%lx xlen:%d",
                                         (ulong) xaddr, xlen);
@@ -2583,9 +2591,9 @@ void txFreeMap(struct inode *ip,
 }
 
 /*
- *      txFreelock()
+ *     txFreelock()
  *
- * function:    remove tlock from inode anonymous locklist
+ * function:   remove tlock from inode anonymous locklist
  */
 void txFreelock(struct inode *ip)
 {
@@ -2623,7 +2631,7 @@ void txFreelock(struct inode *ip)
 }
 
 /*
- *      txAbort()
+ *     txAbort()
  *
  * function: abort tx before commit;
  *
@@ -2683,7 +2691,7 @@ void txAbort(tid_t tid, int dirty)
 }
 
 /*
- *      txLazyCommit(void)
+ *     txLazyCommit(void)
  *
  *     All transactions except those changing ipimap (COMMIT_FORCE) are
  *     processed by this routine.  This insures that the inode and block
@@ -2732,7 +2740,7 @@ static void txLazyCommit(struct tblock * tblk)
 }
 
 /*
- *      jfs_lazycommit(void)
+ *     jfs_lazycommit(void)
  *
  *     To be run as a kernel daemon.  If lbmIODone is called in an interrupt
  *     context, or where blocking is not wanted, this routine will process
@@ -2745,10 +2753,6 @@ int jfs_lazycommit(void *arg)
        unsigned long flags;
        struct jfs_sb_info *sbi;
 
-       daemonize("jfsCommit");
-
-       complete(&jfsIOwait);
-
        do {
                LAZY_LOCK(flags);
                jfs_commit_thread_waking = 0;   /* OK to wake another thread */
@@ -2805,16 +2809,16 @@ int jfs_lazycommit(void *arg)
                        set_current_state(TASK_INTERRUPTIBLE);
                        LAZY_UNLOCK(flags);
                        schedule();
-                       current->state = TASK_RUNNING;
+                       __set_current_state(TASK_RUNNING);
                        remove_wait_queue(&jfs_commit_thread_wait, &wq);
                }
-       } while (!jfs_stop_threads);
+       } while (!kthread_should_stop());
 
        if (!list_empty(&TxAnchor.unlock_queue))
                jfs_err("jfs_lazycommit being killed w/pending transactions!");
        else
                jfs_info("jfs_lazycommit being killed\n");
-       complete_and_exit(&jfsIOwait, 0);
+       return 0;
 }
 
 void txLazyUnlock(struct tblock * tblk)
@@ -2878,10 +2882,10 @@ restart:
                 */
                TXN_UNLOCK();
                tid = txBegin(ip->i_sb, COMMIT_INODE | COMMIT_FORCE);
-               down(&jfs_ip->commit_sem);
+               mutex_lock(&jfs_ip->commit_mutex);
                txCommit(tid, 1, &ip, 0);
                txEnd(tid);
-               up(&jfs_ip->commit_sem);
+               mutex_unlock(&jfs_ip->commit_mutex);
                /*
                 * Just to be safe.  I don't know how
                 * long we can run without blocking
@@ -2921,7 +2925,7 @@ void txResume(struct super_block *sb)
 }
 
 /*
- *      jfs_sync(void)
+ *     jfs_sync(void)
  *
  *     To be run as a kernel daemon.  This is awakened when tlocks run low.
  *     We write any inodes that have anonymous tlocks so they will become
@@ -2934,10 +2938,6 @@ int jfs_sync(void *arg)
        int rc;
        tid_t tid;
 
-       daemonize("jfsSync");
-
-       complete(&jfsIOwait);
-
        do {
                /*
                 * write each inode on the anonymous inode list
@@ -2954,7 +2954,7 @@ int jfs_sync(void *arg)
                                 * Inode is being freed
                                 */
                                list_del_init(&jfs_ip->anon_inode_list);
-                       } else if (! down_trylock(&jfs_ip->commit_sem)) {
+                       } else if (mutex_trylock(&jfs_ip->commit_mutex)) {
                                /*
                                 * inode will be removed from anonymous list
                                 * when it is committed
@@ -2963,7 +2963,7 @@ int jfs_sync(void *arg)
                                tid = txBegin(ip->i_sb, COMMIT_INODE);
                                rc = txCommit(tid, 1, &ip, 0);
                                txEnd(tid);
-                               up(&jfs_ip->commit_sem);
+                               mutex_unlock(&jfs_ip->commit_mutex);
 
                                iput(ip);
                                /*
@@ -2973,7 +2973,7 @@ int jfs_sync(void *arg)
                                cond_resched();
                                TXN_LOCK();
                        } else {
-                               /* We can't get the commit semaphore.  It may
+                               /* We can't get the commit mutex.  It may
                                 * be held by a thread waiting for tlock's
                                 * so let's not block here.  Save it to
                                 * put back on the anon_list.
@@ -2998,27 +2998,20 @@ int jfs_sync(void *arg)
                        TXN_UNLOCK();
                        refrigerator();
                } else {
-                       DECLARE_WAITQUEUE(wq, current);
-
-                       add_wait_queue(&jfs_sync_thread_wait, &wq);
                        set_current_state(TASK_INTERRUPTIBLE);
                        TXN_UNLOCK();
                        schedule();
-                       current->state = TASK_RUNNING;
-                       remove_wait_queue(&jfs_sync_thread_wait, &wq);
+                       __set_current_state(TASK_RUNNING);
                }
-       } while (!jfs_stop_threads);
+       } while (!kthread_should_stop());
 
        jfs_info("jfs_sync being killed");
-       complete_and_exit(&jfsIOwait, 0);
+       return 0;
 }
 
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_JFS_DEBUG)
-int jfs_txanchor_read(char *buffer, char **start, off_t offset, int length,
-                     int *eof, void *data)
+static int jfs_txanchor_proc_show(struct seq_file *m, void *v)
 {
-       int len = 0;
-       off_t begin;
        char *freewait;
        char *freelockwait;
        char *lowlockwait;
@@ -3030,7 +3023,7 @@ int jfs_txanchor_read(char *buffer, char **start, off_t offset, int length,
        lowlockwait =
            waitqueue_active(&TxAnchor.lowlockwait) ? "active" : "empty";
 
-       len += sprintf(buffer,
+       seq_printf(m,
                       "JFS TxAnchor\n"
                       "============\n"
                       "freetid = %d\n"
@@ -3049,31 +3042,27 @@ int jfs_txanchor_read(char *buffer, char **start, off_t offset, int length,
                       TxAnchor.tlocksInUse,
                       jfs_tlocks_low,
                       list_empty(&TxAnchor.unlock_queue) ? "" : "not ");
+       return 0;
+}
 
-       begin = offset;
-       *start = buffer + begin;
-       len -= begin;
-
-       if (len > length)
-               len = length;
-       else
-               *eof = 1;
-
-       if (len < 0)
-               len = 0;
-
-       return len;
+static int jfs_txanchor_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, jfs_txanchor_proc_show, NULL);
 }
+
+const struct file_operations jfs_txanchor_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = jfs_txanchor_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 #endif
 
 #if defined(CONFIG_PROC_FS) && defined(CONFIG_JFS_STATISTICS)
-int jfs_txstats_read(char *buffer, char **start, off_t offset, int length,
-                    int *eof, void *data)
+static int jfs_txstats_proc_show(struct seq_file *m, void *v)
 {
-       int len = 0;
-       off_t begin;
-
-       len += sprintf(buffer,
+       seq_printf(m,
                       "JFS TxStats\n"
                       "===========\n"
                       "calls to txBegin = %d\n"
@@ -3094,19 +3083,19 @@ int jfs_txstats_read(char *buffer, char **start, off_t offset, int length,
                       TxStat.txBeginAnon_lockslow,
                       TxStat.txLockAlloc,
                       TxStat.txLockAlloc_freelock);
+       return 0;
+}
 
-       begin = offset;
-       *start = buffer + begin;
-       len -= begin;
-
-       if (len > length)
-               len = length;
-       else
-               *eof = 1;
-
-       if (len < 0)
-               len = 0;
-
-       return len;
+static int jfs_txstats_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, jfs_txstats_proc_show, NULL);
 }
+
+const struct file_operations jfs_txstats_proc_fops = {
+       .owner          = THIS_MODULE,
+       .open           = jfs_txstats_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
 #endif