aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h12
-rw-r--r--fs/btrfs/super.c63
2 files changed, 66 insertions, 9 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index f6bca05a4b4c..8829f8099851 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2964,13 +2964,21 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
2964/* super.c */ 2964/* super.c */
2965int btrfs_parse_options(struct btrfs_root *root, char *options); 2965int btrfs_parse_options(struct btrfs_root *root, char *options);
2966int btrfs_sync_fs(struct super_block *sb, int wait); 2966int btrfs_sync_fs(struct super_block *sb, int wait);
2967void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...);
2967void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, 2968void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function,
2968 unsigned int line, int errno); 2969 unsigned int line, int errno, const char *fmt, ...);
2969 2970
2970#define btrfs_std_error(fs_info, errno) \ 2971#define btrfs_std_error(fs_info, errno) \
2971do { \ 2972do { \
2972 if ((errno)) \ 2973 if ((errno)) \
2973 __btrfs_std_error((fs_info), __func__, __LINE__, (errno));\ 2974 __btrfs_std_error((fs_info), __func__, \
2975 __LINE__, (errno), NULL); \
2976} while (0)
2977
2978#define btrfs_error(fs_info, errno, fmt, args...) \
2979do { \
2980 __btrfs_std_error((fs_info), __func__, __LINE__, \
2981 (errno), fmt, ##args); \
2974} while (0) 2982} while (0)
2975 2983
2976void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function, 2984void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function,
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index ae7963b2d527..7fe69eef7607 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -127,25 +127,74 @@ static void btrfs_handle_error(struct btrfs_fs_info *fs_info)
127 * invokes the approciate error response. 127 * invokes the approciate error response.
128 */ 128 */
129void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, 129void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function,
130 unsigned int line, int errno) 130 unsigned int line, int errno, const char *fmt, ...)
131{ 131{
132 struct super_block *sb = fs_info->sb; 132 struct super_block *sb = fs_info->sb;
133 char nbuf[16]; 133 char nbuf[16];
134 const char *errstr; 134 const char *errstr;
135 va_list args;
136 va_start(args, fmt);
135 137
136 /* 138 /*
137 * Special case: if the error is EROFS, and we're already 139 * Special case: if the error is EROFS, and we're already
138 * under MS_RDONLY, then it is safe here. 140 * under MS_RDONLY, then it is safe here.
139 */ 141 */
140 if (errno == -EROFS && (sb->s_flags & MS_RDONLY)) 142 if (errno == -EROFS && (sb->s_flags & MS_RDONLY))
141 return; 143 return;
142 144
143 errstr = btrfs_decode_error(fs_info, errno, nbuf); 145 errstr = btrfs_decode_error(fs_info, errno, nbuf);
144 printk(KERN_CRIT "BTRFS error (device %s) in %s:%d: %s\n", 146 if (fmt) {
145 sb->s_id, function, line, errstr); 147 struct va_format vaf = {
146 save_error_info(fs_info); 148 .fmt = fmt,
149 .va = &args,
150 };
151
152 printk(KERN_CRIT "BTRFS error (device %s) in %s:%d: %s (%pV)\n",
153 sb->s_id, function, line, errstr, &vaf);
154 } else {
155 printk(KERN_CRIT "BTRFS error (device %s) in %s:%d: %s\n",
156 sb->s_id, function, line, errstr);
157 }
158
159 /* Don't go through full error handling during mount */
160 if (sb->s_flags & MS_BORN) {
161 save_error_info(fs_info);
162 btrfs_handle_error(fs_info);
163 }
164 va_end(args);
165}
147 166
148 btrfs_handle_error(fs_info); 167const char *logtypes[] = {
168 "emergency",
169 "alert",
170 "critical",
171 "error",
172 "warning",
173 "notice",
174 "info",
175 "debug",
176};
177
178void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...)
179{
180 struct super_block *sb = fs_info->sb;
181 char lvl[4];
182 struct va_format vaf;
183 va_list args;
184 const char *type = logtypes[4];
185
186 va_start(args, fmt);
187
188 if (fmt[0] == '<' && isdigit(fmt[1]) && fmt[2] == '>') {
189 strncpy(lvl, fmt, 3);
190 fmt += 3;
191 type = logtypes[fmt[1] - '0'];
192 } else
193 *lvl = '\0';
194
195 vaf.fmt = fmt;
196 vaf.va = &args;
197 printk("%sBTRFS %s (device %s): %pV", lvl, type, sb->s_id, &vaf);
149} 198}
150 199
151/* 200/*