aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
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
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')
-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/*