All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/5] btrfs-progs: add detection for unexpected file extents
@ 2026-08-18  9:29 Qu Wenruo
  2026-08-18  9:29 ` [PATCH 1/5] btrfs-progs: corrupt-block: allow inode corruption to use --value option Qu Wenruo
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Qu Wenruo @ 2026-08-18  9:29 UTC (permalink / raw)
  To: linux-btrfs

There is a kernel patch (*) which mentioned a corrupted fs image where
there is at least one file extent item which shouldn't exist, as the
inode is not a symlink or regular file.

It turns out btrfs check can not detect such case.

The first 3 patches introduce the ability to generate such image.

The 4th patch adds the detection ability, and the last one is the test
case.

*: https://lore.kernel.org/linux-btrfs/20260817132051.267646-1-gality369@gmail.com/


Qu Wenruo (5):
  btrfs-progs: corrupt-block: allow inode corruption to use --value
    option
  btrfs-progs: corrupt-block: allow dir item corruption to use --value
    option
  btrfs-progs: corrupt-block: allow corrupting dir item flags
  btrfs-progs: check: detect invalid file extent items
  btrfs-progs: fsck-test: add a test case for unexpected file extent
    items

 btrfs-corrupt-block.c                         |  68 ++++++++++--------
 check/main.c                                  |   5 ++
 check/mode-lowmem.c                           |  26 ++++---
 .../075-blk-inode-with-data/default.img.xz    | Bin 0 -> 2104 bytes
 .../075-blk-inode-with-data/test.sh           |  16 +++++
 5 files changed, 77 insertions(+), 38 deletions(-)
 create mode 100644 tests/fsck-tests/075-blk-inode-with-data/default.img.xz
 create mode 100755 tests/fsck-tests/075-blk-inode-with-data/test.sh

--
2.54.0


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/5] btrfs-progs: corrupt-block: allow inode corruption to use --value option
  2026-08-18  9:29 [PATCH 0/5] btrfs-progs: add detection for unexpected file extents Qu Wenruo
@ 2026-08-18  9:29 ` Qu Wenruo
  2026-08-18  9:29 ` [PATCH 2/5] btrfs-progs: corrupt-block: allow dir item " Qu Wenruo
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Qu Wenruo @ 2026-08-18  9:29 UTC (permalink / raw)
  To: linux-btrfs

This allows us to do more accurate inode item corruption, not only to
inject random number, but more targeted values.

This feature will be later utilized to change inode's mode from REG to
BLK.

Assisted-by: LLM (coding)
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 btrfs-corrupt-block.c | 51 +++++++++++++++++++++----------------------
 1 file changed, 25 insertions(+), 26 deletions(-)

diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c
index 69893f66a32a..9323643d2366 100644
--- a/btrfs-corrupt-block.c
+++ b/btrfs-corrupt-block.c
@@ -694,14 +694,13 @@ out:
 }
 
 static int corrupt_inode(struct btrfs_trans_handle *trans,
-			 struct btrfs_root *root, u64 inode, char *field)
+			 struct btrfs_root *root, u64 inode, char *field,
+			 u64 bogus)
 {
 	struct btrfs_inode_item *ei;
 	struct btrfs_path *path;
 	struct btrfs_key key;
 	enum btrfs_inode_field corrupt_field = convert_inode_field(field);
-	u64 bogus;
-	u64 orig;
 	int ret;
 
 	if (corrupt_field == BTRFS_INODE_FIELD_BAD) {
@@ -741,49 +740,49 @@ static int corrupt_inode(struct btrfs_trans_handle *trans,
 			    struct btrfs_inode_item);
 	switch (corrupt_field) {
 	case BTRFS_INODE_FIELD_ISIZE:
-		orig = btrfs_inode_size(path->nodes[0], ei);
-		bogus = generate_u64(orig);
+		if (bogus == (u64)-1)
+			bogus = generate_u64(btrfs_inode_size(path->nodes[0], ei));
 		btrfs_set_inode_size(path->nodes[0], ei, bogus);
 		break;
 	case BTRFS_INODE_FIELD_NBYTES:
-		orig = btrfs_inode_nbytes(path->nodes[0], ei);
-		bogus = generate_u64(orig);
+		if (bogus == (u64)-1)
+			bogus = generate_u64(btrfs_inode_nbytes(path->nodes[0], ei));
 		btrfs_set_inode_nbytes(path->nodes[0], ei, bogus);
 		break;
 	case BTRFS_INODE_FIELD_NLINK:
-		orig = btrfs_inode_nlink(path->nodes[0], ei);
-		bogus = generate_u32(orig);
-		btrfs_set_inode_nlink(path->nodes[0], ei, bogus);
+		if (bogus == (u64)-1)
+			bogus = generate_u32(btrfs_inode_nlink(path->nodes[0], ei));
+		btrfs_set_inode_nlink(path->nodes[0], ei, (u32)bogus);
 		break;
 	case BTRFS_INODE_FIELD_GENERATION:
-		orig = btrfs_inode_generation(path->nodes[0], ei);
-		bogus = generate_u64(orig);
+		if (bogus == (u64)-1)
+			bogus = generate_u64(btrfs_inode_generation(path->nodes[0], ei));
 		btrfs_set_inode_generation(path->nodes[0], ei, bogus);
 		break;
 	case BTRFS_INODE_FIELD_TRANSID:
-		orig = btrfs_inode_transid(path->nodes[0], ei);
-		bogus = generate_u64(orig);
+		if (bogus == (u64)-1)
+			bogus = generate_u64(btrfs_inode_transid(path->nodes[0], ei));
 		btrfs_set_inode_transid(path->nodes[0], ei, bogus);
 		break;
 	case BTRFS_INODE_FIELD_BLOCK_GROUP:
-		orig = btrfs_inode_block_group(path->nodes[0], ei);
-		bogus = generate_u64(orig);
+		if (bogus == (u64)-1)
+			bogus = generate_u64(btrfs_inode_block_group(path->nodes[0], ei));
 		btrfs_set_inode_block_group(path->nodes[0], ei, bogus);
 		break;
 	case BTRFS_INODE_FIELD_MODE:
-		orig = btrfs_inode_mode(path->nodes[0], ei);
-		bogus = generate_u32(orig);
-		btrfs_set_inode_mode(path->nodes[0], ei, bogus);
+		if (bogus == (u64)-1)
+			bogus = generate_u32(btrfs_inode_mode(path->nodes[0], ei));
+		btrfs_set_inode_mode(path->nodes[0], ei, (u32)bogus);
 		break;
 	case BTRFS_INODE_FIELD_UID:
-		orig = btrfs_inode_uid(path->nodes[0], ei);
-		bogus = generate_u32(orig);
-		btrfs_set_inode_uid(path->nodes[0], ei, bogus);
+		if (bogus == (u64)-1)
+			bogus = generate_u32(btrfs_inode_uid(path->nodes[0], ei));
+		btrfs_set_inode_uid(path->nodes[0], ei, (u32)bogus);
 		break;
 	case BTRFS_INODE_FIELD_GID:
-		orig = btrfs_inode_gid(path->nodes[0], ei);
-		bogus = generate_u32(orig);
-		btrfs_set_inode_gid(path->nodes[0], ei, bogus);
+		if (bogus == (u64)-1)
+			bogus = generate_u32(btrfs_inode_gid(path->nodes[0], ei));
+		btrfs_set_inode_gid(path->nodes[0], ei, (u32)bogus);
 		break;
 	default:
 		ret = -EINVAL;
@@ -1542,7 +1541,7 @@ int main(int argc, char **argv)
 		BUG_ON(IS_ERR(trans));
 		if (file_extent == (u64)-1) {
 			printf("corrupting inode\n");
-			ret = corrupt_inode(trans, root, inode, field);
+			ret = corrupt_inode(trans, root, inode, field, bogus_value);
 		} else {
 			ret = corrupt_file_extent(trans, root, inode,
 						  file_extent, field, bogus_value);
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/5] btrfs-progs: corrupt-block: allow dir item corruption to use --value option
  2026-08-18  9:29 [PATCH 0/5] btrfs-progs: add detection for unexpected file extents Qu Wenruo
  2026-08-18  9:29 ` [PATCH 1/5] btrfs-progs: corrupt-block: allow inode corruption to use --value option Qu Wenruo
