diff options
author | Theodore Ts'o <tytso@mit.edu> | 2023-01-30 01:15:55 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2023-01-30 01:15:55 -0500 |
commit | 5adb971551656597c568bac6b6c06e1506f89046 (patch) | |
tree | 5cfa6d5d3189e6de8ad583c5f141b9ecf7c43609 /e2fsck | |
parent | 9d25847b3ce3df3adaa20a466af9fb7af287a567 (diff) | |
parent | b0101535a35c07975227128875204fab07e72996 (diff) | |
download | e2fsprogs-5adb971551656597c568bac6b6c06e1506f89046.tar.gz |
Merge branch 'maint' into next
Diffstat (limited to 'e2fsck')
-rw-r--r-- | e2fsck/jfs_user.h | 10 | ||||
-rw-r--r-- | e2fsck/pass1.c | 15 |
2 files changed, 21 insertions, 4 deletions
diff --git a/e2fsck/jfs_user.h b/e2fsck/jfs_user.h index 1167c80d..5928a8a8 100644 --- a/e2fsck/jfs_user.h +++ b/e2fsck/jfs_user.h @@ -179,7 +179,17 @@ _INLINE_ void *kmalloc(size_t size, gfp_t flags EXT2FS_ATTR((unused))) _INLINE_ void kfree(const void *objp) { +#ifdef HAVE_INTPTR_T + /* + * Work around a botch in the C standard, which triggers + * compiler warnings. For better or for worse, the kernel + * uses const void * for kfree, while the C standard mandates + * the use of void *. See: https://yarchive.net/comp/const.html + */ + free((void *)(intptr_t)objp); +#else free((void *)objp); +#endif } /* generic hashing taken from the Linux kernel */ diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c index 591acad5..a341c72a 100644 --- a/e2fsck/pass1.c +++ b/e2fsck/pass1.c @@ -331,7 +331,7 @@ static problem_t check_large_ea_inode(e2fsck_t ctx, blk64_t *quota_blocks) { struct ext2_inode inode; - __u32 hash; + __u32 hash, signed_hash; errcode_t retval; /* Check if inode is within valid range */ @@ -343,7 +343,8 @@ static problem_t check_large_ea_inode(e2fsck_t ctx, e2fsck_read_inode(ctx, entry->e_value_inum, &inode, "pass1"); - retval = ext2fs_ext_attr_hash_entry2(ctx->fs, entry, NULL, &hash); + retval = ext2fs_ext_attr_hash_entry3(ctx->fs, entry, NULL, &hash, + &signed_hash); if (retval) { com_err("check_large_ea_inode", retval, _("while hashing entry with e_value_inum = %u"), @@ -351,7 +352,7 @@ static problem_t check_large_ea_inode(e2fsck_t ctx, fatal_error(ctx, 0); } - if (hash == entry->e_hash) { + if ((hash == entry->e_hash) || (signed_hash == entry->e_hash)) { *quota_blocks = size_to_quota_blocks(ctx->fs, entry->e_value_size); } else { @@ -495,7 +496,10 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx, } hash = ext2fs_ext_attr_hash_entry(entry, - start + entry->e_value_offs); + start + entry->e_value_offs); + if (entry->e_hash != 0 && entry->e_hash != hash) + hash = ext2fs_ext_attr_hash_entry_signed(entry, + start + entry->e_value_offs); /* e_hash may be 0 in older inode's ea */ if (entry->e_hash != 0 && entry->e_hash != hash) { @@ -2602,6 +2606,9 @@ static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx, hash = ext2fs_ext_attr_hash_entry(entry, block_buf + entry->e_value_offs); + if (entry->e_hash != hash) + hash = ext2fs_ext_attr_hash_entry_signed(entry, + block_buf + entry->e_value_offs); if (entry->e_hash != hash) { pctx->num = entry->e_hash; |