Skip to content

Commit 3934e8e

Browse files
author
Darrick J. Wong
committed
xfs: create a big array data structure
Create a simple 'big array' data structure for storage of fixed-size metadata records that will be used to reconstruct a btree index. For repair operations, the most important operations are append, iterate, and sort. Earlier implementations of the big array used linked lists and suffered from severe problems -- pinning all records in kernel memory was not a good idea and frequently lead to OOM situations; random access was very inefficient; and record overhead for the lists was unacceptably high at 40-60%. Therefore, the big memory array relies on the 'xfile' abstraction, which creates a memfd file and stores the records in page cache pages. Since the memfd is created in tmpfs, the memory pages can be pushed out to disk if necessary and we have a built-in usage limit of 50% of physical memory. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Kent Overstreet <kent.overstreet@linux.dev> Reviewed-by: Dave Chinner <dchinner@redhat.com>
1 parent 014ad53 commit 3934e8e

8 files changed

Lines changed: 922 additions & 1 deletion

File tree

fs/xfs/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ config XFS_ONLINE_SCRUB
128128
bool "XFS online metadata check support"
129129
default n
130130
depends on XFS_FS
131+
depends on TMPFS && SHMEM
131132
select XFS_DRAIN_INTENTS
132133
help
133134
If you say Y here you will be able to check metadata on a

fs/xfs/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,8 @@ xfs-y += $(addprefix scrub/, \
164164
rmap.o \
165165
scrub.o \
166166
symlink.o \
167+
xfarray.o \
168+
xfile.o \
167169
)
168170

169171
xfs-$(CONFIG_XFS_RT) += scrub/rtbitmap.o

fs/xfs/scrub/trace.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@
1212
#include "xfs_mount.h"
1313
#include "xfs_inode.h"
1414
#include "xfs_btree.h"
15-
#include "scrub/scrub.h"
1615
#include "xfs_ag.h"
16+
#include "scrub/scrub.h"
17+
#include "scrub/xfile.h"
18+
#include "scrub/xfarray.h"
1719

1820
/* Figure out which block the btree cursor was pointing to. */
1921
static inline xfs_fsblock_t

fs/xfs/scrub/trace.h

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
#include <linux/tracepoint.h>
1717
#include "xfs_bit.h"
1818

19+
struct xfile;
20+
struct xfarray;
21+
1922
/*
2023
* ftrace's __print_symbolic requires that all enum values be wrapped in the
2124
* TRACE_DEFINE_ENUM macro so that the enum value can be encoded in the ftrace
@@ -725,6 +728,124 @@ TRACE_EVENT(xchk_refcount_incorrect,
725728
__entry->seen)
726729
)
727730

731+
TRACE_EVENT(xfile_create,
732+
TP_PROTO(struct xfile *xf),
733+
TP_ARGS(xf),
734+
TP_STRUCT__entry(
735+
__field(dev_t, dev)
736+
__field(unsigned long, ino)
737+
__array(char, pathname, 256)
738+
),
739+
TP_fast_assign(
740+
char pathname[257];
741+
char *path;
742+
743+
__entry->ino = file_inode(xf->file)->i_ino;
744+
memset(pathname, 0, sizeof(pathname));
745+
path = file_path(xf->file, pathname, sizeof(pathname) - 1);
746+
if (IS_ERR(path))
747+
path = "(unknown)";
748+
strncpy(__entry->pathname, path, sizeof(__entry->pathname));
749+
),
750+
TP_printk("xfino 0x%lx path '%s'",
751+
__entry->ino,
752+
__entry->pathname)
753+
);
754+
755+
TRACE_EVENT(xfile_destroy,
756+
TP_PROTO(struct xfile *xf),
757+
TP_ARGS(xf),
758+
TP_STRUCT__entry(
759+
__field(unsigned long, ino)
760+
__field(unsigned long long, bytes)
761+
__field(loff_t, size)
762+
),
763+
TP_fast_assign(
764+
struct xfile_stat statbuf;
765+
int ret;
766+
767+
ret = xfile_stat(xf, &statbuf);
768+
if (!ret) {
769+
__entry->bytes = statbuf.bytes;
770+
__entry->size = statbuf.size;
771+
} else {
772+
__entry->bytes = -1;
773+
__entry->size = -1;
774+
}
775+
__entry->ino = file_inode(xf->file)->i_ino;
776+
),
777+
TP_printk("xfino 0x%lx mem_bytes 0x%llx isize 0x%llx",
778+
__entry->ino,
779+
__entry->bytes,
780+
__entry->size)
781+
);
782+
783+
DECLARE_EVENT_CLASS(xfile_class,
784+
TP_PROTO(struct xfile *xf, loff_t pos, unsigned long long bytecount),
785+
TP_ARGS(xf, pos, bytecount),
786+
TP_STRUCT__entry(
787+
__field(unsigned long, ino)
788+
__field(unsigned long long, bytes_used)
789+
__field(loff_t, pos)
790+
__field(loff_t, size)
791+
__field(unsigned long long, bytecount)
792+
),
793+
TP_fast_assign(
794+
struct xfile_stat statbuf;
795+
int ret;
796+
797+
ret = xfile_stat(xf, &statbuf);
798+
if (!ret) {
799+
__entry->bytes_used = statbuf.bytes;
800+
__entry->size = statbuf.size;
801+
} else {
802+
__entry->bytes_used = -1;
803+
__entry->size = -1;
804+
}
805+
__entry->ino = file_inode(xf->file)->i_ino;
806+
__entry->pos = pos;
807+
__entry->bytecount = bytecount;
808+
),
809+
TP_printk("xfino 0x%lx mem_bytes 0x%llx pos 0x%llx bytecount 0x%llx isize 0x%llx",
810+
__entry->ino,
811+
__entry->bytes_used,
812+
__entry->pos,
813+
__entry->bytecount,
814+
__entry->size)
815+
);
816+
#define DEFINE_XFILE_EVENT(name) \
817+
DEFINE_EVENT(xfile_class, name, \
818+
TP_PROTO(struct xfile *xf, loff_t pos, unsigned long long bytecount), \
819+
TP_ARGS(xf, pos, bytecount))
820+
DEFINE_XFILE_EVENT(xfile_pread);
821+
DEFINE_XFILE_EVENT(xfile_pwrite);
822+
DEFINE_XFILE_EVENT(xfile_seek_data);
823+
824+
TRACE_EVENT(xfarray_create,
825+
TP_PROTO(struct xfarray *xfa, unsigned long long required_capacity),
826+
TP_ARGS(xfa, required_capacity),
827+
TP_STRUCT__entry(
828+
__field(unsigned long, ino)
829+
__field(uint64_t, max_nr)
830+
__field(size_t, obj_size)
831+
__field(int, obj_size_log)
832+
__field(unsigned long long, required_capacity)
833+
),
834+
TP_fast_assign(
835+
__entry->max_nr = xfa->max_nr;
836+
__entry->obj_size = xfa->obj_size;
837+
__entry->obj_size_log = xfa->obj_size_log;
838+
__entry->ino = file_inode(xfa->xfile->file)->i_ino;
839+
__entry->required_capacity = required_capacity;
840+
),
841+
TP_printk("xfino 0x%lx max_nr %llu reqd_nr %llu objsz %zu objszlog %d",
842+
__entry->ino,
843+
__entry->max_nr,
844+
__entry->required_capacity,
845+
__entry->obj_size,
846+
__entry->obj_size_log)
847+
);
848+
728849
/* repair tracepoints */
729850
#if IS_ENABLED(CONFIG_XFS_ONLINE_REPAIR)
730851

0 commit comments

Comments
 (0)