mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-24 04:34:08 +08:00
Stability improvements.
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEIodevzQLVs53l6BhNqiEXrVAjGQFAmWcF7sACgkQNqiEXrVA jGQCOw//RdOt12/cDRZxIgdhCotNBNAde/BtG95Mv8KnmYKpnFAWx1piAhDxyVun 4oUSJ6fG9VBJeKogQnP1LDW3oBH3WZ3twM4lrTxHo0BOhuv/u/CXJkchR6LHpl20 9ewtbQ3MOBh2MHhXd2Siyc0sp14STk0F8yNGOJawM1lw5GiTMkZMb6BdGaoRSahF bqjjJnlOeDF0Znzg+CL5X2pWAsUa0oPXzFXuuEYySvTn9EkwPK0D/kllGiwqt7yq XIULsUd89Nj7hznUT+ylFzctwxIlM5DB3z81eP9rsf+R7dHkriBRCJVPBuxvKajJ MTKxzEBP0/I0v276T4DYABVdYZu9BL9dK/eSgo3lxjQnC5BoDMR/AHcP93NQknxf 2aNb8mt1Uq44Qh7iyrtJuB6OlfnlK5rVtYJcGgHfhEWL7Gf4y2UiJH7QspVwH7J5 KQwOmXvUpR5dHPbnEQIgYKM0LlAapQQ9jnzf2y4i/Z33l2EE/KNsI6+K5VG6oTDS RDYASqH0hd+P+7z+7Qhuwu2cFG8oRcvCQh6nEcrvq1md1WEIspt1frrNDEeDmw6o pvwflfjvD3126sqnlIkAOJlqvthERcA13mhvgj891IXlCSlth65IYM83i57MxCUd uZcDkYKsmXhUYo5MEM0dPfP3+LKml52XJqGjR7gOSZ8hm0tHo8k= =RXjP -----END PGP SIGNATURE----- Merge tag 'jfs-6.8' of github.com:kleikamp/linux-shaggy Pull jfs updates from David Kleikamp: "Stability improvements" * tag 'jfs-6.8' of github.com:kleikamp/linux-shaggy: jfs: Add missing set_freezable() for freezable kthread jfs: fix array-index-out-of-bounds in diNewExt jfs: fix shift-out-of-bounds in dbJoin jfs: fix uaf in jfs_evict_inode jfs: fix array-index-out-of-bounds in dbAdjTree jfs: fix slab-out-of-bounds Read in dtSearch UBSAN: array-index-out-of-bounds in dtSplitRoot FS:JFS:UBSAN:array-index-out-of-bounds in dbAdjTree
This commit is contained in:
commit
032500abc5
@ -63,10 +63,10 @@
|
||||
*/
|
||||
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 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 void dbSplit(dmtree_t *tp, int leafno, int splitsz, int newval, bool is_ctl);
|
||||
static int dbBackSplit(dmtree_t *tp, int leafno, bool is_ctl);
|
||||
static int dbJoin(dmtree_t *tp, int leafno, int newval, bool is_ctl);
|
||||
static void dbAdjTree(dmtree_t *tp, int leafno, int newval, bool is_ctl);
|
||||
static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc,
|
||||
int level);
|
||||
static int dbAllocAny(struct bmap * bmp, s64 nblocks, int l2nb, s64 * results);
|
||||
@ -2103,7 +2103,7 @@ static int dbFreeDmap(struct bmap * bmp, struct dmap * dp, s64 blkno,
|
||||
* system.
|
||||
*/
|
||||
if (dp->tree.stree[word] == NOFREE)
|
||||
dbBackSplit((dmtree_t *) & dp->tree, word);
|
||||
dbBackSplit((dmtree_t *)&dp->tree, word, false);
|
||||
|
||||
dbAllocBits(bmp, dp, blkno, nblocks);
|
||||
}
|
||||
@ -2189,7 +2189,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
|
||||
* the binary system of the leaves if need be.
|
||||
*/
|
||||
dbSplit(tp, word, BUDMIN,
|
||||
dbMaxBud((u8 *) & dp->wmap[word]));
|
||||
dbMaxBud((u8 *)&dp->wmap[word]), false);
|
||||
|
||||
word += 1;
|
||||
} else {
|
||||
@ -2229,7 +2229,7 @@ static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
|
||||
* system of the leaves to reflect the current
|
||||
* allocation (size).
|
||||
*/
|
||||
dbSplit(tp, word, size, NOFREE);
|
||||
dbSplit(tp, word, size, NOFREE, false);
|
||||
|
||||
/* get the number of dmap words handled */
|
||||
nw = BUDSIZE(size, BUDMIN);
|
||||
@ -2336,7 +2336,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
|
||||
/* update the leaf for this dmap word.
|
||||
*/
|
||||
rc = dbJoin(tp, word,
|
||||
dbMaxBud((u8 *) & dp->wmap[word]));
|
||||
dbMaxBud((u8 *)&dp->wmap[word]), false);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@ -2369,7 +2369,7 @@ static int dbFreeBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
|
||||
|
||||
/* update the leaf.
|
||||
*/
|
||||
rc = dbJoin(tp, word, size);
|
||||
rc = dbJoin(tp, word, size, false);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
@ -2521,16 +2521,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) {
|
||||
rc = dbBackSplit((dmtree_t *) dcp, leafno);
|
||||
rc = dbBackSplit((dmtree_t *)dcp, leafno, true);
|
||||
if (rc) {
|
||||
release_metapage(mp);
|
||||
return rc;
|
||||
}
|
||||
oldval = dcp->stree[ti];
|
||||
}
|
||||
dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval);
|
||||
dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval, true);
|
||||
} else {
|
||||
rc = dbJoin((dmtree_t *) dcp, leafno, newval);
|
||||
rc = dbJoin((dmtree_t *) dcp, leafno, newval, true);
|
||||
if (rc) {
|
||||
release_metapage(mp);
|
||||
return rc;
|
||||
@ -2561,7 +2561,7 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level)
|
||||
*/
|
||||
if (alloc) {
|
||||
dbJoin((dmtree_t *) dcp, leafno,
|
||||
oldval);
|
||||
oldval, true);
|
||||
} else {
|
||||
/* the dbJoin() above might have
|
||||
* caused a larger binary buddy system
|
||||
@ -2571,9 +2571,9 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level)
|
||||
*/
|
||||
if (dcp->stree[ti] == NOFREE)
|
||||
dbBackSplit((dmtree_t *)
|
||||
dcp, leafno);
|
||||
dcp, leafno, true);
|
||||
dbSplit((dmtree_t *) dcp, leafno,
|
||||
dcp->budmin, oldval);
|
||||
dcp->budmin, oldval, true);
|
||||
}
|
||||
|
||||
/* release the buffer and return the error.
|
||||
@ -2621,7 +2621,7 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level)
|
||||
*
|
||||
* serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
|
||||
*/
|
||||
static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
|
||||
static void dbSplit(dmtree_t *tp, int leafno, int splitsz, int newval, bool is_ctl)
|
||||
{
|
||||
int budsz;
|
||||
int cursz;
|
||||
@ -2643,7 +2643,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
|
||||
while (cursz >= splitsz) {
|
||||
/* update the buddy's leaf with its new value.
|
||||
*/
|
||||
dbAdjTree(tp, leafno ^ budsz, cursz);
|
||||
dbAdjTree(tp, leafno ^ budsz, cursz, is_ctl);
|
||||
|
||||
/* on to the next size and buddy.
|
||||
*/
|
||||
@ -2655,7 +2655,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
|
||||
/* adjust the dmap tree to reflect the specified leaf's new
|
||||
* value.
|
||||
*/
|
||||
dbAdjTree(tp, leafno, newval);
|
||||
dbAdjTree(tp, leafno, newval, is_ctl);
|
||||
}
|
||||
|
||||
|
||||
@ -2686,7 +2686,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
|
||||
*
|
||||
* serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
|
||||
*/
|
||||
static int dbBackSplit(dmtree_t * tp, int leafno)
|
||||
static int dbBackSplit(dmtree_t *tp, int leafno, bool is_ctl)
|
||||
{
|
||||
int budsz, bud, w, bsz, size;
|
||||
int cursz;
|
||||
@ -2737,7 +2737,7 @@ static int dbBackSplit(dmtree_t * tp, int leafno)
|
||||
* system in two.
|
||||
*/
|
||||
cursz = leaf[bud] - 1;
|
||||
dbSplit(tp, bud, cursz, cursz);
|
||||
dbSplit(tp, bud, cursz, cursz, is_ctl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2763,9 +2763,11 @@ static int dbBackSplit(dmtree_t * tp, int leafno)
|
||||
* leafno - the number of the leaf to be updated.
|
||||
* newval - the new value for the leaf.
|
||||
*
|
||||
* RETURN VALUES: none
|
||||
* RETURN VALUES:
|
||||
* 0 - success
|
||||
* -EIO - i/o error
|
||||
*/
|
||||
static int dbJoin(dmtree_t * tp, int leafno, int newval)
|
||||
static int dbJoin(dmtree_t *tp, int leafno, int newval, bool is_ctl)
|
||||
{
|
||||
int budsz, buddy;
|
||||
s8 *leaf;
|
||||
@ -2790,6 +2792,10 @@ static int dbJoin(dmtree_t * tp, int leafno, int newval)
|
||||
* get the buddy size (number of words covered) of
|
||||
* the new value.
|
||||
*/
|
||||
|
||||
if ((newval - tp->dmt_budmin) > BUDMIN)
|
||||
return -EIO;
|
||||
|
||||
budsz = BUDSIZE(newval, tp->dmt_budmin);
|
||||
|
||||
/* try to join.
|
||||
@ -2820,12 +2826,12 @@ static int dbJoin(dmtree_t * tp, int leafno, int newval)
|
||||
if (leafno < buddy) {
|
||||
/* leafno is the left buddy.
|
||||
*/
|
||||
dbAdjTree(tp, buddy, NOFREE);
|
||||
dbAdjTree(tp, buddy, NOFREE, is_ctl);
|
||||
} else {
|
||||
/* buddy is the left buddy and becomes
|
||||
* leafno.
|
||||
*/
|
||||
dbAdjTree(tp, leafno, NOFREE);
|
||||
dbAdjTree(tp, leafno, NOFREE, is_ctl);
|
||||
leafno = buddy;
|
||||
}
|
||||
|
||||
@ -2838,7 +2844,7 @@ static int dbJoin(dmtree_t * tp, int leafno, int newval)
|
||||
|
||||
/* update the leaf value.
|
||||
*/
|
||||
dbAdjTree(tp, leafno, newval);
|
||||
dbAdjTree(tp, leafno, newval, is_ctl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -2859,15 +2865,20 @@ static int dbJoin(dmtree_t * tp, int leafno, int newval)
|
||||
*
|
||||
* RETURN VALUES: none
|
||||
*/
|
||||
static void dbAdjTree(dmtree_t * tp, int leafno, int newval)
|
||||
static void dbAdjTree(dmtree_t *tp, int leafno, int newval, bool is_ctl)
|
||||
{
|
||||
int lp, pp, k;
|
||||
int max;
|
||||
int max, size;
|
||||
|
||||
size = is_ctl ? CTLTREESIZE : TREESIZE;
|
||||
|
||||
/* pick up the index of the leaf for this leafno.
|
||||
*/
|
||||
lp = leafno + le32_to_cpu(tp->dmt_leafidx);
|
||||
|
||||
if (WARN_ON_ONCE(lp >= size || lp < 0))
|
||||
return;
|
||||
|
||||
/* is the current value the same as the old value ? if so,
|
||||
* there is nothing to do.
|
||||
*/
|
||||
|
@ -633,6 +633,11 @@ int dtSearch(struct inode *ip, struct component_name * key, ino_t * data,
|
||||
for (base = 0, lim = p->header.nextindex; lim; lim >>= 1) {
|
||||
index = base + (lim >> 1);
|
||||
|
||||
if (stbl[index] < 0) {
|
||||
rc = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (p->header.flag & BT_LEAF) {
|
||||
/* uppercase leaf name to compare */
|
||||
cmp =
|
||||
@ -1970,7 +1975,7 @@ static int dtSplitRoot(tid_t tid,
|
||||
do {
|
||||
f = &rp->slot[fsi];
|
||||
fsi = f->next;
|
||||
} while (fsi != -1);
|
||||
} while (fsi >= 0);
|
||||
|
||||
f->next = n;
|
||||
}
|
||||
|
@ -2179,6 +2179,9 @@ static int diNewExt(struct inomap * imap, struct iag * iagp, int extno)
|
||||
/* get the ag and iag numbers for this iag.
|
||||
*/
|
||||
agno = BLKTOAG(le64_to_cpu(iagp->agstart), sbi);
|
||||
if (agno >= MAXAG || agno < 0)
|
||||
return -EIO;
|
||||
|
||||
iagno = le32_to_cpu(iagp->iagnum);
|
||||
|
||||
/* check if this is the last free extent within the
|
||||
|
@ -172,15 +172,15 @@ int jfs_mount(struct super_block *sb)
|
||||
}
|
||||
jfs_info("jfs_mount: ipimap:0x%p", ipimap);
|
||||
|
||||
/* map further access of per fileset inodes by the fileset inode */
|
||||
sbi->ipimap = ipimap;
|
||||
|
||||
/* initialize fileset inode allocation map */
|
||||
if ((rc = diMount(ipimap))) {
|
||||
jfs_err("jfs_mount: diMount failed w/rc = %d", rc);
|
||||
goto err_ipimap;
|
||||
}
|
||||
|
||||
/* map further access of per fileset inodes by the fileset inode */
|
||||
sbi->ipimap = ipimap;
|
||||
|
||||
return rc;
|
||||
|
||||
/*
|
||||
|
@ -2702,6 +2702,7 @@ int jfs_lazycommit(void *arg)
|
||||
unsigned long flags;
|
||||
struct jfs_sb_info *sbi;
|
||||
|
||||
set_freezable();
|
||||
do {
|
||||
LAZY_LOCK(flags);
|
||||
jfs_commit_thread_waking = 0; /* OK to wake another thread */
|
||||
@ -2884,6 +2885,7 @@ int jfs_sync(void *arg)
|
||||
struct jfs_inode_info *jfs_ip;
|
||||
tid_t tid;
|
||||
|
||||
set_freezable();
|
||||
do {
|
||||
/*
|
||||
* write each inode on the anonymous inode list
|
||||
|
Loading…
Reference in New Issue
Block a user