MOn Nov 7, 2022, at 06:23, Ritesh Harjani (IBM) <ritesh.list@xxxxxxxxx> wrote: > > From: Li Xi <lixi@xxxxxxx> > > Merge inode_count and inode_link_info properly after > threads finish. > > Signed-off-by: Li Xi <lixi@xxxxxxx> > Signed-off-by: Wang Shilong <wshilong@xxxxxxx> > [Note: splitted the patch to seperate libext2fs changes from e2fsck] > Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@xxxxxxxxx> Reviewed-by: Andreas Dilger <adilger@xxxxxxxxx> > --- > lib/ext2fs/ext2fs.h | 1 + > lib/ext2fs/icount.c | 103 ++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 104 insertions(+) > > diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h > index 54aed5d1..139a25fc 100644 > --- a/lib/ext2fs/ext2fs.h > +++ b/lib/ext2fs/ext2fs.h > @@ -1546,6 +1546,7 @@ extern errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino, > __u16 *ret); > extern errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino, > __u16 count); > +extern errcode_t ext2fs_icount_merge(ext2_icount_t src, ext2_icount_t dest); > extern ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount); > errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *); > > diff --git a/lib/ext2fs/icount.c b/lib/ext2fs/icount.c > index 888a90b2..766eccca 100644 > --- a/lib/ext2fs/icount.c > +++ b/lib/ext2fs/icount.c > @@ -13,6 +13,7 @@ > #if HAVE_UNISTD_H > #include <unistd.h> > #endif > +#include <assert.h> > #include <string.h> > #include <stdio.h> > #include <sys/stat.h> > @@ -701,6 +702,108 @@ errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino, > return 0; > } > > +errcode_t ext2fs_icount_merge_full_map(ext2_icount_t src, ext2_icount_t dest) > +{ > + /* TODO: add the support for full map */ > + return EOPNOTSUPP; > +} > + > +errcode_t ext2fs_icount_merge_el(ext2_icount_t src, ext2_icount_t dest) > +{ > + int src_count = src->count; > + int dest_count = dest->count; > + int size = src_count + dest_count; > + int size_entry = sizeof(struct ext2_icount_el); > + struct ext2_icount_el *array; > + struct ext2_icount_el *array_ptr; > + struct ext2_icount_el *src_array = src->list; > + struct ext2_icount_el *dest_array = dest->list; > + int src_index = 0; > + int dest_index = 0; > + errcode_t retval; > + > + if (src_count == 0) > + return 0; > + > + retval = ext2fs_get_array(size, size_entry, &array); > + if (retval) > + return retval; > + > + array_ptr = array; > + /* > + * This can be improved by binary search and memcpy, but codes > + * would be more complex. And if number of bad blocks is small, > + * the optimization won't improve performance a lot. > + */ > + while (src_index < src_count || dest_index < dest_count) { > + if (src_index >= src_count) { > + memcpy(array_ptr, &dest_array[dest_index], > + (dest_count - dest_index) * size_entry); > + break; > + } > + if (dest_index >= dest_count) { > + memcpy(array_ptr, &src_array[src_index], > + (src_count - src_index) * size_entry); > + break; > + } > + if (src_array[src_index].ino < dest_array[dest_index].ino) { > + *array_ptr = src_array[src_index]; > + src_index++; > + } else { > + assert(src_array[src_index].ino > > + dest_array[dest_index].ino); > + *array_ptr = dest_array[dest_index]; > + dest_index++; > + } > + array_ptr++; > + } > + > + ext2fs_free_mem(&dest->list); > + dest->list = array; > + dest->count = src_count + dest_count; > + dest->size = size; > + dest->last_lookup = NULL; > + return 0; > +} > + > +errcode_t ext2fs_icount_merge(ext2_icount_t src, ext2_icount_t dest) > +{ > + errcode_t retval; > + > + if (src->fullmap && !dest->fullmap) > + return EINVAL; > + > + if (!src->fullmap && dest->fullmap) > + return EINVAL; > + > + if (src->multiple && !dest->multiple) > + return EINVAL; > + > + if (!src->multiple && dest->multiple) > + return EINVAL; > + > + if (src->fullmap) > + return ext2fs_icount_merge_full_map(src, dest); > + > + retval = ext2fs_merge_bitmap(src->single, dest->single, NULL, > + NULL); > + if (retval) > + return retval; > + > + if (src->multiple) { > + retval = ext2fs_merge_bitmap(src->multiple, dest->multiple, > + NULL, NULL); > + if (retval) > + return retval; > + } > + > + retval = ext2fs_icount_merge_el(src, dest); > + if (retval) > + return retval; > + > + return 0; > +} > + > ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount) > { > if (!icount || icount->magic != EXT2_ET_MAGIC_ICOUNT) > -- > 2.37.3 >