aboutsummaryrefslogtreecommitdiff
path: root/lib/sqfshelper
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-09-28 23:08:39 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-09-28 23:34:17 +0200
commitd758950ac88c2c6759d1616ac8be2c70c9dcf761 (patch)
treee96860712abea784525a2b7feb3a690b443e1372 /lib/sqfshelper
parent9bcb6edfe419d390acddc2ed7d0c04d37b753ac3 (diff)
Replace fstree/sqfshelper xattr code with sqfs_xattr_writer_t
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/sqfshelper')
-rw-r--r--lib/sqfshelper/Makemodule.am3
-rw-r--r--lib/sqfshelper/serialize_fstree.c2
-rw-r--r--lib/sqfshelper/tree_node_to_inode.c41
-rw-r--r--lib/sqfshelper/write_xattr.c278
4 files changed, 13 insertions, 311 deletions
diff --git a/lib/sqfshelper/Makemodule.am b/lib/sqfshelper/Makemodule.am
index 896605a..2ae1ac2 100644
--- a/lib/sqfshelper/Makemodule.am
+++ b/lib/sqfshelper/Makemodule.am
@@ -6,8 +6,7 @@ libsqfshelper_a_SOURCES += lib/sqfshelper/print_version.c
libsqfshelper_a_SOURCES += lib/sqfshelper/inode_stat.c
libsqfshelper_a_SOURCES += lib/sqfshelper/data_reader_dump.c
libsqfshelper_a_SOURCES += lib/sqfshelper/compress.c lib/sqfshelper/comp_opt.c
-libsqfshelper_a_SOURCES += lib/sqfshelper/data_writer.c
-libsqfshelper_a_SOURCES += lib/sqfshelper/write_xattr.c include/highlevel.h
+libsqfshelper_a_SOURCES += lib/sqfshelper/data_writer.c include/highlevel.h
libsqfshelper_a_SOURCES += lib/sqfshelper/get_path.c lib/sqfshelper/io_stdin.c
noinst_LIBRARIES += libsqfshelper.a
diff --git a/lib/sqfshelper/serialize_fstree.c b/lib/sqfshelper/serialize_fstree.c
index 2ec7daa..9a122ac 100644
--- a/lib/sqfshelper/serialize_fstree.c
+++ b/lib/sqfshelper/serialize_fstree.c
@@ -36,7 +36,7 @@ static sqfs_inode_generic_t *write_dir_entries(sqfs_dir_writer_t *dirw,
if (sqfs_dir_writer_end(dirw))
return NULL;
- xattr = (node->xattr == NULL) ? 0xFFFFFFFF : node->xattr->index;
+ xattr = node->xattr_idx;
parent_inode = (node->parent == NULL) ? 1 : node->parent->inode_num;
inode = sqfs_dir_writer_create_inode(dirw, 0, xattr, parent_inode);
diff --git a/lib/sqfshelper/tree_node_to_inode.c b/lib/sqfshelper/tree_node_to_inode.c
index d75e959..bafaaf7 100644
--- a/lib/sqfshelper/tree_node_to_inode.c
+++ b/lib/sqfshelper/tree_node_to_inode.c
@@ -18,26 +18,11 @@
static int get_type(tree_node_t *node)
{
switch (node->mode & S_IFMT) {
- case S_IFSOCK:
- if (node->xattr != NULL)
- return SQFS_INODE_EXT_SOCKET;
- return SQFS_INODE_SOCKET;
- case S_IFIFO:
- if (node->xattr != NULL)
- return SQFS_INODE_EXT_FIFO;
- return SQFS_INODE_FIFO;
- case S_IFLNK:
- if (node->xattr != NULL)
- return SQFS_INODE_EXT_SLINK;
- return SQFS_INODE_SLINK;
- case S_IFBLK:
- if (node->xattr != NULL)
- return SQFS_INODE_EXT_BDEV;
- return SQFS_INODE_BDEV;
- case S_IFCHR:
- if (node->xattr != NULL)
- return SQFS_INODE_EXT_CDEV;
- return SQFS_INODE_CDEV;
+ case S_IFSOCK: return SQFS_INODE_SOCKET;
+ case S_IFIFO: return SQFS_INODE_FIFO;
+ case S_IFLNK: return SQFS_INODE_SLINK;
+ case S_IFBLK: return SQFS_INODE_BDEV;
+ case S_IFCHR: return SQFS_INODE_CDEV;
}
assert(0);
}
@@ -47,7 +32,6 @@ sqfs_inode_generic_t *tree_node_to_inode(sqfs_id_table_t *idtbl,
{
sqfs_inode_generic_t *inode;
sqfs_u16 uid_idx, gid_idx;
- sqfs_u32 xattr = 0xFFFFFFFF;
size_t extra = 0;
if (S_ISREG(node->mode)) {
@@ -78,8 +62,8 @@ sqfs_inode_generic_t *tree_node_to_inode(sqfs_id_table_t *idtbl,
if (sqfs_id_table_id_to_index(idtbl, node->gid, &gid_idx))
goto fail;
- if (node->xattr != NULL)
- xattr = node->xattr->index;
+ if (node->xattr_idx != 0xFFFFFFFF)
+ sqfs_inode_make_extended(inode);
inode->base.mode = node->mode;
inode->base.uid_idx = uid_idx;
@@ -95,7 +79,7 @@ sqfs_inode_generic_t *tree_node_to_inode(sqfs_id_table_t *idtbl,
case SQFS_INODE_EXT_FIFO:
case SQFS_INODE_EXT_SOCKET:
inode->data.ipc_ext.nlink = 1;
- inode->data.ipc_ext.xattr_idx = xattr;
+ inode->data.ipc_ext.xattr_idx = node->xattr_idx;
break;
case SQFS_INODE_SLINK:
inode->data.slink.nlink = 1;
@@ -104,7 +88,7 @@ sqfs_inode_generic_t *tree_node_to_inode(sqfs_id_table_t *idtbl,
case SQFS_INODE_EXT_SLINK:
inode->data.slink_ext.nlink = 1;
inode->data.slink_ext.target_size = extra;
- inode->data.slink_ext.xattr_idx = xattr;
+ inode->data.slink_ext.xattr_idx = node->xattr_idx;
break;
case SQFS_INODE_BDEV:
case SQFS_INODE_CDEV:
@@ -115,15 +99,12 @@ sqfs_inode_generic_t *tree_node_to_inode(sqfs_id_table_t *idtbl,
case SQFS_INODE_EXT_CDEV:
inode->data.dev_ext.nlink = 1;
inode->data.dev_ext.devno = node->data.devno;
- inode->data.dev_ext.xattr_idx = xattr;
+ inode->data.dev_ext.xattr_idx = node->xattr_idx;
break;
case SQFS_INODE_FILE:
- if (xattr != 0xFFFFFFFF) {
- sqfs_inode_make_extended(inode);
- inode->data.file_ext.xattr_idx = xattr;
- }
break;
case SQFS_INODE_EXT_FILE:
+ inode->data.file_ext.xattr_idx = node->xattr_idx;
break;
default:
goto fail;
diff --git a/lib/sqfshelper/write_xattr.c b/lib/sqfshelper/write_xattr.c
deleted file mode 100644
index a3f5170..0000000
--- a/lib/sqfshelper/write_xattr.c
+++ /dev/null
@@ -1,278 +0,0 @@
-/* SPDX-License-Identifier: GPL-3.0-or-later */
-/*
- * write_xattr.c
- *
- * Copyright (C) 2019 David Oberhollenzer <goliath@infraroot.at>
- */
-#include "config.h"
-
-#include "sqfs/meta_writer.h"
-#include "sqfs/xattr.h"
-#include "highlevel.h"
-#include "util.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-static int write_key(sqfs_meta_writer_t *mw, const char *key,
- tree_xattr_t *xattr, bool value_is_ool)
-{
- sqfs_xattr_entry_t kent;
- int type;
-
- type = sqfs_get_xattr_prefix_id(key);
- if (type < 0) {
- fprintf(stderr, "unsupported xattr key '%s'\n", key);
- return -1;
- }
-
- key = strchr(key, '.');
- assert(key != NULL);
- ++key;
-
- if (value_is_ool)
- type |= SQFS_XATTR_FLAG_OOL;
-
- kent.type = htole16(type);
- kent.size = htole16(strlen(key));
-
- if (sqfs_meta_writer_append(mw, &kent, sizeof(kent)))
- return -1;
- if (sqfs_meta_writer_append(mw, key, strlen(key)))
- return -1;
-
- xattr->size += sizeof(sqfs_xattr_entry_t) + strlen(key);
- return 0;
-}
-
-static int write_value(sqfs_meta_writer_t *mw, const char *value,
- tree_xattr_t *xattr, sqfs_u64 *value_ref_out)
-{
- sqfs_xattr_value_t vent;
- sqfs_u32 offset;
- sqfs_u64 block;
-
- sqfs_meta_writer_get_position(mw, &block, &offset);
- *value_ref_out = (block << 16) | (offset & 0xFFFF);
-
- vent.size = htole32(strlen(value));
-
- if (sqfs_meta_writer_append(mw, &vent, sizeof(vent)))
- return -1;
-
- if (sqfs_meta_writer_append(mw, value, strlen(value)))
- return -1;
-
- xattr->size += sizeof(vent) + strlen(value);
- return 0;
-}
-
-static int write_value_ool(sqfs_meta_writer_t *mw, sqfs_u64 location,
- tree_xattr_t *xattr)
-{
- sqfs_xattr_value_t vent;
- sqfs_u64 ref;
-
- vent.size = htole32(sizeof(location));
- if (sqfs_meta_writer_append(mw, &vent, sizeof(vent)))
- return -1;
-
- ref = htole64(location);
- if (sqfs_meta_writer_append(mw, &ref, sizeof(ref)))
- return -1;
-
- xattr->size += sizeof(vent) + sizeof(ref);
- return 0;
-}
-
-static bool should_store_ool(fstree_t *fs, const char *value, size_t index)
-{
- size_t refcount;
-
- refcount = str_table_get_ref_count(&fs->xattr_values, index);
- if (refcount < 2)
- return false;
-
- /*
- Storing in line needs this many bytes: refcount * len
-
- Storing out-of-line needs this many: len + (refcount - 1) * 8
-
- Out-of-line prefereable if:
- refcount * len > len + (refcount - 1) * 8
- => refcount * len - len > (refcount - 1) * 8
- => (refcount - 1) * len > (refcount - 1) * 8
- => len > 8
-
- Note that this only holds iff refcount - 1 != 0, i.e. refcount > 1,
- otherwise we would be dividing by 0 in the 3rd step.
- */
- return strlen(value) > sizeof(sqfs_u64);
-}
-
-static int write_kv_pairs(fstree_t *fs, sqfs_meta_writer_t *mw,
- tree_xattr_t *xattr, sqfs_u64 *ool_locations)
-{
- sqfs_u32 key_idx, val_idx;
- const char *key, *value;
- sqfs_u64 ref;
- size_t i;
-
- for (i = 0; i < xattr->num_attr; ++i) {
- key_idx = xattr->attr[i].key_index;
- val_idx = xattr->attr[i].value_index;
-
- key = str_table_get_string(&fs->xattr_keys, key_idx);
- value = str_table_get_string(&fs->xattr_values, val_idx);
-
- if (ool_locations[val_idx] == 0xFFFFFFFFFFFFFFFF) {
- if (write_key(mw, key, xattr, false))
- return -1;
-
- if (write_value(mw, value, xattr, &ref))
- return -1;
-
- if (should_store_ool(fs, value, val_idx))
- ool_locations[val_idx] = ref;
- } else {
- if (write_key(mw, key, xattr, true))
- return -1;
-
- if (write_value_ool(mw, ool_locations[val_idx], xattr))
- return -1;
- }
- }
-
- return 0;
-}
-
-static sqfs_u64 *create_ool_locations_table(fstree_t *fs)
-{
- sqfs_u64 *table;
- size_t i;
-
- table = alloc_array(sizeof(sqfs_u64), fs->xattr_values.num_strings);
-
- if (table == NULL) {
- perror("allocating Xattr OOL locations table");
- return NULL;
- }
-
- for (i = 0; i < fs->xattr_values.num_strings; ++i) {
- table[i] = 0xFFFFFFFFFFFFFFFFUL;
- }
-
- return table;
-}
-
-int write_xattr(sqfs_file_t *file, fstree_t *fs, sqfs_super_t *super,
- sqfs_compressor_t *cmp)
-{
- sqfs_u64 kv_start, id_start, block, off, *tbl, *ool_locations;
- size_t i = 0, count = 0, blocks;
- sqfs_xattr_id_table_t idtbl;
- sqfs_xattr_id_t id_ent;
- sqfs_meta_writer_t *mw;
- tree_xattr_t *it;
- sqfs_u32 offset;
-
- if (fs->xattr == NULL)
- return 0;
-
- ool_locations = create_ool_locations_table(fs);
- if (ool_locations == NULL)
- return -1;
-
- mw = sqfs_meta_writer_create(file, cmp, 0);
- if (mw == NULL)
- goto fail_ool;
-
- /* write xattr key-value pairs */
- kv_start = file->get_size(file);
-
- for (it = fs->xattr; it != NULL; it = it->next) {
- sqfs_meta_writer_get_position(mw, &it->block, &it->offset);
- it->size = 0;
-
- if (write_kv_pairs(fs, mw, it, ool_locations))
- goto fail_mw;
-
- ++count;
- }
-
- if (sqfs_meta_writer_flush(mw))
- goto fail_mw;
-
- sqfs_meta_writer_reset(mw);
-
- /* allocate location table */
- blocks = (count * sizeof(id_ent)) / SQFS_META_BLOCK_SIZE;
-
- if ((count * sizeof(id_ent)) % SQFS_META_BLOCK_SIZE)
- ++blocks;
-
- tbl = alloc_array(sizeof(sqfs_u64), blocks);
-
- if (tbl == NULL) {
- perror("generating xattr ID table");
- goto fail_mw;
- }
-
- /* write ID table referring to key value pairs, record offsets */
- id_start = 0;
- off = file->get_size(file);
- tbl[i++] = htole64(off);
-
- for (it = fs->xattr; it != NULL; it = it->next) {
- id_ent.xattr = htole64((it->block << 16) | it->offset);
- id_ent.count = htole32(it->num_attr);
- id_ent.size = htole32(it->size);
-
- if (sqfs_meta_writer_append(mw, &id_ent, sizeof(id_ent)))
- goto fail_tbl;
-
- sqfs_meta_writer_get_position(mw, &block, &offset);
-
- if (block != id_start) {
- id_start = block;
- tbl[i++] = htole64(off + id_start);
- }
- }
-
- if (sqfs_meta_writer_flush(mw))
- goto fail_tbl;
-
- /* write offset table */
- idtbl.xattr_table_start = htole64(kv_start);
- idtbl.xattr_ids = htole32(count);
- idtbl.unused = 0;
-
- super->xattr_id_table_start = file->get_size(file);
- super->flags &= ~SQFS_FLAG_NO_XATTRS;
-
- if (file->write_at(file, super->xattr_id_table_start,
- &idtbl, sizeof(idtbl))) {
- perror("writing xattr ID table");
- goto fail_tbl;
- }
-
- if (file->write_at(file, super->xattr_id_table_start + sizeof(idtbl),
- tbl, sizeof(tbl[0]) * blocks)) {
- perror("writing xattr ID table");
- goto fail_tbl;
- }
-
- free(tbl);
- sqfs_meta_writer_destroy(mw);
- free(ool_locations);
- return 0;
-fail_tbl:
- free(tbl);
-fail_mw:
- sqfs_meta_writer_destroy(mw);
-fail_ool:
- free(ool_locations);
- return -1;
-}