[PATCH 8/8] xfs_repair: try to reuse nameblob names for file pptr scan names

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Darrick J. Wong <djwong@xxxxxxxxxx>

When we're scanning a file's parent pointers, see if the name already
exists in the nameblobs structure to save memory.  If not, we'll
continue to use the file scan xfblob, because we don't want to pollute
the nameblob structure with names we didn't see in the directory walk.

Each of the parent pointer scanner threads can access the nameblob
structure locklessly since they don't modify the nameblob.

Signed-off-by: Darrick J. Wong <djwong@xxxxxxxxxx>
---
 repair/pptr.c |   62 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 55 insertions(+), 7 deletions(-)


diff --git a/repair/pptr.c b/repair/pptr.c
index c1cd9060..a5cf89b9 100644
--- a/repair/pptr.c
+++ b/repair/pptr.c
@@ -133,8 +133,11 @@ struct ag_pptr {
 };
 
 struct file_pptr {
+	/* Is the name stored in the global nameblobs structure? */
+	unsigned int		name_in_nameblobs:1;
+
 	/* parent directory handle */
-	xfs_ino_t		parent_ino;
+	unsigned long long	parent_ino:63;
 	unsigned int		parent_gen;
 
 	/* dirent offset */
@@ -467,6 +470,32 @@ record_garbage_xattr(
 				strerror(error));
 }
 
+/*
+ * Store this file parent pointer's name in the file scan namelist unless it's
+ * already in the global list.
+ */
+static int
+store_file_pptr_name(
+	struct file_scan			*fscan,
+	struct file_pptr			*file_pptr,
+	const struct xfs_parent_name_irec	*irec)
+{
+	int					error;
+
+	error = strblobs_lookup(nameblobs, &file_pptr->name_cookie,
+			irec->p_name, irec->p_namelen);
+	if (!error) {
+		file_pptr->name_in_nameblobs = true;
+		return 0;
+	}
+	if (error != ENOENT)
+		return error;
+
+	file_pptr->name_in_nameblobs = false;
+	return -xfblob_store(fscan->file_pptr_names, &file_pptr->name_cookie,
+			irec->p_name, irec->p_namelen);
+}
+
 /* Decide if this is a directory parent pointer and stash it if so. */
 static int
 examine_xattr(
@@ -505,8 +534,7 @@ examine_xattr(
 	file_pptr.diroffset = irec.p_diroffset;
 	file_pptr.namelen = irec.p_namelen;
 
-	error = -xfblob_store(fscan->file_pptr_names,
-			&file_pptr.name_cookie, irec.p_name, irec.p_namelen);
+	error = store_file_pptr_name(fscan, &file_pptr, &irec);
 	if (error)
 		do_error(
  _("storing ino %llu parent pointer '%.*s' failed: %s\n"),
@@ -568,6 +596,21 @@ remove_file_pptr(
 	return -libxfs_parent_unset(ip, &pptr_rec, &scratch);
 }
 
+/* Load a file parent pointer name from wherever we stored it. */
+static int
+load_file_pptr_name(
+	struct file_scan	*fscan,
+	const struct file_pptr	*file_pptr,
+	unsigned char		*name)
+{
+	if (file_pptr->name_in_nameblobs)
+		return strblobs_load(nameblobs, file_pptr->name_cookie,
+				name, file_pptr->namelen);
+
+	return -xfblob_load(fscan->file_pptr_names, file_pptr->name_cookie,
+			name, file_pptr->namelen);
+}
+
 /* Remove all pptrs from @ip. */
 static void
 clear_all_pptrs(
@@ -665,8 +708,7 @@ remove_incorrect_parent_ptr(
 	unsigned char		name[MAXNAMELEN] = { };
 	int			error;
 
-	error = -xfblob_load(fscan->file_pptr_names, file_pptr->name_cookie,
-			name, file_pptr->namelen);
+	error = load_file_pptr_name(fscan, file_pptr, name);
 	if (error)
 		do_error(
  _("loading incorrect name for ino %llu parent pointer (ino %llu gen 0x%x diroffset %u namecookie 0x%llx) failed: %s\n"),
@@ -729,8 +771,7 @@ compare_parent_pointers(
 				(unsigned long long)ag_pptr->name_cookie,
 				ag_pptr->namelen, strerror(error));
 
-	error = -xfblob_load(fscan->file_pptr_names, file_pptr->name_cookie,
-			name2, file_pptr->namelen);
+	error = load_file_pptr_name(fscan, file_pptr, name2);
 	if (error)
 		do_error(
  _("loading file-list name for ino %llu parent pointer (ino %llu gen 0x%x diroffset %u namecookie 0x%llx namelen %u) failed: %s\n"),
@@ -1051,6 +1092,13 @@ check_parent_ptrs(
 	struct workqueue	wq;
 	xfs_agnumber_t		agno;
 
+	/*
+	 * We only store the lower 63 bits of the inode number in struct
+	 * file_pptr to save space, so we must guarantee that we'll never
+	 * encounter an inumber with the top bit set.
+	 */
+	BUILD_BUG_ON((1ULL << 63) & XFS_MAXINUMBER);
+
 	if (!xfs_has_parent(mp))
 		return;
 




[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux