Signed-off-by: Philip Tricca <fl...@twobit.us> --- .../misc-xattr-create-xattr-block-node.patch | 175 +++++++++++++++++++++ .../e2fsprogs/e2fsprogs_1.42.9.bbappend | 1 + 2 files changed, 176 insertions(+) create mode 100644 recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block-node.patch
diff --git a/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block-node.patch b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block-node.patch new file mode 100644 index 0000000..f2e4582 --- /dev/null +++ b/recipes-devtools/e2fsprogs/e2fsprogs/misc-xattr-create-xattr-block-node.patch @@ -0,0 +1,175 @@ +Add two new functions to manage a cache of xattr blocks as well as a new struct +to build a linked list of xattr blocks. + +xattr_add_block: Adds a block to the cache. This function is supplied with a +pointer to the head of a linked list of xattr blocks and an xattr block to add. +The purpose of this cache is to allow sharing of what would otherwise be +duplicate xattr blocks and so duplicates are not allowed in this cache. If an +identical block is already in the cache a pointer to this block will be +returned. + +xattr_rm_block: Removes a block from the cache. This function is supplied with +a pointer to the cache and a node that shall be removed from the cache. The +cache is searched for the node and the node is removed if found. + +Both functions are integrated into the 'set_inode_xattr'. Here the logic is +rearranged to cope with associating preexisting xattr blocks with inodes as +well as creating new blocks when necessary. + +Signed-off-by: Philip Tricca <fl...@twobit.us> + +Index: e2fsprogs-1.42.9/misc/xattr.c +=================================================================== +--- e2fsprogs-1.42.9.orig/misc/xattr.c ++++ e2fsprogs-1.42.9/misc/xattr.c +@@ -25,6 +25,19 @@ + #define XATTR_STDERR(fmt, args...) do {} while (0) + #endif + ++/* nodes for simple linked list to track xattr blocks, calling it a cache ++ * would be a stretch ... ++ */ ++typedef struct xattr_node xattr_node_t; ++ ++struct xattr_node { ++ struct ext2_ext_attr_header *header; ++ blk_t block; ++ struct xattr_node *next; ++}; ++ ++xattr_node_t *xattr_list_head = NULL; ++ + /* structure for mapping xattr name prefix data */ + typedef struct xattr_prefix { + int index; +@@ -48,6 +61,17 @@ xattr_prefix_t xattr_prefixes [] = { + { 0 }, + }; + ++/* free xattr node and the buffer holding the xattr block */ ++static void ++xattr_free_node (xattr_node_t *node) ++{ ++ if (node) { ++ if (node->header) ++ free (node->header); ++ free (node); ++ } ++} ++ + /* Free remaining resources after all files have been processed. */ + void + xattr_cleanup () +@@ -260,6 +284,28 @@ out: + return ret; + } + ++/* Add an xattr node to the list specified by head. This function will update ++ * head as necessary. It will return a pointer to the xattr_node_t added to the ++ * list. In the event that an identical xattr block is already on the list this ++ * function will return a pointer to the pre-existing node. ++ */ ++static xattr_node_t* ++xattr_add_block (xattr_node_t **head, xattr_node_t *node) ++{ ++ XATTR_STDERR ("Adding xattr to the the node list.\n"); ++ return node; ++} ++ ++/* Remove xattr node from list. Returns pointer to the node being removed. ++ * NOTE: We're not comparing the xattr blocks, just the nodes. ++ */ ++static xattr_node_t* ++xattr_rm_block (xattr_node_t **head, xattr_node_t *node) ++{ ++ XATTR_STDERR ("Removing xattr from the node list.\n"); ++ return node; ++} ++ + /* This is the entry point to the xattr module. This function copies the xattrs + * from the file at 'path' to the file system object at 'ino'. + * +@@ -274,16 +320,21 @@ set_inode_xattr (ext2_filsys fs, ext2_in + errcode_t ret = 0; + char *buf = NULL; + struct ext2_inode inode = { 0 }; +- blk_t block = 0; +- struct ext2_ext_attr_header *header = NULL; ++ xattr_node_t *node = NULL, *node_tmp = NULL; + uint32_t newcount = 0; + + XATTR_STDERR ("Copying xattrs from %s to inode 0x%x.\n", path, ino); ++ /* Create an xattr_node_t for it and add it to the cache if appropriate */ ++ if (!(node = calloc (1, sizeof (xattr_node_t)))) { ++ com_err (__func__, errno, "calloc"); ++ ret = errno; ++ goto out; ++ } + /* Populate the xattr block for the file at path */ +- if (ret = xattr_build_block (path, &header, fs->blocksize)) { ++ if (ret = xattr_build_block (path, &(node->header), fs->blocksize)) { + goto out; + } +- if (header == NULL) { ++ if (node->header == NULL) { + XATTR_STDERR ("set_inode_xattrs: no xattrs for %s\n", path); + goto out; + } +@@ -291,23 +342,38 @@ set_inode_xattr (ext2_filsys fs, ext2_in + com_err(__func__, ret, "ext2fs_read_inode"); + goto out; + } +- if (ret = ext2fs_alloc_block (fs, 0, NULL, &block)) { +- com_err(__func__, ret, "ext2fs_alloc_block: returned %d", ret); ++ if (!(node_tmp = xattr_add_block (&xattr_list_head, node))) { ++ fprintf (stderr, "Cannot add NULL node to xattr_block list.\n"); + goto out; + } +- ext2fs_mark_block_bitmap2 (fs->block_map, block); +- XATTR_STDERR ("writing xattr block 0x%x to disk:\n", block); +- if (ret = ext2fs_write_ext_attr (fs, block, header)) { +- com_err(__func__, ret, "ext2fs_write_ext_attr: returned %d", ret); +- goto out; ++ if (node == node_tmp) { ++ /* xattr block is new: add to list & write to disk */ ++ XATTR_STDERR ("no pre-existing xattr block, creating / adding\n"); ++ if (ret = ext2fs_alloc_block (fs, 0, NULL, &node->block)) { ++ com_err(__func__, ret, "ext2fs_alloc_block: returned %d", ret); ++ xattr_rm_block (&xattr_list_head, node); ++ goto out; ++ } ++ ext2fs_mark_block_bitmap2 (fs->block_map, node->block); ++ XATTR_STDERR ("writing xattr block 0x%x to disk:\n", node->block); ++ if (ret = ext2fs_write_ext_attr (fs, node->block, node->header)) { ++ com_err(__func__, ret, "ext2fs_write_ext_attr: returned %d", ret); ++ xattr_rm_block (&xattr_list_head, node); ++ goto out; ++ } ++ } else { ++ /* already have an identical xattr block, free the one we just made */ ++ XATTR_STDERR ("using xattr from existing block: 0x%x\n", node_tmp->block); ++ xattr_free_node (node); ++ node = node_tmp; + } + /* point inode for current file to xattr block, update block count and + * write inode to disk + */ +- inode.i_file_acl = block; ++ inode.i_file_acl = node->block; + if (ret = ext2fs_adjust_ea_refcount2(fs, +- block, +- (char*)header, ++ node->block, ++ (char*)(node->header), + 1, + &newcount)) + { +@@ -321,7 +387,6 @@ set_inode_xattr (ext2_filsys fs, ext2_in + if (ret = ext2fs_write_inode (fs, ino, &inode)) + com_err(__func__, ret, "ext2fs_write_inode: returned %d", ret); + out: +- if (header) +- free (header); ++ xattr_free_node (node); + return ret; + } diff --git a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend index edc94d8..0705ec4 100644 --- a/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend +++ b/recipes-devtools/e2fsprogs/e2fsprogs_1.42.9.bbappend @@ -5,4 +5,5 @@ SRC_URI += " \ file://mke2fs.c-create_inode.c-copy-xattrs.patch \ file://lib-ext2fs-ext2_ext_attr.h-add-xattr-index.patch \ file://misc-xattr-create-xattr-block.patch \ + file://misc-xattr-create-xattr-block-node.patch \ " -- 2.1.4 -- _______________________________________________ yocto mailing list yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/yocto