]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: cache unlinked pointers in an rhashtable
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 6 May 2019 22:00:28 +0000 (18:00 -0400)
committerEric Sandeen <sandeen@redhat.com>
Mon, 6 May 2019 22:00:28 +0000 (18:00 -0400)
Source kernel commit: 9b2471797942a5947664818cfe2c6de93b43f37a

Use a rhashtable to cache the unlinked list incore.  This should speed
up unlinked processing considerably when there are a lot of inodes on
the unlinked list because iunlink_remove no longer has to traverse an
entire bucket list to find which inode points to the one being removed.

The incore list structure records "X.next_unlinked = Y" relations, with
the rhashtable using Y to index the records.  This makes finding the
inode X that points to a inode Y very quick.  If our cache fails to find
anything we can always fall back on the old method.

FWIW this drastically reduces the amount of time it takes to remove
inodes from the unlinked list.  I wrote a program to open a lot of
O_TMPFILE files and then close them in the same order, which takes
a very long time if we have to traverse the unlinked lists.  With the
ptach, I see:

+ /d/t/tmpfile/tmpfile
Opened 193531 files in 6.33s.
Closed 193531 files in 5.86s

real    0m12.192s
user    0m0.064s
sys     0m11.619s
+ cd /
+ umount /mnt

real    0m0.050s
user    0m0.004s
sys     0m0.030s

And without the patch:

+ /d/t/tmpfile/tmpfile
Opened 193588 files in 6.35s.
Closed 193588 files in 751.61s

real    12m38.853s
user    0m0.084s
sys     12m34.470s
+ cd /
+ umount /mnt

real    0m0.086s
user    0m0.000s
sys     0m0.060s

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
io/inject.c
libxfs/xfs_errortag.h

index 2061c95771a0182b91e24b3ae69946720468203f..cabfc3e362d94b1d2035c99a084c7fab4e7ca7a7 100644 (file)
@@ -53,6 +53,7 @@ error_tag(char *name)
                { XFS_ERRTAG_BUF_LRU_REF,               "buf_lru_ref" },
                { XFS_ERRTAG_FORCE_SCRUB_REPAIR,        "force_repair" },
                { XFS_ERRTAG_FORCE_SUMMARY_RECALC,      "bad_summary" },
+               { XFS_ERRTAG_IUNLINK_FALLBACK,          "iunlink_fallback" },
                { XFS_ERRTAG_MAX,                       NULL }
        };
        int     count;
index 66077a105cbb7408131a6b9d5580e6a0c12599ca..79e6c4fb1d8a8440ae744c2bc032658da0bb5da0 100644 (file)
@@ -54,7 +54,8 @@
 #define XFS_ERRTAG_BUF_LRU_REF                         31
 #define XFS_ERRTAG_FORCE_SCRUB_REPAIR                  32
 #define XFS_ERRTAG_FORCE_SUMMARY_RECALC                        33
-#define XFS_ERRTAG_MAX                                 34
+#define XFS_ERRTAG_IUNLINK_FALLBACK                    34
+#define XFS_ERRTAG_MAX                                 35
 
 /*
  * Random factors for above tags, 1 means always, 2 means 1/2 time, etc.
@@ -93,5 +94,6 @@
 #define XFS_RANDOM_BUF_LRU_REF                         2
 #define XFS_RANDOM_FORCE_SCRUB_REPAIR                  1
 #define XFS_RANDOM_FORCE_SUMMARY_RECALC                        1
+#define XFS_RANDOM_IUNLINK_FALLBACK                    (XFS_RANDOM_DEFAULT/10)
 
 #endif /* __XFS_ERRORTAG_H_ */