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