162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * debug.c - NTFS kernel debug support. Part of the Linux-NTFS project. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2001-2004 Anton Altaparmakov 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 862306a36Sopenharmony_ci#include "debug.h" 962306a36Sopenharmony_ci 1062306a36Sopenharmony_ci/** 1162306a36Sopenharmony_ci * __ntfs_warning - output a warning to the syslog 1262306a36Sopenharmony_ci * @function: name of function outputting the warning 1362306a36Sopenharmony_ci * @sb: super block of mounted ntfs filesystem 1462306a36Sopenharmony_ci * @fmt: warning string containing format specifications 1562306a36Sopenharmony_ci * @...: a variable number of arguments specified in @fmt 1662306a36Sopenharmony_ci * 1762306a36Sopenharmony_ci * Outputs a warning to the syslog for the mounted ntfs filesystem described 1862306a36Sopenharmony_ci * by @sb. 1962306a36Sopenharmony_ci * 2062306a36Sopenharmony_ci * @fmt and the corresponding @... is printf style format string containing 2162306a36Sopenharmony_ci * the warning string and the corresponding format arguments, respectively. 2262306a36Sopenharmony_ci * 2362306a36Sopenharmony_ci * @function is the name of the function from which __ntfs_warning is being 2462306a36Sopenharmony_ci * called. 2562306a36Sopenharmony_ci * 2662306a36Sopenharmony_ci * Note, you should be using debug.h::ntfs_warning(@sb, @fmt, @...) instead 2762306a36Sopenharmony_ci * as this provides the @function parameter automatically. 2862306a36Sopenharmony_ci */ 2962306a36Sopenharmony_civoid __ntfs_warning(const char *function, const struct super_block *sb, 3062306a36Sopenharmony_ci const char *fmt, ...) 3162306a36Sopenharmony_ci{ 3262306a36Sopenharmony_ci struct va_format vaf; 3362306a36Sopenharmony_ci va_list args; 3462306a36Sopenharmony_ci int flen = 0; 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci#ifndef DEBUG 3762306a36Sopenharmony_ci if (!printk_ratelimit()) 3862306a36Sopenharmony_ci return; 3962306a36Sopenharmony_ci#endif 4062306a36Sopenharmony_ci if (function) 4162306a36Sopenharmony_ci flen = strlen(function); 4262306a36Sopenharmony_ci va_start(args, fmt); 4362306a36Sopenharmony_ci vaf.fmt = fmt; 4462306a36Sopenharmony_ci vaf.va = &args; 4562306a36Sopenharmony_ci if (sb) 4662306a36Sopenharmony_ci pr_warn("(device %s): %s(): %pV\n", 4762306a36Sopenharmony_ci sb->s_id, flen ? function : "", &vaf); 4862306a36Sopenharmony_ci else 4962306a36Sopenharmony_ci pr_warn("%s(): %pV\n", flen ? function : "", &vaf); 5062306a36Sopenharmony_ci va_end(args); 5162306a36Sopenharmony_ci} 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/** 5462306a36Sopenharmony_ci * __ntfs_error - output an error to the syslog 5562306a36Sopenharmony_ci * @function: name of function outputting the error 5662306a36Sopenharmony_ci * @sb: super block of mounted ntfs filesystem 5762306a36Sopenharmony_ci * @fmt: error string containing format specifications 5862306a36Sopenharmony_ci * @...: a variable number of arguments specified in @fmt 5962306a36Sopenharmony_ci * 6062306a36Sopenharmony_ci * Outputs an error to the syslog for the mounted ntfs filesystem described 6162306a36Sopenharmony_ci * by @sb. 6262306a36Sopenharmony_ci * 6362306a36Sopenharmony_ci * @fmt and the corresponding @... is printf style format string containing 6462306a36Sopenharmony_ci * the error string and the corresponding format arguments, respectively. 6562306a36Sopenharmony_ci * 6662306a36Sopenharmony_ci * @function is the name of the function from which __ntfs_error is being 6762306a36Sopenharmony_ci * called. 6862306a36Sopenharmony_ci * 6962306a36Sopenharmony_ci * Note, you should be using debug.h::ntfs_error(@sb, @fmt, @...) instead 7062306a36Sopenharmony_ci * as this provides the @function parameter automatically. 7162306a36Sopenharmony_ci */ 7262306a36Sopenharmony_civoid __ntfs_error(const char *function, const struct super_block *sb, 7362306a36Sopenharmony_ci const char *fmt, ...) 7462306a36Sopenharmony_ci{ 7562306a36Sopenharmony_ci struct va_format vaf; 7662306a36Sopenharmony_ci va_list args; 7762306a36Sopenharmony_ci int flen = 0; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci#ifndef DEBUG 8062306a36Sopenharmony_ci if (!printk_ratelimit()) 8162306a36Sopenharmony_ci return; 8262306a36Sopenharmony_ci#endif 8362306a36Sopenharmony_ci if (function) 8462306a36Sopenharmony_ci flen = strlen(function); 8562306a36Sopenharmony_ci va_start(args, fmt); 8662306a36Sopenharmony_ci vaf.fmt = fmt; 8762306a36Sopenharmony_ci vaf.va = &args; 8862306a36Sopenharmony_ci if (sb) 8962306a36Sopenharmony_ci pr_err("(device %s): %s(): %pV\n", 9062306a36Sopenharmony_ci sb->s_id, flen ? function : "", &vaf); 9162306a36Sopenharmony_ci else 9262306a36Sopenharmony_ci pr_err("%s(): %pV\n", flen ? function : "", &vaf); 9362306a36Sopenharmony_ci va_end(args); 9462306a36Sopenharmony_ci} 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci#ifdef DEBUG 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci/* If 1, output debug messages, and if 0, don't. */ 9962306a36Sopenharmony_ciint debug_msgs = 0; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_civoid __ntfs_debug(const char *file, int line, const char *function, 10262306a36Sopenharmony_ci const char *fmt, ...) 10362306a36Sopenharmony_ci{ 10462306a36Sopenharmony_ci struct va_format vaf; 10562306a36Sopenharmony_ci va_list args; 10662306a36Sopenharmony_ci int flen = 0; 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci if (!debug_msgs) 10962306a36Sopenharmony_ci return; 11062306a36Sopenharmony_ci if (function) 11162306a36Sopenharmony_ci flen = strlen(function); 11262306a36Sopenharmony_ci va_start(args, fmt); 11362306a36Sopenharmony_ci vaf.fmt = fmt; 11462306a36Sopenharmony_ci vaf.va = &args; 11562306a36Sopenharmony_ci pr_debug("(%s, %d): %s(): %pV", file, line, flen ? function : "", &vaf); 11662306a36Sopenharmony_ci va_end(args); 11762306a36Sopenharmony_ci} 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci/* Dump a runlist. Caller has to provide synchronisation for @rl. */ 12062306a36Sopenharmony_civoid ntfs_debug_dump_runlist(const runlist_element *rl) 12162306a36Sopenharmony_ci{ 12262306a36Sopenharmony_ci int i; 12362306a36Sopenharmony_ci const char *lcn_str[5] = { "LCN_HOLE ", "LCN_RL_NOT_MAPPED", 12462306a36Sopenharmony_ci "LCN_ENOENT ", "LCN_unknown " }; 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci if (!debug_msgs) 12762306a36Sopenharmony_ci return; 12862306a36Sopenharmony_ci pr_debug("Dumping runlist (values in hex):\n"); 12962306a36Sopenharmony_ci if (!rl) { 13062306a36Sopenharmony_ci pr_debug("Run list not present.\n"); 13162306a36Sopenharmony_ci return; 13262306a36Sopenharmony_ci } 13362306a36Sopenharmony_ci pr_debug("VCN LCN Run length\n"); 13462306a36Sopenharmony_ci for (i = 0; ; i++) { 13562306a36Sopenharmony_ci LCN lcn = (rl + i)->lcn; 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_ci if (lcn < (LCN)0) { 13862306a36Sopenharmony_ci int index = -lcn - 1; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci if (index > -LCN_ENOENT - 1) 14162306a36Sopenharmony_ci index = 3; 14262306a36Sopenharmony_ci pr_debug("%-16Lx %s %-16Lx%s\n", 14362306a36Sopenharmony_ci (long long)(rl + i)->vcn, lcn_str[index], 14462306a36Sopenharmony_ci (long long)(rl + i)->length, 14562306a36Sopenharmony_ci (rl + i)->length ? "" : 14662306a36Sopenharmony_ci " (runlist end)"); 14762306a36Sopenharmony_ci } else 14862306a36Sopenharmony_ci pr_debug("%-16Lx %-16Lx %-16Lx%s\n", 14962306a36Sopenharmony_ci (long long)(rl + i)->vcn, 15062306a36Sopenharmony_ci (long long)(rl + i)->lcn, 15162306a36Sopenharmony_ci (long long)(rl + i)->length, 15262306a36Sopenharmony_ci (rl + i)->length ? "" : 15362306a36Sopenharmony_ci " (runlist end)"); 15462306a36Sopenharmony_ci if (!(rl + i)->length) 15562306a36Sopenharmony_ci break; 15662306a36Sopenharmony_ci } 15762306a36Sopenharmony_ci} 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci#endif 160