Commit e9806ff8 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'jfs-6.7' of https://github.com/kleikamp/linux-shaggy

Pull jfs updates from Dave Kleikamp:
 "Minor stability improvements"

* tag 'jfs-6.7' of https://github.com/kleikamp/linux-shaggy:
  jfs: define xtree root and page independently
  jfs: fix array-index-out-of-bounds in diAlloc
  jfs: fix array-index-out-of-bounds in dbFindLeaf
  fs/jfs: Add validity check for db_maxag and db_agpref
  fs/jfs: Add check for negative db_l2nbperpage
parents dc737f11 a779ed75
...@@ -96,7 +96,7 @@ struct dinode { ...@@ -96,7 +96,7 @@ struct dinode {
#define di_gengen u._file._u1._imap._gengen #define di_gengen u._file._u1._imap._gengen
union { union {
xtpage_t _xtroot; xtroot_t _xtroot;
struct { struct {
u8 unused[16]; /* 16: */ u8 unused[16]; /* 16: */
dxd_t _dxd; /* 16: */ dxd_t _dxd; /* 16: */
......
...@@ -87,7 +87,7 @@ static int dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno, ...@@ -87,7 +87,7 @@ static int dbAllocCtl(struct bmap * bmp, s64 nblocks, int l2nb, s64 blkno,
static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks); static int dbExtend(struct inode *ip, s64 blkno, s64 nblocks, s64 addnblocks);
static int dbFindBits(u32 word, int l2nb); static int dbFindBits(u32 word, int l2nb);
static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno); static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno);
static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx); static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl);
static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno, static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
int nblocks); int nblocks);
static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno, static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
...@@ -180,7 +180,8 @@ int dbMount(struct inode *ipbmap) ...@@ -180,7 +180,8 @@ int dbMount(struct inode *ipbmap)
bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree); bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree);
bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage); bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage);
if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE) { if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE ||
bmp->db_l2nbperpage < 0) {
err = -EINVAL; err = -EINVAL;
goto err_release_metapage; goto err_release_metapage;
} }
...@@ -194,6 +195,12 @@ int dbMount(struct inode *ipbmap) ...@@ -194,6 +195,12 @@ int dbMount(struct inode *ipbmap)
bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel); bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel);
bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag); bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag);
bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref); bmp->db_agpref = le32_to_cpu(dbmp_le->dn_agpref);
if (bmp->db_maxag >= MAXAG || bmp->db_maxag < 0 ||
bmp->db_agpref >= MAXAG || bmp->db_agpref < 0) {
err = -EINVAL;
goto err_release_metapage;
}
bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel); bmp->db_aglevel = le32_to_cpu(dbmp_le->dn_aglevel);
bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight); bmp->db_agheight = le32_to_cpu(dbmp_le->dn_agheight);
bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth); bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
...@@ -1710,7 +1717,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno) ...@@ -1710,7 +1717,7 @@ static int dbFindCtl(struct bmap * bmp, int l2nb, int level, s64 * blkno)
* dbFindLeaf() returns the index of the leaf at which * dbFindLeaf() returns the index of the leaf at which
* free space was found. * free space was found.
*/ */
rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx); rc = dbFindLeaf((dmtree_t *) dcp, l2nb, &leafidx, true);
/* release the buffer. /* release the buffer.
*/ */
...@@ -1957,7 +1964,7 @@ dbAllocDmapLev(struct bmap * bmp, ...@@ -1957,7 +1964,7 @@ dbAllocDmapLev(struct bmap * bmp,
* free space. if sufficient free space is found, dbFindLeaf() * free space. if sufficient free space is found, dbFindLeaf()
* returns the index of the leaf at which free space was found. * returns the index of the leaf at which free space was found.
*/ */
if (dbFindLeaf((dmtree_t *) & dp->tree, l2nb, &leafidx)) if (dbFindLeaf((dmtree_t *) &dp->tree, l2nb, &leafidx, false))
return -ENOSPC; return -ENOSPC;
if (leafidx < 0) if (leafidx < 0)
...@@ -2921,14 +2928,18 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval) ...@@ -2921,14 +2928,18 @@ static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
* leafidx - return pointer to be set to the index of the leaf * leafidx - return pointer to be set to the index of the leaf
* describing at least l2nb free blocks if sufficient * describing at least l2nb free blocks if sufficient
* free blocks are found. * free blocks are found.
* is_ctl - determines if the tree is of type ctl
* *
* RETURN VALUES: * RETURN VALUES:
* 0 - success * 0 - success
* -ENOSPC - insufficient free blocks. * -ENOSPC - insufficient free blocks.
*/ */
static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx) static int dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx, bool is_ctl)
{ {
int ti, n = 0, k, x = 0; int ti, n = 0, k, x = 0;
int max_size;
max_size = is_ctl ? CTLTREESIZE : TREESIZE;
/* first check the root of the tree to see if there is /* first check the root of the tree to see if there is
* sufficient free space. * sufficient free space.
...@@ -2949,6 +2960,8 @@ static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx) ...@@ -2949,6 +2960,8 @@ static int dbFindLeaf(dmtree_t * tp, int l2nb, int *leafidx)
/* sufficient free space found. move to the next /* sufficient free space found. move to the next
* level (or quit if this is the last level). * level (or quit if this is the last level).
*/ */
if (x + n > max_size)
return -ENOSPC;
if (l2nb <= tp->dmt_stree[x + n]) if (l2nb <= tp->dmt_stree[x + n])
break; break;
} }
......
...@@ -670,7 +670,7 @@ int diWrite(tid_t tid, struct inode *ip) ...@@ -670,7 +670,7 @@ int diWrite(tid_t tid, struct inode *ip)
* This is the special xtree inside the directory for storing * This is the special xtree inside the directory for storing
* the directory table * the directory table
*/ */
xtpage_t *p, *xp; xtroot_t *p, *xp;
xad_t *xad; xad_t *xad;
jfs_ip->xtlid = 0; jfs_ip->xtlid = 0;
...@@ -684,7 +684,7 @@ int diWrite(tid_t tid, struct inode *ip) ...@@ -684,7 +684,7 @@ int diWrite(tid_t tid, struct inode *ip)
* copy xtree root from inode to dinode: * copy xtree root from inode to dinode:
*/ */
p = &jfs_ip->i_xtroot; p = &jfs_ip->i_xtroot;
xp = (xtpage_t *) &dp->di_dirtable; xp = (xtroot_t *) &dp->di_dirtable;
lv = ilinelock->lv; lv = ilinelock->lv;
for (n = 0; n < ilinelock->index; n++, lv++) { for (n = 0; n < ilinelock->index; n++, lv++) {
memcpy(&xp->xad[lv->offset], &p->xad[lv->offset], memcpy(&xp->xad[lv->offset], &p->xad[lv->offset],
...@@ -713,7 +713,7 @@ int diWrite(tid_t tid, struct inode *ip) ...@@ -713,7 +713,7 @@ int diWrite(tid_t tid, struct inode *ip)
* regular file: 16 byte (XAD slot) granularity * regular file: 16 byte (XAD slot) granularity
*/ */
if (type & tlckXTREE) { if (type & tlckXTREE) {
xtpage_t *p, *xp; xtroot_t *p, *xp;
xad_t *xad; xad_t *xad;
/* /*
...@@ -1320,7 +1320,7 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp) ...@@ -1320,7 +1320,7 @@ diInitInode(struct inode *ip, int iagno, int ino, int extno, struct iag * iagp)
int diAlloc(struct inode *pip, bool dir, struct inode *ip) int diAlloc(struct inode *pip, bool dir, struct inode *ip)
{ {
int rc, ino, iagno, addext, extno, bitno, sword; int rc, ino, iagno, addext, extno, bitno, sword;
int nwords, rem, i, agno; int nwords, rem, i, agno, dn_numag;
u32 mask, inosmap, extsmap; u32 mask, inosmap, extsmap;
struct inode *ipimap; struct inode *ipimap;
struct metapage *mp; struct metapage *mp;
...@@ -1356,6 +1356,9 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip) ...@@ -1356,6 +1356,9 @@ int diAlloc(struct inode *pip, bool dir, struct inode *ip)
/* get the ag number of this iag */ /* get the ag number of this iag */
agno = BLKTOAG(JFS_IP(pip)->agstart, JFS_SBI(pip->i_sb)); agno = BLKTOAG(JFS_IP(pip)->agstart, JFS_SBI(pip->i_sb));
dn_numag = JFS_SBI(pip->i_sb)->bmap->db_numag;
if (agno < 0 || agno > dn_numag)
return -EIO;
if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) { if (atomic_read(&JFS_SBI(pip->i_sb)->bmap->db_active[agno])) {
/* /*
......
...@@ -66,7 +66,7 @@ struct jfs_inode_info { ...@@ -66,7 +66,7 @@ struct jfs_inode_info {
lid_t xtlid; /* lid of xtree lock on directory */ lid_t xtlid; /* lid of xtree lock on directory */
union { union {
struct { struct {
xtpage_t _xtroot; /* 288: xtree root */ xtroot_t _xtroot; /* 288: xtree root */
struct inomap *_imap; /* 4: inode map header */ struct inomap *_imap; /* 4: inode map header */
} file; } file;
struct { struct {
......
...@@ -783,7 +783,7 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp, ...@@ -783,7 +783,7 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
if (mp->xflag & COMMIT_PAGE) if (mp->xflag & COMMIT_PAGE)
p = (xtpage_t *) mp->data; p = (xtpage_t *) mp->data;
else else
p = &jfs_ip->i_xtroot; p = (xtpage_t *) &jfs_ip->i_xtroot;
xtlck->lwm.offset = xtlck->lwm.offset =
le16_to_cpu(p->header.nextindex); le16_to_cpu(p->header.nextindex);
} }
...@@ -1676,7 +1676,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd, ...@@ -1676,7 +1676,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
if (tlck->type & tlckBTROOT) { if (tlck->type & tlckBTROOT) {
lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT); lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT);
p = &JFS_IP(ip)->i_xtroot; p = (xtpage_t *) &JFS_IP(ip)->i_xtroot;
if (S_ISDIR(ip->i_mode)) if (S_ISDIR(ip->i_mode))
lrd->log.redopage.type |= lrd->log.redopage.type |=
cpu_to_le16(LOG_DIR_XTREE); cpu_to_le16(LOG_DIR_XTREE);
......
...@@ -1213,7 +1213,7 @@ xtSplitRoot(tid_t tid, ...@@ -1213,7 +1213,7 @@ xtSplitRoot(tid_t tid,
struct xtlock *xtlck; struct xtlock *xtlck;
int rc; int rc;
sp = &JFS_IP(ip)->i_xtroot; sp = (xtpage_t *) &JFS_IP(ip)->i_xtroot;
INCREMENT(xtStat.split); INCREMENT(xtStat.split);
...@@ -2098,7 +2098,7 @@ int xtAppend(tid_t tid, /* transaction id */ ...@@ -2098,7 +2098,7 @@ int xtAppend(tid_t tid, /* transaction id */
*/ */
void xtInitRoot(tid_t tid, struct inode *ip) void xtInitRoot(tid_t tid, struct inode *ip)
{ {
xtpage_t *p; xtroot_t *p;
/* /*
* acquire a transaction lock on the root * acquire a transaction lock on the root
......
...@@ -65,11 +65,7 @@ struct xadlist { ...@@ -65,11 +65,7 @@ struct xadlist {
#define XTPAGEMAXSLOT 256 #define XTPAGEMAXSLOT 256
#define XTENTRYSTART 2 #define XTENTRYSTART 2
/* struct xtheader {
* xtree page:
*/
typedef union {
struct xtheader {
__le64 next; /* 8: */ __le64 next; /* 8: */
__le64 prev; /* 8: */ __le64 prev; /* 8: */
...@@ -80,9 +76,22 @@ typedef union { ...@@ -80,9 +76,22 @@ typedef union {
__le16 rsrvd2; /* 2: */ __le16 rsrvd2; /* 2: */
pxd_t self; /* 8: self */ pxd_t self; /* 8: self */
} header; /* (32) */ };
/*
* xtree root (in inode):
*/
typedef union {
struct xtheader header;
xad_t xad[XTROOTMAXSLOT]; /* 16 * maxentry: xad array */ xad_t xad[XTROOTMAXSLOT]; /* 16 * maxentry: xad array */
} xtroot_t;
/*
* xtree page:
*/
typedef union {
struct xtheader header;
xad_t xad[XTPAGEMAXSLOT]; /* 16 * maxentry: xad array */
} xtpage_t; } xtpage_t;
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment