diff options
-rw-r--r-- | fs/btrfs/ctree.h | 12 | ||||
-rw-r--r-- | fs/btrfs/super.c | 63 |
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 */ |
2965 | int btrfs_parse_options(struct btrfs_root *root, char *options); | 2965 | int btrfs_parse_options(struct btrfs_root *root, char *options); |
2966 | int btrfs_sync_fs(struct super_block *sb, int wait); | 2966 | int btrfs_sync_fs(struct super_block *sb, int wait); |
2967 | void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...); | ||
2967 | void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, | 2968 | 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, ...); |
2969 | 2970 | ||
2970 | #define btrfs_std_error(fs_info, errno) \ | 2971 | #define btrfs_std_error(fs_info, errno) \ |
2971 | do { \ | 2972 | do { \ |
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...) \ | ||
2979 | do { \ | ||
2980 | __btrfs_std_error((fs_info), __func__, __LINE__, \ | ||
2981 | (errno), fmt, ##args); \ | ||
2974 | } while (0) | 2982 | } while (0) |
2975 | 2983 | ||
2976 | void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function, | 2984 | void __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 | */ |
129 | void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, | 129 | 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, ...) |
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); | 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); | ||
149 | } | 198 | } |
150 | 199 | ||
151 | /* | 200 | /* |