xref: /linux/fs/ntfs/debug.c (revision cdd4dc3aebeab43a72ce0bc2b5bab6f0a80b97a5)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * NTFS kernel debug support.
4  *
5  * Copyright (c) 2001-2004 Anton Altaparmakov
6  */
7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8 #include "debug.h"
9 
10 /*
11  * __ntfs_warning - output a warning to the syslog
12  * @function:	name of function outputting the warning
13  * @sb:		super block of mounted ntfs filesystem
14  * @fmt:	warning string containing format specifications
15  * @...:	a variable number of arguments specified in @fmt
16  *
17  * Outputs a warning to the syslog for the mounted ntfs filesystem described
18  * by @sb.
19  *
20  * @fmt and the corresponding @... is printf style format string containing
21  * the warning string and the corresponding format arguments, respectively.
22  *
23  * @function is the name of the function from which __ntfs_warning is being
24  * called.
25  *
26  * Note, you should be using debug.h::ntfs_warning(@sb, @fmt, @...) instead
27  * as this provides the @function parameter automatically.
28  */
29 void __ntfs_warning(const char *function, const struct super_block *sb,
30 		const char *fmt, ...)
31 {
32 	struct va_format vaf;
33 	va_list args;
34 	int flen = 0;
35 
36 	if (function)
37 		flen = strlen(function);
38 	va_start(args, fmt);
39 	vaf.fmt = fmt;
40 	vaf.va = &args;
41 #ifdef DEBUG
42 	if (sb)
43 		pr_warn("(device %s): %s(): %pV\n",
44 			sb->s_id, flen ? function : "", &vaf);
45 	else
46 		pr_warn("%s(): %pV\n", flen ? function : "", &vaf);
47 #else
48 	if (sb)
49 		pr_warn_ratelimited("(device %s): %s(): %pV\n",
50 			sb->s_id, flen ? function : "", &vaf);
51 	else
52 		pr_warn_ratelimited("%s(): %pV\n", flen ? function : "", &vaf);
53 #endif
54 	va_end(args);
55 }
56 
57 /*
58  * __ntfs_error - output an error to the syslog
59  * @function:	name of function outputting the error
60  * @sb:		super block of mounted ntfs filesystem
61  * @fmt:	error string containing format specifications
62  * @...:	a variable number of arguments specified in @fmt
63  *
64  * Outputs an error to the syslog for the mounted ntfs filesystem described
65  * by @sb.
66  *
67  * @fmt and the corresponding @... is printf style format string containing
68  * the error string and the corresponding format arguments, respectively.
69  *
70  * @function is the name of the function from which __ntfs_error is being
71  * called.
72  *
73  * Note, you should be using debug.h::ntfs_error(@sb, @fmt, @...) instead
74  * as this provides the @function parameter automatically.
75  */
76 void __ntfs_error(const char *function, struct super_block *sb,
77 		const char *fmt, ...)
78 {
79 	struct va_format vaf;
80 	va_list args;
81 	int flen = 0;
82 
83 	if (function)
84 		flen = strlen(function);
85 	va_start(args, fmt);
86 	vaf.fmt = fmt;
87 	vaf.va = &args;
88 #ifdef DEBUG
89 	if (sb)
90 		pr_err("(device %s): %s(): %pV\n",
91 		       sb->s_id, flen ? function : "", &vaf);
92 	else
93 		pr_err("%s(): %pV\n", flen ? function : "", &vaf);
94 #else
95 	if (sb)
96 		pr_err_ratelimited("(device %s): %s(): %pV\n",
97 		       sb->s_id, flen ? function : "", &vaf);
98 	else
99 		pr_err_ratelimited("%s(): %pV\n", flen ? function : "", &vaf);
100 #endif
101 	va_end(args);
102 
103 	if (sb)
104 		ntfs_handle_error(sb);
105 }
106 
107 #ifdef DEBUG
108 
109 /* If 1, output debug messages, and if 0, don't. */
110 int debug_msgs;
111 
112 void __ntfs_debug(const char *file, int line, const char *function,
113 		const char *fmt, ...)
114 {
115 	struct va_format vaf;
116 	va_list args;
117 	int flen = 0;
118 
119 	if (!debug_msgs)
120 		return;
121 	if (function)
122 		flen = strlen(function);
123 	va_start(args, fmt);
124 	vaf.fmt = fmt;
125 	vaf.va = &args;
126 	pr_debug("(%s, %d): %s(): %pV", file, line, flen ? function : "", &vaf);
127 	va_end(args);
128 }
129 
130 /* Dump a runlist. Caller has to provide synchronisation for @rl. */
131 void ntfs_debug_dump_runlist(const struct runlist_element *rl)
132 {
133 	int i;
134 	const char *lcn_str[5] = { "LCN_DELALLOC     ", "LCN_HOLE         ",
135 				   "LCN_RL_NOT_MAPPED", "LCN_ENOENT       ",
136 				   "LCN_unknown      " };
137 
138 	if (!debug_msgs)
139 		return;
140 	pr_debug("Dumping runlist (values in hex):\n");
141 	if (!rl) {
142 		pr_debug("Run list not present.\n");
143 		return;
144 	}
145 	pr_debug("VCN              LCN               Run length\n");
146 	for (i = 0; ; i++) {
147 		s64 lcn = (rl + i)->lcn;
148 
149 		if (lcn < 0) {
150 			int index = -lcn - 1;
151 
152 			if (index > -LCN_ENOENT - 1)
153 				index = 3;
154 			pr_debug("%-16Lx %s %-16Lx%s\n",
155 					(long long)(rl + i)->vcn, lcn_str[index],
156 					(long long)(rl + i)->length,
157 					(rl + i)->length ? "" :
158 						" (runlist end)");
159 		} else
160 			pr_debug("%-16Lx %-16Lx  %-16Lx%s\n",
161 					(long long)(rl + i)->vcn,
162 					(long long)(rl + i)->lcn,
163 					(long long)(rl + i)->length,
164 					(rl + i)->length ? "" :
165 						" (runlist end)");
166 		if (!(rl + i)->length)
167 			break;
168 	}
169 }
170 
171 #endif
172