|
|
@@ -1,101 +0,0 @@
|
|
|
-From 767d44ceff8fc8e1e7a47a0bcafdcc40eaeb6503 Mon Sep 17 00:00:00 2001
|
|
|
-From: Phillip Lougher <[email protected]>
|
|
|
-Date: Thu, 8 Jan 2026 01:20:40 +0000
|
|
|
-Subject: [PATCH] mksquashfs: don't create duplicate virtual -> real disk
|
|
|
- mappings
|
|
|
-
|
|
|
-This bug is caused by commit 472588dc40292fa3d047369f1e758016a6b26e70,
|
|
|
-but it is exposed by commit 078529915caab11e85299aac1304671151d507a3.
|
|
|
-
|
|
|
-The first commit adds a virtual -> real disk mapping in cases where a
|
|
|
-multi-block file contains all sparse blocks. In this case no data
|
|
|
-block has been written for this file, and it may mean no virtual -> real
|
|
|
-disk mapping will exist otherwise.
|
|
|
-
|
|
|
-However, a side effect of this is two duplicate virtual -> real disk
|
|
|
-mappings may be created, with different values.
|
|
|
-
|
|
|
-Now previously before commit 078529915caab11e85299aac1304671151d507a3,
|
|
|
-Mksquashfs waited for all outstanding data blocks to be processed by the
|
|
|
-orderer thread before creating the metadata. At this point all the
|
|
|
-duplicate virtual -> real disk mappings will exist, and the lookup
|
|
|
-routine will return the last one created - which happens to be the
|
|
|
-correct one.
|
|
|
-
|
|
|
-After commit 078529915caab11e85299aac1304671151d507a3, Mksquashfs no
|
|
|
-longer waits for all outstanding data blocks to be processed by the
|
|
|
-orderer thread, which means when the lookup takes place in metadata
|
|
|
-creation, there may exist only the first wrong duplicate, which will be
|
|
|
-returned. Obviously there may exist both duplicate values in which case
|
|
|
-the correct one will be returned. In other words this is a race
|
|
|
-condition, and it is highly dependent on hardware and input data
|
|
|
-whether it triggers.
|
|
|
-
|
|
|
-The fix is to increment the virtual disk position after creating a
|
|
|
-mapping when a multi-block file contains all sparse blocks. This
|
|
|
-obviously prevents duplicate mappings from being created.
|
|
|
-
|
|
|
-Fixes https://github.com/plougher/squashfs-tools/issues/339
|
|
|
-
|
|
|
-Signed-off-by: Phillip Lougher <[email protected]>
|
|
|
----
|
|
|
- squashfs-tools/mksquashfs.c | 12 +++++++++---
|
|
|
- squashfs-tools/virt_disk_pos.h | 9 +++++++++
|
|
|
- 2 files changed, 18 insertions(+), 3 deletions(-)
|
|
|
-
|
|
|
---- a/squashfs-tools/mksquashfs.c
|
|
|
-+++ b/squashfs-tools/mksquashfs.c
|
|
|
-@@ -2923,8 +2923,10 @@ static struct file_info *write_file_proc
|
|
|
- fragment_buffer ? fragment_buffer->checksum : 0, FALSE,
|
|
|
- TRUE);
|
|
|
-
|
|
|
-- if(!is_vpos_marked())
|
|
|
-+ if(!is_vpos_marked()) {
|
|
|
- send_orderer_create_map(get_marked_vpos());
|
|
|
-+ inc_vpos();
|
|
|
-+ }
|
|
|
-
|
|
|
- gen_cache_block_put(fragment_buffer);
|
|
|
- file_count ++;
|
|
|
-@@ -3027,8 +3029,10 @@ static struct file_info *write_file_bloc
|
|
|
- if(buffer_list[block])
|
|
|
- put_write_buffer_hash(buffer_list[block]);
|
|
|
-
|
|
|
-- if(!is_vpos_marked())
|
|
|
-+ if(!is_vpos_marked()) {
|
|
|
- send_orderer_create_map(get_marked_vpos());
|
|
|
-+ inc_vpos();
|
|
|
-+ }
|
|
|
- } else {
|
|
|
- for(block = thresh; block < blocks; block ++)
|
|
|
- gen_cache_block_put(buffer_list[block]);
|
|
|
-@@ -3140,8 +3144,10 @@ static struct file_info *write_file_bloc
|
|
|
- block_list, get_marked_vpos(), fragment, 0, fragment_buffer ?
|
|
|
- fragment_buffer->checksum : 0, FALSE, TRUE);
|
|
|
-
|
|
|
-- if(!is_vpos_marked())
|
|
|
-+ if(!is_vpos_marked()) {
|
|
|
- send_orderer_create_map(get_marked_vpos());
|
|
|
-+ inc_vpos();
|
|
|
-+ }
|
|
|
-
|
|
|
- gen_cache_block_put(fragment_buffer);
|
|
|
- file_count ++;
|
|
|
---- a/squashfs-tools/virt_disk_pos.h
|
|
|
-+++ b/squashfs-tools/virt_disk_pos.h
|
|
|
-@@ -96,6 +96,15 @@ static inline long long get_and_inc_vpos
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-+static inline void inc_vpos()
|
|
|
-+{
|
|
|
-+ if(marked_vpos == 0)
|
|
|
-+ BAD_ERROR("BUG: Saved write position is empty!\n");
|
|
|
-+
|
|
|
-+ vpos ++;
|
|
|
-+}
|
|
|
-+
|
|
|
-+
|
|
|
- static inline int reset_vpos(void)
|
|
|
- {
|
|
|
- if(marked_vpos == 0)
|