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