Btrfs: always pin metadata in discard mode
[safe/jmp/linux-2.6] / fs / jfs / jfs_dmap.c
index cced2fe..2bc7d8a 100644 (file)
@@ -3,16 +3,16 @@
  *
  *   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
  */
 
 #include "jfs_debug.h"
 
 /*
- *     Debug code for double-checking block map
- */
-/* #define     _JFS_DEBUG_DMAP 1 */
-
-#ifdef _JFS_DEBUG_DMAP
-#define DBINITMAP(size,ipbmap,results) \
-       DBinitmap(size,ipbmap,results)
-#define DBALLOC(dbmap,mapsize,blkno,nblocks) \
-       DBAlloc(dbmap,mapsize,blkno,nblocks)
-#define DBFREE(dbmap,mapsize,blkno,nblocks) \
-       DBFree(dbmap,mapsize,blkno,nblocks)
-#define DBALLOCCK(dbmap,mapsize,blkno,nblocks) \
-       DBAllocCK(dbmap,mapsize,blkno,nblocks)
-#define DBFREECK(dbmap,mapsize,blkno,nblocks) \
-       DBFreeCK(dbmap,mapsize,blkno,nblocks)
-
-static void DBinitmap(s64, struct inode *, u32 **);
-static void DBAlloc(uint *, s64, s64, s64);
-static void DBFree(uint *, s64, s64, s64);
-static void DBAllocCK(uint *, s64, s64, s64);
-static void DBFreeCK(uint *, s64, s64, s64);
-#else
-#define DBINITMAP(size,ipbmap,results)
-#define DBALLOC(dbmap, mapsize, blkno, nblocks)
-#define DBFREE(dbmap, mapsize, blkno, nblocks)
-#define DBALLOCCK(dbmap, mapsize, blkno, nblocks)
-#define DBFREECK(dbmap, mapsize, blkno, nblocks)
-#endif                         /* _JFS_DEBUG_DMAP */
-
-/*
  *     SERIALIZATION of the Block Allocation Map.
  *
  *     the working state of the block allocation map is accessed in
  *     two directions:
- *     
+ *
  *     1) allocation and free requests that start at the dmap
  *        level and move up through the dmap control pages (i.e.
  *        the vast majority of requests).
- * 
- *     2) allocation requests that start at dmap control page
+ *
+ *     2) allocation requests that start at dmap control page
  *        level and work down towards the dmaps.
- *     
- *     the serialization scheme used here is as follows. 
  *
- *     requests which start at the bottom are serialized against each 
- *     other through buffers and each requests holds onto its buffers 
- *     as it works it way up from a single dmap to the required level 
+ *     the serialization scheme used here is as follows.
+ *
+ *     requests which start at the bottom are serialized against each
+ *     other through buffers and each requests holds onto its buffers
+ *     as it works it way up from a single dmap to the required level
  *     of dmap control page.
  *     requests that start at the top are serialized against each other
  *     and request that start from the bottom by the multiple read/single
  *     write inode lock of the bmap inode. requests starting at the top
  *     take this lock in write mode while request starting at the bottom
  *     take the lock in read mode.  a single top-down request may proceed
- *     exclusively while multiple bottoms-up requests may proceed 
- *     simultaneously (under the protection of busy buffers).
- *     
+ *     exclusively while multiple bottoms-up requests may proceed
+ *     simultaneously (under the protection of busy buffers).
+ *
  *     in addition to information found in dmaps and dmap control pages,
  *     the working state of the block allocation map also includes read/
  *     write information maintained in the bmap descriptor (i.e. total
@@ -89,14 +59,14 @@ static void DBFreeCK(uint *, s64, s64, s64);
  *     a single exclusive lock (BMAP_LOCK) is used to guard this information
  *     in the face of multiple-bottoms up requests.
  *     (lock ordering: IREAD_LOCK, BMAP_LOCK);
- *     
+ *
  *     accesses to the persistent state of the block allocation map (limited
  *     to the persistent bitmaps in dmaps) is guarded by (busy) buffers.
  */
 
-#define BMAP_LOCK_INIT(bmp)    init_MUTEX(&bmp->db_bmaplock)
-#define BMAP_LOCK(bmp)         down(&bmp->db_bmaplock)
-#define BMAP_UNLOCK(bmp)       up(&bmp->db_bmaplock)
+#define BMAP_LOCK_INIT(bmp)    mutex_init(&bmp->db_bmaplock)
+#define BMAP_LOCK(bmp)         mutex_lock(&bmp->db_bmaplock)
+#define BMAP_UNLOCK(bmp)       mutex_unlock(&bmp->db_bmaplock)
 
 /*
  * forward references
@@ -104,8 +74,8 @@ static void DBFreeCK(uint *, s64, s64, s64);
 static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
                        int nblocks);
 static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval);
-static void dbBackSplit(dmtree_t * tp, int leafno);
-static void dbJoin(dmtree_t * tp, int leafno, int newval);
+static int dbBackSplit(dmtree_t * tp, int leafno);
+static int dbJoin(dmtree_t * tp, int leafno, int newval);
 static void dbAdjTree(dmtree_t * tp, int leafno, int newval);
 static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc,
                    int level);
@@ -128,8 +98,8 @@ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks);
 static int dbFindBits(u32 word, int l2nb);
 static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno);
 static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx);
-static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
-                      int nblocks);
+static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
+                     int nblocks);
 static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
                      int nblocks);
 static int dbMaxBud(u8 * cp);
@@ -150,12 +120,12 @@ static int dbGetL2AGSize(s64 nblocks);
 /*
  *     buddy table
  *
- * table used for determining buddy sizes within characters of 
+ * table used for determining buddy sizes within characters of
  * dmap bitmap words.  the characters themselves serve as indexes
  * into the table, with the table elements yielding the maximum
  * binary buddy of free bits within the character.
  */
