xref: /linux/fs/ntfs/debug.c (revision cdd4dc3aebeab43a72ce0bc2b5bab6f0a80b97a5)
11e9ea7e0SNamjae Jeon // SPDX-License-Identifier: GPL-2.0-or-later
21e9ea7e0SNamjae Jeon /*
3*5218cd10SNamjae Jeon  * NTFS kernel debug support.
41e9ea7e0SNamjae Jeon  *
51e9ea7e0SNamjae Jeon  * Copyright (c) 2001-2004 Anton Altaparmakov
61e9ea7e0SNamjae Jeon  */
71e9ea7e0SNamjae Jeon #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
81e9ea7e0SNamjae Jeon #include "debug.h"
91e9ea7e0SNamjae Jeon 
10*5218cd10SNamjae Jeon /*
111e9ea7e0SNamjae Jeon  * __ntfs_warning - output a warning to the syslog
121e9ea7e0SNamjae Jeon  * @function:	name of function outputting the warning
131e9ea7e0SNamjae Jeon  * @sb:		super block of mounted ntfs filesystem
141e9ea7e0SNamjae Jeon  * @fmt:	warning string containing format specifications
151e9ea7e0SNamjae Jeon  * @...:	a variable number of arguments specified in @fmt
161e9ea7e0SNamjae Jeon  *
171e9ea7e0SNamjae Jeon  * Outputs a warning to the syslog for the mounted ntfs filesystem described
181e9ea7e0SNamjae Jeon  * by @sb.
191e9ea7e0SNamjae Jeon  *
201e9ea7e0SNamjae Jeon  * @fmt and the corresponding @... is printf style format string containing
211e9ea7e0SNamjae Jeon  * the warning string and the corresponding format arguments, respectively.
221e9ea7e0SNamjae Jeon  *
231e9ea7e0SNamjae Jeon  * @function is the name of the function from which __ntfs_warning is being
241e9ea7e0SNamjae Jeon  * called.
251e9ea7e0SNamjae Jeon  *
261e9ea7e0SNamjae Jeon  * Note, you should be using debug.h::ntfs_warning(@sb, @fmt, @...) instead
271e9ea7e0SNamjae Jeon  * as this provides the @function parameter automatically.
281e9ea7e0SNamjae Jeon  */
291e9ea7e0SNamjae Jeon void __ntfs_warning(const char *function, const struct super_block *sb,
301e9ea7e0SNamjae Jeon 		const char *fmt, ...)
311e9ea7e0SNamjae Jeon {
321e9ea7e0SNamjae Jeon 	struct va_format vaf;
331e9ea7e0SNamjae Jeon 	va_list args;
341e9ea7e0SNamjae Jeon 	int flen = 0;
351e9ea7e0SNamjae Jeon 
361e9ea7e0SNamjae Jeon 	if (function)
371e9ea7e0SNamjae Jeon 		flen = strlen(function);
381e9ea7e0SNamjae Jeon 	va_start(args, fmt);
391e9ea7e0SNamjae Jeon 	vaf.fmt = fmt;
401e9ea7e0SNamjae Jeon 	vaf.va = &args;
41*5218cd10SNamjae Jeon #ifdef DEBUG
421e9ea7e0SNamjae Jeon 	if (sb)
431e9ea7e0SNamjae Jeon 		pr_warn("(device %s): %s(): %pV\n",
441e9ea7e0SNamjae Jeon 			sb->s_id, flen ? function : "", &vaf);
451e9ea7e0SNamjae Jeon 	else
461e9ea7e0SNamjae Jeon 		pr_warn("%s(): %pV\n", flen ? function : "", &vaf);
47*5218cd10SNamjae Jeon #else
48*5218cd10SNamjae Jeon 	if (sb)
49*5218cd10SNamjae Jeon 		pr_warn_ratelimited("(device %s): %s(): %pV\n",
50*5218cd10SNamjae Jeon 			sb->s_id, flen ? function : "", &vaf);
51*5218cd10SNamjae Jeon 	else
52*5218cd10SNamjae Jeon 		pr_warn_ratelimited("%s(): %pV\n", flen ? function : "", &vaf);
53*5218cd10SNamjae Jeon #endif
541e9ea7e0SNamjae Jeon 	va_end(args);
551e9ea7e0SNamjae Jeon }
561e9ea7e0SNamjae Jeon 
57*5218cd10SNamjae Jeon /*
581e9ea7e0SNamjae Jeon  * __ntfs_error - output an error to the syslog
591e9ea7e0SNamjae Jeon  * @function:	name of function outputting the error
601e9ea7e0SNamjae Jeon  * @sb:		super block of mounted ntfs filesystem
611e9ea7e0SNamjae Jeon  * @fmt:	error string containing format specifications
621e9ea7e0SNamjae Jeon  * @...:	a variable number of arguments specified in @fmt
631e9ea7e0SNamjae Jeon  *
641e9ea7e0SNamjae Jeon  * Outputs an error to the syslog for the mounted ntfs filesystem described
651e9ea7e0SNamjae Jeon  * by @sb.
661e9ea7e0SNamjae Jeon  *
671e9ea7e0SNamjae Jeon  * @fmt and the corresponding @... is printf style format string containing
681e9ea7e0SNamjae Jeon  * the error string and the corresponding format arguments, respectively.
691e9ea7e0SNamjae Jeon  *
701e9ea7e0SNamjae Jeon  * @function is the name of the function from which __ntfs_error is being
711e9ea7e0SNamjae Jeon  * called.
721e9ea7e0SNamjae Jeon  *
731e9ea7e0SNamjae Jeon  * Note, you should be using debug.h::ntfs_error(@sb, @fmt, @...) instead
741e9ea7e0SNamjae Jeon  * as this provides the @function parameter automatically.
751e9ea7e0SNamjae Jeon  */
76*5218cd10SNamjae Jeon void __ntfs_error(const char *function, struct super_block *sb,
771e9ea7e0SNamjae Jeon 		const char *fmt, ...)
781e9ea7e0SNamjae Jeon {
791e9ea7e0SNamjae Jeon 	struct va_format vaf;
801e9ea7e0SNamjae Jeon 	va_list args;
811e9ea7e0SNamjae Jeon 	int flen = 0;
821e9ea7e0SNamjae Jeon 
831e9ea7e0SNamjae Jeon 	if (function)
841e9ea7e0SNamjae Jeon 		flen = strlen(function);
851e9ea7e0SNamjae Jeon 	va_start(args, fmt);
861e9ea7e0SNamjae Jeon 	vaf.fmt = fmt;
871e9ea7e0SNamjae Jeon 	vaf.va = &args;
88*5218cd10SNamjae Jeon #ifdef DEBUG
891e9ea7e0SNamjae Jeon 	if (sb)
901e9ea7e0SNamjae Jeon 		pr_err("(device %s): %s(): %pV\n",
911e9ea7e0SNamjae Jeon 		       sb->s_id, flen ? function : "", &vaf);
921e9ea7e0SNamjae Jeon 	else
931e9ea7e0SNamjae Jeon 		pr_err("%s(): %pV\n", flen ? function : "", &vaf);
94*5218cd10SNamjae Jeon #else
95*5218cd10SNamjae Jeon 	if (sb)
96*5218cd10SNamjae Jeon 		pr_err_ratelimited("(device %s): %s(): %pV\n",
97*5218cd10SNamjae Jeon 		       sb->s_id, flen ? function : "", &vaf);
98*5218cd10SNamjae Jeon 	else
99*5218cd10SNamjae Jeon 		pr_err_ratelimited("%s(): %pV\n", flen ? function : "", &vaf);
100*5218cd10SNamjae Jeon #endif
1011e9ea7e0SNamjae Jeon 	va_end(args);
102*5218cd10SNamjae Jeon 
103*5218cd10SNamjae Jeon 	if (sb)
104*5218cd10SNamjae Jeon 		ntfs_handle_error(sb);
1051e9ea7e0SNamjae Jeon }
1061e9ea7e0SNamjae Jeon 
1071e9ea7e0SNamjae Jeon #ifdef DEBUG
1081e9ea7e0SNamjae Jeon 
1091e9ea7e0SNamjae Jeon /* If 1, output debug messages, and if 0, don't. */
110*5218cd10SNamjae Jeon int debug_msgs;
1111e9ea7e0SNamjae Jeon 
1121e9ea7e0SNamjae Jeon void __ntfs_debug(const char *file, int line, const char *function,
1131e9ea7e0SNamjae Jeon 		const char *fmt, ...)
1141e9ea7e0SNamjae Jeon {
1151e9ea7e0SNamjae Jeon 	struct va_format vaf;
1161e9ea7e0SNamjae Jeon 	va_list args;
1171e9ea7e0SNamjae Jeon 	int flen = 0;
1181e9ea7e0SNamjae Jeon 
1191e9ea7e0SNamjae Jeon 	if (!debug_msgs)
1201e9ea7e0SNamjae Jeon 		return;
1211e9ea7e0SNamjae Jeon 	if (function)
1221e9ea7e0SNamjae Jeon 		flen = strlen(function);
1231e9ea7e0SNamjae Jeon 	va_start(args, fmt);
1241e9ea7e0SNamjae Jeon 	vaf.fmt = fmt;
1251e9ea7e0SNamjae Jeon 	vaf.va = &args;
1261e9ea7e0SNamjae Jeon 	pr_debug("(%s, %d): %s(): %pV", file, line, flen ? function : "", &vaf);
1271e9ea7e0SNamjae Jeon 	va_end(args);
1281e9ea7e0SNamjae Jeon }
1291e9ea7e0SNamjae Jeon 
1301e9ea7e0SNamjae Jeon /* Dump a runlist. Caller has to provide synchronisation for @rl. */
131*5218cd10SNamjae Jeon void ntfs_debug_dump_runlist(const struct runlist_element *rl)
1321e9ea7e0SNamjae Jeon {
1331e9ea7e0SNamjae Jeon 	int i;
134*5218cd10SNamjae Jeon 	const char *lcn_str[5] = { "LCN_DELALLOC     ", "LCN_HOLE         ",
135*5218cd10SNamjae Jeon 				   "LCN_RL_NOT_MAPPED", "LCN_ENOENT       ",
136*5218cd10SNamjae Jeon 				   "LCN_unknown      " };
1371e9ea7e0SNamjae Jeon 
1381e9ea7e0SNamjae Jeon 	if (!debug_msgs)
1391e9ea7e0SNamjae Jeon 		return;
1401e9ea7e0SNamjae Jeon 	pr_debug("Dumping runlist (values in hex):\n");
1411e9ea7e0SNamjae Jeon 	if (!rl) {
1421e9ea7e0SNamjae Jeon 		pr_debug("Run list not present.\n");
1431e9ea7e0SNamjae Jeon 		return;
1441e9ea7e0SNamjae Jeon 	}
1451e9ea7e0SNamjae Jeon 	pr_debug("VCN              LCN               Run length\n");
1461e9ea7e0SNamjae Jeon 	for (i = 0; ; i++) {
147*5218cd10SNamjae Jeon 		s64 lcn = (rl + i)->lcn;
1481e9ea7e0SNamjae Jeon 
149*5218cd10SNamjae Jeon 		if (lcn < 0) {
1501e9ea7e0SNamjae Jeon 			int index = -lcn - 1;
1511e9ea7e0SNamjae Jeon 
1521e9ea7e0SNamjae Jeon 			if (index > -LCN_ENOENT - 1)
1531e9ea7e0SNamjae Jeon 				index = 3;
1541e9ea7e0SNamjae Jeon 			pr_debug("%-16Lx %s %-16Lx%s\n",
1551e9ea7e0SNamjae Jeon 					(long long)(rl + i)->vcn, lcn_str[index],
1561e9ea7e0SNamjae Jeon 					(long long)(rl + i)->length,
1571e9ea7e0SNamjae Jeon 					(rl + i)->length ? "" :
1581e9ea7e0SNamjae Jeon 						" (runlist end)");
1591e9ea7e0SNamjae Jeon 		} else
1601e9ea7e0SNamjae Jeon 			pr_debug("%-16Lx %-16Lx  %-16Lx%s\n",
1611e9ea7e0SNamjae Jeon 					(long long)(rl + i)->vcn,
1621e9ea7e0SNamjae Jeon 					(long long)(rl + i)->lcn,
1631e9ea7e0SNamjae Jeon 					(long long)(rl + i)->length,
1641e9ea7e0SNamjae Jeon 					(rl + i)->length ? "" :
1651e9ea7e0SNamjae Jeon 						" (runlist end)");
1661e9ea7e0SNamjae Jeon 		if (!(rl + i)->length)
1671e9ea7e0SNamjae Jeon 			break;
1681e9ea7e0SNamjae Jeon 	}
1691e9ea7e0SNamjae Jeon }
1701e9ea7e0SNamjae Jeon 
1711e9ea7e0SNamjae Jeon #endif
172