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 | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ repair/strblobs.h | 20 +++++++++++++ 4 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 repair/strblobs.c create mode 100644 repair/strblobs.h diff --git a/repair/Makefile b/repair/Makefile index 18731613b..395466026 100644 --- a/repair/Makefile +++ b/repair/Makefile @@ -32,6 +32,7 @@ HFILES = \ rt.h \ scan.h \ slab.h \ + strblobs.h \ threads.h \ versions.h @@ -69,6 +70,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 f1b3332fc..d18fa0493 100644 --- a/repair/pptr.c +++ b/repair/pptr.c @@ -9,6 +9,7 @@ #include "repair/err_protos.h" #include "repair/slab.h" #include "repair/pptr.h" +#include "repair/strblobs.h" #undef PPTR_DEBUG @@ -55,7 +56,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 { @@ -85,7 +86,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; @@ -105,7 +106,7 @@ parent_ptr_free( free(fs_pptrs); fs_pptrs = NULL; - xfblob_destroy(names); + strblobs_destroy(&nameblobs); } void @@ -118,7 +119,7 @@ parent_ptr_init( if (!xfs_has_parent(mp)) return; - error = -xfblob_create(mp, "parent pointer names", &names); + error = strblobs_init(mp, "parent pointer names", &nameblobs); if (error) do_error(_("init parent pointer names failed: %s\n"), strerror(error)); @@ -173,7 +174,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 000000000..2b7a7a5e0 --- /dev/null +++ b/repair/strblobs.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2023 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( + struct xfs_mount *mp, + const char *descr, + struct strblobs **sblobs) +{ + struct strblobs *sb; + int error; + + sb = malloc(sizeof(struct strblobs)); + if (!sb) + return ENOMEM; + + error = -xfblob_create(mp, 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 000000000..f56801754 --- /dev/null +++ b/repair/strblobs.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2023 Oracle. All Rights Reserved. + * Author: Darrick J. Wong <djwong@xxxxxxxxxx> + */ +#ifndef __REPAIR_STRBLOBS_H__ +#define __REPAIR_STRBLOBS_H__ + +struct strblobs; + +int strblobs_init(struct xfs_mount *mp, 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__ */