Skip to content

Commit e7582e1

Browse files
dhowellsAl Viro
authored andcommitted
vfs: Implement logging through fs_context
Implement the ability for filesystems to log error, warning and informational messages through the fs_context. In the future, these will be extractable by userspace by reading from an fd created by the fsopen() syscall. Error messages are prefixed with "e ", warnings with "w " and informational messages with "i ". In the future, inside the kernel, formatted messages will be malloc'd but unformatted messages will not copied if they're either in the core .rodata section or in the .rodata section of the filesystem module pinned by fs_context::fs_type. The messages will only be good till the fs_type is released. Note that the logging object will be shared between duplicated fs_context structures. This is so that such as NFS which do a mount within a mount can get at least some of the errors from the inner mount. Five logging functions are provided for this: (1) void logfc(struct fs_context *fc, const char *fmt, ...); This logs a message into the context. If the buffer is full, the earliest message is discarded. (2) void errorf(fc, fmt, ...); This wraps logfc() to log an error. (3) void invalf(fc, fmt, ...); This wraps errorf() and returns -EINVAL for convenience. (4) void warnf(fc, fmt, ...); This wraps logfc() to log a warning. (5) void infof(fc, fmt, ...); This wraps logfc() to log an informational message. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
1 parent 5fe1890 commit e7582e1

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

fs/fs_context.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,36 @@ struct fs_context *vfs_dup_fs_context(struct fs_context *src_fc)
378378
}
379379
EXPORT_SYMBOL(vfs_dup_fs_context);
380380

381+
#ifdef CONFIG_PRINTK
382+
/**
383+
* logfc - Log a message to a filesystem context
384+
* @fc: The filesystem context to log to.
385+
* @fmt: The format of the buffer.
386+
*/
387+
void logfc(struct fs_context *fc, const char *fmt, ...)
388+
{
389+
va_list va;
390+
391+
va_start(va, fmt);
392+
393+
switch (fmt[0]) {
394+
case 'w':
395+
vprintk_emit(0, LOGLEVEL_WARNING, NULL, 0, fmt, va);
396+
break;
397+
case 'e':
398+
vprintk_emit(0, LOGLEVEL_ERR, NULL, 0, fmt, va);
399+
break;
400+
default:
401+
vprintk_emit(0, LOGLEVEL_NOTICE, NULL, 0, fmt, va);
402+
break;
403+
}
404+
405+
pr_cont("\n");
406+
va_end(va);
407+
}
408+
EXPORT_SYMBOL(logfc);
409+
#endif
410+
381411
/**
382412
* put_fs_context - Dispose of a superblock configuration context.
383413
* @fc: The context to dispose of.

include/linux/fs_context.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,17 @@ extern int vfs_get_super(struct fs_context *fc,
133133
int (*fill_super)(struct super_block *sb,
134134
struct fs_context *fc));
135135

136-
#define logfc(FC, FMT, ...) pr_notice(FMT, ## __VA_ARGS__)
136+
extern const struct file_operations fscontext_fops;
137+
138+
#ifdef CONFIG_PRINTK
139+
extern __attribute__((format(printf, 2, 3)))
140+
void logfc(struct fs_context *fc, const char *fmt, ...);
141+
#else
142+
static inline __attribute__((format(printf, 2, 3)))
143+
void logfc(struct fs_context *fc, const char *fmt, ...)
144+
{
145+
}
146+
#endif
137147

138148
/**
139149
* infof - Store supplementary informational message
@@ -143,7 +153,7 @@ extern int vfs_get_super(struct fs_context *fc,
143153
* Store the supplementary informational message for the process if the process
144154
* has enabled the facility.
145155
*/
146-
#define infof(fc, fmt, ...) ({ logfc(fc, fmt, ## __VA_ARGS__); })
156+
#define infof(fc, fmt, ...) ({ logfc(fc, "i "fmt, ## __VA_ARGS__); })
147157

148158
/**
149159
* warnf - Store supplementary warning message
@@ -153,7 +163,7 @@ extern int vfs_get_super(struct fs_context *fc,
153163
* Store the supplementary warning message for the process if the process has
154164
* enabled the facility.
155165
*/
156-
#define warnf(fc, fmt, ...) ({ logfc(fc, fmt, ## __VA_ARGS__); })
166+
#define warnf(fc, fmt, ...) ({ logfc(fc, "w "fmt, ## __VA_ARGS__); })
157167

158168
/**
159169
* errorf - Store supplementary error message
@@ -163,7 +173,7 @@ extern int vfs_get_super(struct fs_context *fc,
163173
* Store the supplementary error message for the process if the process has
164174
* enabled the facility.
165175
*/
166-
#define errorf(fc, fmt, ...) ({ logfc(fc, fmt, ## __VA_ARGS__); })
176+
#define errorf(fc, fmt, ...) ({ logfc(fc, "e "fmt, ## __VA_ARGS__); })
167177

168178
/**
169179
* invalf - Store supplementary invalid argument error message

0 commit comments

Comments
 (0)