aboutsummaryrefslogtreecommitdiff
path: root/fs/jfs/jfs_dmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jfs/jfs_dmap.c')
-rw-r--r--fs/jfs/jfs_dmap.c344
1 files changed, 38 insertions, 306 deletions
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index cced2fed9d0..c739626f5bf 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -26,36 +26,6 @@
#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
@@ -105,7 +75,7 @@ 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 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);
@@ -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
@@ -407,16 +376,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. */
@@ -775,10 +741,6 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
IWRITE_LOCK(ipbmap);
rc = dbAllocAny(bmp, nblocks, l2nb, results);
- if (rc == 0) {
- DBALLOC(bmp->db_DBmap, bmp->db_mapsize, *results,
- nblocks);
- }
goto write_unlock;
}
@@ -836,8 +798,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 +823,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 +835,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;
@@ -896,13 +850,9 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
* 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);
+ if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results)) != -ENOSPC)
goto write_unlock;
- }
+
IWRITE_UNLOCK(ipbmap);
@@ -918,9 +868,6 @@ int dbAlloc(struct inode *ip, s64 hint, s64 nblocks, s64 * results)
*/
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);
@@ -992,10 +939,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);
@@ -1144,7 +1090,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 +1100,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);
@@ -2078,7 +2021,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,11 +2029,11 @@ 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,
@@ -2279,15 +2222,16 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
* 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
@@ -2336,8 +2280,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 +2314,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.
*/
@@ -2415,6 +2363,8 @@ static void dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
}
BMAP_UNLOCK(bmp);
+
+ return 0;
}
@@ -2522,7 +2472,9 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level)
}
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
@@ -2747,7 +2699,7 @@ static void dbBackSplit(dmtree_t * tp, int leafno)
*
* 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 +2739,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,6 +2773,8 @@ static void dbJoin(dmtree_t * tp, int leafno, int newval)
/* update the leaf value.
*/
dbAdjTree(tp, leafno, newval);
+
+ return 0;
}
@@ -3185,16 +3141,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. */
@@ -4041,223 +3993,3 @@ s64 dbMapFileSizeToMapSize(struct inode * ipbmap)
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 */