From 0e7fba27a26694f6babe5bd5de93733760cd770d Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sun, 12 May 2019 11:30:22 +0200 Subject: Add xattr indices to inodes Signed-off-by: David Oberhollenzer --- include/fstree.h | 14 +++++++++ lib/fstree/fstree.c | 11 +++++++ mkfs/meta.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 105 insertions(+), 7 deletions(-) diff --git a/include/fstree.h b/include/fstree.h index a7d19c2..96294b8 100644 --- a/include/fstree.h +++ b/include/fstree.h @@ -28,6 +28,11 @@ struct tree_xattr_t { size_t num_attr; size_t max_attr; + /** + * @brief Incremental index within all xattr blocks + */ + size_t index; + /** * @brief Back reference to the tree node this was created for */ @@ -349,6 +354,15 @@ tree_node_t *fstree_add_file(fstree_t *fs, const char *path, uint16_t mode, int fstree_add_xattr(fstree_t *fs, tree_node_t *node, const char *key, const char *value); +/** + * @brief Recompute index number of all xattr blocks + * + * @memberof fstree_t + * + * @param fs A pointer to the fstree object + */ +void fstree_xattr_reindex(fstree_t *fs); + /** * @brief Remove dupliciate xattr listings * diff --git a/lib/fstree/fstree.c b/lib/fstree/fstree.c index 356f65a..0c3f13d 100644 --- a/lib/fstree/fstree.c +++ b/lib/fstree/fstree.c @@ -260,6 +260,15 @@ static int cmp_u64(const void *lhs, const void *rhs) return l < r ? -1 : (l > r ? 1 : 0); } +void fstree_xattr_reindex(fstree_t *fs) +{ + tree_xattr_t *it; + size_t index = 0; + + for (it = fs->xattr; it != NULL; it = it->next) + it->index = index++; +} + void fstree_xattr_deduplicate(fstree_t *fs) { tree_xattr_t *it, *it1, *prev; @@ -293,6 +302,8 @@ void fstree_xattr_deduplicate(fstree_t *fs) it = it->next; } } + + fstree_xattr_reindex(fs); } int fstree_init(fstree_t *fs, size_t block_size, uint32_t mtime, diff --git a/mkfs/meta.c b/mkfs/meta.c index 0e8dad5..58f82d7 100644 --- a/mkfs/meta.c +++ b/mkfs/meta.c @@ -152,11 +152,31 @@ static int write_inode(sqfs_info_t *info, meta_writer_t *im, meta_writer_t *dm, info->super.inode_count += 1; switch (node->mode & S_IFMT) { - case S_IFSOCK: node->type = SQFS_INODE_SOCKET; break; - case S_IFIFO: node->type = SQFS_INODE_FIFO; break; - case S_IFLNK: node->type = SQFS_INODE_SLINK; break; - case S_IFBLK: node->type = SQFS_INODE_BDEV; break; - case S_IFCHR: node->type = SQFS_INODE_CDEV; break; + case S_IFSOCK: + node->type = SQFS_INODE_SOCKET; + if (node->xattr != NULL) + node->type = SQFS_INODE_EXT_SOCKET; + break; + case S_IFIFO: + node->type = SQFS_INODE_FIFO; + if (node->xattr != NULL) + node->type = SQFS_INODE_EXT_FIFO; + break; + case S_IFLNK: + node->type = SQFS_INODE_SLINK; + if (node->xattr != NULL) + node->type = SQFS_INODE_EXT_SLINK; + break; + case S_IFBLK: + node->type = SQFS_INODE_BDEV; + if (node->xattr != NULL) + node->type = SQFS_INODE_EXT_BDEV; + break; + case S_IFCHR: + node->type = SQFS_INODE_CDEV; + if (node->xattr != NULL) + node->type = SQFS_INODE_EXT_CDEV; + break; case S_IFDIR: di = node->data.dir; node->type = SQFS_INODE_DIR; @@ -164,7 +184,8 @@ static int write_inode(sqfs_info_t *info, meta_writer_t *im, meta_writer_t *dm, if (write_dir(dm, di, &diridx)) return -1; - if ((di->start_block) > 0xFFFFFFFFUL || di->size > 0xFFFF) { + if ((di->start_block) > 0xFFFFFFFFUL || di->size > 0xFFFF || + (node->xattr != NULL && di->size != 0)) { node->type = SQFS_INODE_EXT_DIR; } else { free(diridx); @@ -176,7 +197,7 @@ static int write_inode(sqfs_info_t *info, meta_writer_t *im, meta_writer_t *dm, node->type = SQFS_INODE_FILE; if (fi->startblock > 0xFFFFFFFFUL || fi->size > 0xFFFFFFFFUL || - hard_link_count(node) > 1) { + hard_link_count(node) > 1 || node->xattr != NULL) { node->type = SQFS_INODE_EXT_FILE; } break; @@ -205,6 +226,18 @@ static int write_inode(sqfs_info_t *info, meta_writer_t *im, meta_writer_t *dm, return meta_writer_append(im, &ipc, sizeof(ipc)); } + case SQFS_INODE_EXT_FIFO: + case SQFS_INODE_EXT_SOCKET: { + sqfs_inode_ipc_ext_t ipc = { + .nlink = hard_link_count(node), + .xattr_idx = htole32(0xFFFFFFFF), + }; + + if (node->xattr != NULL) + ipc.xattr_idx = htole32(node->xattr->index); + + return meta_writer_append(im, &ipc, sizeof(ipc)); + } case SQFS_INODE_SLINK: { sqfs_inode_slink_t slink = { .nlink = htole32(hard_link_count(node)), @@ -219,6 +252,26 @@ static int write_inode(sqfs_info_t *info, meta_writer_t *im, meta_writer_t *dm, } break; } + case SQFS_INODE_EXT_SLINK: { + sqfs_inode_slink_t slink = { + .nlink = htole32(hard_link_count(node)), + .target_size = htole32(strlen(node->data.slink_target)), + }; + uint32_t xattr = htole32(0xFFFFFFFF); + + if (node->xattr != NULL) + xattr = htole32(node->xattr->index); + + if (meta_writer_append(im, &slink, sizeof(slink))) + return -1; + if (meta_writer_append(im, node->data.slink_target, + le32toh(slink.target_size))) { + return -1; + } + if (meta_writer_append(im, &xattr, sizeof(xattr))) + return -1; + break; + } case SQFS_INODE_BDEV: case SQFS_INODE_CDEV: { sqfs_inode_dev_t dev = { @@ -228,6 +281,20 @@ static int write_inode(sqfs_info_t *info, meta_writer_t *im, meta_writer_t *dm, return meta_writer_append(im, &dev, sizeof(dev)); } + case SQFS_INODE_EXT_BDEV: + case SQFS_INODE_EXT_CDEV: { + sqfs_inode_dev_ext_t dev = { + .nlink = htole32(hard_link_count(node)), + .devno = htole32(node->data.devno), + .xattr_idx = htole32(0xFFFFFFFF), + }; + + if (node->xattr != NULL) + dev.xattr_idx = htole32(node->xattr->index); + + return meta_writer_append(im, &dev, sizeof(dev)); + } + case SQFS_INODE_EXT_FILE: { sqfs_inode_file_ext_t ext = { .blocks_start = htole64(fi->startblock), @@ -239,6 +306,9 @@ static int write_inode(sqfs_info_t *info, meta_writer_t *im, meta_writer_t *dm, .xattr_idx = htole32(0xFFFFFFFF), }; + if (node->xattr != NULL) + ext.xattr_idx = htole32(node->xattr->index); + if (meta_writer_append(im, &ext, sizeof(ext))) return -1; goto out_file_blocks; @@ -281,6 +351,9 @@ static int write_inode(sqfs_info_t *info, meta_writer_t *im, meta_writer_t *dm, .xattr_idx = htole32(0xFFFFFFFF), }; + if (node->xattr != NULL) + ext.xattr_idx = htole32(node->xattr->index); + if (meta_writer_append(im, &ext, sizeof(ext))) { free(diridx); return -1; -- cgit v1.2.3