]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs_repair: move the global dirent name store to a separate object
authorDarrick J. Wong <djwong@kernel.org>
Tue, 9 Jan 2024 17:39:28 +0000 (09:39 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 10 Apr 2024 00:21:31 +0000 (17:21 -0700)
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@kernel.org>
repair/Makefile
repair/pptr.c
repair/strblobs.c [new file with mode: 0644]
repair/strblobs.h [new file with mode: 0644]

index a5102015651c87f9c52011f29054af3b15037c22..320f2f9a21d6838f322fcae1add8f780ef57fcb0 100644 (file)
@@ -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
index fd1f27f722fbe6cc9ed772aa783f69de6b424ef5..4ec631584352ab8879f2b607bddf8114ed783638 100644 (file)
@@ -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(GFP_KERNEL, "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 (file)
index 0000000..45d2559
--- /dev/null
@@ -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@kernel.org>
+ */
+#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 (file)
index 0000000..27e98ee
--- /dev/null
@@ -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@kernel.org>
+ */
+#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__ */