aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2023-01-19 15:18:43 +0100
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2024-01-24 09:56:10 +0100
commitd81b85ba4db12c2052a8fdd3b4e77343740d6fba (patch)
tree7d3bc26ffb041ce601d6c894687b8cb65683155a
parent78a6f0b30e648c8ba3a3fb28f1f818548a81978b (diff)
libsqfs: add a threshold for extended directory inodes with index
mksquashfs generates extended inodes if a directory contains 256 entries. libsquashfs so far only generated extended inodes if there is no other way to encode it. Mimic the behaviour of mksquashfs by adding a threshold. For this to work, the "sqfs_inode_set_xattr_index" function has to be changed to not immediately try to demote inodes to basic types. The fstree serialization is modified to do that itself if the index is 0xFFFFFFFF and the target is not a directory inode. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--include/sqfs/inode.h7
-rw-r--r--lib/common/writer/serialize_fstree.c3
-rw-r--r--lib/sqfs/dir_writer.c5
-rw-r--r--lib/sqfs/inode.c6
4 files changed, 12 insertions, 9 deletions
diff --git a/include/sqfs/inode.h b/include/sqfs/inode.h
index 8df7158..7f4e7b5 100644
--- a/include/sqfs/inode.h
+++ b/include/sqfs/inode.h
@@ -576,9 +576,10 @@ SQFS_API int sqfs_inode_get_xattr_index(const sqfs_inode_generic_t *inode,
*
* @memberof sqfs_inode_generic_t
*
- * For basic inodes, this function promes the inodes to extended inodes if the
- * index is not 0xFFFFFFFF. If the index is 0xFFFFFFFF, the function tries to
- * demote extended inode to a basic inode after setting the index.
+ * For basic inodes, this function promotes the inodes to extended inodes if
+ * the index is not 0xFFFFFFFF. The function does not try to demote extended
+ * inodes if the index is 0xFFFFFFFF, because that would cause additional
+ * information like a directory index to be lost.
*
* @param inode A pointer to an inode.
* @param index The extended attribute index.
diff --git a/lib/common/writer/serialize_fstree.c b/lib/common/writer/serialize_fstree.c
index b15f30d..9776874 100644
--- a/lib/common/writer/serialize_fstree.c
+++ b/lib/common/writer/serialize_fstree.c
@@ -144,6 +144,9 @@ static int serialize_tree_node(const char *filename, sqfs_writer_t *wr,
sqfs_inode_set_xattr_index(inode, n->xattr_idx);
+ if (n->xattr_idx == 0xFFFFFFFF && !S_ISDIR(n->mode))
+ sqfs_inode_make_basic(inode);
+
ret = sqfs_id_table_id_to_index(wr->idtbl, n->uid,
&inode->base.uid_idx);
if (ret)
diff --git a/lib/sqfs/dir_writer.c b/lib/sqfs/dir_writer.c
index a02faa7..ce63a1e 100644
--- a/lib/sqfs/dir_writer.c
+++ b/lib/sqfs/dir_writer.c
@@ -21,6 +21,8 @@
#include <stdlib.h>
#include <string.h>
+#define DIR_INDEX_THRESHOLD (256)
+
typedef struct dir_entry_t {
struct dir_entry_t *next;
sqfs_u64 inode_ref;
@@ -385,6 +387,9 @@ sqfs_inode_generic_t
inode->base.type = SQFS_INODE_DIR;
}
+ if (writer->ent_count >= DIR_INDEX_THRESHOLD)
+ inode->base.type = SQFS_INODE_EXT_DIR;
+
if (inode->base.type == SQFS_INODE_DIR) {
inode->data.dir.start_block = start_block;
inode->data.dir.nlink = writer->ent_count + hlinks + 2;
diff --git a/lib/sqfs/inode.c b/lib/sqfs/inode.c
index 0fb4809..ce51cf5 100644
--- a/lib/sqfs/inode.c
+++ b/lib/sqfs/inode.c
@@ -110,12 +110,6 @@ int sqfs_inode_set_xattr_index(sqfs_inode_generic_t *inode, sqfs_u32 index)
return SQFS_ERROR_CORRUPTED;
}
- if (index == 0xFFFFFFFF) {
- err = sqfs_inode_make_basic(inode);
- if (err)
- return err;
- }
-
return 0;
}