@ 2026-08-18  9:29 ` Qu Wenruo
  2026-08-18  9:29 ` [PATCH 3/5] btrfs-progs: corrupt-block: allow corrupting dir item flags Qu Wenruo
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Qu Wenruo @ 2026-08-18  9:29 UTC (permalink / raw)
  To: linux-btrfs

For now this only affects DIR_ITEM location objectid corruption, but
later this will be utilized for more dir item member corruption.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 btrfs-corrupt-block.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c
index 9323643d2366..1e49f6ec50db 100644
--- a/btrfs-corrupt-block.c
+++ b/btrfs-corrupt-block.c
@@ -625,7 +625,7 @@ out:
 }
 
 static int corrupt_dir_item(struct btrfs_root *root, struct btrfs_key *key,
-			    char *field)
+			    char *field, u64 bogus)
 {
 	struct btrfs_trans_handle *trans;
 	struct btrfs_dir_item *di;
@@ -636,7 +636,6 @@ static int corrupt_dir_item(struct btrfs_root *root, struct btrfs_key *key,
 	unsigned long name_ptr;
 	enum btrfs_dir_item_field corrupt_field =
 		convert_dir_item_field(field);
-	u64 bogus;
 	u16 name_len;
 	int ret;
 
@@ -677,7 +676,8 @@ static int corrupt_dir_item(struct btrfs_root *root, struct btrfs_key *key,
 		goto out;
 	case BTRFS_DIR_ITEM_LOCATION_OBJECTID:
 		btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location);
-		bogus = generate_u64(location.objectid);
+		if (bogus == (u64)-1)
+			bogus = generate_u64(location.objectid);
 		location.objectid = bogus;
 		btrfs_cpu_key_to_disk(&disk_key, &location);
 		btrfs_set_dir_item_key(path->nodes[0], di, &disk_key);
@@ -1559,7 +1559,7 @@ int main(int argc, char **argv)
 	if (corrupt_di) {
 		if (!key.objectid || *field == 0)
 			usage(&corrupt_block_cmd, 1);
-		ret = corrupt_dir_item(target_root, &key, field);
+		ret = corrupt_dir_item(target_root, &key, field, bogus_value);
 		goto out_close;
 	}
 	if (csum_bytenr) {
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/5] btrfs-progs: corrupt-block: allow corrupting dir item flags
  2026-08-18  9:29 [PATCH 0/5] btrfs-progs: add detection for unexpected file extents Qu Wenruo
  2026-08-18  9:29 ` [PATCH 1/5] btrfs-progs: corrupt-block: allow inode corruption to use --value option Qu Wenruo
  2026-08-18  9:29 ` [PATCH 2/5] btrfs-progs: corrupt-block: allow dir item " Qu Wenruo
@ 2026-08-18  9:29 ` Qu Wenruo
  2026-08-18  9:29 ` [PATCH 4/5] btrfs-progs: check: detect invalid file extent items Qu Wenruo
  2026-08-18  9:29 ` [PATCH 5/5] btrfs-progs: fsck-test: add a test case for unexpected " Qu Wenruo
  4 siblings, 0 replies; 6+ messages in thread
From: Qu Wenruo @ 2026-08-18  9:29 UTC (permalink / raw)
  To: linux-btrfs

With this feature and the previous inode corruption, we can change the
type in inode item, dir item, dir index to be consistent with each
other.

Assisted-by: LLM (coding)
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 btrfs-corrupt-block.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/btrfs-corrupt-block.c b/btrfs-corrupt-block.c
index 1e49f6ec50db..83910f1394f1 100644
--- a/btrfs-corrupt-block.c
+++ b/btrfs-corrupt-block.c
@@ -343,6 +343,7 @@ enum btrfs_file_extent_field {
 enum btrfs_dir_item_field {
 	BTRFS_DIR_ITEM_NAME,
 	BTRFS_DIR_ITEM_LOCATION_OBJECTID,
+	BTRFS_DIR_ITEM_FLAGS,
 	BTRFS_DIR_ITEM_BAD,
 };
 
@@ -448,6 +449,8 @@ static enum btrfs_dir_item_field convert_dir_item_field(char *field)
 		return BTRFS_DIR_ITEM_NAME;
 	if (strncmp(field, "location_objectid", FIELD_BUF_LEN) == 0)
 		return BTRFS_DIR_ITEM_LOCATION_OBJECTID;
+	if (strncmp(field, "flags", FIELD_BUF_LEN) == 0)
+		return BTRFS_DIR_ITEM_FLAGS;
 	return BTRFS_DIR_ITEM_BAD;
 }
 
@@ -683,6 +686,12 @@ static int corrupt_dir_item(struct btrfs_root *root, struct btrfs_key *key,
 		btrfs_set_dir_item_key(path->nodes[0], di, &disk_key);
 		btrfs_mark_buffer_dirty(path->nodes[0]);
 		goto out;
+	case BTRFS_DIR_ITEM_FLAGS:
+		if (bogus == (u64)-1)
+			bogus = generate_u8(btrfs_dir_flags(path->nodes[0], di));
+		btrfs_set_dir_flags(path->nodes[0], di, bogus);
+		btrfs_mark_buffer_dirty(path->nodes[0]);
+		goto out;
 	default:
 		ret = -EINVAL;
 		goto out;
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/5] btrfs-progs: check: detect invalid file extent items
  2026-08-18  9:29 [PATCH 0/5] btrfs-progs: add detection for unexpected file extents Qu Wenruo
                   ` (2 preceding siblings ...)
  2026-08-18  9:29 ` [PATCH 3/5] btrfs-progs: corrupt-block: allow corrupting dir item flags Qu Wenruo
@ 2026-08-18  9:29 ` Qu Wenruo
  2026-08-18  9:29 ` [PATCH 5/5] btrfs-progs: fsck-test: add a test case for unexpected " Qu Wenruo
  4 siblings, 0 replies; 6+ messages in thread
From: Qu Wenruo @ 2026-08-18  9:29 UTC (permalink / raw)
  To: linux-btrfs

File extent items should only exist for regular and symlink inodes.
And for symlink inodes, the file extent must be inlined.

Add such check for lowmem mode to detect those invalid file extents.

Now for a corrupted image with the following fs tree layout:

	item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160
		generation 3 transid 9 size 12 nbytes 16384
		block group 0 mode 40755 links 1 uid 0 gid 0 rdev 0
		sequence 1 flags 0x0(none)
	item 1 key (256 INODE_REF 256) itemoff 16111 itemsize 12
		index 0 namelen 2 name: ..
	item 2 key (256 DIR_ITEM 496027801) itemoff 16075 itemsize 36
		location key (257 INODE_ITEM 0) type BLKDEV
		transid 9 data_len 0 name_len 6
		name: foobar
	item 3 key (256 DIR_INDEX 2) itemoff 16039 itemsize 36
		location key (257 INODE_ITEM 0) type BLKDEV
		transid 9 data_len 0 name_len 6
		name: foobar
	item 4 key (257 INODE_ITEM 0) itemoff 15879 itemsize 160
		generation 9 transid 9 size 8192 nbytes 8192
		block group 0 mode 60660 links 1 uid 0 gid 0 rdev 0
		sequence 2 flags 0x0(none)
	item 5 key (257 INODE_REF 256) itemoff 15863 itemsize 16
		index 2 namelen 6 name: foobar
	item 6 key (257 EXTENT_DATA 0) itemoff 15810 itemsize 53
		generation 9 type 1 (regular)
		extent data disk byte 13631488 nr 8192
		extent data offset 0 nr 8192 ram 8192
		extent compression 0 (none)

Lowmem mode will detect the error like the following:

 [5/8] checking fs roots
 ERROR: root 5 ino 257 should not have file extent
 ERROR: root 5 INODE[257] nbytes 8192 not equal to extent_size 0
 ERROR: errors found in fs roots
 found 172032 bytes used, error(s) found

For the original mode, it's less strict than the lowmem mode, and it
only rejects the obvious cases, without the extra verification on
inlined extent for symlinks:

 [5/8] checking fs roots
 root 5 inode 257 errors 40, bad file extent
 ERROR: errors found in fs roots
 found 172032 bytes used, error(s) found

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 check/main.c        |  5 +++++
 check/mode-lowmem.c | 26 ++++++++++++++++++--------
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/check/main.c b/check/main.c
index 3f162ad408d1..b96498294645 100644
--- a/check/main.c
+++ b/check/main.c
@@ -844,6 +844,11 @@ static void maybe_free_inode_rec(struct cache_tree *inode_cache,
 	if (!rec->found_inode_item)
 		return;
 
+	/* If it's not REG or SYMLNK, there should be no file extent. */
+	if (is_valid_imode(rec->imode) && !S_ISREG(rec->imode) &&
+	    !S_ISLNK(rec->imode) && rec->found_file_extent)
+		rec->errors |= I_ERR_BAD_FILE_EXTENT;
+
 	filetype = imode_to_type(rec->imode);
 	list_for_each_entry_safe(backref, tmp, &rec->backrefs, list) {
 		if (backref->found_dir_item && backref->found_dir_index) {
diff --git a/check/mode-lowmem.c b/check/mode-lowmem.c
index a3c590051054..813e29e2a9bb 100644
--- a/check/mode-lowmem.c
+++ b/check/mode-lowmem.c
@@ -2093,8 +2093,8 @@ static int check_file_extent_inline(struct btrfs_root *root,
  * Return 0 if no error occurred.
  */
 static int check_file_extent(struct btrfs_root *root, struct btrfs_path *path,
-			     unsigned int nodatasum, u64 isize, u64 *size,
-			     u64 *end)
+			     unsigned int nodatasum, u64 isize, u32 mode,
+			     u64 *size, u64 *end)
 {
 	struct btrfs_file_extent_item *fi;
 	struct btrfs_key fkey;
@@ -2119,6 +2119,14 @@ static int check_file_extent(struct btrfs_root *root, struct btrfs_path *path,
 	fi = btrfs_item_ptr(node, slot, struct btrfs_file_extent_item);
 	extent_type = btrfs_file_extent_type(node, fi);
 
+	/* Only regular and symlink can have file extents. */
+	if (is_valid_imode(mode) && !S_ISREG(mode) && !S_ISLNK(mode)) {
+		err |= FILE_EXTENT_ERROR;
+		error("root %llu ino %llu should not have file extent",
+			btrfs_root_id(root), fkey.objectid);
+		return err;
+	}
+
 	/* Check extent type */
 	if (extent_type != BTRFS_FILE_EXTENT_REG &&
 	    extent_type != BTRFS_FILE_EXTENT_PREALLOC &&
@@ -2129,6 +2137,13 @@ static int check_file_extent(struct btrfs_root *root, struct btrfs_path *path,
 		return err;
 	}
 
+	if (S_ISLNK(mode) && extent_type != BTRFS_FILE_EXTENT_INLINE) {
+		err |= FILE_EXTENT_ERROR;
+		error("root %llu ino %llu should not have regular/prealloc file extent",
+		      root->objectid, fkey.objectid);
+		return err;
+	}
+
 	/* Check inline extent */
 	if (extent_type == BTRFS_FILE_EXTENT_INLINE)
 		return check_file_extent_inline(root, path, size, end);
@@ -2807,12 +2822,7 @@ static int check_inode_item(struct btrfs_root *root, struct btrfs_path *path)
 			err |= ret;
 			break;
 		case BTRFS_EXTENT_DATA_KEY:
-			if (dir) {
-				warning("root %llu DIR INODE[%llu] shouldn't EXTENT_DATA[%llu %llu]",
-					root->objectid, inode_id, key.objectid,
-					key.offset);
-			}
-			ret = check_file_extent(root, path, nodatasum, isize,
+			ret = check_file_extent(root, path, nodatasum, isize, mode,
 						&extent_size, &extent_end);
 			err |= ret;
 			break;
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 5/5] btrfs-progs: fsck-test: add a test case for unexpected file extent items
  2026-08-18  9:29 [PATCH 0/5] btrfs-progs: add detection for unexpected file extents Qu Wenruo
                   ` (3 preceding siblings ...)
  2026-08-18  9:29 ` [PATCH 4/5] btrfs-progs: check: detect invalid file extent items Qu Wenruo
@ 2026-08-18  9:29 ` Qu Wenruo
  4 siblings, 0 replies; 6+ messages in thread
From: Qu Wenruo @ 2026-08-18  9:29 UTC (permalink / raw)
  To: linux-btrfs

The image is created using btrfs-corrupt-block, the fs tree leaf looks
like this:

	item 0 key (256 INODE_ITEM 0) itemoff 16123 itemsize 160
		generation 3 transid 9 size 12 nbytes 16384
		block group 0 mode 40755 links 1 uid 0 gid 0 rdev 0
		sequence 1 flags 0x0(none)
	item 1 key (256 INODE_REF 256) itemoff 16111 itemsize 12
		index 0 namelen 2 name: ..
	item 2 key (256 DIR_ITEM 496027801) itemoff 16075 itemsize 36
		location key (257 INODE_ITEM 0) type BLKDEV <<<
		transid 9 data_len 0 name_len 6
		name: foobar
	item 3 key (256 DIR_INDEX 2) itemoff 16039 itemsize 36
		location key (257 INODE_ITEM 0) type BLKDEV <<<
		transid 9 data_len 0 name_len 6
		name: foobar
	item 4 key (257 INODE_ITEM 0) itemoff 15879 itemsize 160
		generation 9 transid 9 size 8192 nbytes 8192
		block group 0 mode 60660 links 1 uid 0 gid 0 rdev 0 <<<
		sequence 2 flags 0x0(none)
	item 5 key (257 INODE_REF 256) itemoff 15863 itemsize 16
		index 2 namelen 6 name: foobar
	item 6 key (257 EXTENT_DATA 0) itemoff 15810 itemsize 53
		generation 9 type 1 (regular)
		extent data disk byte 13631488 nr 8192
		extent data offset 0 nr 8192 ram 8192
		extent compression 0 (none)

The image is generated by the following steps:

 # mkfs.btrfs -f $dev
 # mount $dev $mnt
 # xfs_io -f -c "pwrite 0 4k" $mnt/foobar
 # umount $mnt

 ## Change the inode's mode from REG to BLK
 # btrfs-corrupt-block -i 257 -f mode --value 25008 $dev

 ## Change the dir item's flag from REG to BLK
 # btrfs-corrupt-block -D 256,84,496027801 -f flags --value 4 $dev

 ## Change the dir index's flag from REG to BLK
 # btrfs-corrupt-block -D 256,96,2 -f flags --value 4 $dev

The inode's mode and dir flags all match, but there is one unexpected
file extent item there.

Both lowmem and original mode should detect such problem.

Signed-off-by: Qu Wenruo <wqu@suse.com>
---
 .../075-blk-inode-with-data/default.img.xz      | Bin 0 -> 2104 bytes
 .../fsck-tests/075-blk-inode-with-data/test.sh  |  16 ++++++++++++++++
 2 files changed, 16 insertions(+)
 create mode 100644 tests/fsck-tests/075-blk-inode-with-data/default.img.xz
 create mode 100755 tests/fsck-tests/075-blk-inode-with-data/test.sh

diff --git a/tests/fsck-tests/075-blk-inode-with-data/default.img.xz b/tests/fsck-tests/075-blk-inode-with-data/default.img.xz
new file mode 100644
index 0000000000000000000000000000000000000000..7fc1c58b8a3d71dce36d0612fd8da52a6d586e87
GIT binary patch
literal 2104
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

literal 0
HcmV?d00001

diff --git a/tests/fsck-tests/075-blk-inode-with-data/test.sh b/tests/fsck-tests/075-blk-inode-with-data/test.sh
new file mode 100755
index 000000000000..a98310e9b29d
--- /dev/null
+++ b/tests/fsck-tests/075-blk-inode-with-data/test.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+#
+# Verify that check can detect unexpected file extent items for special inodes
+# which should not have any file extent.
+
+source "$TEST_TOP/common" || exit
+
+check_prereq btrfs
+
+check_image() {
+	# The image contains an BLK inode, with a file extent.
+	# The check should report an error.
+	run_mustfail "unexpected file extent not detected" "$TOP/btrfs" check "$1"
+}
+
+check_all_images
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-08-18  9:30 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-18  9:29 [PATCH 0/5] btrfs-progs: add detection for unexpected file extents Qu Wenruo
2026-08-18  9:29 ` [PATCH 1/5] btrfs-progs: corrupt-block: allow inode corruption to use --value option Qu Wenruo
2026-08-18  9:29 ` [PATCH 2/5] btrfs-progs: corrupt-block: allow dir item " Qu Wenruo
2026-08-18  9:29 ` [PATCH 3/5] btrfs-progs: corrupt-block: allow corrupting dir item flags Qu Wenruo
2026-08-18  9:29 ` [PATCH 4/5] btrfs-progs: check: detect invalid file extent items Qu Wenruo
2026-08-18  9:29 ` [PATCH 5/5] btrfs-progs: fsck-test: add a test case for unexpected " Qu Wenruo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.