Skip to content

Commit 4da3511

Browse files
jeffmahoneykdave
authored andcommitted
btrfs: add varargs to btrfs_error
btrfs currently handles most errors with BUG_ON. This patch is a work-in- progress but aims to handle most errors other than internal logic errors and ENOMEM more gracefully. This iteration prevents most crashes but can run into lockups with the page lock on occasion when the timing "works out." Signed-off-by: Jeff Mahoney <jeffm@suse.com>
1 parent 3acd395 commit 4da3511

File tree

2 files changed

+66
-9
lines changed

2 files changed

+66
-9
lines changed

fs/btrfs/ctree.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2964,13 +2964,21 @@ ssize_t btrfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
29642964
/* super.c */
29652965
int btrfs_parse_options(struct btrfs_root *root, char *options);
29662966
int btrfs_sync_fs(struct super_block *sb, int wait);
2967+
void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...);
29672968
void __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, ...);
29692970

29702971
#define btrfs_std_error(fs_info, errno) \
29712972
do { \
29722973
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...) \
2979+
do { \
2980+
__btrfs_std_error((fs_info), __func__, __LINE__, \
2981+
(errno), fmt, ##args); \
29742982
} while (0)
29752983

29762984
void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function,

fs/btrfs/super.c

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -127,25 +127,74 @@ static void btrfs_handle_error(struct btrfs_fs_info *fs_info)
127127
* invokes the approciate error response.
128128
*/
129129
void __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, ...)
131131
{
132132
struct super_block *sb = fs_info->sb;
133133
char nbuf[16];
134134
const char *errstr;
135+
va_list args;
136+
va_start(args, fmt);
135137

136138
/*
137139
* Special case: if the error is EROFS, and we're already
138140
* under MS_RDONLY, then it is safe here.
139141
*/
140142
if (errno == -EROFS && (sb->s_flags & MS_RDONLY))
141-
return;
143+
return;
142144

143-
errstr = btrfs_decode_error(fs_info, errno, nbuf);
144-
printk(KERN_CRIT "BTRFS error (device %s) in %s:%d: %s\n",
145-
sb->s_id, function, line, errstr);
146-
save_error_info(fs_info);
145+
errstr = btrfs_decode_error(fs_info, errno, nbuf);
146+
if (fmt) {
147+
struct va_format vaf = {
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+
}
147166

148-
btrfs_handle_error(fs_info);
167+
const char *logtypes[] = {
168+
"emergency",
169+
"alert",
170+
"critical",
171+
"error",
172+
"warning",
173+
"notice",
174+
"info",
175+
"debug",
176+
};
177+
178+
void 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);
149198
}
150199

151200
/*

0 commit comments

Comments
 (0)