aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2012-03-01 08:57:30 -0500
committerDavid Sterba <dsterba@suse.cz>2012-03-21 20:45:40 -0400
commit4da35113426d16673aa1fb0613c14ca2e419e7fd (patch)
tree32a72e44ec480ee127b860f2dc5bcc3698a352e5 /fs/btrfs/super.c
parent3acd395317f22b4346a139571cd4723408c5d4af (diff)
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>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c63
1 files changed, 56 insertions, 7 deletions
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/*