summaryrefslogtreecommitdiff
path: root/e2fsck
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2023-01-30 01:15:55 -0500
committerTheodore Ts'o <tytso@mit.edu>2023-01-30 01:15:55 -0500
commit5adb971551656597c568bac6b6c06e1506f89046 (patch)
tree5cfa6d5d3189e6de8ad583c5f141b9ecf7c43609 /e2fsck
parent9d25847b3ce3df3adaa20a466af9fb7af287a567 (diff)
parentb0101535a35c07975227128875204fab07e72996 (diff)
downloade2fsprogs-5adb971551656597c568bac6b6c06e1506f89046.tar.gz
Merge branch 'maint' into next
Diffstat (limited to 'e2fsck')
-rw-r--r--e2fsck/jfs_user.h10
-rw-r--r--e2fsck/pass1.c15
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;