{
 }
 
-#ifdef CONFIG_PRINTK
+#ifdef CONFIG_PRINTK_INDEX
+
+#define btrfs_printk(fs_info, fmt, args...)                                    \
+do {                                                                           \
+       printk_index_subsys_emit("%sBTRFS %s (device %s): ", NULL, fmt);        \
+       _btrfs_printk(fs_info, fmt, ##args);                                    \
+} while (0)
+
+__printf(2, 3)
+__cold
+void _btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...);
+
+#elif defined(CONFIG_PRINTK)
+
+#define btrfs_printk(fs_info, fmt, args...)                            \
+       _btrfs_printk(fs_info, fmt, ##args)
+
 __printf(2, 3)
 __cold
-void btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...);
+void _btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...);
+
 #else
+
 #define btrfs_printk(fs_info, fmt, args...) \
        btrfs_no_printk(fs_info, fmt, ##args)
 #endif
                                  __LINE__, (errno));           \
 } while (0)
 
+#ifdef CONFIG_PRINTK_INDEX
+
 #define btrfs_handle_fs_error(fs_info, errno, fmt, args...)            \
-do {                                                           \
-       __btrfs_handle_fs_error((fs_info), __func__, __LINE__,  \
-                         (errno), fmt, ##args);                \
+do {                                                                   \
+       printk_index_subsys_emit(                                       \
+               "BTRFS: error (device %s%s) in %s:%d: errno=%d %s",     \
+               KERN_CRIT, fmt);                                        \
+       __btrfs_handle_fs_error((fs_info), __func__, __LINE__,          \
+                               (errno), fmt, ##args);                  \
 } while (0)
 
+#else
+
+#define btrfs_handle_fs_error(fs_info, errno, fmt, args...)            \
+       __btrfs_handle_fs_error((fs_info), __func__, __LINE__,          \
+                               (errno), fmt, ##args)
+
+#endif
+
 #define BTRFS_FS_ERROR(fs_info)        (unlikely(test_bit(BTRFS_FS_STATE_ERROR, \
                                                   &(fs_info)->fs_state)))
 #define BTRFS_FS_LOG_CLEANUP_ERROR(fs_info)                            \
 
        RATELIMIT_STATE_INIT(printk_limits[7], DEFAULT_RATELIMIT_INTERVAL, 100),
 };
 
-void __cold btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...)
+void __cold _btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...)
 {
        char lvl[PRINTK_MAX_SINGLE_HEADER_LEN + 1] = "\0";
        struct va_format vaf;
                        char statestr[STATE_STRING_BUF_LEN];
 
                        btrfs_state_to_string(fs_info, statestr);
-                       printk("%sBTRFS %s (device %s%s): %pV\n", lvl, type,
+                       _printk("%sBTRFS %s (device %s%s): %pV\n", lvl, type,
                                fs_info->sb->s_id, statestr, &vaf);
                } else {
-                       printk("%sBTRFS %s: %pV\n", lvl, type, &vaf);
+                       _printk("%sBTRFS %s: %pV\n", lvl, type, &vaf);
                }
        }