OSDN Git Service

teach logfc() to handle prefices, give it saner calling conventions
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 21 Dec 2019 03:10:36 +0000 (22:10 -0500)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 7 Feb 2020 19:48:32 +0000 (14:48 -0500)
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/fs_context.c
include/linux/fs_context.h

index ea97a24..fb6329c 100644 (file)
@@ -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->need_free &= ~(1 << index);
-               log->need_free |= freeable << index;
+               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->head++;
        }
        va_end(va);
index c7c6964..d18ff42 100644 (file)
@@ -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 */