diff options
| author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-09-28 23:08:39 +0200 | 
|---|---|---|
| committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-09-28 23:34:17 +0200 | 
| commit | d758950ac88c2c6759d1616ac8be2c70c9dcf761 (patch) | |
| tree | e96860712abea784525a2b7feb3a690b443e1372 /lib/sqfshelper | |
| parent | 9bcb6edfe419d390acddc2ed7d0c04d37b753ac3 (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.am | 3 | ||||
| -rw-r--r-- | lib/sqfshelper/serialize_fstree.c | 2 | ||||
| -rw-r--r-- | lib/sqfshelper/tree_node_to_inode.c | 41 | ||||
| -rw-r--r-- | lib/sqfshelper/write_xattr.c | 278 | 
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; -} | 
