Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
182741d
Documentation
LICENSES
arch
block
certs
crypto
drivers
fs
9p
adfs
affs
afs
autofs
befs
bfs
btrfs
tests
Kconfig
Makefile
accessors.c
accessors.h
acl.c
acl.h
async-thread.c
async-thread.h
backref.c
backref.h
bio.c
bio.h
block-group.c
block-group.h
block-rsv.c
block-rsv.h
btrfs_inode.h
check-integrity.c
check-integrity.h
compression.c
compression.h
ctree.c
ctree.h
defrag.c
defrag.h
delalloc-space.c
delalloc-space.h
delayed-inode.c
delayed-inode.h
delayed-ref.c
delayed-ref.h
dev-replace.c
dev-replace.h
dir-item.c
dir-item.h
discard.c
discard.h
disk-io.c
disk-io.h
export.c
export.h
extent-io-tree.c
extent-io-tree.h
extent-tree.c
extent-tree.h
extent_io.c
extent_io.h
extent_map.c
extent_map.h
file-item.c
file-item.h
file.c
file.h
free-space-cache.c
free-space-cache.h
free-space-tree.c
free-space-tree.h
fs.c
fs.h
inode-item.c
inode-item.h
inode.c
ioctl.c
ioctl.h
locking.c
locking.h
lru_cache.c
lru_cache.h
lzo.c
messages.c
messages.h
misc.h
ordered-data.c
ordered-data.h
orphan.c
orphan.h
print-tree.c
print-tree.h
props.c
props.h
qgroup.c
qgroup.h
raid56.c
raid56.h
rcu-string.h
ref-verify.c
ref-verify.h
reflink.c
reflink.h
relocation.c
relocation.h
root-tree.c
root-tree.h
scrub.c
scrub.h
send.c
send.h
space-info.c
space-info.h
subpage.c
subpage.h
super.c
super.h
sysfs.c
sysfs.h
transaction.c
transaction.h
tree-checker.c
tree-checker.h
tree-log.c
tree-log.h
tree-mod-log.c
tree-mod-log.h
ulist.c
ulist.h
uuid-tree.c
uuid-tree.h
verity.c
verity.h
volumes.c
volumes.h
xattr.c
xattr.h
zlib.c
zoned.c
zoned.h
zstd.c
cachefiles
ceph
coda
configfs
cramfs
crypto
debugfs
devpts
dlm
ecryptfs
efivarfs
efs
erofs
exfat
exportfs
ext2
ext4
f2fs
fat
freevxfs
fscache
fuse
gfs2
hfs
hfsplus
hostfs
hpfs
hugetlbfs
iomap
isofs
jbd2
jffs2
jfs
kernfs
lockd
minix
netfs
nfs
nfs_common
nfsd
nilfs2
nls
notify
ntfs
ntfs3
ocfs2
omfs
openpromfs
orangefs
overlayfs
proc
pstore
qnx4
qnx6
quota
ramfs
reiserfs
romfs
smb
squashfs
sysfs
sysv
tracefs
ubifs
udf
ufs
unicode
vboxsf
verity
xfs
zonefs
Kconfig
Kconfig.binfmt
Makefile
aio.c
anon_inodes.c
attr.c
bad_inode.c
binfmt_elf.c
binfmt_elf_fdpic.c
binfmt_elf_test.c
binfmt_flat.c
binfmt_misc.c
binfmt_script.c
buffer.c
char_dev.c
compat_binfmt_elf.c
coredump.c
d_path.c
dax.c
dcache.c
direct-io.c
drop_caches.c
eventfd.c
eventpoll.c
exec.c
fcntl.c
fhandle.c
file.c
file_table.c
filesystems.c
fs-writeback.c
fs_context.c
fs_parser.c
fs_pin.c
fs_struct.c
fs_types.c
fsopen.c
init.c
inode.c
internal.h
ioctl.c
kernel_read_file.c
libfs.c
locks.c
mbcache.c
mnt_idmapping.c
mount.h
mpage.c
namei.c
namespace.c
nsfs.c
open.c
pipe.c
pnode.c
pnode.h
posix_acl.c
proc_namespace.c
read_write.c
readdir.c
remap_range.c
select.c
seq_file.c
signalfd.c
splice.c
stack.c
stat.c
statfs.c
super.c
sync.c
sysctls.c
timerfd.c
userfaultfd.c
utimes.c
xattr.c
include
init
io_uring
ipc
kernel
lib
mm
net
rust
samples
scripts
security
sound
tools
usr
virt
.clang-format
.cocciconfig
.get_maintainer.ignore
.gitattributes
.gitignore
.mailmap
.rustfmt.toml
COPYING
CREDITS
Kbuild
Kconfig
MAINTAINERS
Makefile
README
Breadcrumbs
linux
/
fs
/
btrfs
/
messages.c
Copy path
Blame
Blame
Latest commit
Qu Wenruo
and
David Sterba
btrfs: remove v0 extent handling
Aug 21, 2023
182741d
·
Aug 21, 2023
History
History
313 lines (271 loc) · 8.57 KB
Breadcrumbs
linux
/
fs
/
btrfs
/
messages.c
Top
File metadata and controls
Code
Blame
313 lines (271 loc) · 8.57 KB
Raw
// SPDX-License-Identifier: GPL-2.0 #include "fs.h" #include "messages.h" #include "discard.h" #include "transaction.h" #include "space-info.h" #include "super.h" #ifdef CONFIG_PRINTK #define STATE_STRING_PREFACE ": state " #define STATE_STRING_BUF_LEN (sizeof(STATE_STRING_PREFACE) + BTRFS_FS_STATE_COUNT + 1) /* * Characters to print to indicate error conditions or uncommon filesystem state. * RO is not an error. */ static const char fs_state_chars[] = { [BTRFS_FS_STATE_REMOUNTING] = 'M', [BTRFS_FS_STATE_RO] = 0, [BTRFS_FS_STATE_TRANS_ABORTED] = 'A', [BTRFS_FS_STATE_DEV_REPLACING] = 'R', [BTRFS_FS_STATE_DUMMY_FS_INFO] = 0, [BTRFS_FS_STATE_NO_CSUMS] = 'C', [BTRFS_FS_STATE_LOG_CLEANUP_ERROR] = 'L', }; static void btrfs_state_to_string(const struct btrfs_fs_info *info, char *buf) { unsigned int bit; bool states_printed = false; unsigned long fs_state = READ_ONCE(info->fs_state); char *curr = buf; memcpy(curr, STATE_STRING_PREFACE, sizeof(STATE_STRING_PREFACE)); curr += sizeof(STATE_STRING_PREFACE) - 1; if (BTRFS_FS_ERROR(info)) { *curr++ = 'E'; states_printed = true; } for_each_set_bit(bit, &fs_state, sizeof(fs_state)) { WARN_ON_ONCE(bit >= BTRFS_FS_STATE_COUNT); if ((bit < BTRFS_FS_STATE_COUNT) && fs_state_chars[bit]) { *curr++ = fs_state_chars[bit]; states_printed = true; } } /* If no states were printed, reset the buffer */ if (!states_printed) curr = buf; *curr++ = 0; } #endif /* * Generally the error codes correspond to their respective errors, but there * are a few special cases. * * EUCLEAN: Any sort of corruption that we encounter. The tree-checker for * instance will return EUCLEAN if any of the blocks are corrupted in * a way that is problematic. We want to reserve EUCLEAN for these * sort of corruptions. * * EROFS: If we check BTRFS_FS_STATE_ERROR and fail out with a return error, we * need to use EROFS for this case. We will have no idea of the * original failure, that will have been reported at the time we tripped * over the error. Each subsequent error that doesn't have any context * of the original error should use EROFS when handling BTRFS_FS_STATE_ERROR. */ const char * __attribute_const__ btrfs_decode_error(int errno) { char *errstr = "unknown"; switch (errno) { case -ENOENT: /* -2 */ errstr = "No such entry"; break; case -EIO: /* -5 */ errstr = "IO failure"; break; case -ENOMEM: /* -12*/ errstr = "Out of memory"; break; case -EEXIST: /* -17 */ errstr = "Object already exists"; break; case -ENOSPC: /* -28 */ errstr = "No space left"; break; case -EROFS: /* -30 */ errstr = "Readonly filesystem"; break; case -EOPNOTSUPP: /* -95 */ errstr = "Operation not supported"; break; case -EUCLEAN: /* -117 */ errstr = "Filesystem corrupted"; break; case -EDQUOT: /* -122 */ errstr = "Quota exceeded"; break; } return errstr; } /* * __btrfs_handle_fs_error decodes expected errors from the caller and * invokes the appropriate error response. */ __cold void __btrfs_handle_fs_error(struct btrfs_fs_info *fs_info, const char *function, unsigned int line, int errno, const char *fmt, ...) { struct super_block *sb = fs_info->sb; #ifdef CONFIG_PRINTK char statestr[STATE_STRING_BUF_LEN]; const char *errstr; #endif #ifdef CONFIG_PRINTK_INDEX printk_index_subsys_emit( "BTRFS: error (device %s%s) in %s:%d: errno=%d %s", KERN_CRIT, fmt); #endif /* * Special case: if the error is EROFS, and we're already under * SB_RDONLY, then it is safe here. */ if (errno == -EROFS && sb_rdonly(sb)) return; #ifdef CONFIG_PRINTK errstr = btrfs_decode_error(errno); btrfs_state_to_string(fs_info, statestr); if (fmt) { struct va_format vaf; va_list args; va_start(args, fmt); vaf.fmt = fmt; vaf.va = &args; pr_crit("BTRFS: error (device %s%s) in %s:%d: errno=%d %s (%pV)\n", sb->s_id, statestr, function, line, errno, errstr, &vaf); va_end(args); } else { pr_crit("BTRFS: error (device %s%s) in %s:%d: errno=%d %s\n", sb->s_id, statestr, function, line, errno, errstr); } #endif /* * Today we only save the error info to memory. Long term we'll also * send it down to the disk. */ WRITE_ONCE(fs_info->fs_error, errno); /* Don't go through full error handling during mount. */ if (!(sb->s_flags & SB_BORN)) return; if (sb_rdonly(sb)) return; btrfs_discard_stop(fs_info); /* Handle error by forcing the filesystem readonly. */ btrfs_set_sb_rdonly(sb); btrfs_info(fs_info, "forced readonly"); /* * Note that a running device replace operation is not canceled here * although there is no way to update the progress. It would add the * risk of a deadlock, therefore the canceling is omitted. The only * penalty is that some I/O remains active until the procedure * completes. The next time when the filesystem is mounted writable * again, the device replace operation continues. */ } #ifdef CONFIG_PRINTK static const char * const logtypes[] = { "emergency", "alert", "critical", "error", "warning", "notice", "info", "debug", }; /* * Use one ratelimit state per log level so that a flood of less important * messages doesn't cause more important ones to be dropped. */ static struct ratelimit_state printk_limits[] = { RATELIMIT_STATE_INIT(printk_limits[0], DEFAULT_RATELIMIT_INTERVAL, 100), RATELIMIT_STATE_INIT(printk_limits[1], DEFAULT_RATELIMIT_INTERVAL, 100), RATELIMIT_STATE_INIT(printk_limits[2], DEFAULT_RATELIMIT_INTERVAL, 100), RATELIMIT_STATE_INIT(printk_limits[3], DEFAULT_RATELIMIT_INTERVAL, 100), RATELIMIT_STATE_INIT(printk_limits[4], DEFAULT_RATELIMIT_INTERVAL, 100), RATELIMIT_STATE_INIT(printk_limits[5], DEFAULT_RATELIMIT_INTERVAL, 100), RATELIMIT_STATE_INIT(printk_limits[6], DEFAULT_RATELIMIT_INTERVAL, 100), RATELIMIT_STATE_INIT(printk_limits[7], DEFAULT_RATELIMIT_INTERVAL, 100), }; void __cold _btrfs_printk(const struct btrfs_fs_info *fs_info, const char *fmt, ...) { char lvl[PRINTK_MAX_SINGLE_HEADER_LEN + 1] = "\0"; struct va_format vaf; va_list args; int kern_level; const char *type = logtypes[4]; struct ratelimit_state *ratelimit = &printk_limits[4]; #ifdef CONFIG_PRINTK_INDEX printk_index_subsys_emit("%sBTRFS %s (device %s): ", NULL, fmt); #endif va_start(args, fmt); while ((kern_level = printk_get_level(fmt)) != 0) { size_t size = printk_skip_level(fmt) - fmt; if (kern_level >= '0' && kern_level <= '7') { memcpy(lvl, fmt, size); lvl[size] = '\0'; type = logtypes[kern_level - '0']; ratelimit = &printk_limits[kern_level - '0']; } fmt += size; } vaf.fmt = fmt; vaf.va = &args; if (__ratelimit(ratelimit)) { if (fs_info) { char statestr[STATE_STRING_BUF_LEN]; btrfs_state_to_string(fs_info, statestr); _printk("%sBTRFS %s (device %s%s): %pV\n", lvl, type, fs_info->sb->s_id, statestr, &vaf); } else { _printk("%sBTRFS %s: %pV\n", lvl, type, &vaf); } } va_end(args); } #endif #if BITS_PER_LONG == 32 void __cold btrfs_warn_32bit_limit(struct btrfs_fs_info *fs_info) { if (!test_and_set_bit(BTRFS_FS_32BIT_WARN, &fs_info->flags)) { btrfs_warn(fs_info, "reaching 32bit limit for logical addresses"); btrfs_warn(fs_info, "due to page cache limit on 32bit systems, btrfs can't access metadata at or beyond %lluT", BTRFS_32BIT_MAX_FILE_SIZE >> 40); btrfs_warn(fs_info, "please consider upgrading to 64bit kernel/hardware"); } } void __cold btrfs_err_32bit_limit(struct btrfs_fs_info *fs_info) { if (!test_and_set_bit(BTRFS_FS_32BIT_ERROR, &fs_info->flags)) { btrfs_err(fs_info, "reached 32bit limit for logical addresses"); btrfs_err(fs_info, "due to page cache limit on 32bit systems, metadata beyond %lluT can't be accessed", BTRFS_32BIT_MAX_FILE_SIZE >> 40); btrfs_err(fs_info, "please consider upgrading to 64bit kernel/hardware"); } } #endif /* * __btrfs_panic decodes unexpected, fatal errors from the caller, issues an * alert, and either panics or BUGs, depending on mount options. */ __cold void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function, unsigned int line, int errno, const char *fmt, ...) { char *s_id = "<unknown>"; const char *errstr; struct va_format vaf = { .fmt = fmt }; va_list args; if (fs_info) s_id = fs_info->sb->s_id; va_start(args, fmt); vaf.va = &args; errstr = btrfs_decode_error(errno); if (fs_info && (btrfs_test_opt(fs_info, PANIC_ON_FATAL_ERROR))) panic(KERN_CRIT "BTRFS panic (device %s) in %s:%d: %pV (errno=%d %s)\n", s_id, function, line, &vaf, errno, errstr); btrfs_crit(fs_info, "panic in %s:%d: %pV (errno=%d %s)", function, line, &vaf, errno, errstr); va_end(args); /* Caller calls BUG() */ }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
You can’t perform that action at this time.