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