mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 03:24:45 +01:00
Various bug fixes and cleanups for JFS
-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEIodevzQLVs53l6BhNqiEXrVAjGQFAmfkKcAACgkQNqiEXrVA jGSE+g//ce4sps0QtKuVVQehW7+dp5OxGpNPwuqySbQ6p59QotyyFVnlqGV/927R NdnxcgK8Hd50XHWIsZbfFZQMuTM9c9ZzkvAna1w3xw+jXtc0S1Ym9zZY47Bq4cX2 D5A9bP5LONdyTgSGlA1P8e+NAfLnrMoO9kdef8EZC9iXpfY8RQj9sgF0TAmeQshU oMxcXoUWJj1zB9QzaikYzPCkr3AMWatR1CtWkLMs/IHTmEF8e3XhZOFhSfVlzZqO aN2YkxJG+E85Na8c7erPNFHuRtUzGu3v9J673aKfuWjpZEbYaFhSAoViESCQfeeu o/ArJurb6wNzYYNTTa1KG4083jWJZMoK582J/LHhpiUqikS5ovFkmcRYEEqWHHAW /ORLcqO+FX/hdbqomcmlSFJjMtaMiKIoM3KiXgAIjhrbh5vsOX+k60XfyJnCbakn IPEv1OyVX//V+UvK9dXAU7FLn94Xs9s1OehFYrAbns+zznp2bcfZHP3e6BYmPsyn FlRI8kc9K5+tbIrOdksAmopH00Ao9DjzGQUmh38ozOgKofLpJYYnwb7nV0pMPz3g ervm/9b+JUamtqwypY5YgKHV0K/BU9EenDkHKhhceAOGtV/Er4iIGJhL/Du97jqG M1Ow6Cr5mD/DF0DYQ1xfTWpiW+VaPvOmlIBjBU/kaKuoIzbg3Rg= =YeWl -----END PGP SIGNATURE----- Merge tag 'jfs-6.14' of github.com:kleikamp/linux-shaggy Pull jfs updates from David Kleikamp: "Various bug fixes and cleanups for JFS" * tag 'jfs-6.14' of github.com:kleikamp/linux-shaggy: jfs: add index corruption check to DT_GETPAGE() fs/jfs: consolidate sanity checking in dbMount jfs: add sanity check for agwidth in dbMount jfs: Prevent copying of nlink with value 0 from disk inode fs/jfs: Prevent integer overflow in AG size calculation fs/jfs: cast inactags to s64 to prevent potential overflow jfs: Fix uninit-value access of imap allocated in the diMount() function jfs: fix slab-out-of-bounds read in ea_get() jfs: add check read-only before truncation in jfs_truncate_nolock() jfs: add check read-only before txBeginAnon() call jfs: reject on-disk inodes of an unsupported type jfs: Remove reference to bh->b_page jfs: Delete a couple tabs in jfs_reconfigure()
This commit is contained in:
commit
f79adee883
7 changed files with 50 additions and 40 deletions
|
|
@ -369,7 +369,7 @@ void jfs_truncate_nolock(struct inode *ip, loff_t length)
|
|||
|
||||
ASSERT(length >= 0);
|
||||
|
||||
if (test_cflag(COMMIT_Nolink, ip)) {
|
||||
if (test_cflag(COMMIT_Nolink, ip) || isReadOnly(ip)) {
|
||||
xtTruncate(0, ip, length, COMMIT_WMAP);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,41 +178,26 @@ int dbMount(struct inode *ipbmap)
|
|||
dbmp_le = (struct dbmap_disk *) mp->data;
|
||||
bmp->db_mapsize = le64_to_cpu(dbmp_le->dn_mapsize);
|
||||
bmp->db_nfree = le64_to_cpu(dbmp_le->dn_nfree);
|
||||
|
||||
bmp->db_l2nbperpage = le32_to_cpu(dbmp_le->dn_l2nbperpage);
|
||||
if (bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE ||
|
||||
bmp->db_l2nbperpage < 0) {
|
||||
err = -EINVAL;
|
||||
goto err_release_metapage;
|
||||
}
|
||||
|
||||
bmp->db_numag = le32_to_cpu(dbmp_le->dn_numag);
|
||||
if (!bmp->db_numag || bmp->db_numag > MAXAG) {
|
||||
err = -EINVAL;
|
||||
goto err_release_metapage;
|
||||
}
|
||||
|
||||
bmp->db_maxlevel = le32_to_cpu(dbmp_le->dn_maxlevel);
|
||||
bmp->db_maxag = le32_to_cpu(dbmp_le->dn_maxag);
|
||||
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_agheight = le32_to_cpu(dbmp_le->dn_agheight);
|
||||
bmp->db_agwidth = le32_to_cpu(dbmp_le->dn_agwidth);
|
||||
bmp->db_agstart = le32_to_cpu(dbmp_le->dn_agstart);
|
||||
bmp->db_agl2size = le32_to_cpu(dbmp_le->dn_agl2size);
|
||||
if (bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG ||
|
||||
bmp->db_agl2size < 0) {
|
||||
err = -EINVAL;
|
||||
goto err_release_metapage;
|
||||
}
|
||||
|
||||
if (((bmp->db_mapsize - 1) >> bmp->db_agl2size) > MAXAG) {
|
||||
if ((bmp->db_l2nbperpage > L2PSIZE - L2MINBLOCKSIZE) ||
|
||||
(bmp->db_l2nbperpage < 0) ||
|
||||
!bmp->db_numag || (bmp->db_numag > MAXAG) ||
|
||||
(bmp->db_maxag >= MAXAG) || (bmp->db_maxag < 0) ||
|
||||
(bmp->db_agpref >= MAXAG) || (bmp->db_agpref < 0) ||
|
||||
!bmp->db_agwidth ||
|
||||
(bmp->db_agl2size > L2MAXL2SIZE - L2MAXAG) ||
|
||||
(bmp->db_agl2size < 0) ||
|
||||
((bmp->db_mapsize - 1) >> bmp->db_agl2size) > MAXAG) {
|
||||
err = -EINVAL;
|
||||
goto err_release_metapage;
|
||||
}
|
||||
|
|
@ -3403,7 +3388,7 @@ int dbExtendFS(struct inode *ipbmap, s64 blkno, s64 nblocks)
|
|||
oldl2agsize = bmp->db_agl2size;
|
||||
|
||||
bmp->db_agl2size = l2agsize;
|
||||
bmp->db_agsize = 1 << l2agsize;
|
||||
bmp->db_agsize = (s64)1 << l2agsize;
|
||||
|
||||
/* compute new number of AG */
|
||||
agno = bmp->db_numag;
|
||||
|
|
@ -3666,8 +3651,8 @@ void dbFinalizeBmap(struct inode *ipbmap)
|
|||
* system size is not a multiple of the group size).
|
||||
*/
|
||||
inactfree = (inactags && ag_rem) ?
|
||||
((inactags - 1) << bmp->db_agl2size) + ag_rem
|
||||
: inactags << bmp->db_agl2size;
|
||||
(((s64)inactags - 1) << bmp->db_agl2size) + ag_rem
|
||||
: ((s64)inactags << bmp->db_agl2size);
|
||||
|
||||
/* determine how many free blocks are in the active
|
||||
* allocation groups plus the average number of free blocks
|
||||
|
|
|
|||
|
|
@ -117,7 +117,8 @@ do { \
|
|||
if (!(RC)) { \
|
||||
if (((P)->header.nextindex > \
|
||||
(((BN) == 0) ? DTROOTMAXSLOT : (P)->header.maxslot)) || \
|
||||
((BN) && ((P)->header.maxslot > DTPAGEMAXSLOT))) { \
|
||||
((BN) && (((P)->header.maxslot > DTPAGEMAXSLOT) || \
|
||||
((P)->header.stblindex >= DTPAGEMAXSLOT)))) { \
|
||||
BT_PUTPAGE(MP); \
|
||||
jfs_error((IP)->i_sb, \
|
||||
"DT_GETPAGE: dtree page corrupt\n"); \
|
||||
|
|
|
|||
|
|
@ -74,6 +74,11 @@ extAlloc(struct inode *ip, s64 xlen, s64 pno, xad_t * xp, bool abnr)
|
|||
int rc;
|
||||
int xflag;
|
||||
|
||||
if (isReadOnly(ip)) {
|
||||
jfs_error(ip->i_sb, "read-only filesystem\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
/* This blocks if we are low on resources */
|
||||
txBeginAnon(ip->i_sb);
|
||||
|
||||
|
|
@ -253,6 +258,11 @@ int extRecord(struct inode *ip, xad_t * xp)
|
|||
{
|
||||
int rc;
|
||||
|
||||
if (isReadOnly(ip)) {
|
||||
jfs_error(ip->i_sb, "read-only filesystem\n");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
txBeginAnon(ip->i_sb);
|
||||
|
||||
mutex_lock(&JFS_IP(ip)->commit_mutex);
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ int diMount(struct inode *ipimap)
|
|||
* allocate/initialize the in-memory inode map control structure
|
||||
*/
|
||||
/* allocate the in-memory inode map control structure. */
|
||||
imap = kmalloc(sizeof(struct inomap), GFP_KERNEL);
|
||||
imap = kzalloc(sizeof(struct inomap), GFP_KERNEL);
|
||||
if (imap == NULL)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -456,7 +456,7 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
|
|||
dp += inum % 8; /* 8 inodes per 4K page */
|
||||
|
||||
/* copy on-disk inode to in-memory inode */
|
||||
if ((copy_from_dinode(dp, ip)) != 0) {
|
||||
if ((copy_from_dinode(dp, ip) != 0) || (ip->i_nlink == 0)) {
|
||||
/* handle bad return by returning NULL for ip */
|
||||
set_nlink(ip, 1); /* Don't want iput() deleting it */
|
||||
iput(ip);
|
||||
|
|
@ -3029,14 +3029,23 @@ static void duplicateIXtree(struct super_block *sb, s64 blkno,
|
|||
*
|
||||
* RETURN VALUES:
|
||||
* 0 - success
|
||||
* -ENOMEM - insufficient memory
|
||||
* -EINVAL - unexpected inode type
|
||||
*/
|
||||
static int copy_from_dinode(struct dinode * dip, struct inode *ip)
|
||||
{
|
||||
struct jfs_inode_info *jfs_ip = JFS_IP(ip);
|
||||
struct jfs_sb_info *sbi = JFS_SBI(ip->i_sb);
|
||||
int fileset = le32_to_cpu(dip->di_fileset);
|
||||
|
||||
jfs_ip->fileset = le32_to_cpu(dip->di_fileset);
|
||||
switch (fileset) {
|
||||
case AGGR_RESERVED_I: case AGGREGATE_I: case BMAP_I:
|
||||
case LOG_I: case BADBLOCK_I: case FILESYSTEM_I:
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
jfs_ip->fileset = fileset;
|
||||
jfs_ip->mode2 = le32_to_cpu(dip->di_mode);
|
||||
jfs_set_inode_flags(ip);
|
||||
|
||||
|
|
|
|||
|
|
@ -389,8 +389,8 @@ static int jfs_reconfigure(struct fs_context *fc)
|
|||
|
||||
if (!ctx->newLVSize) {
|
||||
ctx->newLVSize = sb_bdev_nr_blocks(sb);
|
||||
if (ctx->newLVSize == 0)
|
||||
pr_err("JFS: Cannot determine volume size\n");
|
||||
if (ctx->newLVSize == 0)
|
||||
pr_err("JFS: Cannot determine volume size\n");
|
||||
}
|
||||
|
||||
rc = jfs_extendfs(sb, ctx->newLVSize, 0);
|
||||
|
|
@ -766,7 +766,7 @@ static ssize_t jfs_quota_write(struct super_block *sb, int type,
|
|||
}
|
||||
lock_buffer(bh);
|
||||
memcpy(bh->b_data+offset, data, tocopy);
|
||||
flush_dcache_page(bh->b_page);
|
||||
flush_dcache_folio(bh->b_folio);
|
||||
set_buffer_uptodate(bh);
|
||||
mark_buffer_dirty(bh);
|
||||
unlock_buffer(bh);
|
||||
|
|
|
|||
|
|
@ -559,11 +559,16 @@ static int ea_get(struct inode *inode, struct ea_buffer *ea_buf, int min_size)
|
|||
|
||||
size_check:
|
||||
if (EALIST_SIZE(ea_buf->xattr) != ea_size) {
|
||||
int size = clamp_t(int, ea_size, 0, EALIST_SIZE(ea_buf->xattr));
|
||||
if (unlikely(EALIST_SIZE(ea_buf->xattr) > INT_MAX)) {
|
||||
printk(KERN_ERR "ea_get: extended attribute size too large: %u > INT_MAX\n",
|
||||
EALIST_SIZE(ea_buf->xattr));
|
||||
} else {
|
||||
int size = clamp_t(int, ea_size, 0, EALIST_SIZE(ea_buf->xattr));
|
||||
|
||||
printk(KERN_ERR "ea_get: invalid extended attribute\n");
|
||||
print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1,
|
||||
ea_buf->xattr, size, 1);
|
||||
printk(KERN_ERR "ea_get: invalid extended attribute\n");
|
||||
print_hex_dump(KERN_ERR, "", DUMP_PREFIX_ADDRESS, 16, 1,
|
||||
ea_buf->xattr, size, 1);
|
||||
}
|
||||
ea_release(inode, ea_buf);
|
||||
rc = -EIO;
|
||||
goto clean_up;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue