mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-02 15:18:19 +00:00
fscache: Introduce new driver
Introduce basic skeleton of the new, rewritten fscache driver. Changes ======= ver #3: - Use remove_proc_subtree(), not remove_proc_entry() to remove a populated dir. Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> cc: linux-cachefs@redhat.com Link: https://lore.kernel.org/r/163819584034.215744.4290533472390439030.stgit@warthog.procyon.org.uk/ # v1 Link: https://lore.kernel.org/r/163906887770.143852.3577888294989185666.stgit@warthog.procyon.org.uk/ # v2 Link: https://lore.kernel.org/r/163967080039.1823006.5702921801104057922.stgit@warthog.procyon.org.uk/ # v3 Link: https://lore.kernel.org/r/164021491014.640689.4292699878317589512.stgit@warthog.procyon.org.uk/ # v4
This commit is contained in:
parent
a39c41b853
commit
1e1236b841
10 changed files with 420 additions and 1 deletions
|
@ -67,6 +67,7 @@ obj-$(CONFIG_DLM) += dlm/
|
||||||
|
|
||||||
# Do not add any filesystems before this line
|
# Do not add any filesystems before this line
|
||||||
obj-$(CONFIG_NETFS_SUPPORT) += netfs/
|
obj-$(CONFIG_NETFS_SUPPORT) += netfs/
|
||||||
|
obj-$(CONFIG_FSCACHE) += fscache/
|
||||||
obj-$(CONFIG_REISERFS_FS) += reiserfs/
|
obj-$(CONFIG_REISERFS_FS) += reiserfs/
|
||||||
obj-$(CONFIG_EXT4_FS) += ext4/
|
obj-$(CONFIG_EXT4_FS) += ext4/
|
||||||
# We place ext4 before ext2 so that clean ext3 root fs's do NOT mount using the
|
# We place ext4 before ext2 so that clean ext3 root fs's do NOT mount using the
|
||||||
|
|
|
@ -1,4 +1,43 @@
|
||||||
# SPDX-License-Identifier: GPL-2.0-only
|
# SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
|
config FSCACHE
|
||||||
|
tristate "General filesystem local caching manager"
|
||||||
|
select NETFS_SUPPORT
|
||||||
|
help
|
||||||
|
This option enables a generic filesystem caching manager that can be
|
||||||
|
used by various network and other filesystems to cache data locally.
|
||||||
|
Different sorts of caches can be plugged in, depending on the
|
||||||
|
resources available.
|
||||||
|
|
||||||
|
See Documentation/filesystems/caching/fscache.rst for more information.
|
||||||
|
|
||||||
|
config FSCACHE_STATS
|
||||||
|
bool "Gather statistical information on local caching"
|
||||||
|
depends on FSCACHE && PROC_FS
|
||||||
|
select NETFS_STATS
|
||||||
|
help
|
||||||
|
This option causes statistical information to be gathered on local
|
||||||
|
caching and exported through file:
|
||||||
|
|
||||||
|
/proc/fs/fscache/stats
|
||||||
|
|
||||||
|
The gathering of statistics adds a certain amount of overhead to
|
||||||
|
execution as there are a quite a few stats gathered, and on a
|
||||||
|
multi-CPU system these may be on cachelines that keep bouncing
|
||||||
|
between CPUs. On the other hand, the stats are very useful for
|
||||||
|
debugging purposes. Saying 'Y' here is recommended.
|
||||||
|
|
||||||
|
See Documentation/filesystems/caching/fscache.rst for more information.
|
||||||
|
|
||||||
|
config FSCACHE_DEBUG
|
||||||
|
bool "Debug FS-Cache"
|
||||||
|
depends on FSCACHE
|
||||||
|
help
|
||||||
|
This permits debugging to be dynamically enabled in the local caching
|
||||||
|
management module. If this is set, the debugging output may be
|
||||||
|
enabled by setting bits in /sys/modules/fscache/parameter/debug.
|
||||||
|
|
||||||
|
See Documentation/filesystems/caching/fscache.rst for more information.
|
||||||
|
|
||||||
config FSCACHE_OLD_API
|
config FSCACHE_OLD_API
|
||||||
bool
|
bool
|
||||||
|
|
12
fs/fscache/Makefile
Normal file
12
fs/fscache/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
#
|
||||||
|
# Makefile for general filesystem caching code
|
||||||
|
#
|
||||||
|
|
||||||
|
fscache-y := \
|
||||||
|
main.o
|
||||||
|
|
||||||
|
fscache-$(CONFIG_PROC_FS) += proc.o
|
||||||
|
fscache-$(CONFIG_FSCACHE_STATS) += stats.o
|
||||||
|
|
||||||
|
obj-$(CONFIG_FSCACHE) := fscache.o
|
183
fs/fscache/internal.h
Normal file
183
fs/fscache/internal.h
Normal file
|
@ -0,0 +1,183 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
/* Internal definitions for FS-Cache
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
|
||||||
|
* Written by David Howells (dhowells@redhat.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef pr_fmt
|
||||||
|
#undef pr_fmt
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define pr_fmt(fmt) "FS-Cache: " fmt
|
||||||
|
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/fscache-cache.h>
|
||||||
|
#include <trace/events/fscache.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* main.c
|
||||||
|
*/
|
||||||
|
extern unsigned fscache_debug;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* proc.c
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_PROC_FS
|
||||||
|
extern int __init fscache_proc_init(void);
|
||||||
|
extern void fscache_proc_cleanup(void);
|
||||||
|
#else
|
||||||
|
#define fscache_proc_init() (0)
|
||||||
|
#define fscache_proc_cleanup() do {} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* stats.c
|
||||||
|
*/
|
||||||
|
#ifdef CONFIG_FSCACHE_STATS
|
||||||
|
|
||||||
|
static inline void fscache_stat(atomic_t *stat)
|
||||||
|
{
|
||||||
|
atomic_inc(stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void fscache_stat_d(atomic_t *stat)
|
||||||
|
{
|
||||||
|
atomic_dec(stat);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define __fscache_stat(stat) (stat)
|
||||||
|
|
||||||
|
int fscache_stats_show(struct seq_file *m, void *v);
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define __fscache_stat(stat) (NULL)
|
||||||
|
#define fscache_stat(stat) do {} while (0)
|
||||||
|
#define fscache_stat_d(stat) do {} while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
/*
|
||||||
|
* debug tracing
|
||||||
|
*/
|
||||||
|
#define dbgprintk(FMT, ...) \
|
||||||
|
printk("[%-6.6s] "FMT"\n", current->comm, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define kenter(FMT, ...) dbgprintk("==> %s("FMT")", __func__, ##__VA_ARGS__)
|
||||||
|
#define kleave(FMT, ...) dbgprintk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
|
||||||
|
#define kdebug(FMT, ...) dbgprintk(FMT, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#define kjournal(FMT, ...) no_printk(FMT, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#ifdef __KDEBUG
|
||||||
|
#define _enter(FMT, ...) kenter(FMT, ##__VA_ARGS__)
|
||||||
|
#define _leave(FMT, ...) kleave(FMT, ##__VA_ARGS__)
|
||||||
|
#define _debug(FMT, ...) kdebug(FMT, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
#elif defined(CONFIG_FSCACHE_DEBUG)
|
||||||
|
#define _enter(FMT, ...) \
|
||||||
|
do { \
|
||||||
|
if (__do_kdebug(ENTER)) \
|
||||||
|
kenter(FMT, ##__VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define _leave(FMT, ...) \
|
||||||
|
do { \
|
||||||
|
if (__do_kdebug(LEAVE)) \
|
||||||
|
kleave(FMT, ##__VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define _debug(FMT, ...) \
|
||||||
|
do { \
|
||||||
|
if (__do_kdebug(DEBUG)) \
|
||||||
|
kdebug(FMT, ##__VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define _enter(FMT, ...) no_printk("==> %s("FMT")", __func__, ##__VA_ARGS__)
|
||||||
|
#define _leave(FMT, ...) no_printk("<== %s()"FMT"", __func__, ##__VA_ARGS__)
|
||||||
|
#define _debug(FMT, ...) no_printk(FMT, ##__VA_ARGS__)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* determine whether a particular optional debugging point should be logged
|
||||||
|
* - we need to go through three steps to persuade cpp to correctly join the
|
||||||
|
* shorthand in FSCACHE_DEBUG_LEVEL with its prefix
|
||||||
|
*/
|
||||||
|
#define ____do_kdebug(LEVEL, POINT) \
|
||||||
|
unlikely((fscache_debug & \
|
||||||
|
(FSCACHE_POINT_##POINT << (FSCACHE_DEBUG_ ## LEVEL * 3))))
|
||||||
|
#define ___do_kdebug(LEVEL, POINT) \
|
||||||
|
____do_kdebug(LEVEL, POINT)
|
||||||
|
#define __do_kdebug(POINT) \
|
||||||
|
___do_kdebug(FSCACHE_DEBUG_LEVEL, POINT)
|
||||||
|
|
||||||
|
#define FSCACHE_DEBUG_CACHE 0
|
||||||
|
#define FSCACHE_DEBUG_COOKIE 1
|
||||||
|
#define FSCACHE_DEBUG_OBJECT 2
|
||||||
|
#define FSCACHE_DEBUG_OPERATION 3
|
||||||
|
|
||||||
|
#define FSCACHE_POINT_ENTER 1
|
||||||
|
#define FSCACHE_POINT_LEAVE 2
|
||||||
|
#define FSCACHE_POINT_DEBUG 4
|
||||||
|
|
||||||
|
#ifndef FSCACHE_DEBUG_LEVEL
|
||||||
|
#define FSCACHE_DEBUG_LEVEL CACHE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* assertions
|
||||||
|
*/
|
||||||
|
#if 1 /* defined(__KDEBUGALL) */
|
||||||
|
|
||||||
|
#define ASSERT(X) \
|
||||||
|
do { \
|
||||||
|
if (unlikely(!(X))) { \
|
||||||
|
pr_err("\n"); \
|
||||||
|
pr_err("Assertion failed\n"); \
|
||||||
|
BUG(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define ASSERTCMP(X, OP, Y) \
|
||||||
|
do { \
|
||||||
|
if (unlikely(!((X) OP (Y)))) { \
|
||||||
|
pr_err("\n"); \
|
||||||
|
pr_err("Assertion failed\n"); \
|
||||||
|
pr_err("%lx " #OP " %lx is false\n", \
|
||||||
|
(unsigned long)(X), (unsigned long)(Y)); \
|
||||||
|
BUG(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define ASSERTIF(C, X) \
|
||||||
|
do { \
|
||||||
|
if (unlikely((C) && !(X))) { \
|
||||||
|
pr_err("\n"); \
|
||||||
|
pr_err("Assertion failed\n"); \
|
||||||
|
BUG(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define ASSERTIFCMP(C, X, OP, Y) \
|
||||||
|
do { \
|
||||||
|
if (unlikely((C) && !((X) OP (Y)))) { \
|
||||||
|
pr_err("\n"); \
|
||||||
|
pr_err("Assertion failed\n"); \
|
||||||
|
pr_err("%lx " #OP " %lx is false\n", \
|
||||||
|
(unsigned long)(X), (unsigned long)(Y)); \
|
||||||
|
BUG(); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define ASSERT(X) do {} while (0)
|
||||||
|
#define ASSERTCMP(X, OP, Y) do {} while (0)
|
||||||
|
#define ASSERTIF(C, X) do {} while (0)
|
||||||
|
#define ASSERTIFCMP(C, X, OP, Y) do {} while (0)
|
||||||
|
|
||||||
|
#endif /* assert or not */
|
65
fs/fscache/main.c
Normal file
65
fs/fscache/main.c
Normal file
|
@ -0,0 +1,65 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
/* General filesystem local caching manager
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
|
||||||
|
* Written by David Howells (dhowells@redhat.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FSCACHE_DEBUG_LEVEL CACHE
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#define CREATE_TRACE_POINTS
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("FS Cache Manager");
|
||||||
|
MODULE_AUTHOR("Red Hat, Inc.");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
unsigned fscache_debug;
|
||||||
|
module_param_named(debug, fscache_debug, uint,
|
||||||
|
S_IWUSR | S_IRUGO);
|
||||||
|
MODULE_PARM_DESC(fscache_debug,
|
||||||
|
"FS-Cache debugging mask");
|
||||||
|
|
||||||
|
struct workqueue_struct *fscache_wq;
|
||||||
|
EXPORT_SYMBOL(fscache_wq);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* initialise the fs caching module
|
||||||
|
*/
|
||||||
|
static int __init fscache_init(void)
|
||||||
|
{
|
||||||
|
int ret = -ENOMEM;
|
||||||
|
|
||||||
|
fscache_wq = alloc_workqueue("fscache", WQ_UNBOUND | WQ_FREEZABLE, 0);
|
||||||
|
if (!fscache_wq)
|
||||||
|
goto error_wq;
|
||||||
|
|
||||||
|
ret = fscache_proc_init();
|
||||||
|
if (ret < 0)
|
||||||
|
goto error_proc;
|
||||||
|
|
||||||
|
pr_notice("Loaded\n");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error_proc:
|
||||||
|
destroy_workqueue(fscache_wq);
|
||||||
|
error_wq:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs_initcall(fscache_init);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clean up on module removal
|
||||||
|
*/
|
||||||
|
static void __exit fscache_exit(void)
|
||||||
|
{
|
||||||
|
_enter("");
|
||||||
|
|
||||||
|
fscache_proc_cleanup();
|
||||||
|
destroy_workqueue(fscache_wq);
|
||||||
|
pr_notice("Unloaded\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
module_exit(fscache_exit);
|
42
fs/fscache/proc.c
Normal file
42
fs/fscache/proc.c
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
/* FS-Cache statistics viewing interface
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
|
||||||
|
* Written by David Howells (dhowells@redhat.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FSCACHE_DEBUG_LEVEL CACHE
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/proc_fs.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* initialise the /proc/fs/fscache/ directory
|
||||||
|
*/
|
||||||
|
int __init fscache_proc_init(void)
|
||||||
|
{
|
||||||
|
if (!proc_mkdir("fs/fscache", NULL))
|
||||||
|
goto error_dir;
|
||||||
|
|
||||||
|
#ifdef CONFIG_FSCACHE_STATS
|
||||||
|
if (!proc_create_single("fs/fscache/stats", S_IFREG | 0444, NULL,
|
||||||
|
fscache_stats_show))
|
||||||
|
goto error;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error:
|
||||||
|
remove_proc_entry("fs/fscache", NULL);
|
||||||
|
error_dir:
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* clean up the /proc/fs/fscache/ directory
|
||||||
|
*/
|
||||||
|
void fscache_proc_cleanup(void)
|
||||||
|
{
|
||||||
|
remove_proc_subtree("fs/fscache", NULL);
|
||||||
|
}
|
22
fs/fscache/stats.c
Normal file
22
fs/fscache/stats.c
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
/* FS-Cache statistics
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
|
||||||
|
* Written by David Howells (dhowells@redhat.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define FSCACHE_DEBUG_LEVEL CACHE
|
||||||
|
#include <linux/proc_fs.h>
|
||||||
|
#include <linux/seq_file.h>
|
||||||
|
#include "internal.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* display the general statistics
|
||||||
|
*/
|
||||||
|
int fscache_stats_show(struct seq_file *m, void *v)
|
||||||
|
{
|
||||||
|
seq_puts(m, "FS-Cache statistics\n");
|
||||||
|
|
||||||
|
netfs_stats_show(m);
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -16,4 +16,6 @@
|
||||||
|
|
||||||
#include <linux/fscache.h>
|
#include <linux/fscache.h>
|
||||||
|
|
||||||
|
extern struct workqueue_struct *fscache_wq;
|
||||||
|
|
||||||
#endif /* _LINUX_FSCACHE_CACHE_H */
|
#endif /* _LINUX_FSCACHE_CACHE_H */
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
/* General filesystem caching interface
|
/* General filesystem caching interface
|
||||||
*
|
*
|
||||||
* Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
|
* Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
|
||||||
* Written by David Howells (dhowells@redhat.com)
|
* Written by David Howells (dhowells@redhat.com)
|
||||||
*
|
*
|
||||||
* NOTE!!! See:
|
* NOTE!!! See:
|
||||||
|
@ -18,9 +18,13 @@
|
||||||
#include <linux/netfs.h>
|
#include <linux/netfs.h>
|
||||||
|
|
||||||
#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
|
#if defined(CONFIG_FSCACHE) || defined(CONFIG_FSCACHE_MODULE)
|
||||||
|
#define __fscache_available (1)
|
||||||
|
#define fscache_available() (1)
|
||||||
#define fscache_cookie_valid(cookie) (cookie)
|
#define fscache_cookie_valid(cookie) (cookie)
|
||||||
#define fscache_cookie_enabled(cookie) (cookie)
|
#define fscache_cookie_enabled(cookie) (cookie)
|
||||||
#else
|
#else
|
||||||
|
#define __fscache_available (0)
|
||||||
|
#define fscache_available() (0)
|
||||||
#define fscache_cookie_valid(cookie) (0)
|
#define fscache_cookie_valid(cookie) (0)
|
||||||
#define fscache_cookie_enabled(cookie) (0)
|
#define fscache_cookie_enabled(cookie) (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
49
include/trace/events/fscache.h
Normal file
49
include/trace/events/fscache.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
/* FS-Cache tracepoints
|
||||||
|
*
|
||||||
|
* Copyright (C) 2021 Red Hat, Inc. All Rights Reserved.
|
||||||
|
* Written by David Howells (dhowells@redhat.com)
|
||||||
|
*/
|
||||||
|
#undef TRACE_SYSTEM
|
||||||
|
#define TRACE_SYSTEM fscache
|
||||||
|
|
||||||
|
#if !defined(_TRACE_FSCACHE_H) || defined(TRACE_HEADER_MULTI_READ)
|
||||||
|
#define _TRACE_FSCACHE_H
|
||||||
|
|
||||||
|
#include <linux/fscache.h>
|
||||||
|
#include <linux/tracepoint.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define enums for tracing information.
|
||||||
|
*/
|
||||||
|
#ifndef __FSCACHE_DECLARE_TRACE_ENUMS_ONCE_ONLY
|
||||||
|
#define __FSCACHE_DECLARE_TRACE_ENUMS_ONCE_ONLY
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Declare tracing information enums and their string mappings for display.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Export enum symbols via userspace.
|
||||||
|
*/
|
||||||
|
#undef EM
|
||||||
|
#undef E_
|
||||||
|
#define EM(a, b) TRACE_DEFINE_ENUM(a);
|
||||||
|
#define E_(a, b) TRACE_DEFINE_ENUM(a);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now redefine the EM() and E_() macros to map the enums to the strings that
|
||||||
|
* will be printed in the output.
|
||||||
|
*/
|
||||||
|
#undef EM
|
||||||
|
#undef E_
|
||||||
|
#define EM(a, b) { a, b },
|
||||||
|
#define E_(a, b) { a, b }
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _TRACE_FSCACHE_H */
|
||||||
|
|
||||||
|
/* This part must be outside protection */
|
||||||
|
#include <trace/define_trace.h>
|
Loading…
Reference in a new issue