Commit 9f09f649 authored by Al Viro's avatar Al Viro
Browse files

teach logfc() to handle prefices, give it saner calling conventions



Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent fbc2d168
Loading
Loading
Loading
Loading
+17 −46
Original line number Diff line number Diff line
@@ -388,64 +388,33 @@ EXPORT_SYMBOL(vfs_dup_fs_context);
 * @fc: The filesystem context to log to.
 * @fmt: The format of the buffer.
 */
void logfc(struct fs_context *fc, const char *fmt, ...)
void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, ...)
{
	static const char store_failure[] = "OOM: Can't store error string";
	struct fc_log *log = fc ? fc->log : NULL;
	const char *p;
	va_list va;
	char *q;
	u8 freeable;
	struct va_format vaf = {.fmt = fmt, .va = &va};

	va_start(va, fmt);
	if (!strchr(fmt, '%')) {
		p = fmt;
		goto unformatted_string;
	}
	if (strcmp(fmt, "%s") == 0) {
		p = va_arg(va, const char *);
		goto unformatted_string;
	}

	q = kvasprintf(GFP_KERNEL, fmt, va);
copied_string:
	if (!q)
		goto store_failure;
	freeable = 1;
	goto store_string;

unformatted_string:
	if ((unsigned long)p >= (unsigned long)__start_rodata &&
	    (unsigned long)p <  (unsigned long)__end_rodata)
		goto const_string;
	if (log && within_module_core((unsigned long)p, log->owner))
		goto const_string;
	q = kstrdup(p, GFP_KERNEL);
	goto copied_string;

store_failure:
	p = store_failure;
const_string:
	q = (char *)p;
	freeable = 0;
store_string:
	if (!log) {
		switch (fmt[0]) {
		switch (level) {
		case 'w':
			printk(KERN_WARNING "%s\n", q + 2);
			printk(KERN_WARNING "%s%s%pV\n", prefix ? prefix : "",
						prefix ? ": " : "", &vaf);
			break;
		case 'e':
			printk(KERN_ERR "%s\n", q + 2);
			printk(KERN_ERR "%s%s%pV\n", prefix ? prefix : "",
						prefix ? ": " : "", &vaf);
			break;
		default:
			printk(KERN_NOTICE "%s\n", q + 2);
			printk(KERN_NOTICE "%s%s%pV\n", prefix ? prefix : "",
						prefix ? ": " : "", &vaf);
			break;
		}
		if (freeable)
			kfree(q);
	} else {
		unsigned int logsize = ARRAY_SIZE(log->buffer);
		u8 index;
		char *q = kasprintf(GFP_KERNEL, "%c %s%s%pV\n", level,
						prefix ? prefix : "",
						prefix ? ": " : "", &vaf);

		index = log->head & (logsize - 1);
		BUILD_BUG_ON(sizeof(log->head) != sizeof(u8) ||
@@ -457,9 +426,11 @@ store_string:
			log->tail++;
		}

		log->buffer[index] = q;
		log->buffer[index] = q ? q : "OOM: Can't store error string";
		if (q)
			log->need_free |= 1 << index;
		else
			log->need_free &= ~(1 << index);
		log->need_free |= freeable << index;
		log->head++;
	}
	va_end(va);
+10 −6
Original line number Diff line number Diff line
@@ -181,9 +181,13 @@ struct fc_log {
	char		*buffer[8];
};

extern __attribute__((format(printf, 2, 3)))
void logfc(struct fs_context *fc, const char *fmt, ...);
extern __attribute__((format(printf, 4, 5)))
void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, ...);

#define __logfc(fc, l, fmt, ...) ({		\
	struct fs_context *__fc = (fc);		\
	logfc(__fc ? __fc->log : NULL, NULL,	\
		l, fmt, ## __VA_ARGS__);})
/**
 * infof - Store supplementary informational message
 * @fc: The context in which to log the informational message
@@ -192,7 +196,7 @@ void logfc(struct fs_context *fc, const char *fmt, ...);
 * Store the supplementary informational message for the process if the process
 * has enabled the facility.
 */
#define infof(fc, fmt, ...) ({ logfc(fc, "i "fmt, ## __VA_ARGS__); })
#define infof(fc, fmt, ...) __logfc(fc, 'i', fmt, ## __VA_ARGS__)

/**
 * warnf - Store supplementary warning message
@@ -202,7 +206,7 @@ void logfc(struct fs_context *fc, const char *fmt, ...);
 * Store the supplementary warning message for the process if the process has
 * enabled the facility.
 */
#define warnf(fc, fmt, ...) ({ logfc(fc, "w "fmt, ## __VA_ARGS__); })
#define warnf(fc, fmt, ...) __logfc(fc, 'w', fmt, ## __VA_ARGS__)

/**
 * errorf - Store supplementary error message
@@ -212,7 +216,7 @@ void logfc(struct fs_context *fc, const char *fmt, ...);
 * Store the supplementary error message for the process if the process has
 * enabled the facility.
 */
#define errorf(fc, fmt, ...) ({ logfc(fc, "e "fmt, ## __VA_ARGS__); })
#define errorf(fc, fmt, ...) __logfc(fc, 'e', fmt, ## __VA_ARGS__)

/**
 * invalf - Store supplementary invalid argument error message
@@ -222,6 +226,6 @@ void logfc(struct fs_context *fc, const char *fmt, ...);
 * Store the supplementary error message for the process if the process has
 * enabled the facility and return -EINVAL.
 */
#define invalf(fc, fmt, ...) ({	errorf(fc, fmt, ## __VA_ARGS__); -EINVAL; })
#define invalf(fc, fmt, ...) (errorf(fc, fmt, ## __VA_ARGS__), -EINVAL)

#endif /* _LINUX_FS_CONTEXT_H */