-static s8 budtab[256] = {
+static const s8 budtab[256] = {
        3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
        2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
        2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -176,7 +146,7 @@ static s8 budtab[256] = {
 
 
 /*
- * NAME:       dbMount()
+ * NAME:       dbMount()
  *
  * FUNCTION:   initializate the block allocation map.
  *
@@ -184,12 +154,12 @@ static s8 budtab[256] = {
  *             the in-core descriptor is initialized from disk.
  *
  * PARAMETERS:
- *      ipbmap -  pointer to in-core inode for the block map.
+ *     ipbmap  - pointer to in-core inode for the block map.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOMEM        - insufficient memory
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOMEM - insufficient memory
+ *     -EIO    - i/o error
  */
 int dbMount(struct inode *ipbmap)
 {
@@ -242,7 +212,6 @@ int dbMount(struct inode *ipbmap)
        JFS_SBI(ipbmap->i_sb)->bmap = bmp;
 
        memset(bmp->db_active, 0, sizeof(bmp->db_active));
-       DBINITMAP(bmp->db_mapsize, ipbmap, &bmp->db_DBmap);
 
        /*
         * allocate/initialize the bmap lock
@@ -254,20 +223,20 @@ int dbMount(struct inode *ipbmap)
 
 
 /*
- * NAME:       dbUnmount()
+ * NAME:       dbUnmount()
  *
  * FUNCTION:   terminate the block allocation map in preparation for
  *             file system unmount.
  *
- *             the in-core bmap descriptor is written to disk and
+ *             the in-core bmap descriptor is written to disk and
  *             the memory for this descriptor is freed.
  *
  * PARAMETERS:
- *      ipbmap -  pointer to in-core inode for the block map.
+ *     ipbmap  - pointer to in-core inode for the block map.
  *
  * RETURN VALUES:
- *      0      - success
- *      -EIO   - i/o error
+ *           - success
+ *     -EIO    - i/o error
  */
 int dbUnmount(struct inode *ipbmap, int mounterror)
 {
@@ -333,10 +302,8 @@ int dbSync(struct inode *ipbmap)
        /*
         * write out dirty pages of bmap
         */
-       filemap_fdatawrite(ipbmap->i_mapping);
-       filemap_fdatawait(ipbmap->i_mapping);
+       filemap_write_and_wait(ipbmap->i_mapping);
 
-       ipbmap->i_state |= I_DIRTY;
        diWriteSpecial(ipbmap, 0);
 
        return (0);
@@ -344,7 +311,7 @@ int dbSync(struct inode *ipbmap)
 
 
 /*
- * NAME:       dbFree()
+ * NAME:       dbFree()
  *
  * FUNCTION:   free the specified block range from the working block
  *             allocation map.
@@ -353,13 +320,13 @@ int dbSync(struct inode *ipbmap)
  *             at a time.
  *
  * PARAMETERS:
- *      ip     -  pointer to in-core inode;
- *      blkno  -  starting block number to be freed.
- *      nblocks        -  number of blocks to be freed.
+ *     ip      - pointer to in-core inode;
+ *     blkno   - starting block number to be freed.
+ *     nblocks - number of blocks to be freed.
  *
  * RETURN VALUES:
- *      0      - success
- *      -EIO   - i/o error
+ *           - success
+ *     -EIO    - i/o error
  */
 int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
 {
@@ -370,7 +337,7 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
        struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
        struct bmap *bmp = JFS_SBI(ip->i_sb)->bmap;
 
-       IREAD_LOCK(ipbmap);
+       IREAD_LOCK(ipbmap, RDWRLOCK_DMAP);
 
        /* block to be freed better be within the mapsize. */
        if (unlikely((blkno == 0) || (blkno + nblocks > bmp->db_mapsize))) {
@@ -407,16 +374,13 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
                 */
                nb = min(rem, BPERDMAP - (blkno & (BPERDMAP - 1)));
 
-               DBALLOCCK(bmp->db_DBmap, bmp->db_mapsize, blkno, nb);
-
                /* free the blocks. */
                if ((rc = dbFreeDmap(bmp, dp, blkno, nb))) {
+                       jfs_error(ip->i_sb, "dbFree: error in block map\n");
                        release_metapage(mp);
                        IREAD_UNLOCK(ipbmap);
                        return (rc);
                }
-
-               DBFREE(bmp->db_DBmap, bmp->db_mapsize, blkno, nb);
        }
 
        /* write the last buffer. */
@@ -431,23 +395,23 @@ int dbFree(struct inode *ip, s64 blkno, s64 nblocks)
 /*
  * NAME:       dbUpdatePMap()
  *
- * FUNCTION:    update the allocation state (free or allocate) of the
+ * FUNCTION:   update the allocation state (free or allocate) of the
  *             specified block range in the persistent block allocation map.
- *             
+ *
  *             the blocks will be updated in the persistent map one
  *             dmap at a time.
  *
  * PARAMETERS:
- *      ipbmap -  pointer to in-core inode for the block map.
- *      free   - TRUE if block range is to be freed from the persistent
- *               map; FALSE if it is to   be allocated.
- *      blkno  -  starting block number of the range.
- *      nblocks        -  number of contiguous blocks in the range.
- *      tblk   -  transaction block;
+ *     ipbmap  - pointer to in-core inode for the block map.
+ *     free    - 'true' if block range is to be freed from the persistent
+ *               map; 'false' if it is to be allocated.
+ *     blkno   - starting block number of the range.
+ *     nblocks - number of contiguous blocks in the range.
+ *     tblk    - transaction block;
  *
  * RETURN VALUES:
- *      0      - success
- *      -EIO   - i/o error
+ *           - success
+ *     -EIO    - i/o error
  */
 int
 dbUpdatePMap(struct inode *ipbmap,
@@ -511,7 +475,7 @@ dbUpdatePMap(struct inode *ipbmap,
                /* update the bits of the dmap words. the first and last
                 * words may only have a subset of their bits updated. if
                 * this is the case, we'll work against that word (i.e.
-                * partial first and/or last) only in a single pass.  a 
+                * partial first and/or last) only in a single pass.  a
                 * single pass will also be used to update all words that
                 * are to have all their bits updated.
                 */
@@ -568,10 +532,10 @@ dbUpdatePMap(struct inode *ipbmap,
 
                lastlblkno = lblkno;
 
+               LOGSYNC_LOCK(log, flags);
                if (mp->lsn != 0) {
                        /* inherit older/smaller lsn */
                        logdiff(diffp, mp->lsn, log);
-                       LOGSYNC_LOCK(log, flags);
                        if (difft < diffp) {
                                mp->lsn = lsn;
 
@@ -584,20 +548,17 @@ dbUpdatePMap(struct inode *ipbmap,
                        logdiff(diffp, mp->clsn, log);
                        if (difft > diffp)
                                mp->clsn = tblk->clsn;
-                       LOGSYNC_UNLOCK(log, flags);
                } else {
                        mp->log = log;
                        mp->lsn = lsn;
 
                        /* insert bp after tblock in logsync list */
-                       LOGSYNC_LOCK(log, flags);
-
                        log->count++;
                        list_add(&mp->synclist, &tblk->synclist);
 
                        mp->clsn = tblk->clsn;
-                       LOGSYNC_UNLOCK(log, flags);
                }
+               LOGSYNC_UNLOCK(log, flags);
        }
 
        /* write the last buffer. */
@@ -612,7 +573,7 @@ dbUpdatePMap(struct inode *ipbmap,
 /*
  * NAME:       dbNextAG()
  *
- * FUNCTION:    find the preferred allocation group for new allocations.
+ * FUNCTION:   find the preferred allocation group for new allocations.
  *
  *             Within the allocation groups, we maintain a preferred
  *             allocation group which consists of a group with at least
@@ -628,10 +589,10 @@ dbUpdatePMap(struct inode *ipbmap,
  *             empty ags around for large allocations.
  *
  * PARAMETERS:
- *      ipbmap -  pointer to in-core inode for the block map.
+ *     ipbmap  - pointer to in-core inode for the block map.
  *
  * RETURN VALUES:
- *      the preferred allocation group number.
+ *     the preferred allocation group number.
  */
 int dbNextAG(struct inode *ipbmap)
 {
@@ -695,17 +656,17 @@ unlock:
 /*
  * NAME:       dbAlloc()
  *
- * FUNCTION:    attempt to allocate a specified number of contiguous free
+ * FUNCTION:   attempt to allocate a specified number of contiguous free
  *             blocks from the working allocation block map.
  *
  *             the block allocation policy uses hints and a multi-step
  *             approach.
  *
- *             for allocation requests smaller than the number of blocks
+ *             for allocation requests smaller than the number of blocks
  *             per dmap, we first try to allocate the new blocks
  *             immediately following the hint.  if these blocks are not
  *             available, we try to allocate blocks near the hint.  if
- *             no blocks near the hint are available, we next try to 
+ *             no blocks near the hint are available, we next try to
  *             allocate within the same dmap as contains the hint.
  *
  *             if no blocks are available in the dmap or the allocation
@@ -719,16 +680,16 @@ unlock:
  *             size or requests that specify no hint value.
  *
  * PARAMETERS:
- *      ip     -  pointer to in-core inode;
- *      hint   - allocation hint.
- *      nblocks        - number of contiguous blocks in the range.
- *      results        - on successful return, set to the starting block number
+ *     ip      - pointer to in-core inode;
+ *     hint    - allocation hint.
+ *     nblocks - number of contiguous blocks in the range.
+ *     results - on successful return, set to the starting block number
  *               of the newly allocated contiguous range.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  */
 int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
 {
@@ -745,21 +706,14 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
        /* assert that nblocks is valid */
        assert(nblocks > 0);
 
-#ifdef _STILL_TO_PORT
-       /* DASD limit check                                     F226941 */
-       if (OVER_LIMIT(ip, nblocks))
-               return -ENOSPC;
-#endif                         /* _STILL_TO_PORT */
-
        /* get the log2 number of blocks to be allocated.
-        * if the number of blocks is not a log2 multiple, 
+        * if the number of blocks is not a log2 multiple,
         * it will be rounded up to the next log2 multiple.
         */
        l2nb = BLKSTOL2(nblocks);
 
        bmp = JFS_SBI(ip->i_sb)->bmap;
 
-//retry:        /* serialize w.r.t.extendfs() */
        mapSize = bmp->db_mapsize;
 
        /* the hint should be within the map */
@@ -772,13 +726,9 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
         * allocation group size, try to allocate anywhere.
         */
        if (l2nb > bmp->db_agl2size) {
-               IWRITE_LOCK(ipbmap);
+               IWRITE_LOCK(ipbmap, RDWRLOCK_DMAP);
 
                rc = dbAllocAny(bmp, nblocks, l2nb, results);
-               if (rc == 0) {
-                       DBALLOC(bmp->db_DBmap, bmp->db_mapsize, *results,
-                               nblocks);
-               }
 
                goto write_unlock;
        }
@@ -817,7 +767,7 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
         * the hint using a tiered strategy.
         */
        if (nblocks <= BPERDMAP) {
-               IREAD_LOCK(ipbmap);
+               IREAD_LOCK(ipbmap, RDWRLOCK_DMAP);
 
                /* get the buffer for the dmap containing the hint.
                 */
@@ -836,8 +786,6 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
                    != -ENOSPC) {
                        if (rc == 0) {
                                *results = blkno;
-                               DBALLOC(bmp->db_DBmap, bmp->db_mapsize,
-                                       *results, nblocks);
                                mark_metapage_dirty(mp);
                        }
 
@@ -863,11 +811,8 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
                if ((rc =
                     dbAllocNear(bmp, dp, blkno, (int) nblocks, l2nb, results))
                    != -ENOSPC) {
-                       if (rc == 0) {
-                               DBALLOC(bmp->db_DBmap, bmp->db_mapsize,
-                                       *results, nblocks);
+                       if (rc == 0)
                                mark_metapage_dirty(mp);
-                       }
 
                        release_metapage(mp);
                        goto read_unlock;
@@ -878,11 +823,8 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
                 */
                if ((rc = dbAllocDmapLev(bmp, dp, (int) nblocks, l2nb, results))
                    != -ENOSPC) {
-                       if (rc == 0) {
-                               DBALLOC(bmp->db_DBmap, bmp->db_mapsize,
-                                       *results, nblocks);
+                       if (rc == 0)
                                mark_metapage_dirty(mp);
-                       }
 
                        release_metapage(mp);
                        goto read_unlock;
@@ -895,14 +837,10 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
        /* try to satisfy the allocation request with blocks within
         * the same allocation group as the hint.
         */
-       IWRITE_LOCK(ipbmap);
-       if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results))
-           != -ENOSPC) {
-               if (rc == 0)
-                       DBALLOC(bmp->db_DBmap, bmp->db_mapsize,
-                               *results, nblocks);
+       IWRITE_LOCK(ipbmap, RDWRLOCK_DMAP);
+       if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results)) != -ENOSPC)
                goto write_unlock;
-       }
+
        IWRITE_UNLOCK(ipbmap);
 
 
@@ -911,16 +849,13 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
         * Let dbNextAG recommend a preferred allocation group
         */
        agno = dbNextAG(ipbmap);
-       IWRITE_LOCK(ipbmap);
+       IWRITE_LOCK(ipbmap, RDWRLOCK_DMAP);
 
        /* Try to allocate within this allocation group.  if that fails, try to
         * allocate anywhere in the map.
         */
        if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results)) == -ENOSPC)
                rc = dbAllocAny(bmp, nblocks, l2nb, results);
-       if (rc == 0) {
-               DBALLOC(bmp->db_DBmap, bmp->db_mapsize, *results, nblocks);
-       }
 
       write_unlock:
        IWRITE_UNLOCK(ipbmap);
@@ -937,17 +872,17 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
 /*
  * NAME:       dbAllocExact()
  *
- * FUNCTION:    try to allocate the requested extent;
+ * FUNCTION:   try to allocate the requested extent;
  *
  * PARAMETERS:
- *      ip     - pointer to in-core inode;
- *      blkno  - extent address;
- *      nblocks        - extent length;
+ *     ip      - pointer to in-core inode;
+ *     blkno   - extent address;
+ *     nblocks - extent length;
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  */
 int dbAllocExact(struct inode *ip, s64 blkno, int nblocks)
 {
@@ -958,13 +893,13 @@ int dbAllocExact(struct inode *ip, s64 blkno, int nblocks)
        s64 lblkno;
        struct metapage *mp;
 
-       IREAD_LOCK(ipbmap);
+       IREAD_LOCK(ipbmap, RDWRLOCK_DMAP);
 
        /*
         * validate extent request:
         *
         * note: defragfs policy:
-        *  max 64 blocks will be moved.  
+        *  max 64 blocks will be moved.
         *  allocation request size must be satisfied from a single dmap.
         */
        if (nblocks <= 0 || nblocks > BPERDMAP || blkno >= bmp->db_mapsize) {
@@ -992,10 +927,9 @@ int dbAllocExact(struct inode *ip, s64 blkno, int nblocks)
 
        IREAD_UNLOCK(ipbmap);
 
-       if (rc == 0) {
-               DBALLOC(bmp->db_DBmap, bmp->db_mapsize, blkno, nblocks);
+       if (rc == 0)
                mark_metapage_dirty(mp);
-       }
+
        release_metapage(mp);
 
        return (rc);
@@ -1005,7 +939,7 @@ int dbAllocExact(struct inode *ip, s64 blkno, int nblocks)
 /*
  * NAME:       dbReAlloc()
  *
- * FUNCTION:    attempt to extend a current allocation by a specified
+ * FUNCTION:   attempt to extend a current allocation by a specified
  *             number of blocks.
  *
  *             this routine attempts to satisfy the allocation request
@@ -1018,21 +952,21 @@ int dbAllocExact(struct inode *ip, s64 blkno, int nblocks)
  *             number of blocks required.
  *
  * PARAMETERS:
- *      ip         -  pointer to in-core inode requiring allocation.
- *      blkno      -  starting block of the current allocation.
- *      nblocks            -  number of contiguous blocks within the current
+ *     ip          -  pointer to in-core inode requiring allocation.
+ *     blkno       -  starting block of the current allocation.
+ *     nblocks     -  number of contiguous blocks within the current
  *                    allocation.
- *      addnblocks  -  number of blocks to add to the allocation.
- *      results        -      on successful return, set to the starting block number
+ *     addnblocks  -  number of blocks to add to the allocation.
+ *     results -      on successful return, set to the starting block number
  *                    of the existing allocation if the existing allocation
  *                    was extended in place or to a newly allocated contiguous
  *                    range if the existing allocation could not be extended
  *                    in place.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  */
 int
 dbReAlloc(struct inode *ip,
@@ -1063,7 +997,7 @@ dbReAlloc(struct inode *ip,
 /*
  * NAME:       dbExtend()
  *
- * FUNCTION:    attempt to extend a current allocation by a specified
+ * FUNCTION:   attempt to extend a current allocation by a specified
  *             number of blocks.
  *
  *             this routine attempts to satisfy the allocation request
@@ -1072,16 +1006,16 @@ dbReAlloc(struct inode *ip,
  *             immediately following the current allocation.
  *
  * PARAMETERS:
- *      ip         -  pointer to in-core inode requiring allocation.
- *      blkno      -  starting block of the current allocation.
- *      nblocks            -  number of contiguous blocks within the current
+ *     ip          -  pointer to in-core inode requiring allocation.
+ *     blkno       -  starting block of the current allocation.
+ *     nblocks     -  number of contiguous blocks within the current
  *                    allocation.
- *      addnblocks  -  number of blocks to add to the allocation.
+ *     addnblocks  -  number of blocks to add to the allocation.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  */
 static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks)
 {
@@ -1109,7 +1043,7 @@ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks)
         */
        extblkno = lastblkno + 1;
 
-       IREAD_LOCK(ipbmap);
+       IREAD_LOCK(ipbmap, RDWRLOCK_DMAP);
 
        /* better be within the file system */
        bmp = sbi->bmap;
@@ -1144,7 +1078,6 @@ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks)
                return -EIO;
        }
 
-       DBALLOCCK(bmp->db_DBmap, bmp->db_mapsize, blkno, nblocks);
        dp = (struct dmap *) mp->data;
 
        /* try to allocate the blocks immediately following the
@@ -1155,11 +1088,9 @@ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks)
        IREAD_UNLOCK(ipbmap);
 
        /* were we successful ? */
-       if (rc == 0) {
-               DBALLOC(bmp->db_DBmap, bmp->db_mapsize, extblkno,
-                       addnblocks);
+       if (rc == 0)
                write_metapage(mp);
-       else
+       else
                /* we were not successful */
                release_metapage(mp);
 
@@ -1171,19 +1102,19 @@ static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks)
 /*
  * NAME:       dbAllocNext()
  *
- * FUNCTION:    attempt to allocate the blocks of the specified block
+ * FUNCTION:   attempt to allocate the blocks of the specified block
  *             range within a dmap.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      dp     -  pointer to dmap.
- *      blkno  -  starting block number of the range.
- *      nblocks        -  number of contiguous free blocks of the range.
+ *     bmp     -  pointer to bmap descriptor
+ *     dp      -  pointer to dmap.
+ *     blkno   -  starting block number of the range.
+ *     nblocks -  number of contiguous free blocks of the range.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  *
  * serialization: IREAD_LOCK(ipbmap) held on entry/exit;
  */
@@ -1295,7 +1226,7 @@ static int dbAllocNext(struct bmap * bmp, struct dmap * dp, s64 blkno,
 /*
  * NAME:       dbAllocNear()
  *
- * FUNCTION:    attempt to allocate a number of contiguous free blocks near
+ * FUNCTION:   attempt to allocate a number of contiguous free blocks near
  *             a specified block (hint) within a dmap.
  *
  *             starting with the dmap leaf that covers the hint, we'll
@@ -1304,18 +1235,18 @@ static int dbAllocNext(struct bmap * bmp, struct dmap * dp, s64 blkno,
  *             the desired free space.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      dp     -  pointer to dmap.
- *      blkno  -  block number to allocate near.
- *      nblocks        -  actual number of contiguous free blocks desired.
- *      l2nb   -  log2 number of contiguous free blocks desired.
- *      results        -  on successful return, set to the starting block number
+ *     bmp     -  pointer to bmap descriptor
+ *     dp      -  pointer to dmap.
+ *     blkno   -  block number to allocate near.
+ *     nblocks -  actual number of contiguous free blocks desired.
+ *     l2nb    -  log2 number of contiguous free blocks desired.
+ *     results -  on successful return, set to the starting block number
  *                of the newly allocated range.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  *
  * serialization: IREAD_LOCK(ipbmap) held on entry/exit;
  */
@@ -1378,7 +1309,7 @@ dbAllocNear(struct bmap * bmp,
 /*
  * NAME:       dbAllocAG()
  *
- * FUNCTION:    attempt to allocate the specified number of contiguous
+ * FUNCTION:   attempt to allocate the specified number of contiguous
  *             free blocks within the specified allocation group.
  *
  *             unless the allocation group size is equal to the number
@@ -1395,7 +1326,7 @@ dbAllocNear(struct bmap * bmp,
  *             or two sub-trees, depending on the allocation group size.
  *             we search the top nodes of these subtrees left to right for
  *             sufficient free space.  if sufficient free space is found,
- *             the subtree is searched to find the leftmost leaf that 
+ *             the subtree is searched to find the leftmost leaf that
  *             has free space.  once we have made it to the leaf, we
  *             move the search to the next lower level dmap control page
  *             corresponding to this leaf.  we continue down the dmap control
@@ -1415,17 +1346,17 @@ dbAllocNear(struct bmap * bmp,
  *             the allocation group.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
+ *     bmp     -  pointer to bmap descriptor
  *     agno    - allocation group number.
- *      nblocks        -  actual number of contiguous free blocks desired.
- *      l2nb   -  log2 number of contiguous free blocks desired.
- *      results        -  on successful return, set to the starting block number
+ *     nblocks -  actual number of contiguous free blocks desired.
+ *     l2nb    -  log2 number of contiguous free blocks desired.
+ *     results -  on successful return, set to the starting block number
  *                of the newly allocated range.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  *
  * note: IWRITE_LOCK(ipmap) held on entry/exit;
  */
@@ -1460,7 +1391,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
         * that fully describes the allocation group since the allocation
         * group is already fully described by a dmap.  in this case, we
         * just call dbAllocCtl() to search the dmap tree and allocate the
-        * required space if available.  
+        * required space if available.
         *
         * if the allocation group is completely free, dbAllocCtl() is
         * also called to allocate the required space.  this is done for
@@ -1512,7 +1443,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
            (1 << (L2LPERCTL - (bmp->db_agheigth << 1))) / bmp->db_agwidth;
        ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1));
 
-       /* dmap control page trees fan-out by 4 and a single allocation 
+       /* dmap control page trees fan-out by 4 and a single allocation
         * group may be described by 1 or 2 subtrees within the ag level
         * dmap control page, depending upon the ag size. examine the ag's
         * subtrees for sufficient free space, starting with the leftmost
@@ -1569,7 +1500,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
                if (l2nb < budmin) {
 
                        /* search the lower level dmap control pages to get
-                        * the starting block number of the the dmap that
+                        * the starting block number of the dmap that
                         * contains or starts off the free space.
                         */
                        if ((rc =
@@ -1608,7 +1539,7 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
 /*
  * NAME:       dbAllocAny()
  *
- * FUNCTION:    attempt to allocate the specified number of contiguous
+ * FUNCTION:   attempt to allocate the specified number of contiguous
  *             free blocks anywhere in the file system.
  *
  *             dbAllocAny() attempts to find the sufficient free space by
@@ -1618,16 +1549,16 @@ dbAllocAG(struct bmap * bmp, int agno, s64 nblocks, int l2nb, s64 * results)
  *             desired free space is allocated.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      nblocks         -  actual number of contiguous free blocks desired.
- *      l2nb    -  log2 number of contiguous free blocks desired.
- *      results        -  on successful return, set to the starting block number
+ *     bmp     -  pointer to bmap descriptor
+ *     nblocks  -  actual number of contiguous free blocks desired.
+ *     l2nb     -  log2 number of contiguous free blocks desired.
+ *     results -  on successful return, set to the starting block number
  *                of the newly allocated range.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  *
  * serialization: IWRITE_LOCK(ipbmap) held on entry/exit;
  */
@@ -1660,9 +1591,9 @@ static int dbAllocAny(struct bmap * bmp, s64 nblocks, int l2nb, s64 * results)
 /*
  * NAME:       dbFindCtl()
  *
- * FUNCTION:    starting at a specified dmap control page level and block
+ * FUNCTION:   starting at a specified dmap control page level and block
  *             number, search down the dmap control levels for a range of
- *             contiguous free blocks large enough to satisfy an allocation
+ *             contiguous free blocks large enough to satisfy an allocation
  *             request for the specified number of free blocks.
  *
  *             if sufficient contiguous free blocks are found, this routine
@@ -1671,17 +1602,17 @@ static int dbAllocAny(struct bmap * bmp, s64 nblocks, int l2nb, s64 * results)
  *             is sufficient in size.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      level  -  starting dmap control page level.
- *      l2nb   -  log2 number of contiguous free blocks desired.
- *      *blkno -  on entry, starting block number for conducting the search.
+ *     bmp     -  pointer to bmap descriptor
+ *     level   -  starting dmap control page level.
+ *     l2nb    -  log2 number of contiguous free blocks desired.
+ *     *blkno  -  on entry, starting block number for conducting the search.
  *                on successful return, the first block within a dmap page
  *                that contains or starts a range of contiguous free blocks.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  *
  * serialization: IWRITE_LOCK(ipbmap) held on entry/exit;
  */
@@ -1695,7 +1626,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
 
        /* starting at the specified dmap control page level and block
         * number, search down the dmap control levels for the starting
-        * block number of a dmap page that contains or starts off 
+        * block number of a dmap page that contains or starts off
         * sufficient free blocks.
         */
        for (lev = level, b = *blkno; lev >= 0; lev--) {
@@ -1739,7 +1670,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
                }
 
                /* adjust the block number to reflect the location within
-                * the dmap control page (i.e. the leaf) at which free 
+                * the dmap control page (i.e. the leaf) at which free
                 * space was found.
                 */
                b += (((s64) leafidx) << budmin);
@@ -1761,13 +1692,13 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
 /*
  * NAME:       dbAllocCtl()
  *
- * FUNCTION:    attempt to allocate a specified number of contiguous
- *             blocks starting within a specific dmap.  
- *             
+ * FUNCTION:   attempt to allocate a specified number of contiguous
+ *             blocks starting within a specific dmap.
+ *
  *             this routine is called by higher level routines that search
  *             the dmap control pages above the actual dmaps for contiguous
  *             free space.  the result of successful searches by these
- *             routines are the starting block numbers within dmaps, with
+ *             routines are the starting block numbers within dmaps, with
  *             the dmaps themselves containing the desired contiguous free
  *             space or starting a contiguous free space of desired size
  *             that is made up of the blocks of one or more dmaps. these
@@ -1788,18 +1719,18 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
  *             first dmap (i.e. blkno).
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      nblocks         -  actual number of contiguous free blocks to allocate.
- *      l2nb    -  log2 number of contiguous free blocks to allocate.
- *      blkno   -  starting block number of the dmap to start the allocation
+ *     bmp     -  pointer to bmap descriptor
+ *     nblocks  -  actual number of contiguous free blocks to allocate.
+ *     l2nb     -  log2 number of contiguous free blocks to allocate.
+ *     blkno    -  starting block number of the dmap to start the allocation
  *                 from.
- *      results        -  on successful return, set to the starting block number
+ *     results -  on successful return, set to the starting block number
  *                of the newly allocated range.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  *
  * serialization: IWRITE_LOCK(ipbmap) held on entry/exit;
  */
@@ -1932,27 +1863,27 @@ dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, s64 * results)
 /*
  * NAME:       dbAllocDmapLev()
  *
- * FUNCTION:    attempt to allocate a specified number of contiguous blocks
+ * FUNCTION:   attempt to allocate a specified number of contiguous blocks
  *             from a specified dmap.
- *             
+ *
  *             this routine checks if the contiguous blocks are available.
  *             if so, nblocks of blocks are allocated; otherwise, ENOSPC is
  *             returned.
  *
  * PARAMETERS:
- *      mp     -  pointer to bmap descriptor
- *      dp     -  pointer to dmap to attempt to allocate blocks from. 
- *      l2nb   -  log2 number of contiguous block desired.
- *      nblocks        -  actual number of contiguous block desired.
- *      results        -  on successful return, set to the starting block number
+ *     mp      -  pointer to bmap descriptor
+ *     dp      -  pointer to dmap to attempt to allocate blocks from.
+ *     l2nb    -  log2 number of contiguous block desired.
+ *     nblocks -  actual number of contiguous block desired.
+ *     results -  on successful return, set to the starting block number
  *                of the newly allocated range.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient disk resources
- *      -EIO   - i/o error
+ *           - success
+ *     -ENOSPC - insufficient disk resources
+ *     -EIO    - i/o error
  *
- * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or 
+ * serialization: IREAD_LOCK(ipbmap), e.g., from dbAlloc(), or
  *     IWRITE_LOCK(ipbmap), e.g., dbAllocCtl(), held on entry/exit;
  */
 static int
@@ -1995,7 +1926,7 @@ dbAllocDmapLev(struct bmap * bmp,
 /*
  * NAME:       dbAllocDmap()
  *
- * FUNCTION:    adjust the disk allocation map to reflect the allocation
+ * FUNCTION:   adjust the disk allocation map to reflect the allocation
  *             of a specified block range within a dmap.
  *
  *             this routine allocates the specified blocks from the dmap
@@ -2008,14 +1939,14 @@ dbAllocDmapLev(struct bmap * bmp,
  *             covers this dmap.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      dp     -  pointer to dmap to allocate the block range from.
- *      blkno  -  starting block number of the block to be allocated.
- *      nblocks        -  number of blocks to be allocated.
+ *     bmp     -  pointer to bmap descriptor
+ *     dp      -  pointer to dmap to allocate the block range from.
+ *     blkno   -  starting block number of the block to be allocated.
+ *     nblocks -  number of blocks to be allocated.
  *
  * RETURN VALUES:
- *      0      - success
- *      -EIO   - i/o error
+ *           - success
+ *     -EIO    - i/o error
  *
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  */
@@ -2051,7 +1982,7 @@ static int dbAllocDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
 /*
  * NAME:       dbFreeDmap()
  *
- * FUNCTION:    adjust the disk allocation map to reflect the allocation
+ * FUNCTION:   adjust the disk allocation map to reflect the allocation
  *             of a specified block range within a dmap.
  *
  *             this routine frees the specified blocks from the dmap through
@@ -2059,18 +1990,18 @@ static int dbAllocDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
  *             causes the maximum string of free blocks within the dmap to
  *             change (i.e. the value of the root of the dmap's dmtree), this
  *             routine will cause this change to be reflected up through the
- *             appropriate levels of the dmap control pages by a call to
+ *             appropriate levels of the dmap control pages by a call to
  *             dbAdjCtl() for the L0 dmap control page that covers this dmap.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      dp     -  pointer to dmap to free the block range from.
- *      blkno  -  starting block number of the block to be freed.
- *      nblocks        -  number of blocks to be freed.
+ *     bmp     -  pointer to bmap descriptor
+ *     dp      -  pointer to dmap to free the block range from.
+ *     blkno   -  starting block number of the block to be freed.
+ *     nblocks -  number of blocks to be freed.
  *
  * RETURN VALUES:
- *      0      - success
- *      -EIO   - i/o error
+ *           - success
+ *     -EIO    - i/o error
  *
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  */
@@ -2078,7 +2009,7 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
                      int nblocks)
 {
        s8 oldroot;
-       int rc, word;
+       int rc = 0, word;
 
        /* save the current value of the root (i.e. maximum free string)
         * of the dmap tree.
@@ -2086,15 +2017,15 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
        oldroot = dp->tree.stree[ROOT];
 
        /* free the specified (blocks) bits */
-       dbFreeBits(bmp, dp, blkno, nblocks);
+       rc = dbFreeBits(bmp, dp, blkno, nblocks);
 
-       /* if the root has not changed, done. */
-       if (dp->tree.stree[ROOT] == oldroot)
-               return (0);
+       /* if error or the root has not changed, done. */
+       if (rc || (dp->tree.stree[ROOT] == oldroot))
+               return (rc);
 
        /* root changed. bubble the change up to the dmap control pages.
         * if the adjustment of the upper level control pages fails,
-        * backout the deallocation. 
+        * backout the deallocation.
         */
        if ((rc = dbAdjCtl(bmp, blkno, dp->tree.stree[ROOT], 0, 0))) {
                word = (blkno & (BPERDMAP - 1)) >> L2DBWORD;
@@ -2117,7 +2048,7 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
 /*
  * NAME:       dbAllocBits()
  *
- * FUNCTION:    allocate a specified block range from a dmap.
+ * FUNCTION:   allocate a specified block range from a dmap.
  *
  *             this routine updates the dmap to reflect the working
  *             state allocation of the specified block range. it directly
@@ -2127,10 +2058,10 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
  *             dmap's dmtree, as a whole, to reflect the allocated range.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      dp     -  pointer to dmap to allocate bits from.
- *      blkno  -  starting block number of the bits to be allocated.
- *      nblocks        -  number of bits to be allocated.
+ *     bmp     -  pointer to bmap descriptor
+ *     dp      -  pointer to dmap to allocate bits from.
+ *     blkno   -  starting block number of the bits to be allocated.
+ *     nblocks -  number of bits to be allocated.
  *
  * RETURN VALUES: none
  *
@@ -2211,7 +2142,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
                         * the allocated words.
                         */
                        for (; nwords > 0; nwords -= nw) {
-                               if (leaf[word] < BUDMIN) {
+                               if (leaf[word] < BUDMIN) {
                                        jfs_error(bmp->db_ipbmap->i_sb,
                                                  "dbAllocBits: leaf page "
                                                  "corrupt");
@@ -2241,7 +2172,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
        }
 
        /* update the free count for this dmap */
-       dp->nfree = cpu_to_le32(le32_to_cpu(dp->nfree) - nblocks);
+       le32_add_cpu(&dp->nfree, -nblocks);
 
        BMAP_LOCK(bmp);
 
@@ -2264,7 +2195,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
 /*
  * NAME:       dbFreeBits()
  *
- * FUNCTION:    free a specified block range from a dmap.
+ * FUNCTION:   free a specified block range from a dmap.
  *
  *             this routine updates the dmap to reflect the working
  *             state allocation of the specified block range. it directly
@@ -2274,20 +2205,21 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
  *             dmtree, as a whole, to reflect the deallocated range.
  *
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      dp     -  pointer to dmap to free bits from.
- *      blkno  -  starting block number of the bits to be freed.
- *      nblocks        -  number of bits to be freed.
+ *     bmp     -  pointer to bmap descriptor
+ *     dp      -  pointer to dmap to free bits from.
+ *     blkno   -  starting block number of the bits to be freed.
+ *     nblocks -  number of bits to be freed.
  *
- * RETURN VALUES: none
+ * RETURN VALUES: 0 for success
  *
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  */
-static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
+static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
                       int nblocks)
 {
        int dbitno, word, rembits, nb, nwords, wbitno, nw, agno;
        dmtree_t *tp = (dmtree_t *) & dp->tree;
+       int rc = 0;
        int size;
 
        /* determine the bit number and word within the dmap of the
@@ -2306,7 +2238,7 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
         * words (i.e. partial first and/or last) on an individual basis
         * (a single pass), freeing the bits of interest by hand and updating
         * the leaf corresponding to the dmap word. a single pass will be used
-        * for all dmap words fully contained within the specified range.  
+        * for all dmap words fully contained within the specified range.
         * within this pass, the bits of all fully contained dmap words will
         * be marked as free in a single shot and the leaves will be updated. a
         * single leaf may describe the free space of multiple dmap words,
@@ -2328,7 +2260,7 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
                 */
                if (nb < DBWORD) {
                        /* free (zero) the appropriate bits within this
-                        * dmap word. 
+                        * dmap word.
                         */
                        dp->wmap[word] &=
                            cpu_to_le32(~(ONES << (DBWORD - nb)
@@ -2336,8 +2268,10 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
 
                        /* update the leaf for this dmap word.
                         */
-                       dbJoin(tp, word,
-                              dbMaxBud((u8 *) & dp->wmap[word]));
+                       rc = dbJoin(tp, word,
+                                   dbMaxBud((u8 *) & dp->wmap[word]));
+                       if (rc)
+                               return rc;
 
                        word += 1;
                } else {
@@ -2368,7 +2302,9 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
 
                                /* update the leaf.
                                 */
-                               dbJoin(tp, word, size);
+                               rc = dbJoin(tp, word, size);
+                               if (rc)
+                                       return rc;
 
                                /* get the number of dmap words handled.
                                 */
@@ -2380,11 +2316,11 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
 
        /* update the free count for this dmap.
         */
-       dp->nfree = cpu_to_le32(le32_to_cpu(dp->nfree) + nblocks);
+       le32_add_cpu(&dp->nfree, nblocks);
 
        BMAP_LOCK(bmp);
 
-       /* update the free count for the allocation group and 
+       /* update the free count for the allocation group and
         * map.
         */
        agno = blkno >> bmp->db_agl2size;
@@ -2415,6 +2351,8 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
        }
 
        BMAP_UNLOCK(bmp);
+
+       return 0;
 }
 
 
@@ -2433,7 +2371,7 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
  *             or deallocation resulted in the root change.  this range
  *             is respresented by a single leaf of the current dmapctl
  *             and the leaf will be updated with this value, possibly
- *             causing a binary buddy system within the leaves to be 
+ *             causing a binary buddy system within the leaves to be
  *             split or joined.  the update may also cause the dmapctl's
  *             dmtree to be updated.
  *
@@ -2443,19 +2381,19 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
  *             the new root value and the next dmap control page level to
  *             be adjusted.
  * PARAMETERS:
- *      bmp    -  pointer to bmap descriptor
- *      blkno  -  the first block of a block range within a dmap.  it is
+ *     bmp     -  pointer to bmap descriptor
+ *     blkno   -  the first block of a block range within a dmap.  it is
  *                the allocation or deallocation of this block range that
  *                requires the dmap control page to be adjusted.
- *      newval -  the new value of the lower level dmap or dmap control
+ *     newval  -  the new value of the lower level dmap or dmap control
  *                page root.
- *      alloc  -  TRUE if adjustment is due to an allocation.
- *      level  -  current level of dmap control page (i.e. L0, L1, L2) to
+ *     alloc   -  'true' if adjustment is due to an allocation.
+ *     level   -  current level of dmap control page (i.e. L0, L1, L2) to
  *                be adjusted.
  *
  * RETURN VALUES:
- *      0      - success
- *      -EIO   - i/o error
+ *           - success
+ *     -EIO    - i/o error
  *
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  */
@@ -2517,12 +2455,16 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level)
                 * that it is at the front of a binary buddy system.
                 */
                if (oldval == NOFREE) {
-                       dbBackSplit((dmtree_t *) dcp, leafno);
+                       rc = dbBackSplit((dmtree_t *) dcp, leafno);
+                       if (rc)
+                               return rc;
                        oldval = dcp->stree[ti];
                }
                dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval);
        } else {
-               dbJoin((dmtree_t *) dcp, leafno, newval);
+               rc = dbJoin((dmtree_t *) dcp, leafno, newval);
+               if (rc)
+                       return rc;
        }
 
        /* check if the root of the current dmap control page changed due
@@ -2595,16 +2537,16 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level)
 /*
  * NAME:       dbSplit()
  *
- * FUNCTION:    update the leaf of a dmtree with a new value, splitting
+ * FUNCTION:   update the leaf of a dmtree with a new value, splitting
  *             the leaf from the binary buddy system of the dmtree's
  *             leaves, as required.
  *
  * PARAMETERS:
- *      tp     - pointer to the tree containing the leaf.
- *      leafno - the number of the leaf to be updated.
- *      splitsz        - the size the binary buddy system starting at the leaf
+ *     tp      - pointer to the tree containing the leaf.
+ *     leafno  - the number of the leaf to be updated.
+ *     splitsz - the size the binary buddy system starting at the leaf
  *               must be split to, specified as the log2 number of blocks.
- *      newval - the new value for the leaf.
+ *     newval  - the new value for the leaf.
  *
  * RETURN VALUES: none
  *
@@ -2641,7 +2583,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
                }
        }
 
-       /* adjust the dmap tree to reflect the specified leaf's new 
+       /* adjust the dmap tree to reflect the specified leaf's new
         * value.
         */
        dbAdjTree(tp, leafno, newval);
@@ -2651,7 +2593,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
 /*
  * NAME:       dbBackSplit()
  *
- * FUNCTION:    back split the binary buddy system of dmtree leaves
+ * FUNCTION:   back split the binary buddy system of dmtree leaves
  *             that hold a specified leaf until the specified leaf
  *             starts its own binary buddy system.
  *
@@ -2668,14 +2610,14 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
  *             in which a previous join operation must be backed out.
  *
  * PARAMETERS:
- *      tp     - pointer to the tree containing the leaf.
- *      leafno - the number of the leaf to be updated.
+ *     tp      - pointer to the tree containing the leaf.
+ *     leafno  - the number of the leaf to be updated.
  *
  * RETURN VALUES: none
  *
  * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
  */
-static void dbBackSplit(dmtree_t * tp, int leafno)
+static int dbBackSplit(dmtree_t * tp, int leafno)
 {
        int budsz, bud, w, bsz, size;
        int cursz;
@@ -2689,7 +2631,7 @@ static void dbBackSplit(dmtree_t * tp, int leafno)
        /* the back split is accomplished by iteratively finding the leaf
         * that starts the buddy system that contains the specified leaf and
         * splitting that system in two.  this iteration continues until
-        * the specified leaf becomes the start of a buddy system. 
+        * the specified leaf becomes the start of a buddy system.
         *
         * determine maximum possible l2 size for the specified leaf.
         */
@@ -2710,7 +2652,10 @@ static void dbBackSplit(dmtree_t * tp, int leafno)
                 */
                for (w = leafno, bsz = budsz;; bsz <<= 1,
                     w = (w < bud) ? w : bud) {
-                       assert(bsz < le32_to_cpu(tp->dmt_nleafs));
+                       if (bsz >= le32_to_cpu(tp->dmt_nleafs)) {
+                               jfs_err("JFS: block map error in dbBackSplit");
+                               return -EIO;
+                       }
 
                        /* determine the buddy.
                         */
@@ -2729,25 +2674,29 @@ static void dbBackSplit(dmtree_t * tp, int leafno)
                }
        }
 
-       assert(leaf[leafno] == size);
+       if (leaf[leafno] != size) {
+               jfs_err("JFS: wrong leaf value in dbBackSplit");
+               return -EIO;
+       }
+       return 0;
 }
 
 
 /*
  * NAME:       dbJoin()
  *
- * FUNCTION:    update the leaf of a dmtree with a new value, joining
+ * FUNCTION:   update the leaf of a dmtree with a new value, joining
  *             the leaf with other leaves of the dmtree into a multi-leaf
  *             binary buddy system, as required.
  *
  * PARAMETERS:
- *      tp     - pointer to the tree containing the leaf.
- *      leafno - the number of the leaf to be updated.
- *      newval - the new value for the leaf.
+ *     tp      - pointer to the tree containing the leaf.
+ *     leafno  - the number of the leaf to be updated.
+ *     newval  - the new value for the leaf.
  *
  * RETURN VALUES: none
  */
-static void dbJoin(dmtree_t * tp, int leafno, int newval)
+static int dbJoin(dmtree_t * tp, int leafno, int newval)
 {
        int budsz, buddy;
        s8 *leaf;
@@ -2787,7 +2736,9 @@ static void dbJoin(dmtree_t * tp, int leafno, int newval)
                        if (newval > leaf[buddy])
                                break;
 
-                       assert(newval == leaf[buddy]);
+                       /* It shouldn't be less */
+                       if (newval < leaf[buddy])
+                               return -EIO;
 
                        /* check which (leafno or buddy) is the left buddy.
                         * the left buddy gets to claim the blocks resulting
@@ -2819,21 +2770,23 @@ static void dbJoin(dmtree_t * tp, int leafno, int newval)
        /* update the leaf value.
         */
        dbAdjTree(tp, leafno, newval);
+
+       return 0;
 }
 
 
 /*
  * NAME:       dbAdjTree()
  *
- * FUNCTION:    update a leaf of a dmtree with a new value, adjusting
+ * FUNCTION:   update a leaf of a dmtree with a new value, adjusting
  *             the dmtree, as required, to reflect the new leaf value.
  *             the combination of any buddies must already be done before
  *             this is called.
  *
  * PARAMETERS:
- *      tp     - pointer to the tree to be adjusted.
- *      leafno - the number of the leaf to be updated.
- *      newval - the new value for the leaf.
+ *     tp      - pointer to the tree to be adjusted.
+ *     leafno  - the number of the leaf to be updated.
+ *     newval  - the new value for the leaf.
  *
  * RETURN VALUES: none
  */
@@ -2892,8 +2845,8 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
 /*
  * NAME:       dbFindLeaf()
  *
- * FUNCTION:    search a dmtree_t for sufficient free blocks, returning
- *             the index of a leaf describing the free blocks if 
+ * FUNCTION:   search a dmtree_t for sufficient free blocks, returning
+ *             the index of a leaf describing the free blocks if
  *             sufficient free blocks are found.
  *
  *             the search starts at the top of the dmtree_t tree and
@@ -2901,15 +2854,15 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
  *             free space.
  *
  * PARAMETERS:
- *      tp     - pointer to the tree to be searched.
- *      l2nb   - log2 number of free blocks to search for.
+ *     tp      - pointer to the tree to be searched.
+ *     l2nb    - log2 number of free blocks to search for.
  *     leafidx - return pointer to be set to the index of the leaf
  *               describing at least l2nb free blocks if sufficient
  *               free blocks are found.
  *
  * RETURN VALUES:
- *      0      - success
- *      -ENOSPC        - insufficient free blocks. 
+ *           - success
+ *     -ENOSPC - insufficient free blocks.
  */
 static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
 {
@@ -2956,18 +2909,18 @@ static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
 /*
  * NAME:       dbFindBits()
  *
- * FUNCTION:    find a specified number of binary buddy free bits within a
+ * FUNCTION:   find a specified number of binary buddy free bits within a
  *             dmap bitmap word value.
  *
  *             this routine searches the bitmap value for (1 << l2nb) free
  *             bits at (1 << l2nb) alignments within the value.
  *
  * PARAMETERS:
- *      word   -  dmap bitmap word value.
- *      l2nb   -  number of free bits specified as a log2 number.
+ *     word    -  dmap bitmap word value.
+ *     l2nb    -  number of free bits specified as a log2 number.
  *
  * RETURN VALUES:
- *      starting bit number of free bits.
+ *     starting bit number of free bits.
  */
 static int dbFindBits(u32 word, int l2nb)
 {
@@ -3003,14 +2956,14 @@ static int dbFindBits(u32 word, int l2nb)
 /*
  * NAME:       dbMaxBud(u8 *cp)
  *
- * FUNCTION:    determine the largest binary buddy string of free
+ * FUNCTION:   determine the largest binary buddy string of free
  *             bits within 32-bits of the map.
  *
  * PARAMETERS:
- *      cp     -  pointer to the 32-bit value.
+ *     cp      -  pointer to the 32-bit value.
  *
  * RETURN VALUES:
- *      largest binary buddy of free bits within a dmap word.
+ *     largest binary buddy of free bits within a dmap word.
  */
 static int dbMaxBud(u8 * cp)
 {
@@ -3040,14 +2993,14 @@ static int dbMaxBud(u8 * cp)
 /*
  * NAME:       cnttz(uint word)
  *
- * FUNCTION:    determine the number of trailing zeros within a 32-bit
+ * FUNCTION:   determine the number of trailing zeros within a 32-bit
  *             value.
  *
  * PARAMETERS:
- *      value  -  32-bit value to be examined.
+ *     value   -  32-bit value to be examined.
  *
  * RETURN VALUES:
- *      count of trailing zeros
+ *     count of trailing zeros
  */
 static int cnttz(u32 word)
 {
@@ -3065,14 +3018,14 @@ static int cnttz(u32 word)
 /*
  * NAME:       cntlz(u32 value)
  *
- * FUNCTION:    determine the number of leading zeros within a 32-bit
+ * FUNCTION:   determine the number of leading zeros within a 32-bit
  *             value.
  *
  * PARAMETERS:
- *      value  -  32-bit value to be examined.
+ *     value   -  32-bit value to be examined.
  *
  * RETURN VALUES:
- *      count of leading zeros
+ *     count of leading zeros
  */
 static int cntlz(u32 value)
 {
@@ -3090,16 +3043,16 @@ static int cntlz(u32 value)
  * NAME:       blkstol2(s64 nb)
  *
  * FUNCTION:   convert a block count to its log2 value. if the block
- *             count is not a l2 multiple, it is rounded up to the next
+ *             count is not a l2 multiple, it is rounded up to the next
  *             larger l2 multiple.
  *
  * PARAMETERS:
- *      nb     -  number of blocks
+ *     nb      -  number of blocks
  *
  * RETURN VALUES:
- *      log2 number of blocks
+ *     log2 number of blocks
  */
-int blkstol2(s64 nb)
+static int blkstol2(s64 nb)
 {
        int l2nb;
        s64 mask;               /* meant to be signed */
@@ -3130,7 +3083,7 @@ int blkstol2(s64 nb)
 
 
 /*
- * NAME:       dbAllocBottomUp()
+ * NAME:       dbAllocBottomUp()
  *
  * FUNCTION:   alloc the specified block range from the working block
  *             allocation map.
@@ -3139,13 +3092,13 @@ int blkstol2(s64 nb)
  *             at a time.
  *
  * PARAMETERS:
- *      ip     -  pointer to in-core inode;
- *      blkno  -  starting block number to be freed.
- *      nblocks        -  number of blocks to be freed.
+ *     ip      -  pointer to in-core inode;
+ *     blkno   -  starting block number to be freed.
+ *     nblocks -  number of blocks to be freed.
  *
  * RETURN VALUES:
- *      0      - success
- *      -EIO   - i/o error
+ *           - success
+ *     -EIO    - i/o error
  */
 int dbAllocBottomUp(struct inode *ip, s64 blkno, s64 nblocks)
 {
@@ -3156,7 +3109,7 @@ int dbAllocBottomUp(struct inode *ip, s64 blkno, s64 nblocks)
        struct inode *ipbmap = JFS_SBI(ip->i_sb)->ipbmap;
        struct bmap *bmp = JFS_SBI(ip->i_sb)->bmap;
 
-       IREAD_LOCK(ipbmap);
+       IREAD_LOCK(ipbmap, RDWRLOCK_DMAP);
 
        /* block to be allocated better be within the mapsize. */
        ASSERT(nblocks <= bmp->db_mapsize - blkno);
@@ -3185,16 +3138,12 @@ int dbAllocBottomUp(struct inode *ip, s64 blkno, s64 nblocks)
                 */
                nb = min(rem, BPERDMAP - (blkno & (BPERDMAP - 1)));
 
-               DBFREECK(bmp->db_DBmap, bmp->db_mapsize, blkno, nb);
-
                /* allocate the blocks. */
                if ((rc = dbAllocDmapBU(bmp, dp, blkno, nb))) {
                        release_metapage(mp);
                        IREAD_UNLOCK(ipbmap);
                        return (rc);
                }
-
-               DBALLOC(bmp->db_DBmap, bmp->db_mapsize, blkno, nb);
        }
 
        /* write the last buffer. */
@@ -3277,7 +3226,7 @@ static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno,
        }
 
        /* update the free count for this dmap */
-       dp->nfree = cpu_to_le32(le32_to_cpu(dp->nfree) - nblocks);
+       le32_add_cpu(&dp->nfree, -nblocks);
 
        /* reconstruct summary tree */
        dbInitDmapTree(dp);
@@ -3285,7 +3234,7 @@ static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno,
        BMAP_LOCK(bmp);
 
        /* if this allocation group is completely free,
-        * update the highest active allocation group number 
+        * update the highest active allocation group number
         * if this allocation group is the new max.
         */
        agno = blkno >> bmp->db_agl2size;
@@ -3317,24 +3266,24 @@ static int dbAllocDmapBU(struct bmap * bmp, struct dmap * dp, s64 blkno,
  * NAME:       dbExtendFS()
  *
  * FUNCTION:   extend bmap from blkno for nblocks;
- *             dbExtendFS() updates bmap ready for dbAllocBottomUp();
+ *             dbExtendFS() updates bmap ready for dbAllocBottomUp();
  *
  * L2
  *  |
  *   L1---------------------------------L1
- *    |                                  |
- *     L0---------L0---------L0           L0---------L0---------L0
- *      |          |          |            |          |          |
- *       d0,...,dn  d0,...,dn  d0,...,dn    d0,...,dn  d0,...,dn  d0,.,dm;
+ *    |                                         |
+ *     L0---------L0---------L0                  L0---------L0---------L0
+ *      |         |          |            |          |          |
+ *      d0,...,dn  d0,...,dn  d0,...,dn    d0,...,dn  d0,...,dn  d0,.,dm;
  * L2L1L0d0,...,dnL0d0,...,dnL0d0,...,dnL1L0d0,...,dnL0d0,...,dnL0d0,..dm
  *
- * <---old---><----------------------------extend----------------------->   
+ * <---old---><----------------------------extend----------------------->
  */
 int dbExtendFS(struct inode *ipbmap, s64 blkno,        s64 nblocks)
 {
        struct jfs_sb_info *sbi = JFS_SBI(ipbmap->i_sb);
        int nbperpage = sbi->nbperpage;
-       int i, i0 = TRUE, j, j0 = TRUE, k, n;
+       int i, i0 = true, j, j0 = true, k, n;
        s64 newsize;
        s64 p;
        struct metapage *mp, *l2mp, *l1mp = NULL, *l0mp = NULL;
@@ -3351,7 +3300,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno,   s64 nblocks)
                 (long long) blkno, (long long) nblocks, (long long) newsize);
 
        /*
-        *      initialize bmap control page.
+        *      initialize bmap control page.
         *
         * all the data in bmap control page should exclude
         * the mkfs hidden dmap page.
@@ -3374,7 +3323,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno,   s64 nblocks)
        bmp->db_numag += ((u32) newsize % (u32) bmp->db_agsize) ? 1 : 0;
 
        /*
-        *      reconfigure db_agfree[] 
+        *      reconfigure db_agfree[]
         * from old AG configuration to new AG configuration;
         *
         * coalesce contiguous k (newAGSize/oldAGSize) AGs;
@@ -3406,7 +3355,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno,   s64 nblocks)
        bmp->db_maxag = bmp->db_maxag / k;
 
        /*
-        *      extend bmap
+        *      extend bmap
         *
         * update bit maps and corresponding level control pages;
         * global control page db_nfree, db_agfree[agno], db_maxfreebud;
@@ -3442,7 +3391,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno,   s64 nblocks)
                        j = (blkno & (MAXL1SIZE - 1)) >> L2MAXL0SIZE;
                        l1leaf = l1dcp->stree + CTLLEAFIND + j;
                        p = BLKTOL0(blkno, sbi->l2nbperpage);
-                       j0 = FALSE;
+                       j0 = false;
                } else {
                        /* assign/init L1 page */
                        l1mp = get_metapage(ipbmap, p, PSIZE, 0);
@@ -3454,7 +3403,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno,   s64 nblocks)
                        /* compute start L0 */
                        j = 0;
                        l1leaf = l1dcp->stree + CTLLEAFIND;
-                       p += nbperpage; /* 1st L0 of L1.k  */
+                       p += nbperpage; /* 1st L0 of L1.k */
                }
 
                /*
@@ -3476,7 +3425,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno,   s64 nblocks)
                                l0leaf = l0dcp->stree + CTLLEAFIND + i;
                                p = BLKTODMAP(blkno,
                                              sbi->l2nbperpage);
-                               i0 = FALSE;
+                               i0 = false;
                        } else {
                                /* assign/init L0 page */
                                l0mp = get_metapage(ipbmap, p, PSIZE, 0);
@@ -3535,7 +3484,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno,   s64 nblocks)
                        }       /* for each dmap in a L0 */
 
                        /*
-                        * build current L0 page from its leaves, and 
+                        * build current L0 page from its leaves, and
                         * initialize corresponding parent L1 leaf
                         */
                        *l1leaf = dbInitDmapCtl(l0dcp, 0, ++i);
@@ -3559,7 +3508,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno,   s64 nblocks)
                }               /* for each L0 in a L1 */
 
                /*
-                * build current L1 page from its leaves, and 
+                * build current L1 page from its leaves, and
                 * initialize corresponding parent L2 leaf
                 */
                *l2leaf = dbInitDmapCtl(l1dcp, 1, ++j);
@@ -3592,7 +3541,7 @@ errout:
        return -EIO;
 
        /*
-        *      finalize bmap control page
+        *      finalize bmap control page
         */
 finalize:
 
@@ -3611,10 +3560,10 @@ void dbFinalizeBmap(struct inode *ipbmap)
        int i, n;
 
        /*
-        *      finalize bmap control page
+        *      finalize bmap control page
         */
 //finalize:
-       /* 
+       /*
         * compute db_agpref: preferred ag to allocate from
         * (the leftmost ag with average free space in it);
         */
@@ -3658,9 +3607,9 @@ void dbFinalizeBmap(struct inode *ipbmap)
 
        /*
         * compute db_aglevel, db_agheigth, db_width, db_agstart:
-        * an ag is covered in aglevel dmapctl summary tree, 
-        * at agheight level height (from leaf) with agwidth number of nodes 
-        * each, which starts at agstart index node of the smmary tree node 
+        * an ag is covered in aglevel dmapctl summary tree,
+        * at agheight level height (from leaf) with agwidth number of nodes
+        * each, which starts at agstart index node of the smmary tree node
         * array;
         */
        bmp->db_aglevel = BMAPSZTOLEV(bmp->db_agsize);
@@ -3679,13 +3628,13 @@ void dbFinalizeBmap(struct inode *ipbmap)
 
 /*
  * NAME:       dbInitDmap()/ujfs_idmap_page()
- *                                                                    
+ *
  * FUNCTION:   initialize working/persistent bitmap of the dmap page
  *             for the specified number of blocks:
- *                                                                    
+ *
  *             at entry, the bitmaps had been initialized as free (ZEROS);
- *             The number of blocks will only account for the actually 
- *             existing blocks. Blocks which don't actually exist in 
+ *             The number of blocks will only account for the actually
+ *             existing blocks. Blocks which don't actually exist in
  *             the aggregate will be marked as allocated (ONES);
  *
  * PARAMETERS:
@@ -3711,9 +3660,8 @@ static int dbInitDmap(struct dmap * dp, s64 Blkno, int nblocks)
                        goto initTree;
                }
        } else {
-               dp->nblocks =
-                   cpu_to_le32(le32_to_cpu(dp->nblocks) + nblocks);
-               dp->nfree = cpu_to_le32(le32_to_cpu(dp->nfree) + nblocks);
+               le32_add_cpu(&dp->nblocks, nblocks);
+               le32_add_cpu(&dp->nfree, nblocks);
        }
 
        /* word number containing start block number */
@@ -3721,7 +3669,7 @@ static int dbInitDmap(struct dmap * dp, s64 Blkno, int nblocks)
 
        /*
         * free the bits corresponding to the block range (ZEROS):
-        * note: not all bits of the first and last words may be contained 
+        * note: not all bits of the first and last words may be contained
         * within the block range.
         */
        for (r = nblocks; r > 0; r -= nb, blkno += nb) {
@@ -3753,7 +3701,7 @@ static int dbInitDmap(struct dmap * dp, s64 Blkno, int nblocks)
        }
 
        /*
-        * mark bits following the range to be freed (non-existing 
+        * mark bits following the range to be freed (non-existing
         * blocks) as allocated (ONES)
         */
 
@@ -3785,11 +3733,11 @@ static int dbInitDmap(struct dmap * dp, s64 Blkno, int nblocks)
 
 /*
  * NAME:       dbInitDmapTree()/ujfs_complete_dmap()
- *                                                                    
+ *
  * FUNCTION:   initialize summary tree of the specified dmap:
  *
  *             at entry, bitmap of the dmap has been initialized;
- *                                                                    
+ *
  * PARAMETERS:
  *     dp      - dmap to complete
  *     blkno   - starting block number for this dmap
@@ -3813,7 +3761,7 @@ static int dbInitDmapTree(struct dmap * dp)
 
        /* init each leaf from corresponding wmap word:
         * note: leaf is set to NOFREE(-1) if all blocks of corresponding
-        * bitmap word are allocated. 
+        * bitmap word are allocated.
         */
        cp = tp->stree + le32_to_cpu(tp->leafidx);
        for (i = 0; i < LPERDMAP; i++)
@@ -3826,10 +3774,10 @@ static int dbInitDmapTree(struct dmap * dp)
 
 /*
  * NAME:       dbInitTree()/ujfs_adjtree()
- *                                                                    
+ *
  * FUNCTION:   initialize binary buddy summary tree of a dmap or dmapctl.
  *
- *             at entry, the leaves of the tree has been initialized 
+ *             at entry, the leaves of the tree has been initialized
  *             from corresponding bitmap word or root of summary tree
  *             of the child control page;
  *             configure binary buddy system at the leaf level, then
@@ -3857,15 +3805,15 @@ static int dbInitTree(struct dmaptree * dtp)
        /*
         * configure the leaf levevl into binary buddy system
         *
-        * Try to combine buddies starting with a buddy size of 1 
-        * (i.e. two leaves). At a buddy size of 1 two buddy leaves 
-        * can be combined if both buddies have a maximum free of l2min; 
-        * the combination will result in the left-most buddy leaf having 
-        * a maximum free of l2min+1.  
-        * After processing all buddies for a given size, process buddies 
-        * at the next higher buddy size (i.e. current size * 2) and 
-        * the next maximum free (current free + 1).  
-        * This continues until the maximum possible buddy combination 
+        * Try to combine buddies starting with a buddy size of 1
+        * (i.e. two leaves). At a buddy size of 1 two buddy leaves
+        * can be combined if both buddies have a maximum free of l2min;
+        * the combination will result in the left-most buddy leaf having
+        * a maximum free of l2min+1.
+        * After processing all buddies for a given size, process buddies
+        * at the next higher buddy size (i.e. current size * 2) and
+        * the next maximum free (current free + 1).
+        * This continues until the maximum possible buddy combination
         * yields maximum free.
         */
        for (l2free = dtp->budmin, bsize = 1; l2free < l2max;
@@ -3889,10 +3837,10 @@ static int dbInitTree(struct dmaptree * dtp)
         * bubble summary information of leaves up the tree.
         *
         * Starting at the leaf node level, the four nodes described by
-        * the higher level parent node are compared for a maximum free and 
-        * this maximum becomes the value of the parent node.  
-        * when all lower level nodes are processed in this fashion then 
-        * move up to the next level (parent becomes a lower level node) and 
+        * the higher level parent node are compared for a maximum free and
+        * this maximum becomes the value of the parent node.
+        * when all lower level nodes are processed in this fashion then
+        * move up to the next level (parent becomes a lower level node) and
         * continue the process for that level.
         */
        for (child = le32_to_cpu(dtp->leafidx),
@@ -3901,7 +3849,7 @@ static int dbInitTree(struct dmaptree * dtp)
                /* get index of 1st node of parent level */
                parent = (child - 1) >> 2;
 
-               /* set the value of the parent node as the maximum 
+               /* set the value of the parent node as the maximum
                 * of the four nodes of the current level.
                 */
                for (i = 0, cp = tp + child, cp1 = tp + parent;
@@ -3929,8 +3877,8 @@ static int dbInitDmapCtl(struct dmapctl * dcp, int level, int i)
        dcp->budmin = L2BPERDMAP + L2LPERCTL * level;
 
        /*
-        * initialize the leaves of current level that were not covered 
-        * by the specified input block range (i.e. the leaves have no 
+        * initialize the leaves of current level that were not covered
+        * by the specified input block range (i.e. the leaves have no
         * low level dmapctl or dmap).
         */
        cp = &dcp->stree[CTLLEAFIND + i];
@@ -3944,9 +3892,9 @@ static int dbInitDmapCtl(struct dmapctl * dcp, int level, int i)
 
 /*
  * NAME:       dbGetL2AGSize()/ujfs_getagl2size()
- *                                                                    
+ *
  * FUNCTION:   Determine log2(allocation group size) from aggregate size
- *                                                                    
+ *
  * PARAMETERS:
  *     nblocks - Number of blocks in aggregate
  *
@@ -3979,8 +3927,8 @@ static int dbGetL2AGSize(s64 nblocks)
 
 /*
  * NAME:       dbMapFileSizeToMapSize()
- *                                                                    
- * FUNCTION:   compute number of blocks the block allocation map file 
+ *
+ * FUNCTION:   compute number of blocks the block allocation map file
  *             can cover from the map file size;
  *
  * RETURNS:    Number of blocks which can be covered by this block map file;
@@ -3997,8 +3945,8 @@ static int dbGetL2AGSize(s64 nblocks)
  * convert number of map pages to the zero origin top dmapctl level
  */
 #define BMAPPGTOLEV(npages)    \
-       (((npages) <= 3 + MAXL0PAGES) ? 0 \
-       : ((npages) <= 2 + MAXL1PAGES) ? 1 : 2)
+       (((npages) <= 3 + MAXL0PAGES) ? 0 \
+        ((npages) <= 2 + MAXL1PAGES) ? 1 : 2)
 
 s64 dbMapFileSizeToMapSize(struct inode * ipbmap)
 {
@@ -4012,7 +3960,7 @@ s64 dbMapFileSizeToMapSize(struct inode * ipbmap)
        npages = nblocks >> JFS_SBI(sb)->l2nbperpage;
        level = BMAPPGTOLEV(npages);
 
-       /* At each level, accumulate the number of dmap pages covered by 
+       /* At each level, accumulate the number of dmap pages covered by
         * the number of full child levels below it;
         * repeat for the last incomplete child level.
         */
@@ -4025,8 +3973,8 @@ s64 dbMapFileSizeToMapSize(struct inode * ipbmap)
                factor =
                    (i == 2) ? MAXL1PAGES : ((i == 1) ? MAXL0PAGES : 1);
                complete = (u32) npages / factor;
-               ndmaps += complete * ((i == 2) ? LPERCTL * LPERCTL
-                                     ((i == 1) ? LPERCTL : 1));
+               ndmaps += complete * ((i == 2) ? LPERCTL * LPERCTL :
+                                     ((i == 1) ? LPERCTL : 1));
 
                /* pages in last/incomplete child */
                npages = (u32) npages % factor;
@@ -4034,230 +3982,10 @@ s64 dbMapFileSizeToMapSize(struct inode * ipbmap)
                npages--;
        }
 
-       /* convert the number of dmaps into the number of blocks 
+       /* convert the number of dmaps into the number of blocks
         * which can be covered by the dmaps;
         */
        nblocks = ndmaps << L2BPERDMAP;
 
        return (nblocks);
 }
-
-
-#ifdef _JFS_DEBUG_DMAP
-/*
- *     DBinitmap()
- */
-static void DBinitmap(s64 size, struct inode *ipbmap, u32 ** results)
-{
-       int npages;
-       u32 *dbmap, *d;
-       int n;
-       s64 lblkno, cur_block;
-       struct dmap *dp;
-       struct metapage *mp;
-
-       npages = size / 32768;
-       npages += (size % 32768) ? 1 : 0;
-
-       dbmap = (u32 *) xmalloc(npages * 4096, L2PSIZE, kernel_heap);
-       if (dbmap == NULL)
-               BUG();  /* Not robust since this is only unused debug code */
-
-       for (n = 0, d = dbmap; n < npages; n++, d += 1024)
-               bzero(d, 4096);
-
-       /* Need to initialize from disk map pages
-        */
-       for (d = dbmap, cur_block = 0; cur_block < size;
-            cur_block += BPERDMAP, d += LPERDMAP) {
-               lblkno = BLKTODMAP(cur_block,
-                                  JFS_SBI(ipbmap->i_sb)->bmap->
-                                  db_l2nbperpage);
-               mp = read_metapage(ipbmap, lblkno, PSIZE, 0);
-               if (mp == NULL) {
-                       jfs_error(ipbmap->i_sb,
-                                 "DBinitmap: could not read disk map page");
-                       continue;
-               }
-               dp = (struct dmap *) mp->data;
-
-               for (n = 0; n < LPERDMAP; n++)
-                       d[n] = le32_to_cpu(dp->wmap[n]);
-
-               release_metapage(mp);
-       }
-
-       *results = dbmap;
-}
-
-
-/*
- *     DBAlloc()
- */
-void DBAlloc(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks)
-{
-       int word, nb, bitno;
-       u32 mask;
-
-       assert(blkno > 0 && blkno < mapsize);
-       assert(nblocks > 0 && nblocks <= mapsize);
-
-       assert(blkno + nblocks <= mapsize);
-
-       dbmap += (blkno / 32);
-       while (nblocks > 0) {
-               bitno = blkno & (32 - 1);
-               nb = min(nblocks, 32 - bitno);
-
-               mask = (0xffffffff << (32 - nb) >> bitno);
-               assert((mask & *dbmap) == 0);
-               *dbmap |= mask;
-
-               dbmap++;
-               blkno += nb;
-               nblocks -= nb;
-       }
-}
-
-
-/*
- *     DBFree()
- */
-static void DBFree(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks)
-{
-       int word, nb, bitno;
-       u32 mask;
-
-       assert(blkno > 0 && blkno < mapsize);
-       assert(nblocks > 0 && nblocks <= mapsize);
-
-       assert(blkno + nblocks <= mapsize);
-
-       dbmap += (blkno / 32);
-       while (nblocks > 0) {
-               bitno = blkno & (32 - 1);
-               nb = min(nblocks, 32 - bitno);
-
-               mask = (0xffffffff << (32 - nb) >> bitno);
-               assert((mask & *dbmap) == mask);
-               *dbmap &= ~mask;
-
-               dbmap++;
-               blkno += nb;
-               nblocks -= nb;
-       }
-}
-
-
-/*
- *     DBAllocCK()
- */
-static void DBAllocCK(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks)
-{
-       int word, nb, bitno;
-       u32 mask;
-
-       assert(blkno > 0 && blkno < mapsize);
-       assert(nblocks > 0 && nblocks <= mapsize);
-
-       assert(blkno + nblocks <= mapsize);
-
-       dbmap += (blkno / 32);
-       while (nblocks > 0) {
-               bitno = blkno & (32 - 1);
-               nb = min(nblocks, 32 - bitno);
-
-               mask = (0xffffffff << (32 - nb) >> bitno);
-               assert((mask & *dbmap) == mask);
-
-               dbmap++;
-               blkno += nb;
-               nblocks -= nb;
-       }
-}
-
-
-/*
- *     DBFreeCK()
- */
-static void DBFreeCK(uint * dbmap, s64 mapsize, s64 blkno, s64 nblocks)
-{
-       int word, nb, bitno;
-       u32 mask;
-
-       assert(blkno > 0 && blkno < mapsize);
-       assert(nblocks > 0 && nblocks <= mapsize);
-
-       assert(blkno + nblocks <= mapsize);
-
-       dbmap += (blkno / 32);
-       while (nblocks > 0) {
-               bitno = blkno & (32 - 1);
-               nb = min(nblocks, 32 - bitno);
-
-               mask = (0xffffffff << (32 - nb) >> bitno);
-               assert((mask & *dbmap) == 0);
-
-               dbmap++;
-               blkno += nb;
-               nblocks -= nb;
-       }
-}
-
-
-/*
- *     dbPrtMap()
- */
-static void dbPrtMap(struct bmap * bmp)
-{
-       printk("   mapsize:   %d%d\n", bmp->db_mapsize);
-       printk("   nfree:     %d%d\n", bmp->db_nfree);
-       printk("   numag:     %d\n", bmp->db_numag);
-       printk("   agsize:    %d%d\n", bmp->db_agsize);
-       printk("   agl2size:  %d\n", bmp->db_agl2size);
-       printk("   agwidth:   %d\n", bmp->db_agwidth);
-       printk("   agstart:   %d\n", bmp->db_agstart);
-       printk("   agheigth:  %d\n", bmp->db_agheigth);
-       printk("   aglevel:   %d\n", bmp->db_aglevel);
-       printk("   maxlevel:  %d\n", bmp->db_maxlevel);
-       printk("   maxag:     %d\n", bmp->db_maxag);
-       printk("   agpref:    %d\n", bmp->db_agpref);
-       printk("   l2nbppg:   %d\n", bmp->db_l2nbperpage);
-}
-
-
-/*
- *     dbPrtCtl()
- */
-static void dbPrtCtl(struct dmapctl * dcp)
-{
-       int i, j, n;
-
-       printk("   height:    %08x\n", le32_to_cpu(dcp->height));
-       printk("   leafidx:   %08x\n", le32_to_cpu(dcp->leafidx));
-       printk("   budmin:    %08x\n", dcp->budmin);
-       printk("   nleafs:    %08x\n", le32_to_cpu(dcp->nleafs));
-       printk("   l2nleafs:  %08x\n", le32_to_cpu(dcp->l2nleafs));
-
-       printk("\n Tree:\n");
-       for (i = 0; i < CTLLEAFIND; i += 8) {
-               n = min(8, CTLLEAFIND - i);
-
-               for (j = 0; j < n; j++)
-                       printf("  [%03x]: %02x", i + j,
-                              (char) dcp->stree[i + j]);
-               printf("\n");
-       }
-
-       printk("\n Tree Leaves:\n");
-       for (i = 0; i < LPERCTL; i += 8) {
-               n = min(8, LPERCTL - i);
-
-               for (j = 0; j < n; j++)
-                       printf("  [%03x]: %02x",
-                              i + j,
-                              (char) dcp->stree[i + j + CTLLEAFIND]);
-               printf("\n");
-       }
-}
-#endif                         /* _JFS_DEBUG_DMAP */