]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: wipe ondisk parent pointers when there are none
authorDarrick J. Wong <djwong@kernel.org>
Mon, 29 Jul 2024 23:23:27 +0000 (16:23 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Tue, 30 Jul 2024 00:01:13 +0000 (17:01 -0700)
Erase all the parent pointers when there aren't any found by the
directory entry scan.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
repair/pptr.c

index 94d6d834627cddfabaeecc77b2c47b8ae61c6b5c..8ec6a51d2c3dd556ce2611648133f585185b1d4f 100644 (file)
@@ -714,8 +714,13 @@ remove_file_pptr(
 /* Remove all pptrs from @ip. */
 static void
 clear_all_pptrs(
-       struct xfs_inode        *ip)
+       struct xfs_inode        *ip,
+       struct file_scan        *fscan)
 {
+       struct xfs_slab_cursor  *cur;
+       struct file_pptr        *file_pptr;
+       int                     error;
+
        if (no_modify) {
                do_warn(_("would delete unlinked ino %llu parent pointers\n"),
                                (unsigned long long)ip->i_ino);
@@ -724,7 +729,37 @@ clear_all_pptrs(
 
        do_warn(_("deleting unlinked ino %llu parent pointers\n"),
                        (unsigned long long)ip->i_ino);
-       /* XXX actually do the work */
+
+       error = -init_slab_cursor(fscan->file_pptr_recs, NULL, &cur);
+       if (error)
+               do_error(_("init ino %llu pptr cursor failed: %s\n"),
+                               (unsigned long long)ip->i_ino,
+                               strerror(error));
+
+       while ((file_pptr = pop_slab_cursor(cur)) != NULL) {
+               unsigned char   name[MAXNAMELEN];
+
+               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 namecookie 0x%llx) failed: %s\n"),
+                                       (unsigned long long)ip->i_ino,
+                                       (unsigned long long)file_pptr->parent_ino,
+                                       file_pptr->parent_gen,
+                                       (unsigned long long)file_pptr->name_cookie,
+                                       strerror(error));
+
+               error = remove_file_pptr(ip, file_pptr, name);
+               if (error)
+                       do_error(
+ _("wiping ino %llu pptr (ino %llu gen 0x%x) failed: %s\n"),
+                               (unsigned long long)ip->i_ino,
+                               (unsigned long long)file_pptr->parent_ino,
+                               file_pptr->parent_gen,
+                               strerror(error));
+       }
+
+       free_slab_cursor(&cur);
 }
 
 /* Add @ag_pptr to @ip. */
@@ -1028,7 +1063,7 @@ crosscheck_file_parent_ptrs(
                 * file.
                 */
                if (fscan->nr_file_pptrs > 0)
-                       clear_all_pptrs(ip);
+                       clear_all_pptrs(ip, fscan);
 
                return;
        }