From f7fa69e896f0971629f938be93cb30865f92943c Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sat, 27 Jul 2019 17:28:43 +0200 Subject: Add general purpose flags field to file_info_t Simplifies some task if we can just add a flag that a file has a framgent or that it has already been detected as a duplicate. Signed-off-by: David Oberhollenzer --- include/fstree.h | 11 +++++++++++ lib/fstree/mknode.c | 2 -- lib/sqfs/data_reader.c | 3 +-- lib/sqfs/data_writer.c | 21 ++++++++------------- lib/sqfs/tree_node_from_inode.c | 2 ++ lib/sqfs/write_inode.c | 2 +- 6 files changed, 23 insertions(+), 18 deletions(-) diff --git a/include/fstree.h b/include/fstree.h index 23634fc..687b693 100644 --- a/include/fstree.h +++ b/include/fstree.h @@ -22,6 +22,14 @@ typedef struct dir_info_t dir_info_t; typedef struct fstree_t fstree_t; typedef struct tree_xattr_t tree_xattr_t; +enum { + FILE_FLAG_HAS_FRAGMENT = 0x01, + + FILE_FLAG_FRAGMENT_IS_DUPLICATE = 0x02, + + FILE_FLAG_BLOCKS_ARE_DUPLICATE = 0x04, +}; + /* Encapsulates a set of key-value pairs attached to a tree_node_t */ struct tree_xattr_t { /* Number of key-value pairs */ @@ -80,6 +88,9 @@ struct file_info_t { uint32_t fragment_chksum; + /* combination of FILE_FLAG_* flags */ + uint32_t flags; + /* Stores data about each full data block. */ struct { uint32_t chksum; diff --git a/lib/fstree/mknode.c b/lib/fstree/mknode.c index 18602e4..d343145 100644 --- a/lib/fstree/mknode.c +++ b/lib/fstree/mknode.c @@ -60,8 +60,6 @@ tree_node_t *fstree_mknode(fstree_t *fs, tree_node_t *parent, const char *name, case S_IFREG: n->data.file = (file_info_t *)n->payload; n->data.file->size = sb->st_size; - n->data.file->fragment = 0xFFFFFFFF; - n->data.file->fragment_offset = 0xFFFFFFFF; if (extra == NULL) break; diff --git a/lib/sqfs/data_reader.c b/lib/sqfs/data_reader.c index 5facaa1..a7d605e 100644 --- a/lib/sqfs/data_reader.c +++ b/lib/sqfs/data_reader.c @@ -205,8 +205,7 @@ int data_reader_dump_file(data_reader_t *data, file_info_t *fi, int outfd, size_t fragsz = fi->size % data->block_size; size_t count = fi->size / data->block_size; - if (fragsz != 0 && (fi->fragment == 0xFFFFFFFF || - fi->fragment_offset == 0xFFFFFFFF)) { + if (fragsz != 0 && !(fi->flags & FILE_FLAG_HAS_FRAGMENT)) { fragsz = 0; ++count; } diff --git a/lib/sqfs/data_writer.c b/lib/sqfs/data_writer.c index 496d636..e9a6193 100644 --- a/lib/sqfs/data_writer.c +++ b/lib/sqfs/data_writer.c @@ -138,10 +138,10 @@ static file_info_t *fragment_by_chksum(file_info_t *fi, uint32_t chksum, break; } - if (it->fragment == 0xFFFFFFFF) + if (!(it->flags & FILE_FLAG_HAS_FRAGMENT)) continue; - if (it->fragment_offset == 0xFFFFFFFF) + if (it->flags & FILE_FLAG_FRAGMENT_IS_DUPLICATE) continue; if ((it->size % block_size) != frag_size) @@ -158,11 +158,8 @@ static size_t get_block_count(file_info_t *fi, size_t block_size) { size_t count = fi->size / block_size; - if ((fi->size % block_size != 0) && - (fi->fragment == 0xFFFFFFFF || - fi->fragment_offset == 0xFFFFFFFF)) { + if ((fi->size % block_size) && !(fi->flags & FILE_FLAG_HAS_FRAGMENT)) ++count; - } while (count > 0 && fi->blocks[count - 1].size == 0) --count; @@ -201,21 +198,15 @@ static uint64_t find_equal_blocks(file_info_t *file, file_info_t *list, break; } - location = 0; - for (it = list; it != NULL; it = it->next) { if (it == file) { it = NULL; break; } - /* XXX: list assumed to be processed in order, prevent us from - re-checking files we know are duplicates */ - if (it->startblock < location) + if (it->flags & FILE_FLAG_BLOCKS_ARE_DUPLICATE) continue; - location = it->startblock; - cmp_blk_count = get_block_count(it, block_size); if (cmp_blk_count == 0) continue; @@ -279,6 +270,8 @@ static int flush_data_block(data_writer_t *data, size_t size, chksum = update_crc32(0, data->block, size); if (size < data->super->block_size && !(flags & DW_DONT_FRAGMENT)) { + fi->flags |= FILE_FLAG_HAS_FRAGMENT; + ref = fragment_by_chksum(fi, chksum, size, list, data->super->block_size); @@ -286,6 +279,7 @@ static int flush_data_block(data_writer_t *data, size_t size, fi->fragment_chksum = ref->fragment_chksum; fi->fragment_offset = ref->fragment_offset; fi->fragment = ref->fragment; + fi->flags |= FILE_FLAG_FRAGMENT_IS_DUPLICATE; return 0; } @@ -344,6 +338,7 @@ static int end_file(data_writer_t *data, file_info_t *fi, if (ref > 0) { fi->startblock = ref; + fi->flags |= FILE_FLAG_BLOCKS_ARE_DUPLICATE; if (lseek(data->outfd, start, SEEK_SET) == (off_t)-1) goto fail_seek; diff --git a/lib/sqfs/tree_node_from_inode.c b/lib/sqfs/tree_node_from_inode.c index 034218c..84ebbb2 100644 --- a/lib/sqfs/tree_node_from_inode.c +++ b/lib/sqfs/tree_node_from_inode.c @@ -50,6 +50,8 @@ static void copy_block_sizes(sqfs_inode_generic_t *inode, tree_node_t *out, if (out->data.file->fragment == 0xFFFFFFFF || out->data.file->fragment_offset == 0xFFFFFFFF) { ++block_count; + } else { + out->data.file->flags |= FILE_FLAG_HAS_FRAGMENT; } } diff --git a/lib/sqfs/write_inode.c b/lib/sqfs/write_inode.c index 726206e..efb6a7d 100644 --- a/lib/sqfs/write_inode.c +++ b/lib/sqfs/write_inode.c @@ -83,7 +83,7 @@ static int write_file_blocks(fstree_t *fs, file_info_t *fi, meta_writer_t *im) uint32_t bs; if ((fi->size % fs->block_size) != 0 && - (fi->fragment == 0xFFFFFFFF || fi->fragment_offset == 0xFFFFFFFF)) { + !(fi->flags & FILE_FLAG_HAS_FRAGMENT)) { ++count; } -- cgit v1.2.3