0~sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextEnglish}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget/filesystems/debugfsmodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget'/translations/zh_TW/filesystems/debugfsmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget'/translations/it_IT/filesystems/debugfsmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget'/translations/ja_JP/filesystems/debugfsmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget'/translations/ko_KR/filesystems/debugfsmodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget'/translations/sp_SP/filesystems/debugfsmodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageChinese (Simplified)uh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhhT/var/lib/git/docbuild/linux/Documentation/translations/zh_CN/filesystems/debugfs.rsthKubhnote)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]h paragraph)}(hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。h]hX{此文件的目的是为让中文读者更容易阅读和理解,而不是作为一个分支。 因此, 如果您对此文件有任何意见或更新,请先尝试更新原始英文文件。 如果您发现本文档与原始文件有任何不同或者有翻译问题,请发建议或者补丁给 该文件的译者,或者请求中文文档维护者和审阅者的帮助。}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hh5Documentation/translations/zh_CN/disclaimer-zh_CN.rsthKhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhNubh field_list)}(hhh]hfield)}(hhh](h field_name)}(hOriginalh]hOriginal}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhKubh field_body)}(h&Documentation/filesystems/debugfs.rst h]h)}(h%Documentation/filesystems/debugfs.rsth]h%Documentation/filesystems/debugfs.rst}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhubah}(h]h ]h"]h$]h&]uh1hhhubeh}(h]h ]h"]h$]h&]uh1hhhhKhhhhubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubhsection)}(hhh](htitle)}(hDebugfsh]hDebugfs}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1jhjhhhhhK ubh)}(h 译者 ::h]h译者}(hj&hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hjhhubh literal_block)}(h中文版维护者: 罗楚成 Chucheng Luo 中文版翻译者: 罗楚成 Chucheng Luo 中文版校译者: 罗楚成 Chucheng Luo h]h中文版维护者: 罗楚成 Chucheng Luo 中文版翻译者: 罗楚成 Chucheng Luo 中文版校译者: 罗楚成 Chucheng Luo }hj6sbah}(h]h ]h"]h$]h&]hhuh1j4hhhKhjhhubh)}(h1版权所有2020 罗楚成 h](h版权所有2020 罗楚成 <}(hjDhhhNhNubh reference)}(hluochucheng@vivo.comh]hluochucheng@vivo.com}(hjNhhhNhNubah}(h]h ]h"]h$]h&]refurimailto:luochucheng@vivo.comuh1jLhjDubh>}(hjDhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXDebugfs是内核开发人员在用户空间获取信息的简单方法。与/proc不同,proc只提供进程 信息。也不像sysfs,具有严格的“每个文件一个值“的规则。debugfs根本没有规则,开发 人员可以在这里放置他们想要的任何信息。debugfs文件系统也不能用作稳定的ABI接口。 从理论上讲,debugfs导出文件的时候没有任何约束。但是[1]实际情况并不总是那么 简单。即使是debugfs接口,也最好根据需要进行设计,并尽量保持接口不变。h]hXDebugfs是内核开发人员在用户空间获取信息的简单方法。与/proc不同,proc只提供进程 信息。也不像sysfs,具有严格的“每个文件一个值“的规则。debugfs根本没有规则,开发 人员可以在这里放置他们想要的任何信息。debugfs文件系统也不能用作稳定的ABI接口。 从理论上讲,debugfs导出文件的时候没有任何约束。但是[1]实际情况并不总是那么 简单。即使是debugfs接口,也最好根据需要进行设计,并尽量保持接口不变。}(hjhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h'Debugfs通常使用以下命令安装::h]h&Debugfs通常使用以下命令安装:}(hjvhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj5)}(h'mount -t debugfs none /sys/kernel/debugh]h'mount -t debugfs none /sys/kernel/debug}hjsbah}(h]h ]h"]h$]h&]hhuh1j4hhhK hjhhubh)}(h(或等效的/etc/fstab行)。 debugfs根目录默认仅可由root用户访问。要更改对文件树的访问,请使用“ uid”,“ gid” 和“ mode”挂载选项。请注意,debugfs API仅按照GPL协议导出到模块。h]h(或等效的/etc/fstab行)。 debugfs根目录默认仅可由root用户访问。要更改对文件树的访问,请使用“ uid”,“ gid” 和“ mode”挂载选项。请注意,debugfs API仅按照GPL协议导出到模块。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK"hjhhubh)}(h|使用debugfs的代码应包含。然后,首先是创建至少一个目录来保存 一组debugfs文件::h]h{使用debugfs的代码应包含。然后,首先是创建至少一个目录来保存 一组debugfs文件:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK&hjhhubj5)}(hKstruct dentry *debugfs_create_dir(const char *name, struct dentry *parent);h]hKstruct dentry *debugfs_create_dir(const char *name, struct dentry *parent);}hjsbah}(h]h ]h"]h$]h&]hhuh1j4hhhK)hjhhubh)}(hX如果成功,此调用将在指定的父目录下创建一个名为name的目录。如果parent参数为空, 则会在debugfs根目录中创建。创建目录成功时,返回值是一个指向dentry结构体的指针。 该dentry结构体的指针可用于在目录中创建文件(以及最后将其清理干净)。ERR_PTR (-ERROR)返回值表明出错。如果返回ERR_PTR(-ENODEV),则表明内核是在没有debugfs 支持的情况下构建的,并且下述函数都不会起作用。h]hX如果成功,此调用将在指定的父目录下创建一个名为name的目录。如果parent参数为空, 则会在debugfs根目录中创建。创建目录成功时,返回值是一个指向dentry结构体的指针。 该dentry结构体的指针可用于在目录中创建文件(以及最后将其清理干净)。ERR_PTR (-ERROR)返回值表明出错。如果返回ERR_PTR(-ENODEV),则表明内核是在没有debugfs 支持的情况下构建的,并且下述函数都不会起作用。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK+hjhhubh)}(h6在debugfs目录中创建文件的最通用方法是::h]h5在debugfs目录中创建文件的最通用方法是:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK1hjhhubj5)}(hstruct dentry *debugfs_create_file(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops);h]hstruct dentry *debugfs_create_file(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops);}hjsbah}(h]h ]h"]h$]h&]hhuh1j4hhhK3hjhhubh)}(hXg在这里,name是要创建的文件的名称,mode描述了访问文件应具有的权限,parent指向 应该保存文件的目录,data将存储在产生的inode结构体的i_private字段中,而fops是 一组文件操作函数,这些函数中实现文件操作的具体行为。至少,read()和/或 write()操作应提供;其他可以根据需要包括在内。同样的,返回值将是指向创建文件 的dentry指针,错误时返回ERR_PTR(-ERROR),系统不支持debugfs时返回值为ERR_PTR (-ENODEV)。创建一个初始大小的文件,可以使用以下函数代替::h]hXf在这里,name是要创建的文件的名称,mode描述了访问文件应具有的权限,parent指向 应该保存文件的目录,data将存储在产生的inode结构体的i_private字段中,而fops是 一组文件操作函数,这些函数中实现文件操作的具体行为。至少,read()和/或 write()操作应提供;其他可以根据需要包括在内。同样的,返回值将是指向创建文件 的dentry指针,错误时返回ERR_PTR(-ERROR),系统不支持debugfs时返回值为ERR_PTR (-ENODEV)。创建一个初始大小的文件,可以使用以下函数代替:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK7hjhhubj5)}(hstruct dentry *debugfs_create_file_size(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops, loff_t file_size);h]hstruct dentry *debugfs_create_file_size(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops, loff_t file_size);}hjsbah}(h]h ]h"]h$]h&]hhuh1j4hhhK>hjhhubh)}(hUfile_size是初始文件大小。其他参数跟函数debugfs_create_file的相同。h]hUfile_size是初始文件大小。其他参数跟函数debugfs_create_file的相同。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKChjhhubh)}(h在许多情况下,没必要自己去创建一组文件操作;对于一些简单的情况,debugfs代码提供 了许多帮助函数。包含单个整数值的文件可以使用以下任何一项创建::h]h在许多情况下,没必要自己去创建一组文件操作;对于一些简单的情况,debugfs代码提供 了许多帮助函数。包含单个整数值的文件可以使用以下任何一项创建:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKEhjhhubj5)}(hXvoid debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent, u8 *value); void debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent, u16 *value); struct dentry *debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent, u32 *value); void debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent, u64 *value);h]hXvoid debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent, u8 *value); void debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent, u16 *value); struct dentry *debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent, u32 *value); void debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent, u64 *value);}hjsbah}(h]h ]h"]h$]h&]hhuh1j4hhhKHhjhhubh)}(h这些文件支持读取和写入给定值。如果某个文件不支持写入,只需根据需要设置mode 参数位。这些文件中的值以十进制表示;如果需要使用十六进制,可以使用以下函数 替代::h]h这些文件支持读取和写入给定值。如果某个文件不支持写入,只需根据需要设置mode 参数位。这些文件中的值以十进制表示;如果需要使用十六进制,可以使用以下函数 替代:}(hj,hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKQhjhhubj5)}(hXvoid debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, u8 *value); void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, u16 *value); void debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, u32 *value); void debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, u64 *value);h]hXvoid debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, u8 *value); void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, u16 *value); void debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, u32 *value); void debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, u64 *value);}hj:sbah}(h]h ]h"]h$]h&]hhuh1j4hhhKUhjhhubh)}(h这些功能只有在开发人员知道导出值的大小的时候才有用。某些数据类型在不同的架构上 有不同的宽度,这样会使情况变得有些复杂。在这种特殊情况下可以使用以下函数::h]h这些功能只有在开发人员知道导出值的大小的时候才有用。某些数据类型在不同的架构上 有不同的宽度,这样会使情况变得有些复杂。在这种特殊情况下可以使用以下函数:}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK^hjhhubj5)}(h|void debugfs_create_size_t(const char *name, umode_t mode, struct dentry *parent, size_t *value);h]h|void debugfs_create_size_t(const char *name, umode_t mode, struct dentry *parent, size_t *value);}hjVsbah}(h]h ]h"]h$]h&]hhuh1j4hhhKahjhhubh)}(hX不出所料,此函数将创建一个debugfs文件来表示类型为size_t的变量。h]hX不出所料,此函数将创建一个debugfs文件来表示类型为size_t的变量。}(hjdhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKdhjhhubh)}(hk同样地,也有导出无符号长整型变量的函数,分别以十进制和十六进制表示如下::h]hj同样地,也有导出无符号长整型变量的函数,分别以十进制和十六进制表示如下:}(hjrhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKfhjhhubj5)}(hX7struct dentry *debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent, unsigned long *value); void debugfs_create_xul(const char *name, umode_t mode, struct dentry *parent, unsigned long *value);h]hX7struct dentry *debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent, unsigned long *value); void debugfs_create_xul(const char *name, umode_t mode, struct dentry *parent, unsigned long *value);}hjsbah}(h]h ]h"]h$]h&]hhuh1j4hhhKhhjhhubh)}(h6布尔值可以通过以下方式放置在debugfs中::h]h5布尔值可以通过以下方式放置在debugfs中:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKnhjhhubj5)}(hstruct dentry *debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent, bool *value);h]hstruct dentry *debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent, bool *value);}hjsbah}(h]h ]h"]h$]h&]hhuh1j4hhhKphjhhubh)}(h读取结果文件将产生Y(对于非零值)或N,后跟换行符写入的时候,它只接受大写或小写 值或1或0。任何其他输入将被忽略。h]h读取结果文件将产生Y(对于非零值)或N,后跟换行符写入的时候,它只接受大写或小写 值或1或0。任何其他输入将被忽略。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKthjhhubh)}(h;同样,atomic_t类型的值也可以放置在debugfs中::h]h:同样,atomic_t类型的值也可以放置在debugfs中:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKwhjhhubj5)}(hvoid debugfs_create_atomic_t(const char *name, umode_t mode, struct dentry *parent, atomic_t *value)h]hvoid debugfs_create_atomic_t(const char *name, umode_t mode, struct dentry *parent, atomic_t *value)}hjsbah}(h]h ]h"]h$]h&]hhuh1j4hhhKyhjhhubh)}(hL读取此文件将获得atomic_t值,写入此文件将设置atomic_t值。h]hL读取此文件将获得atomic_t值,写入此文件将设置atomic_t值。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK|hjhhubh)}(hV另一个选择是通过以下结构体和函数导出一个任意二进制数据块::h]hU另一个选择是通过以下结构体和函数导出一个任意二进制数据块:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK~hjhhubj5)}(hX struct debugfs_blob_wrapper { void *data; unsigned long size; }; struct dentry *debugfs_create_blob(const char *name, umode_t mode, struct dentry *parent, struct debugfs_blob_wrapper *blob);h]hX struct debugfs_blob_wrapper { void *data; unsigned long size; }; struct dentry *debugfs_create_blob(const char *name, umode_t mode, struct dentry *parent, struct debugfs_blob_wrapper *blob);}hjsbah}(h]h ]h"]h$]h&]hhuh1j4hhhKhjhhubh)}(hXj读取此文件将返回由指针指向debugfs_blob_wrapper结构体的数据。一些驱动使用“blobs” 作为一种返回几行(静态)格式化文本的简单方法。这个函数可用于导出二进制信息,但 似乎在主线中没有任何代码这样做。请注意,使用debugfs_create_blob()命令创建的 所有文件是只读的。h]hXj读取此文件将返回由指针指向debugfs_blob_wrapper结构体的数据。一些驱动使用“blobs” 作为一种返回几行(静态)格式化文本的简单方法。这个函数可用于导出二进制信息,但 似乎在主线中没有任何代码这样做。请注意,使用debugfs_create_blob()命令创建的 所有文件是只读的。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hX如果您要转储一个寄存器块(在开发过程中经常会这么做,但是这样的调试代码很少上传 到主线中。Debugfs提供两个函数:一个用于创建仅寄存器文件,另一个把一个寄存器块 插入一个顺序文件中::h]hX如果您要转储一个寄存器块(在开发过程中经常会这么做,但是这样的调试代码很少上传 到主线中。Debugfs提供两个函数:一个用于创建仅寄存器文件,另一个把一个寄存器块 插入一个顺序文件中:}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj5)}(hXstruct debugfs_reg32 { char *name; unsigned long offset; }; struct debugfs_regset32 { struct debugfs_reg32 *regs; int nregs; void __iomem *base; }; struct dentry *debugfs_create_regset32(const char *name, umode_t mode, struct dentry *parent, struct debugfs_regset32 *regset); void debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs, int nregs, void __iomem *base, char *prefix);h]hXstruct debugfs_reg32 { char *name; unsigned long offset; }; struct debugfs_regset32 { struct debugfs_reg32 *regs; int nregs; void __iomem *base; }; struct dentry *debugfs_create_regset32(const char *name, umode_t mode, struct dentry *parent, struct debugfs_regset32 *regset); void debugfs_print_regs32(struct seq_file *s, struct debugfs_reg32 *regs, int nregs, void __iomem *base, char *prefix);}hjsbah}(h]h ]h"]h$]h&]hhuh1j4hhhKhjhhubh)}(h“base”参数可能为0,但您可能需要使用__stringify构建reg32数组,实际上有许多寄存器 名称(宏)是寄存器块在基址上的字节偏移量。h]h“base”参数可能为0,但您可能需要使用__stringify构建reg32数组,实际上有许多寄存器 名称(宏)是寄存器块在基址上的字节偏移量。}(hj(hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hN如果要在debugfs中转储u32数组,可以使用以下函数创建文件::h]hM如果要在debugfs中转储u32数组,可以使用以下函数创建文件:}(hj6hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj5)}(hvoid debugfs_create_u32_array(const char *name, umode_t mode, struct dentry *parent, u32 *array, u32 elements);h]hvoid debugfs_create_u32_array(const char *name, umode_t mode, struct dentry *parent, u32 *array, u32 elements);}hjDsbah}(h]h ]h"]h$]h&]hhuh1j4hhhKhjhhubh)}(h“array”参数提供数据,而“elements”参数为数组中元素的数量。注意:数组创建后,数组 大小无法更改。h]h“array”参数提供数据,而“elements”参数为数组中元素的数量。注意:数组创建后,数组 大小无法更改。}(hjRhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h4有一个函数来创建与设备相关的seq_file::h]h3有一个函数来创建与设备相关的seq_file:}(hj`hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj5)}(hXstruct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name, struct dentry *parent, int (*read_fn)(struct seq_file *s, void *data));h]hXstruct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name, struct dentry *parent, int (*read_fn)(struct seq_file *s, void *data));}hjnsbah}(h]h ]h"]h$]h&]hhuh1j4hhhKhjhhubh)}(h“dev”参数是与此debugfs文件相关的设备,并且“read_fn”是一个函数指针,这个函数在 打印seq_file内容的时候被回调。h]h“dev”参数是与此debugfs文件相关的设备,并且“read_fn”是一个函数指针,这个函数在 打印seq_file内容的时候被回调。}(hj|hhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h,还有一些其他的面向目录的函数::h]h+还有一些其他的面向目录的函数:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj5)}(hXstruct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, struct dentry *new_dir, const char *new_name); struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, const char *target);h]hXstruct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry, struct dentry *new_dir, const char *new_name); struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, const char *target);}hjsbah}(h]h ]h"]h$]h&]hhuh1j4hhhKhjhhubh)}(h调用debugfs_rename()将为现有的debugfs文件重命名,可能同时切换目录。 new_name 函数调用之前不能存在;返回值为old_dentry,其中包含更新的信息。可以使用 debugfs_create_symlink()创建符号链接。h]h调用debugfs_rename()将为现有的debugfs文件重命名,可能同时切换目录。 new_name 函数调用之前不能存在;返回值为old_dentry,其中包含更新的信息。可以使用 debugfs_create_symlink()创建符号链接。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h1所有debugfs用户必须考虑的一件事是:h]h1所有debugfs用户必须考虑的一件事是:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(hXdebugfs不会自动清除在其中创建的任何目录。如果一个模块在不显式删除debugfs目录的 情况下卸载模块,结果将会遗留很多野指针,从而导致系统不稳定。因此,所有debugfs 用户-至少是那些可以作为模块构建的用户-必须做模块卸载的时候准备删除在此创建的 所有文件和目录。一份文件可以通过以下方式删除::h]hXdebugfs不会自动清除在其中创建的任何目录。如果一个模块在不显式删除debugfs目录的 情况下卸载模块,结果将会遗留很多野指针,从而导致系统不稳定。因此,所有debugfs 用户-至少是那些可以作为模块构建的用户-必须做模块卸载的时候准备删除在此创建的 所有文件和目录。一份文件可以通过以下方式删除:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj5)}(h+void debugfs_remove(struct dentry *dentry);h]h+void debugfs_remove(struct dentry *dentry);}hjsbah}(h]h ]h"]h$]h&]hhuh1j4hhhKhjhhubh)}(h[dentry值可以为NULL或错误值,在这种情况下,不会有任何文件被删除。h]h[dentry值可以为NULL或错误值,在这种情况下,不会有任何文件被删除。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h很久以前,内核开发者使用debugfs时需要记录他们创建的每个dentry指针,以便最后所有 文件都可以被清理掉。但是,现在debugfs用户能调用以下函数递归清除之前创建的文件::h]h很久以前,内核开发者使用debugfs时需要记录他们创建的每个dentry指针,以便最后所有 文件都可以被清理掉。但是,现在debugfs用户能调用以下函数递归清除之前创建的文件:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubj5)}(h5void debugfs_remove_recursive(struct dentry *dentry);h]h5void debugfs_remove_recursive(struct dentry *dentry);}hjsbah}(h]h ]h"]h$]h&]hhuh1j4hhhKhjhhubh)}(hr如果将对应顶层目录的dentry传递给以上函数,则该目录下的整个层次结构将会被删除。h]hr如果将对应顶层目录的dentry传递给以上函数,则该目录下的整个层次结构将会被删除。}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhjhhubh)}(h-注释: [1] http://lwn.net/Articles/309298/h](h注释: [1] }(hjhhhNhNubjM)}(hhttp://lwn.net/Articles/309298/h]hhttp://lwn.net/Articles/309298/}(hjhhhNhNubah}(h]h ]h"]h$]h&]refurij uh1jLhjubeh}(h]h ]h"]h$]h&]uh1hhhhKhjhhubeh}(h]debugfsah ]h"]debugfsah$]h&]uh1jhhhhhhhK ubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(jN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerj^error_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourceh _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}j8j5s nametypes}j8sh}j5js footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]hsystem_message)}(hhh]h)}(hfPossible title underline, too short for the title. Treating it as ordinary text because it's so short.h]hhPossible title underline, too short for the title. Treating it as ordinary text because it’s so short.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjubah}(h]h ]h"]h$]h&]levelKtypeINFOlineK sourcehuh1jhjhhhhhK ubatransform_messages] transformerN include_log]8Documentation/translations/zh_CN/filesystems/debugfs.rst(NNNNta decorationNhhub.