Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

David Howells and committed by
Al Viro
e7582e16 5fe1890d

+44 -4
+30
fs/fs_context.c
··· 378 378 } 379 379 EXPORT_SYMBOL(vfs_dup_fs_context); 380 380 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 + 381 411 /** 382 412 * put_fs_context - Dispose of a superblock configuration context. 383 413 * @fc: The context to dispose of.
+14 -4
include/linux/fs_context.h
··· 133 133 int (*fill_super)(struct super_block *sb, 134 134 struct fs_context *fc)); 135 135 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 137 147 138 148 /** 139 149 * infof - Store supplementary informational message ··· 153 143 * Store the supplementary informational message for the process if the process 154 144 * has enabled the facility. 155 145 */ 156 - #define infof(fc, fmt, ...) ({ logfc(fc, fmt, ## __VA_ARGS__); }) 146 + #define infof(fc, fmt, ...) ({ logfc(fc, "i "fmt, ## __VA_ARGS__); }) 157 147 158 148 /** 159 149 * warnf - Store supplementary warning message ··· 163 153 * Store the supplementary warning message for the process if the process has 164 154 * enabled the facility. 165 155 */ 166 - #define warnf(fc, fmt, ...) ({ logfc(fc, fmt, ## __VA_ARGS__); }) 156 + #define warnf(fc, fmt, ...) ({ logfc(fc, "w "fmt, ## __VA_ARGS__); }) 167 157 168 158 /** 169 159 * errorf - Store supplementary error message ··· 173 163 * Store the supplementary error message for the process if the process has 174 164 * enabled the facility. 175 165 */ 176 - #define errorf(fc, fmt, ...) ({ logfc(fc, fmt, ## __VA_ARGS__); }) 166 + #define errorf(fc, fmt, ...) ({ logfc(fc, "e "fmt, ## __VA_ARGS__); }) 177 167 178 168 /** 179 169 * invalf - Store supplementary invalid argument error message