diff options
-rw-r--r-- | include/fstree.h | 14 | ||||
-rw-r--r-- | lib/fstree/fstree.c | 11 | ||||
-rw-r--r-- | 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 @@ -29,6 +29,11 @@ struct tree_xattr_t { 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 */ tree_node_t *owner; @@ -350,6 +355,15 @@ 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 * * @memberof fstree_t 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; |