21 #include <linux/slab.h>
70 #define BMAP_LOCK_INIT(bmp) mutex_init(&bmp->db_bmaplock)
71 #define BMAP_LOCK(bmp) mutex_lock(&bmp->db_bmaplock)
72 #define BMAP_UNLOCK(bmp) mutex_unlock(&bmp->db_bmaplock)
77 static void dbAllocBits(
struct bmap * bmp,
struct dmap *
dp,
s64 blkno,
79 static void dbSplit(
dmtree_t * tp,
int leafno,
int splitsz,
int newval);
80 static int dbBackSplit(
dmtree_t * tp,
int leafno);
81 static int dbJoin(
dmtree_t * tp,
int leafno,
int newval);
82 static void dbAdjTree(
dmtree_t * tp,
int leafno,
int newval);
83 static int dbAdjCtl(
struct bmap * bmp,
s64 blkno,
int newval,
int alloc,
85 static int dbAllocAny(
struct bmap * bmp,
s64 nblocks,
int l2nb,
s64 * results);
86 static int dbAllocNext(
struct bmap * bmp,
struct dmap *
dp,
s64 blkno,
88 static int dbAllocNear(
struct bmap * bmp,
struct dmap *
dp,
s64 blkno,
90 int l2nb,
s64 * results);
91 static int dbAllocDmap(
struct bmap * bmp,
struct dmap *
dp,
s64 blkno,
93 static int dbAllocDmapLev(
struct bmap * bmp,
struct dmap *
dp,
int nblocks,
96 static int dbAllocAG(
struct bmap * bmp,
int agno,
s64 nblocks,
int l2nb,
98 static int dbAllocCtl(
struct bmap * bmp,
s64 nblocks,
int l2nb,
s64 blkno,
100 static int dbExtend(
struct inode *
ip,
s64 blkno,
s64 nblocks,
s64 addnblocks);
101 static int dbFindBits(
u32 word,
int l2nb);
102 static int dbFindCtl(
struct bmap * bmp,
int l2nb,
int level,
s64 * blkno);
103 static int dbFindLeaf(
dmtree_t * tp,
int l2nb,
int *leafidx);
104 static int dbFreeBits(
struct bmap * bmp,
struct dmap *
dp,
s64 blkno,
106 static int dbFreeDmap(
struct bmap * bmp,
struct dmap *
dp,
s64 blkno,
108 static int dbMaxBud(
u8 *
cp);
109 static int blkstol2(
s64 nb);
114 static int dbAllocDmapBU(
struct bmap * bmp,
struct dmap *
dp,
s64 blkno,
116 static int dbInitDmap(
struct dmap *
dp,
s64 blkno,
int nblocks);
117 static int dbInitDmapTree(
struct dmap *
dp);
118 static int dbInitTree(
struct dmaptree * dtp);
119 static int dbInitDmapCtl(
struct dmapctl * dcp,
int level,
int i);
120 static int dbGetL2AGSize(
s64 nblocks);
130 static const s8 budtab[256] = {
131 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
132 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
133 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
134 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
135 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
136 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
137 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
138 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
139 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
140 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
141 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
142 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
143 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
144 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
145 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
146 2, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -1
203 for (i = 0; i <
MAXAG; i++)
213 JFS_SBI(ipbmap->
i_sb)->bmap = bmp;
244 struct bmap *bmp = JFS_SBI(ipbmap->
i_sb)->bmap;
246 if (!(mounterror || isReadOnly(ipbmap)))
266 struct bmap *bmp = JFS_SBI(ipbmap->
i_sb)->bmap;
278 jfs_err(
"dbSync: read_metapage failed!");
295 for (i = 0; i <
MAXAG; i++)
337 struct inode *ipbmap = JFS_SBI(ip->
i_sb)->ipbmap;
338 struct bmap *bmp = JFS_SBI(ip->
i_sb)->bmap;
344 if (
unlikely((blkno == 0) || (blkno + nblocks > bmp->db_mapsize))) {
347 (
unsigned long long) blkno,
348 (
unsigned long long) nblocks);
350 "dbFree: block to be freed is outside the map");
358 if (JFS_SBI(sb)->minblks_trim <= nblocks)
365 for (rem = nblocks; rem > 0; rem -= nb, blkno += nb) {
372 lblkno =
BLKTODMAP(blkno, bmp->db_l2nbperpage);
386 if ((rc = dbFreeDmap(bmp, dp, blkno, nb))) {
428 int nblks, dbitno, wbitno, rbits;
429 int word, nbits, nwords;
430 struct bmap *bmp = JFS_SBI(ipbmap->
i_sb)->bmap;
431 s64 lblkno, rem, lastlblkno;
436 int lsn, difft, diffp;
440 if (blkno + nblocks > bmp->db_mapsize) {
442 (
unsigned long long) blkno,
443 (
unsigned long long) nblocks);
445 "dbUpdatePMap: blocks are outside the map");
451 log = (
struct jfs_log *) JFS_SBI(tblk->
sb)->log;
459 for (rem = nblocks; rem > 0; rem -= nblks, blkno += nblks) {
461 lblkno =
BLKTODMAP(blkno, bmp->db_l2nbperpage);
462 if (lblkno != lastlblkno) {
471 metapage_wait_for_io(mp);
490 for (rbits = nblks; rbits > 0;
491 rbits -= nbits, dbitno += nbits) {
495 wbitno = dbitno & (
DBWORD - 1);
538 if (lblkno == lastlblkno)
612 struct bmap *bmp = JFS_SBI(ipbmap->
i_sb)->bmap;
617 avgfree = (
u32)bmp->db_nfree / bmp->db_numag;
623 agpref = bmp->db_agpref;
625 (bmp->db_agfree[agpref] >= avgfree))
631 for (i = 0 ; i < bmp->db_numag; i++, agpref++) {
632 if (agpref == bmp->db_numag)
638 if (bmp->db_agfree[agpref] >= avgfree) {
640 bmp->db_agpref = agpref;
642 }
else if (bmp->db_agfree[agpref] > hwm) {
644 hwm = bmp->db_agfree[agpref];
654 bmp->db_agpref = next_best;
661 return (bmp->db_agpref);
705 struct inode *ipbmap = JFS_SBI(ip->
i_sb)->ipbmap;
723 bmp = JFS_SBI(ip->
i_sb)->bmap;
725 mapSize = bmp->db_mapsize;
728 if (hint >= mapSize) {
736 if (l2nb > bmp->db_agl2size) {
739 rc = dbAllocAny(bmp, nblocks, l2nb, results);
756 if (blkno >= bmp->db_mapsize)
759 agno = blkno >> bmp->db_agl2size;
765 if ((blkno & (bmp->db_agsize - 1)) == 0)
783 lblkno =
BLKTODMAP(blkno, bmp->db_l2nbperpage);
793 if ((rc = dbAllocNext(bmp, dp, blkno, (
int) nblocks))
806 ((writers == 1) && (JFS_IP(ip)->active_ag != agno))) {
820 dbAllocNear(bmp, dp, blkno, (
int) nblocks, l2nb, results))
832 if ((rc = dbAllocDmapLev(bmp, dp, (
int) nblocks, l2nb, results))
849 if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results)) != -
ENOSPC)
865 if ((rc = dbAllocAG(bmp, agno, nblocks, l2nb, results)) == -
ENOSPC)
866 rc = dbAllocAny(bmp, nblocks, l2nb, results);
898 struct inode *ipbmap = JFS_SBI(ip->
i_sb)->ipbmap;
899 struct bmap *bmp = JFS_SBI(ip->
i_sb)->bmap;
913 if (nblocks <= 0 || nblocks >
BPERDMAP || blkno >= bmp->db_mapsize) {
918 if (nblocks > ((
s64) 1 << bmp->db_maxfreebud)) {
925 lblkno =
BLKTODMAP(blkno, bmp->db_l2nbperpage);
934 rc = dbAllocNext(bmp, dp, blkno, nblocks);
987 if ((rc = dbExtend(ip, blkno, nblocks, addnblocks)) == 0) {
1001 (ip, blkno + nblocks - 1, addnblocks + nblocks, results));
1028 static int dbExtend(
struct inode *ip,
s64 blkno,
s64 nblocks,
s64 addnblocks)
1031 s64 lblkno, lastblkno, extblkno;
1042 if (((rel_block = blkno & (sbi->
nbperpage - 1))) &&
1043 (rel_block + nblocks + addnblocks > sbi->
nbperpage))
1047 lastblkno = blkno + nblocks - 1;
1052 extblkno = lastblkno + 1;
1058 if (lastblkno < 0 || lastblkno >= bmp->db_mapsize) {
1061 "dbExtend: the block is outside the filesystem");
1073 if (addnblocks >
BPERDMAP || extblkno >= bmp->db_mapsize ||
1074 (extblkno & (bmp->db_agsize - 1)) == 0) {
1082 lblkno =
BLKTODMAP(extblkno, bmp->db_l2nbperpage);
1094 rc = dbAllocNext(bmp, dp, extblkno, (
int) addnblocks);
1128 static int dbAllocNext(
struct bmap * bmp,
struct dmap * dp,
s64 blkno,
1131 int dbitno,
word, rembits, nb, nwords, wbitno, nw;
1138 "dbAllocNext: Corrupt dmap page");
1161 if (leaf[word] ==
NOFREE)
1177 for (rembits = nblocks; rembits > 0; rembits -= nb, dbitno += nb) {
1181 wbitno = dbitno & (
DBWORD - 1);
1205 while (nwords > 0) {
1229 return (dbAllocDmap(bmp, dp, blkno, nblocks));
1261 dbAllocNear(
struct bmap * bmp,
1262 struct dmap * dp,
s64 blkno,
int nblocks,
int l2nb,
s64 * results)
1269 "dbAllocNear: Corrupt dmap page");
1284 for (; word <
lword; word++) {
1287 if (leaf[word] < l2nb)
1306 if ((rc = dbAllocDmap(bmp, dp, blkno, nblocks)) == 0)
1371 dbAllocAG(
struct bmap * bmp,
int agno,
s64 nblocks,
int l2nb,
s64 * results)
1375 int rc, ti,
i,
k,
m,
n, agperlev;
1382 if (l2nb > bmp->db_agl2size) {
1384 "dbAllocAG: allocation request is larger than the "
1385 "allocation group size");
1392 blkno = (
s64) agno << bmp->db_agl2size;
1412 || bmp->db_agfree[agno] == bmp->db_agsize) {
1413 rc = dbAllocCtl(bmp, nblocks, l2nb, blkno, results);
1415 (bmp->db_agfree[agno] == bmp->db_agsize)) {
1417 (
unsigned long long) blkno,
1418 (
unsigned long long) nblocks);
1420 "dbAllocAG: dbAllocCtl failed in free AG");
1428 lblkno =
BLKTOCTL(blkno, bmp->db_l2nbperpage, bmp->db_aglevel);
1437 "dbAllocAG: Corrupt dmapctl page");
1450 (1 << (
L2LPERCTL - (bmp->db_agheight << 1))) / bmp->db_agwidth;
1451 ti = bmp->db_agstart + bmp->db_agwidth * (agno & (agperlev - 1));
1459 for (i = 0; i < bmp->db_agwidth; i++, ti++) {
1462 if (l2nb > dcp->
stree[ti])
1469 for (k = bmp->db_agheight; k > 0; k--) {
1470 for (n = 0, m = (ti << 2) + 1; n < 4; n++) {
1471 if (l2nb <= dcp->
stree[m + n]) {
1478 "dbAllocAG: failed descending stree");
1487 if (bmp->db_aglevel == 2)
1489 else if (bmp->db_aglevel == 1)
1507 if (l2nb < budmin) {
1514 dbFindCtl(bmp, l2nb, bmp->db_aglevel - 1,
1518 "dbAllocAG: control page "
1528 rc = dbAllocCtl(bmp, nblocks, l2nb, blkno, results);
1531 "dbAllocAG: unable to allocate blocks");
1572 static int dbAllocAny(
struct bmap * bmp,
s64 nblocks,
int l2nb,
s64 * results)
1583 if ((rc = dbFindCtl(bmp, l2nb, bmp->db_maxlevel, &blkno)))
1588 rc = dbAllocCtl(bmp, nblocks, l2nb, blkno, results);
1591 "dbAllocAny: unable to allocate blocks");
1630 struct inode *ipbmap = JFS_SBI(ip->
i_sb)->ipbmap;
1631 struct bmap *bmp = JFS_SBI(ip->
i_sb)->bmap;
1643 int count = 0, range_cnt;
1649 nblocks = bmp->db_agfree[agno];
1650 max_ranges = nblocks;
1651 do_div(max_ranges, minlen);
1652 range_cnt =
min_t(
u64, max_ranges + 1, 32 * 1024);
1654 if (totrim ==
NULL) {
1656 "dbDiscardAG: no memory for trim array");
1662 while (nblocks >= minlen) {
1666 rc = dbAllocAG(bmp, agno, nblocks, l2nb, &blkno);
1669 tt->nblocks = nblocks;
1673 if (bmp->db_agfree[agno] == 0)
1677 nblocks = bmp->db_agfree[agno];
1679 }
else if (rc == -
ENOSPC) {
1682 nblocks = 1 << l2nb;
1686 "dbDiscardAG: -EIO");
1691 if (
unlikely(count >= range_cnt - 1))
1697 for (tt = totrim; tt->nblocks != 0; tt++) {
1702 dbFree(ip, tt->blkno, tt->nblocks);
1703 trimmed += tt->nblocks;
1738 static int dbFindCtl(
struct bmap * bmp,
int l2nb,
int level,
s64 * blkno)
1740 int rc, leafidx, lev;
1751 for (lev = level, b = *blkno; lev >= 0; lev--) {
1755 lblkno =
BLKTOCTL(b, bmp->db_l2nbperpage, lev);
1764 "dbFindCtl: Corrupt dmapctl page");
1774 rc = dbFindLeaf((
dmtree_t *) dcp, l2nb, &leafidx);
1785 "dbFindCtl: dmap inconsistent");
1857 dbAllocCtl(
struct bmap * bmp,
s64 nblocks,
int l2nb,
s64 blkno,
s64 * results)
1869 lblkno =
BLKTODMAP(blkno, bmp->db_l2nbperpage);
1877 rc = dbAllocDmapLev(bmp, dp, (
int)
nblocks, l2nb, results);
1893 for (n = nblocks, b = blkno; n > 0; n -= nb, b += nb) {
1896 lblkno =
BLKTODMAP(b, bmp->db_l2nbperpage);
1909 "dbAllocCtl: the dmap is not all free");
1920 if ((rc = dbAllocDmap(bmp, dp, b, nb))) {
1945 for (n = nblocks - n, b = blkno; n > 0;
1949 lblkno =
BLKTODMAP(b, bmp->db_l2nbperpage);
1956 "dbAllocCtl: I/O Error: Block Leakage.");
1969 "dbAllocCtl: Block Leakage.");
2009 dbAllocDmapLev(
struct bmap * bmp,
2010 struct dmap * dp,
int nblocks,
int l2nb,
s64 * results)
2022 if (dbFindLeaf((
dmtree_t *) & dp->
tree, l2nb, &leafidx))
2038 if ((rc = dbAllocDmap(bmp, dp, blkno, nblocks)) == 0)
2072 static int dbAllocDmap(
struct bmap * bmp,
struct dmap * dp,
s64 blkno,
2084 dbAllocBits(bmp, dp, blkno, nblocks);
2087 if (dp->
tree.stree[
ROOT] == oldroot)
2094 if ((rc = dbAdjCtl(bmp, blkno, dp->
tree.stree[
ROOT], 1, 0)))
2095 dbFreeBits(bmp, dp, blkno, nblocks);
2127 static int dbFreeDmap(
struct bmap * bmp,
struct dmap * dp,
s64 blkno,
2139 rc = dbFreeBits(bmp, dp, blkno, nblocks);
2142 if (rc || (dp->
tree.stree[
ROOT] == oldroot))
2149 if ((rc = dbAdjCtl(bmp, blkno, dp->
tree.stree[
ROOT], 0, 0))) {
2160 dbAllocBits(bmp, dp, blkno, nblocks);
2189 static void dbAllocBits(
struct bmap * bmp,
struct dmap * dp,
s64 blkno,
2192 int dbitno,
word, rembits, nb, nwords, wbitno, nw, agno;
2222 for (rembits = nblocks; rembits > 0; rembits -= nb, dbitno += nb) {
2226 wbitno = dbitno & (
DBWORD - 1);
2243 dbSplit(tp, word,
BUDMIN,
2244 dbMaxBud((
u8 *) & dp->
wmap[word]));
2263 for (; nwords > 0; nwords -= nw) {
2264 if (leaf[word] <
BUDMIN) {
2266 "dbAllocBits: leaf page "
2294 le32_add_cpu(&dp->
nfree, -nblocks);
2302 agno = blkno >> bmp->db_agl2size;
2303 if (agno > bmp->db_maxag)
2304 bmp->db_maxag = agno;
2307 bmp->db_agfree[agno] -=
nblocks;
2336 static int dbFreeBits(
struct bmap * bmp,
struct dmap * dp,
s64 blkno,
2339 int dbitno,
word, rembits, nb, nwords, wbitno, nw, agno;
2371 for (rembits = nblocks; rembits > 0; rembits -= nb, dbitno += nb) {
2375 wbitno = dbitno & (
DBWORD - 1);
2390 rc = dbJoin(tp, word,
2391 dbMaxBud((
u8 *) & dp->
wmap[word]));
2411 for (; nwords > 0; nwords -= nw) {
2424 rc = dbJoin(tp, word,
size);
2438 le32_add_cpu(&dp->
nfree, nblocks);
2445 agno = blkno >> bmp->db_agl2size;
2447 bmp->db_agfree[agno] +=
nblocks;
2454 if ((bmp->db_agfree[agno] == bmp->db_agsize && agno == bmp->db_maxag) ||
2455 (agno == bmp->db_numag - 1 &&
2457 while (bmp->db_maxag > 0) {
2459 if (bmp->db_agfree[bmp->db_maxag] !=
2468 if (bmp->db_agpref > bmp->db_maxag)
2469 bmp->db_agpref = bmp->db_maxag;
2520 dbAdjCtl(
struct bmap * bmp,
s64 blkno,
int newval,
int alloc,
int level)
2532 lblkno =
BLKTOCTL(blkno, bmp->db_l2nbperpage, level);
2540 "dbAdjCtl: Corrupt dmapctl page");
2554 oldval = dcp->
stree[ti];
2577 rc = dbBackSplit((
dmtree_t *) dcp, leafno);
2580 oldval = dcp->
stree[ti];
2584 rc = dbJoin((
dmtree_t *) dcp, leafno, newval);
2605 dbAdjCtl(bmp, blkno, dcp->
stree[
ROOT], alloc,
2638 assert(level == bmp->db_maxlevel);
2639 if (bmp->db_maxfreebud != oldroot) {
2641 "dbAdjCtl: the maximum free buddy is "
2642 "not the old root");
2674 static void dbSplit(
dmtree_t * tp,
int leafno,
int splitsz,
int newval)
2682 if (leaf[leafno] > tp->dmt_budmin) {
2688 cursz = leaf[leafno] - 1;
2689 budsz =
BUDSIZE(cursz, tp->dmt_budmin);
2693 while (cursz >= splitsz) {
2696 dbAdjTree(tp, leafno ^ budsz, cursz);
2708 dbAdjTree(tp, leafno, newval);
2739 static int dbBackSplit(
dmtree_t * tp,
int leafno)
2741 int budsz, bud,
w, bsz,
size;
2765 budsz =
BUDSIZE(size, tp->dmt_budmin);
2769 while (leaf[leafno] ==
NOFREE) {
2772 for (w = leafno, bsz = budsz;; bsz <<= 1,
2773 w = (w < bud) ? w : bud) {
2775 jfs_err(
"JFS: block map error in dbBackSplit");
2785 if (leaf[bud] !=
NOFREE) {
2789 cursz = leaf[bud] - 1;
2790 dbSplit(tp, bud, cursz, cursz);
2796 if (leaf[leafno] != size) {
2797 jfs_err(
"JFS: wrong leaf value in dbBackSplit");
2818 static int dbJoin(
dmtree_t * tp,
int leafno,
int newval)
2825 if (newval >= tp->dmt_budmin) {
2828 leaf = tp->dmt_stree +
le32_to_cpu(tp->dmt_leafidx);
2843 budsz =
BUDSIZE(newval, tp->dmt_budmin);
2850 buddy = leafno ^ budsz;
2855 if (newval > leaf[buddy])
2859 if (newval < leaf[buddy])
2870 if (leafno < buddy) {
2873 dbAdjTree(tp, buddy,
NOFREE);
2878 dbAdjTree(tp, leafno,
NOFREE);
2891 dbAdjTree(tp, leafno, newval);
2912 static void dbAdjTree(
dmtree_t * tp,
int leafno,
int newval)
2924 if (tp->dmt_stree[lp] == newval)
2929 tp->dmt_stree[lp] = newval;
2933 for (k = 0; k <
le32_to_cpu(tp->dmt_height); k++) {
2937 lp = ((lp - 1) & ~0x03) + 1;
2945 max = TREEMAX(&tp->dmt_stree[lp]);
2950 if (tp->dmt_stree[pp] == max)
2955 tp->dmt_stree[
pp] =
max;
2986 static int dbFindLeaf(
dmtree_t * tp,
int l2nb,
int *leafidx)
2988 int ti, n = 0,
k,
x = 0;
2993 if (l2nb > tp->dmt_stree[
ROOT])
3001 k > 0; k--, ti = ((ti + n) << 2) + 1) {
3005 for (x = ti, n = 0; n < 4; n++) {
3044 static int dbFindBits(
u32 word,
int l2nb)
3062 for (bitno = 0; mask != 0; bitno += nb, mask >>= nb) {
3063 if ((mask & word) ==
mask)
3087 static int dbMaxBud(
u8 *
cp)
3089 signed char tmp1, tmp2;
3094 if (*((
uint *) cp) == 0)
3100 if (*((
u16 *) cp) == 0 || *((
u16 *) cp + 1) == 0)
3106 tmp1 =
max(budtab[cp[2]], budtab[cp[3]]);
3107 tmp2 =
max(budtab[cp[0]], budtab[cp[1]]);
3108 return (
max(tmp1, tmp2));
3124 static int cnttz(
u32 word)
3128 for (n = 0; n < 32; n++, word >>= 1) {
3153 for (n = 0; n < 32; n++, value <<= 1) {
3174 static int blkstol2(
s64 nb)
3179 mask = (
s64) 1 << (64 - 1);
3183 for (l2nb = 0; l2nb < 64; l2nb++, mask >>= 1) {
3189 l2nb = (64 - 1) - l2nb;
3228 struct inode *ipbmap = JFS_SBI(ip->
i_sb)->ipbmap;
3229 struct bmap *bmp = JFS_SBI(ip->
i_sb)->bmap;
3240 for (rem = nblocks; rem > 0; rem -= nb, blkno += nb) {
3247 lblkno =
BLKTODMAP(blkno, bmp->db_l2nbperpage);
3261 if ((rc = dbAllocDmapBU(bmp, dp, blkno, nb))) {
3277 static int dbAllocDmapBU(
struct bmap * bmp,
struct dmap * dp,
s64 blkno,
3281 int dbitno,
word, rembits, nb, nwords, wbitno, agno;
3312 for (rembits = nblocks; rembits > 0; rembits -= nb, dbitno += nb) {
3316 wbitno = dbitno & (
DBWORD - 1);
3345 le32_add_cpu(&dp->
nfree, -nblocks);
3356 agno = blkno >> bmp->db_agl2size;
3357 if (agno > bmp->db_maxag)
3358 bmp->db_maxag = agno;
3361 bmp->db_agfree[agno] -= nblocks;
3362 bmp->db_nfree -= nblocks;
3374 if ((rc = dbAdjCtl(bmp, blkno, tp->
stree[
ROOT], 1, 0)))
3375 dbFreeBits(bmp, dp, blkno, nblocks);
3402 int i, i0 =
true,
j, j0 =
true,
k,
n;
3406 struct dmapctl *l2dcp, *l1dcp, *l0dcp;
3408 s8 *l0leaf, *l1leaf, *l2leaf;
3410 int agno, l2agsize, oldl2agsize;
3413 newsize = blkno + nblocks;
3415 jfs_info(
"dbExtendFS: blkno:%Ld nblocks:%Ld newsize:%Ld",
3416 (
long long) blkno, (
long long) nblocks, (
long long) newsize);
3426 bmp->db_mapsize = newsize;
3430 l2agsize = dbGetL2AGSize(newsize);
3431 oldl2agsize = bmp->db_agl2size;
3433 bmp->db_agl2size = l2agsize;
3434 bmp->db_agsize = 1 << l2agsize;
3437 agno = bmp->db_numag;
3438 bmp->db_numag = newsize >> l2agsize;
3439 bmp->db_numag += ((
u32) newsize % (
u32) bmp->db_agsize) ? 1 : 0;
3449 if (l2agsize == oldl2agsize)
3451 k = 1 << (l2agsize - oldl2agsize);
3452 ag_rem = bmp->db_agfree[0];
3453 for (i = 0, n = 0; i < agno; n++) {
3454 bmp->db_agfree[
n] = 0;
3457 for (
j = 0;
j < k && i < agno;
j++, i++) {
3459 bmp->db_agfree[
n] += bmp->db_agfree[
i];
3462 bmp->db_agfree[0] += ag_rem;
3464 for (; n <
MAXAG; n++)
3465 bmp->db_agfree[n] = 0;
3471 bmp->db_maxag = bmp->db_maxag / k;
3484 jfs_error(ipbmap->
i_sb,
"dbExtendFS: L2 page could not be read");
3497 for (; k <
LPERCTL; k++, p += nbperpage) {
3536 l0dcp = (
struct dmapctl *) l0mp->data;
3551 l0dcp = (
struct dmapctl *) l0mp->data;
3567 if ((n = blkno & (
BPERDMAP - 1))) {
3585 *l0leaf = dbInitDmap(dp, blkno, n);
3589 bmp->db_agfree[agno] +=
n;
3606 *l1leaf = dbInitDmapCtl(l0dcp, 0, ++i);
3607 write_metapage(l0mp);
3618 bmp->db_maxfreebud = *l1leaf;
3630 *l2leaf = dbInitDmapCtl(l1dcp, 1, ++
j);
3631 write_metapage(l1mp);
3642 bmp->db_maxfreebud = *l2leaf;
3650 "dbExtendFS: function has not returned as expected");
3673 struct bmap *bmp = JFS_SBI(ipbmap->
i_sb)->bmap;
3674 int actags, inactags, l2nl;
3675 s64 ag_rem, actfree, inactfree, avgfree;
3688 actags = bmp->db_maxag + 1;
3689 inactags = bmp->db_numag - actags;
3690 ag_rem = bmp->db_mapsize & (bmp->db_agsize - 1);
3697 inactfree = (inactags && ag_rem) ?
3698 ((inactags - 1) << bmp->db_agl2size) + ag_rem
3699 : inactags << bmp->db_agl2size;
3705 actfree = bmp->db_nfree - inactfree;
3706 avgfree = (
u32) actfree / (
u32) actags;
3712 if (bmp->db_agfree[bmp->db_agpref] < avgfree) {
3713 for (bmp->db_agpref = 0; bmp->db_agpref < actags;
3715 if (bmp->db_agfree[bmp->db_agpref] >= avgfree)
3718 if (bmp->db_agpref >= bmp->db_numag) {
3720 "cannot find ag with average freespace");
3734 bmp->db_agheight = l2nl >> 1;
3735 bmp->db_agwidth = 1 << (l2nl - (bmp->db_agheight << 1));
3736 for (i = 5 - bmp->db_agheight, bmp->db_agstart = 0, n = 1; i > 0;
3738 bmp->db_agstart +=
n;
3762 static int dbInitDmap(
struct dmap * dp,
s64 Blkno,
int nblocks)
3764 int blkno,
w,
b,
r, nw, nb,
i;
3779 le32_add_cpu(&dp->
nblocks, nblocks);
3780 le32_add_cpu(&dp->
nfree, nblocks);
3791 for (r = nblocks; r > 0; r -= nb, blkno += nb) {
3793 b = blkno & (
DBWORD - 1);
3831 b = blkno & (
DBWORD - 1);
3846 return (dbInitDmapTree(dp));
3864 static int dbInitDmapTree(
struct dmap * dp)
3884 *cp++ = dbMaxBud((
u8 *) & dp->
wmap[i]);
3887 return (dbInitTree(tp));
3910 static int dbInitTree(
struct dmaptree * dtp)
3912 int l2max, l2free, bsize, nextb,
i;
3935 for (l2free = dtp->
budmin, bsize = 1; l2free < l2max;
3936 l2free++, bsize = nextb) {
3943 i += nextb, cp += nextb) {
3945 if (*cp == l2free && *(cp + bsize) == l2free) {
3964 nparent > 0; nparent >>= 2, child = parent) {
3966 parent = (child - 1) >> 2;
3971 for (i = 0, cp = tp + child, cp1 = tp + parent;
3972 i < nparent; i++, cp += 4, cp1++)
3985 static int dbInitDmapCtl(
struct dmapctl * dcp,
int level,
int i)
4005 return (dbInitTree((
struct dmaptree *) dcp));
4019 static int dbGetL2AGSize(
s64 nblocks)
4029 m = ((
u64) 1 << (64 - 1));
4030 for (l2sz = 64; l2sz >= 0; l2sz--, m >>= 1) {
4035 sz = (
s64) 1 << l2sz;
4056 #define MAXL0PAGES (1 + LPERCTL)
4057 #define MAXL1PAGES (1 + LPERCTL * MAXL0PAGES)
4058 #define MAXL2PAGES (1 + LPERCTL * MAXL1PAGES)
4063 #define BMAPPGTOLEV(npages) \
4064 (((npages) <= 3 + MAXL0PAGES) ? 0 : \
4065 ((npages) <= 2 + MAXL1PAGES) ? 1 : 2)
4075 nblocks = ipbmap->
i_size >> JFS_SBI(sb)->l2bsize;
4076 npages = nblocks >> JFS_SBI(sb)->l2nbperpage;
4086 npages -= (2 -
level);
4088 for (i = level; i >= 0; i--) {
4091 complete = (
u32) npages / factor;
4092 ndmaps += complete * ((i == 2) ? LPERCTL * LPERCTL :
4093 ((i == 1) ? LPERCTL : 1));
4096 npages = (
u32) npages % factor;