11a59d1b8SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */
21da177e4SLinus Torvalds /*
363f83c9fSDave Kleikamp * Copyright (C) International Business Machines Corp., 2000-2002
41da177e4SLinus Torvalds */
51da177e4SLinus Torvalds #ifndef _H_JFS_DMAP
61da177e4SLinus Torvalds #define _H_JFS_DMAP
71da177e4SLinus Torvalds
81da177e4SLinus Torvalds #include "jfs_txnmgr.h"
91da177e4SLinus Torvalds
101da177e4SLinus Torvalds #define BMAPVERSION 1 /* version number */
111da177e4SLinus Torvalds #define TREESIZE (256+64+16+4+1) /* size of a dmap tree */
121da177e4SLinus Torvalds #define LEAFIND (64+16+4+1) /* index of 1st leaf of a dmap tree */
131da177e4SLinus Torvalds #define LPERDMAP 256 /* num leaves per dmap tree */
141da177e4SLinus Torvalds #define L2LPERDMAP 8 /* l2 number of leaves per dmap tree */
151da177e4SLinus Torvalds #define DBWORD 32 /* # of blks covered by a map word */
161da177e4SLinus Torvalds #define L2DBWORD 5 /* l2 # of blks covered by a mword */
171da177e4SLinus Torvalds #define BUDMIN L2DBWORD /* max free string in a map word */
181da177e4SLinus Torvalds #define BPERDMAP (LPERDMAP * DBWORD) /* num of blks per dmap */
191da177e4SLinus Torvalds #define L2BPERDMAP 13 /* l2 num of blks per dmap */
201da177e4SLinus Torvalds #define CTLTREESIZE (1024+256+64+16+4+1) /* size of a dmapctl tree */
211da177e4SLinus Torvalds #define CTLLEAFIND (256+64+16+4+1) /* idx of 1st leaf of a dmapctl tree */
221da177e4SLinus Torvalds #define LPERCTL 1024 /* num of leaves per dmapctl tree */
231da177e4SLinus Torvalds #define L2LPERCTL 10 /* l2 num of leaves per dmapctl tree */
241da177e4SLinus Torvalds #define ROOT 0 /* index of the root of a tree */
251da177e4SLinus Torvalds #define NOFREE ((s8) -1) /* no blocks free */
261da177e4SLinus Torvalds #define MAXAG 128 /* max number of allocation groups */
271da177e4SLinus Torvalds #define L2MAXAG 7 /* l2 max num of AG */
281da177e4SLinus Torvalds #define L2MINAGSZ 25 /* l2 of minimum AG size in bytes */
291da177e4SLinus Torvalds #define BMAPBLKNO 0 /* lblkno of bmap within the map */
301da177e4SLinus Torvalds
311da177e4SLinus Torvalds /*
321da177e4SLinus Torvalds * maximum l2 number of disk blocks at the various dmapctl levels.
331da177e4SLinus Torvalds */
341da177e4SLinus Torvalds #define L2MAXL0SIZE (L2BPERDMAP + 1 * L2LPERCTL)
351da177e4SLinus Torvalds #define L2MAXL1SIZE (L2BPERDMAP + 2 * L2LPERCTL)
361da177e4SLinus Torvalds #define L2MAXL2SIZE (L2BPERDMAP + 3 * L2LPERCTL)
371da177e4SLinus Torvalds
381da177e4SLinus Torvalds /*
391da177e4SLinus Torvalds * maximum number of disk blocks at the various dmapctl levels.
401da177e4SLinus Torvalds */
411da177e4SLinus Torvalds #define MAXL0SIZE ((s64)1 << L2MAXL0SIZE)
421da177e4SLinus Torvalds #define MAXL1SIZE ((s64)1 << L2MAXL1SIZE)
431da177e4SLinus Torvalds #define MAXL2SIZE ((s64)1 << L2MAXL2SIZE)
441da177e4SLinus Torvalds
451da177e4SLinus Torvalds #define MAXMAPSIZE MAXL2SIZE /* maximum aggregate map size */
461da177e4SLinus Torvalds
471da177e4SLinus Torvalds /*
481da177e4SLinus Torvalds * determine the maximum free string for four (lower level) nodes
491da177e4SLinus Torvalds * of the tree.
501da177e4SLinus Torvalds */
TREEMAX(signed char * cp)5115732a1cSHarvey Harrison static inline signed char TREEMAX(signed char *cp)
521da177e4SLinus Torvalds {
531da177e4SLinus Torvalds signed char tmp1, tmp2;
541da177e4SLinus Torvalds
551da177e4SLinus Torvalds tmp1 = max(*(cp+2), *(cp+3));
561da177e4SLinus Torvalds tmp2 = max(*(cp), *(cp+1));
571da177e4SLinus Torvalds
581da177e4SLinus Torvalds return max(tmp1, tmp2);
591da177e4SLinus Torvalds }
601da177e4SLinus Torvalds
611da177e4SLinus Torvalds /*
621da177e4SLinus Torvalds * convert disk block number to the logical block number of the dmap
631da177e4SLinus Torvalds * describing the disk block. s is the log2(number of logical blocks per page)
641da177e4SLinus Torvalds *
651da177e4SLinus Torvalds * The calculation figures out how many logical pages are in front of the dmap.
661da177e4SLinus Torvalds * - the number of dmaps preceding it
671da177e4SLinus Torvalds * - the number of L0 pages preceding its L0 page
681da177e4SLinus Torvalds * - the number of L1 pages preceding its L1 page
691da177e4SLinus Torvalds * - 3 is added to account for the L2, L1, and L0 page for this dmap
701da177e4SLinus Torvalds * - 1 is added to account for the control page of the map.
711da177e4SLinus Torvalds */
721da177e4SLinus Torvalds #define BLKTODMAP(b,s) \
731da177e4SLinus Torvalds ((((b) >> 13) + ((b) >> 23) + ((b) >> 33) + 3 + 1) << (s))
741da177e4SLinus Torvalds
751da177e4SLinus Torvalds /*
761da177e4SLinus Torvalds * convert disk block number to the logical block number of the LEVEL 0
771da177e4SLinus Torvalds * dmapctl describing the disk block. s is the log2(number of logical blocks
781da177e4SLinus Torvalds * per page)
791da177e4SLinus Torvalds *
801da177e4SLinus Torvalds * The calculation figures out how many logical pages are in front of the L0.
811da177e4SLinus Torvalds * - the number of dmap pages preceding it
821da177e4SLinus Torvalds * - the number of L0 pages preceding it
831da177e4SLinus Torvalds * - the number of L1 pages preceding its L1 page
841da177e4SLinus Torvalds * - 2 is added to account for the L2, and L1 page for this L0
851da177e4SLinus Torvalds * - 1 is added to account for the control page of the map.
861da177e4SLinus Torvalds */
871da177e4SLinus Torvalds #define BLKTOL0(b,s) \
881da177e4SLinus Torvalds (((((b) >> 23) << 10) + ((b) >> 23) + ((b) >> 33) + 2 + 1) << (s))
891da177e4SLinus Torvalds
901da177e4SLinus Torvalds /*
911da177e4SLinus Torvalds * convert disk block number to the logical block number of the LEVEL 1
921da177e4SLinus Torvalds * dmapctl describing the disk block. s is the log2(number of logical blocks
931da177e4SLinus Torvalds * per page)
941da177e4SLinus Torvalds *
951da177e4SLinus Torvalds * The calculation figures out how many logical pages are in front of the L1.
961da177e4SLinus Torvalds * - the number of dmap pages preceding it
971da177e4SLinus Torvalds * - the number of L0 pages preceding it
981da177e4SLinus Torvalds * - the number of L1 pages preceding it
991da177e4SLinus Torvalds * - 1 is added to account for the L2 page
1001da177e4SLinus Torvalds * - 1 is added to account for the control page of the map.
1011da177e4SLinus Torvalds */
1021da177e4SLinus Torvalds #define BLKTOL1(b,s) \
1031da177e4SLinus Torvalds (((((b) >> 33) << 20) + (((b) >> 33) << 10) + ((b) >> 33) + 1 + 1) << (s))
1041da177e4SLinus Torvalds
1051da177e4SLinus Torvalds /*
1061da177e4SLinus Torvalds * convert disk block number to the logical block number of the dmapctl
1071da177e4SLinus Torvalds * at the specified level which describes the disk block.
1081da177e4SLinus Torvalds */
1091da177e4SLinus Torvalds #define BLKTOCTL(b,s,l) \
1101da177e4SLinus Torvalds (((l) == 2) ? 1 : ((l) == 1) ? BLKTOL1((b),(s)) : BLKTOL0((b),(s)))
1111da177e4SLinus Torvalds
1121da177e4SLinus Torvalds /*
1131da177e4SLinus Torvalds * convert aggregate map size to the zero origin dmapctl level of the
1141da177e4SLinus Torvalds * top dmapctl.
1151da177e4SLinus Torvalds */
1161da177e4SLinus Torvalds #define BMAPSZTOLEV(size) \
1171da177e4SLinus Torvalds (((size) <= MAXL0SIZE) ? 0 : ((size) <= MAXL1SIZE) ? 1 : 2)
1181da177e4SLinus Torvalds
1191da177e4SLinus Torvalds /* convert disk block number to allocation group number.
1201da177e4SLinus Torvalds */
1211da177e4SLinus Torvalds #define BLKTOAG(b,sbi) ((b) >> ((sbi)->bmap->db_agl2size))
1221da177e4SLinus Torvalds
1231da177e4SLinus Torvalds /* convert allocation group number to starting disk block
1241da177e4SLinus Torvalds * number.
1251da177e4SLinus Torvalds */
1261da177e4SLinus Torvalds #define AGTOBLK(a,ip) \
1271da177e4SLinus Torvalds ((s64)(a) << (JFS_SBI((ip)->i_sb)->bmap->db_agl2size))
1281da177e4SLinus Torvalds
1291da177e4SLinus Torvalds /*
1301da177e4SLinus Torvalds * dmap summary tree
1311da177e4SLinus Torvalds *
1321da177e4SLinus Torvalds * dmaptree must be consistent with dmapctl.
1331da177e4SLinus Torvalds */
1341da177e4SLinus Torvalds struct dmaptree {
1351da177e4SLinus Torvalds __le32 nleafs; /* 4: number of tree leafs */
1361da177e4SLinus Torvalds __le32 l2nleafs; /* 4: l2 number of tree leafs */
1371da177e4SLinus Torvalds __le32 leafidx; /* 4: index of first tree leaf */
1381da177e4SLinus Torvalds __le32 height; /* 4: height of the tree */
1391da177e4SLinus Torvalds s8 budmin; /* 1: min l2 tree leaf value to combine */
1401da177e4SLinus Torvalds s8 stree[TREESIZE]; /* TREESIZE: tree */
1411da177e4SLinus Torvalds u8 pad[2]; /* 2: pad to word boundary */
1421da177e4SLinus Torvalds }; /* - 360 - */
1431da177e4SLinus Torvalds
1441da177e4SLinus Torvalds /*
1451da177e4SLinus Torvalds * dmap page per 8K blocks bitmap
1461da177e4SLinus Torvalds */
1471da177e4SLinus Torvalds struct dmap {
1481da177e4SLinus Torvalds __le32 nblocks; /* 4: num blks covered by this dmap */
1491da177e4SLinus Torvalds __le32 nfree; /* 4: num of free blks in this dmap */
1501da177e4SLinus Torvalds __le64 start; /* 8: starting blkno for this dmap */
1511da177e4SLinus Torvalds struct dmaptree tree; /* 360: dmap tree */
1521da177e4SLinus Torvalds u8 pad[1672]; /* 1672: pad to 2048 bytes */
1531da177e4SLinus Torvalds __le32 wmap[LPERDMAP]; /* 1024: bits of the working map */
1541da177e4SLinus Torvalds __le32 pmap[LPERDMAP]; /* 1024: bits of the persistent map */
1551da177e4SLinus Torvalds }; /* - 4096 - */
1561da177e4SLinus Torvalds
1571da177e4SLinus Torvalds /*
1581da177e4SLinus Torvalds * disk map control page per level.
1591da177e4SLinus Torvalds *
1601da177e4SLinus Torvalds * dmapctl must be consistent with dmaptree.
1611da177e4SLinus Torvalds */
1621da177e4SLinus Torvalds struct dmapctl {
1631da177e4SLinus Torvalds __le32 nleafs; /* 4: number of tree leafs */
1641da177e4SLinus Torvalds __le32 l2nleafs; /* 4: l2 number of tree leafs */
1651da177e4SLinus Torvalds __le32 leafidx; /* 4: index of the first tree leaf */
1661da177e4SLinus Torvalds __le32 height; /* 4: height of tree */
1671da177e4SLinus Torvalds s8 budmin; /* 1: minimum l2 tree leaf value */
1681da177e4SLinus Torvalds s8 stree[CTLTREESIZE]; /* CTLTREESIZE: dmapctl tree */
1691da177e4SLinus Torvalds u8 pad[2714]; /* 2714: pad to 4096 */
1701da177e4SLinus Torvalds }; /* - 4096 - */
1711da177e4SLinus Torvalds
1721da177e4SLinus Torvalds /*
1731da177e4SLinus Torvalds * common definition for dmaptree within dmap and dmapctl
1741da177e4SLinus Torvalds */
1751da177e4SLinus Torvalds typedef union dmtree {
1761da177e4SLinus Torvalds struct dmaptree t1;
1771da177e4SLinus Torvalds struct dmapctl t2;
1781da177e4SLinus Torvalds } dmtree_t;
1791da177e4SLinus Torvalds
1801da177e4SLinus Torvalds /* macros for accessing fields within dmtree */
1811da177e4SLinus Torvalds #define dmt_nleafs t1.nleafs
1821da177e4SLinus Torvalds #define dmt_l2nleafs t1.l2nleafs
1831da177e4SLinus Torvalds #define dmt_leafidx t1.leafidx
1841da177e4SLinus Torvalds #define dmt_height t1.height
1851da177e4SLinus Torvalds #define dmt_budmin t1.budmin
186*c61b3e48SDave Kleikamp #define dmt_stree t2.stree
1871da177e4SLinus Torvalds
1881da177e4SLinus Torvalds /*
1891da177e4SLinus Torvalds * on-disk aggregate disk allocation map descriptor.
1901da177e4SLinus Torvalds */
1911da177e4SLinus Torvalds struct dbmap_disk {
1921da177e4SLinus Torvalds __le64 dn_mapsize; /* 8: number of blocks in aggregate */
1931da177e4SLinus Torvalds __le64 dn_nfree; /* 8: num free blks in aggregate map */
1941da177e4SLinus Torvalds __le32 dn_l2nbperpage; /* 4: number of blks per page */
1951da177e4SLinus Torvalds __le32 dn_numag; /* 4: total number of ags */
1961da177e4SLinus Torvalds __le32 dn_maxlevel; /* 4: number of active ags */
1971da177e4SLinus Torvalds __le32 dn_maxag; /* 4: max active alloc group number */
1981da177e4SLinus Torvalds __le32 dn_agpref; /* 4: preferred alloc group (hint) */
1991da177e4SLinus Torvalds __le32 dn_aglevel; /* 4: dmapctl level holding the AG */
200d7eecb48SDaniel Mack __le32 dn_agheight; /* 4: height in dmapctl of the AG */
2011da177e4SLinus Torvalds __le32 dn_agwidth; /* 4: width in dmapctl of the AG */
2021da177e4SLinus Torvalds __le32 dn_agstart; /* 4: start tree index at AG height */
2031da177e4SLinus Torvalds __le32 dn_agl2size; /* 4: l2 num of blks per alloc group */
2041da177e4SLinus Torvalds __le64 dn_agfree[MAXAG];/* 8*MAXAG: per AG free count */
2051da177e4SLinus Torvalds __le64 dn_agsize; /* 8: num of blks per alloc group */
2061da177e4SLinus Torvalds s8 dn_maxfreebud; /* 1: max free buddy system */
2071da177e4SLinus Torvalds u8 pad[3007]; /* 3007: pad to 4096 */
2081da177e4SLinus Torvalds }; /* - 4096 - */
2091da177e4SLinus Torvalds
2101da177e4SLinus Torvalds struct dbmap {
2111da177e4SLinus Torvalds s64 dn_mapsize; /* number of blocks in aggregate */
2121da177e4SLinus Torvalds s64 dn_nfree; /* num free blks in aggregate map */
2131da177e4SLinus Torvalds int dn_l2nbperpage; /* number of blks per page */
2141da177e4SLinus Torvalds int dn_numag; /* total number of ags */
2151da177e4SLinus Torvalds int dn_maxlevel; /* number of active ags */
2161da177e4SLinus Torvalds int dn_maxag; /* max active alloc group number */
2171da177e4SLinus Torvalds int dn_agpref; /* preferred alloc group (hint) */
2181da177e4SLinus Torvalds int dn_aglevel; /* dmapctl level holding the AG */
219d7eecb48SDaniel Mack int dn_agheight; /* height in dmapctl of the AG */
2201da177e4SLinus Torvalds int dn_agwidth; /* width in dmapctl of the AG */
2211da177e4SLinus Torvalds int dn_agstart; /* start tree index at AG height */
2221da177e4SLinus Torvalds int dn_agl2size; /* l2 num of blks per alloc group */
2231da177e4SLinus Torvalds s64 dn_agfree[MAXAG]; /* per AG free count */
2241da177e4SLinus Torvalds s64 dn_agsize; /* num of blks per alloc group */
2251da177e4SLinus Torvalds signed char dn_maxfreebud; /* max free buddy system */
2261da177e4SLinus Torvalds }; /* - 4096 - */
2271da177e4SLinus Torvalds /*
2281da177e4SLinus Torvalds * in-memory aggregate disk allocation map descriptor.
2291da177e4SLinus Torvalds */
2301da177e4SLinus Torvalds struct bmap {
2311da177e4SLinus Torvalds struct dbmap db_bmap; /* on-disk aggregate map descriptor */
2321da177e4SLinus Torvalds struct inode *db_ipbmap; /* ptr to aggregate map incore inode */
2331de87444SIngo Molnar struct mutex db_bmaplock; /* aggregate map lock */
2341da177e4SLinus Torvalds atomic_t db_active[MAXAG]; /* count of active, open files in AG */
2351da177e4SLinus Torvalds u32 *db_DBmap;
2361da177e4SLinus Torvalds };
2371da177e4SLinus Torvalds
2381da177e4SLinus Torvalds /* macros for accessing fields within in-memory aggregate map descriptor */
2391da177e4SLinus Torvalds #define db_mapsize db_bmap.dn_mapsize
2401da177e4SLinus Torvalds #define db_nfree db_bmap.dn_nfree
2411da177e4SLinus Torvalds #define db_agfree db_bmap.dn_agfree
2421da177e4SLinus Torvalds #define db_agsize db_bmap.dn_agsize
2431da177e4SLinus Torvalds #define db_agl2size db_bmap.dn_agl2size
2441da177e4SLinus Torvalds #define db_agwidth db_bmap.dn_agwidth
245d7eecb48SDaniel Mack #define db_agheight db_bmap.dn_agheight
2461da177e4SLinus Torvalds #define db_agstart db_bmap.dn_agstart
2471da177e4SLinus Torvalds #define db_numag db_bmap.dn_numag
2481da177e4SLinus Torvalds #define db_maxlevel db_bmap.dn_maxlevel
2491da177e4SLinus Torvalds #define db_aglevel db_bmap.dn_aglevel
2501da177e4SLinus Torvalds #define db_agpref db_bmap.dn_agpref
2511da177e4SLinus Torvalds #define db_maxag db_bmap.dn_maxag
2521da177e4SLinus Torvalds #define db_maxfreebud db_bmap.dn_maxfreebud
2531da177e4SLinus Torvalds #define db_l2nbperpage db_bmap.dn_l2nbperpage
2541da177e4SLinus Torvalds
2551da177e4SLinus Torvalds /*
2561da177e4SLinus Torvalds * macros for various conversions needed by the allocators.
2571da177e4SLinus Torvalds * blkstol2(), cntlz(), and cnttz() are operating system dependent functions.
2581da177e4SLinus Torvalds */
2591da177e4SLinus Torvalds /* convert number of blocks to log2 number of blocks, rounding up to
2601da177e4SLinus Torvalds * the next log2 value if blocks is not a l2 multiple.
2611da177e4SLinus Torvalds */
2621da177e4SLinus Torvalds #define BLKSTOL2(d) (blkstol2(d))
2631da177e4SLinus Torvalds
2641da177e4SLinus Torvalds /* convert number of leafs to log2 leaf value */
2651da177e4SLinus Torvalds #define NLSTOL2BSZ(n) (31 - cntlz((n)) + BUDMIN)
2661da177e4SLinus Torvalds
2671da177e4SLinus Torvalds /* convert leaf index to log2 leaf value */
2681da177e4SLinus Torvalds #define LITOL2BSZ(n,m,b) ((((n) == 0) ? (m) : cnttz((n))) + (b))
2691da177e4SLinus Torvalds
2701da177e4SLinus Torvalds /* convert a block number to a dmap control leaf index */
2711da177e4SLinus Torvalds #define BLKTOCTLLEAF(b,m) \
2721da177e4SLinus Torvalds (((b) & (((s64)1 << ((m) + L2LPERCTL)) - 1)) >> (m))
2731da177e4SLinus Torvalds
2741da177e4SLinus Torvalds /* convert log2 leaf value to buddy size */
2751da177e4SLinus Torvalds #define BUDSIZE(s,m) (1 << ((s) - (m)))
2761da177e4SLinus Torvalds
2771da177e4SLinus Torvalds /*
2781da177e4SLinus Torvalds * external references.
2791da177e4SLinus Torvalds */
2801da177e4SLinus Torvalds extern int dbMount(struct inode *ipbmap);
2811da177e4SLinus Torvalds
2821da177e4SLinus Torvalds extern int dbUnmount(struct inode *ipbmap, int mounterror);
2831da177e4SLinus Torvalds
2841da177e4SLinus Torvalds extern int dbFree(struct inode *ipbmap, s64 blkno, s64 nblocks);
2851da177e4SLinus Torvalds
2861da177e4SLinus Torvalds extern int dbUpdatePMap(struct inode *ipbmap,
2871da177e4SLinus Torvalds int free, s64 blkno, s64 nblocks, struct tblock * tblk);
2881da177e4SLinus Torvalds
2891da177e4SLinus Torvalds extern int dbNextAG(struct inode *ipbmap);
2901da177e4SLinus Torvalds
2911da177e4SLinus Torvalds extern int dbAlloc(struct inode *ipbmap, s64 hint, s64 nblocks, s64 * results);
2921da177e4SLinus Torvalds
2931da177e4SLinus Torvalds extern int dbReAlloc(struct inode *ipbmap,
2941da177e4SLinus Torvalds s64 blkno, s64 nblocks, s64 addnblocks, s64 * results);
2951da177e4SLinus Torvalds
2961da177e4SLinus Torvalds extern int dbSync(struct inode *ipbmap);
2971da177e4SLinus Torvalds extern int dbAllocBottomUp(struct inode *ip, s64 blkno, s64 nblocks);
2981da177e4SLinus Torvalds extern int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks);
2991da177e4SLinus Torvalds extern void dbFinalizeBmap(struct inode *ipbmap);
3001da177e4SLinus Torvalds extern s64 dbMapFileSizeToMapSize(struct inode *ipbmap);
301b40c2e66STino Reichardt extern s64 dbDiscardAG(struct inode *ip, int agno, s64 minlen);
302b40c2e66STino Reichardt
3031da177e4SLinus Torvalds #endif /* _H_JFS_DMAP */
304