From: Darrick J. Wong <djwong@xxxxxxxxxx> Abstract the main parent pointer dirent names xfblob object into a separate data structure to hide implementation details. The goals here are (a) reduce memory usage when we can by deduplicating dirent names that exist in multiple directories; and (b) provide a unique id for each name in the system so that sorting incore parent pointer records can be done in a stable manner. Fast stable sorting of records is required for the dirent <-> pptr matching algorithm. Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx> --- repair/Makefile | 2 + repair/pptr.c | 11 ++++--- repair/strblobs.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++++ repair/strblobs.h | 19 +++++++++++++ 4 files changed, 106 insertions(+), 5 deletions(-) create mode 100644 repair/strblobs.c create mode 100644 repair/strblobs.h diff --git a/repair/Makefile b/repair/Makefile index a5102015651..320f2f9a21d 100644 --- a/repair/Makefile +++ b/repair/Makefile @@ -35,6 +35,7 @@ HFILES = \ rt.h \ scan.h \ slab.h \ + strblobs.h \ threads.h \ versions.h @@ -75,6 +76,7 @@ CFILES = \ sb.c \ scan.c \ slab.c \ + strblobs.c \ threads.c \ versions.c \ xfs_repair.c diff --git a/repair/pptr.c b/repair/pptr.c index 68cdd0ae424..88970f81348 100644 --- a/repair/pptr.c +++ b/repair/pptr.c @@ -10,6 +10,7 @@ #include "repair/err_protos.h" #include "repair/slab.h" #include "repair/pptr.h" +#include "repair/strblobs.h" #undef PPTR_DEBUG @@ -56,7 +57,7 @@ * This tuple is recorded in the per-AG master parent pointer index. Note * that names are stored separately in an xfblob data structure so that the * rest of the information can be sorted and processed as fixed-size records; - * the incore parent pointer record contains a pointer to the xfblob data. + * the incore parent pointer record contains a pointer to the strblob data. */ struct ag_pptr { @@ -86,7 +87,7 @@ struct ag_pptrs { }; /* Global names storage file. */ -static struct xfblob *names; +static struct strblobs *nameblobs; static pthread_mutex_t names_mutex = PTHREAD_MUTEX_INITIALIZER; static struct ag_pptrs *fs_pptrs; @@ -106,7 +107,7 @@ parent_ptr_free( free(fs_pptrs); fs_pptrs = NULL; - xfblob_destroy(names); + strblobs_destroy(&nameblobs); } void @@ -122,7 +123,7 @@ parent_ptr_init( descr = kasprintf("xfs_repair (%s): parent pointer names", mp->m_fsname); - error = -xfblob_create(descr, &names); + error = strblobs_init(descr, &nameblobs); kfree(descr); if (error) do_error(_("init parent pointer names failed: %s\n"), @@ -178,7 +179,7 @@ add_parent_ptr( ag_pptr.namehash = libxfs_dir2_hashname(mp, &dname); pthread_mutex_lock(&names_mutex); - error = -xfblob_store(names, &ag_pptr.name_cookie, fname, + error = strblobs_store(nameblobs, &ag_pptr.name_cookie, fname, ag_pptr.namelen); pthread_mutex_unlock(&names_mutex); if (error) diff --git a/repair/strblobs.c b/repair/strblobs.c new file mode 100644 index 00000000000..45d2559c722 --- /dev/null +++ b/repair/strblobs.c @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2023-2024 Oracle. All Rights Reserved. + * Author: Darrick J. Wong <djwong@xxxxxxxxxx> + */ +#include "libxfs.h" +#include "libxfs/xfile.h" +#include "libxfs/xfblob.h" +#include "repair/strblobs.h" + +/* + * String Blob Structure + * ===================== + * + * This data structure wraps the storage of strings with explicit length in an + * xfblob structure. + */ +struct strblobs { + struct xfblob *strings; +}; + +/* Initialize a string blob structure. */ +int +strblobs_init( + const char *descr, + struct strblobs **sblobs) +{ + struct strblobs *sb; + int error; + + sb = malloc(sizeof(struct strblobs)); + if (!sb) + return ENOMEM; + + error = -xfblob_create(descr, &sb->strings); + if (error) + goto out_free; + + *sblobs = sb; + return 0; + +out_free: + free(sb); + return error; +} + +/* Deconstruct a string blob structure. */ +void +strblobs_destroy( + struct strblobs **sblobs) +{ + struct strblobs *sb = *sblobs; + + xfblob_destroy(sb->strings); + free(sb); + *sblobs = NULL; +} + +/* Store a string and return a cookie for its retrieval. */ +int +strblobs_store( + struct strblobs *sblobs, + xfblob_cookie *str_cookie, + const unsigned char *str, + unsigned int str_len) +{ + return -xfblob_store(sblobs->strings, str_cookie, str, str_len); +} + +/* Retrieve a previously stored string. */ +int +strblobs_load( + struct strblobs *sblobs, + xfblob_cookie str_cookie, + unsigned char *str, + unsigned int str_len) +{ + return -xfblob_load(sblobs->strings, str_cookie, str, str_len); +} diff --git a/repair/strblobs.h b/repair/strblobs.h new file mode 100644 index 00000000000..27e98eee208 --- /dev/null +++ b/repair/strblobs.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2023-2024 Oracle. All Rights Reserved. + * Author: Darrick J. Wong <djwong@xxxxxxxxxx> + */ +#ifndef __REPAIR_STRBLOBS_H__ +#define __REPAIR_STRBLOBS_H__ + +struct strblobs; + +int strblobs_init(const char *descr, struct strblobs **sblobs); +void strblobs_destroy(struct strblobs **sblobs); + +int strblobs_store(struct strblobs *sblobs, xfblob_cookie *str_cookie, + const unsigned char *str, unsigned int str_len); +int strblobs_load(struct strblobs *sblobs, xfblob_cookie str_cookie, + unsigned char *str, unsigned int str_len); + +#endif /* __REPAIR_STRBLOBS_H__ */