Linux 文件系统 API 概述¶
本节包含 API 级别的文档,主要来自源代码本身。
Linux VFS¶
文件系统类型¶
-
enum positive_aop_returns¶
具有特定语义的 aop 返回代码
常量
AOP_WRITEPAGE_ACTIVATE
通知调用者页面写回已完成,该页面仍处于锁定状态,并且应被视为活动状态。 VM 使用此提示将页面返回到活动列表 - 在不久的将来它不会再次成为写回的候选者。 其他调用者必须小心,如果他们获得此返回值,则解锁页面。 由 writepage() 返回;
AOP_TRUNCATED_PAGE
已传递锁定页面的 AOP 方法已将其解锁,并且该页面可能已被截断。 调用者应该备份到获取一个新页面并再次尝试。 aop 将采取合理的预防措施,以防止发生死锁。 如果调用者持有页面引用,则在重试之前应将其删除。 由 read_folio() 返回。
描述
address_space_operation 函数返回这些大的常量,以向调用者指示特殊的语义。 这些常量远大于页面中的字节数,以便允许函数返回给定页面中操作的字节数。
-
struct address_space¶
可缓存、可映射对象的内容。
定义:
struct address_space {
struct inode *host;
struct xarray i_pages;
struct rw_semaphore invalidate_lock;
gfp_t gfp_mask;
atomic_t i_mmap_writable;
#ifdef CONFIG_READ_ONLY_THP_FOR_FS;
atomic_t nr_thps;
#endif;
struct rb_root_cached i_mmap;
unsigned long nrpages;
pgoff_t writeback_index;
const struct address_space_operations *a_ops;
unsigned long flags;
errseq_t wb_err;
spinlock_t i_private_lock;
struct list_head i_private_list;
struct rw_semaphore i_mmap_rwsem;
void * i_private_data;
};
成员
host
所有者,inode 或 block_device。
i_pages
缓存的页面。
invalidate_lock
在无效期间,保护页面缓存内容和文件偏移量->磁盘块映射之间的连贯性。 它还用于阻止通过内存映射修改页面缓存内容。
gfp_mask
用于分配页面的内存分配标志。
i_mmap_writable
VM_SHARED、VM_MAYWRITE 映射的数量。
nr_thps
页面缓存中 THP 的数量(仅限非 shmem)。
i_mmap
私有和共享映射的树。
nrpages
页面条目的数量,由 i_pages 锁保护。
writeback_index
写回从这里开始。
a_ops
方法。
flags
错误位和标志 (AS_*)。
wb_err
最近发生的错误。
i_private_lock
供 address_space 的所有者使用。
i_private_list
供 address_space 的所有者使用。
i_mmap_rwsem
保护 i_mmap 和 i_mmap_writable。
i_private_data
供 address_space 的所有者使用。
-
struct file_ra_state¶
跟踪文件的预读状态。
定义:
struct file_ra_state {
pgoff_t start;
unsigned int size;
unsigned int async_size;
unsigned int ra_pages;
unsigned int mmap_miss;
loff_t prev_pos;
};
成员
start
最近一次预读开始的位置。
size
最近一次预读中读取的页数。
async_size
不需要立即使用,因此确实是“超前”的页数。 当访问这些页面的第一页时,启动下一次预读。
ra_pages
预读请求的最大大小,从 bdi 复制。
mmap_miss
页面缓存中有多少 mmap 访问未命中。
prev_pos
最近一次读取请求中的最后一个字节。
描述
当此结构传递给 ->readahead() 时,“最近”的预读意味着当前的预读。
-
struct file¶
表示一个文件
定义:
struct file {
spinlock_t f_lock;
fmode_t f_mode;
const struct file_operations *f_op;
struct address_space *f_mapping;
void *private_data;
struct inode *f_inode;
unsigned int f_flags;
unsigned int f_iocb_flags;
const struct cred *f_cred;
struct fown_struct *f_owner;
struct path f_path;
union {
struct mutex f_pos_lock;
u64 f_pipe;
};
loff_t f_pos;
#ifdef CONFIG_SECURITY;
void *f_security;
#endif;
errseq_t f_wb_err;
errseq_t f_sb_err;
#ifdef CONFIG_EPOLL;
struct hlist_head *f_ep;
#endif;
union {
struct callback_head f_task_work;
struct llist_node f_llist;
struct file_ra_state f_ra;
freeptr_t f_freeptr;
};
file_ref_t f_ref;
};
成员
f_lock
保护 f_ep、f_flags。 不能从 IRQ 上下文中获取。
f_mode
热路径中常用的 FMODE_* 标志
f_op
文件操作
f_mapping
可缓存、可映射对象的内容。
private_data
文件系统或驱动程序特定的数据
f_inode
缓存的 inode
f_flags
文件标志
f_iocb_flags
iocb 标志
f_cred
创建者/开启者的隐藏凭据
f_owner
文件所有者
f_path
文件的路径
{unnamed_union}
匿名
f_pos_lock
保护文件位置的锁
f_pipe
特定于管道
f_pos
文件位置
f_security
此文件的 LSM 安全上下文
f_wb_err
写回错误
f_sb_err
每个 sb 的写回错误
f_ep
此文件的所有 epoll 钩子的链接
{unnamed_union}
匿名
f_task_work
任务工作入口点
f_llist
工作队列入口点
f_ra
文件的预读状态
f_freeptr
SLAB_TYPESAFE_BY_RCU 文件缓存使用的指针(请勿触摸。)
f_ref
引用计数
-
vfsuid_t i_uid_into_vfsuid(struct mnt_idmap *idmap, const struct inode *inode)¶
根据 idmapping 映射 inode 的 i_uid
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
const struct inode *inode
要映射的 inode
返回
根据 idmap 映射的 whe inode 的 i_uid。 如果 inode 的 i_uid 没有映射,则返回 INVALID_VFSUID。
-
bool i_uid_needs_update(struct mnt_idmap *idmap, const struct iattr *attr, const struct inode *inode)¶
检查 inode 的 i_uid 是否需要更新
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
const struct iattr *attr
inode 的新属性
const struct inode *inode
要更新的 inode
描述
如果文件系统支持,请检查是否需要更新 $inode 的 i_uid 字段,并考虑 idmapped 挂载点。
返回
如果 inode 的 i_uid 字段需要更新,则为 true;否则为 false。
-
void i_uid_update(struct mnt_idmap *idmap, const struct iattr *attr, struct inode *inode)¶
更新 inode 的 i_uid 字段
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
const struct iattr *attr
inode 的新属性
struct inode *inode
要更新的 inode
描述
安全地更新 inode 的 i_uid 字段,将任何 idmapped 挂载点的 vfsuid 转换为文件系统 kuid。
-
vfsgid_t i_gid_into_vfsgid(struct mnt_idmap *idmap, const struct inode *inode)¶
根据 idmapping 映射 inode 的 i_gid
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
const struct inode *inode
要映射的 inode
返回
根据 idmap 映射的 inode 的 i_gid。 如果 inode 的 i_gid 没有映射,则返回 INVALID_VFSGID。
-
bool i_gid_needs_update(struct mnt_idmap *idmap, const struct iattr *attr, const struct inode *inode)¶
检查 inode 的 i_gid 是否需要更新
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
const struct iattr *attr
inode 的新属性
const struct inode *inode
要更新的 inode
描述
如果文件系统支持,请检查是否需要更新 $inode 的 i_gid 字段,并考虑 idmapped 挂载点。
返回
如果 inode 的 i_gid 字段需要更新,则为 true;否则为 false。
-
void i_gid_update(struct mnt_idmap *idmap, const struct iattr *attr, struct inode *inode)¶
更新 inode 的 i_gid 字段
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
const struct iattr *attr
inode 的新属性
struct inode *inode
要更新的 inode
描述
安全地更新 inode 的 i_gid 字段,将任何 idmapped 挂载点的 vfsgid 转换为文件系统 kgid。
-
void inode_fsuid_set(struct inode *inode, struct mnt_idmap *idmap)¶
使用调用者的 fsuid 初始化 inode 的 i_uid 字段
参数
struct inode *inode
要初始化的 inode
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
描述
初始化 inode 的 i_uid 字段。 如果通过 idmapped 挂载点找到/创建了 inode,则根据 idmap 映射调用者的 fsuid。
-
void inode_fsgid_set(struct inode *inode, struct mnt_idmap *idmap)¶
使用调用者的 fsgid 初始化 inode 的 i_gid 字段
参数
struct inode *inode
要初始化的 inode
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
描述
初始化 inode 的 i_gid 字段。 如果通过 idmapped 挂载点找到/创建了 inode,则根据 idmap 映射调用者的 fsgid。
-
bool fsuidgid_has_mapping(struct super_block *sb, struct mnt_idmap *idmap)¶
检查是否映射了调用者的 fsuid/fsgid
参数
struct super_block *sb
我们想要在其中进行映射的超级块
struct mnt_idmap *idmap
相关挂载点的 idmap
描述
检查调用者的 fsuid 和 fsgid 在超级块 sb 的 s_user_ns 中是否具有有效的映射。 如果调用者位于 idmapped 挂载点,则首先根据 idmap 映射调用者的 fsuid 和 fsgid。
返回
如果映射了 fsuid 和 fsgid,则为 true;否则为 false。
参数
struct inode *inode
要在其中设置 ctime 的 inode
time64_t sec
要设置的 tv_sec 值
long nsec
要设置的 tv_nsec 值
描述
将 inode 中的 ctime 设置为 { sec, nsec }
-
int __sb_write_started(const struct super_block *sb, int level)¶
检查是否持有 sb 冻结级别
参数
const struct super_block *sb
我们要写入的 super
int level
冻结级别
描述
> 0 - 持有 sb 冻结级别
0 - 未持有 sb 冻结级别
< 0 - !CONFIG_LOCKDEP/LOCK_STATE_UNKNOWN
-
bool sb_write_started(const struct super_block *sb)¶
检查是否持有 SB_FREEZE_WRITE
参数
const struct super_block *sb
我们要写入的 super
描述
在 !CONFIG_LOCKDEP/LOCK_STATE_UNKNOWN 的情况下可能是误报。
-
bool sb_write_not_started(const struct super_block *sb)¶
检查是否未持有 SB_FREEZE_WRITE
参数
const struct super_block *sb
我们要写入的 super
描述
在 !CONFIG_LOCKDEP/LOCK_STATE_UNKNOWN 的情况下可能是误报。
参数
const struct file *file
我们要写入的文件
描述
在 !CONFIG_LOCKDEP/LOCK_STATE_UNKNOWN 的情况下可能是误报。在 !S_ISREG 的情况下可能是误报,因为 file_start_write()
对 !S_ISREG 没有影响。
参数
const struct file *file
我们要写入的文件
描述
在 !CONFIG_LOCKDEP/LOCK_STATE_UNKNOWN 的情况下可能是误报。在 !S_ISREG 的情况下可能是误报,因为 file_start_write()
对 !S_ISREG 没有影响。
-
void sb_end_write(struct super_block *sb)¶
释放对超级块的写访问权
参数
struct super_block *sb
我们写入的超级块
描述
减少文件系统的写入者数量。唤醒可能想要冻结文件系统的等待者。
-
void sb_end_pagefault(struct super_block *sb)¶
从页面错误中释放对超级块的写访问权
参数
struct super_block *sb
我们写入的超级块
描述
减少处理文件系统写入页面错误的进程数量。唤醒可能想要冻结文件系统的等待者。
-
void sb_end_intwrite(struct super_block *sb)¶
为了文件系统内部目的,释放对超级块的写访问权
参数
struct super_block *sb
我们写入的超级块
描述
减少文件系统内部写入者数量。唤醒可能想要冻结文件系统的等待者。
-
void sb_start_write(struct super_block *sb)¶
获取对超级块的写访问权
参数
struct super_block *sb
我们要写入的 super
描述
当进程想要向文件系统写入数据或元数据(即,弄脏页面或 inode)时,它应该将操作嵌入到 sb_start_write()
- sb_end_write()
对中,以获得针对文件系统冻结的互斥。此函数增加写入者数量,防止冻结。如果文件系统已经冻结,该函数将等待直到文件系统解冻。
由于冻结保护行为类似于锁,因此用户必须保持冻结保护和其他文件系统锁的顺序。通常,冻结保护应该是最外层的锁。特别是,我们有
- sb_start_write
-> i_mutex(写入路径、截断、目录操作...) -> s_umount(freeze_super、thaw_super)
-
void sb_start_pagefault(struct super_block *sb)¶
从页面错误中获取对超级块的写访问权
参数
struct super_block *sb
我们要写入的 super
描述
当进程开始处理写入页面错误时,它应该将操作嵌入到 sb_start_pagefault()
- sb_end_pagefault()
对中,以获得针对文件系统冻结的互斥。这是必需的,因为页面错误将会弄脏页面。此函数增加正在运行的页面错误数量,防止冻结。如果文件系统已经冻结,该函数将等待直到文件系统解冻。
由于页面错误冻结保护行为类似于锁,因此用户必须保持冻结保护和其他文件系统锁的顺序。建议将 sb_start_pagefault()
放置在锁定顺序中靠近 mmap_lock 的位置。页面错误处理代码暗示锁定依赖关系
- mmap_lock
-> sb_start_pagefault
-
void sb_start_intwrite(struct super_block *sb)¶
为了文件系统内部目的,获取对超级块的写访问权
参数
struct super_block *sb
我们要写入的 super
描述
这是防止文件系统冻结的第三级保护。文件系统可以自由使用它。唯一的要求是它必须低于 sb_start_pagefault。
例如,文件系统可以在启动事务时调用 sb_start_intwrite()
,这在一定程度上简化了文件系统更改的内部源(内部文件系统线程、在文件关闭时丢弃预分配等)的冻结处理。
-
struct renamedata¶
包含重命名所需的所有信息
定义:
struct renamedata {
struct mnt_idmap *old_mnt_idmap;
struct inode *old_dir;
struct dentry *old_dentry;
struct mnt_idmap *new_mnt_idmap;
struct inode *new_dir;
struct dentry *new_dentry;
struct inode **delegated_inode;
unsigned int flags;
};
成员
old_mnt_idmap
找到 inode 的旧挂载的 idmap
old_dir
源的父目录
old_dentry
源
new_mnt_idmap
找到 inode 的新挂载的 idmap
new_dir
目标的父目录
new_dentry
目标
delegated_inode
返回需要中断委托的 inode
flags
重命名标志
-
enum freeze_holder¶
冻结的持有者
常量
FREEZE_HOLDER_KERNEL
内核想要冻结或解冻文件系统
FREEZE_HOLDER_USERSPACE
用户空间想要冻结或解冻文件系统
FREEZE_MAY_NEST
是否允许嵌套冻结和解冻请求
FREEZE_EXCL
只能由所有者撤消的冻结
描述
指示冻结或解冻请求的所有者是谁,以及冻结是否需要是独占的或可以嵌套。如果没有 FREEZE_MAY_NEST,则不允许来自同一持有者的多个冻结和解冻请求。但是,允许同时持有单个 FREEZE_HOLDER_USERSPACE 和单个 FREEZE_HOLDER_KERNEL 冻结。某些文件系统在在线修复或类似过程中依赖于此。
参数
const struct inode *inode
要测试多粒度时间戳的 inode
描述
如果 inode 使用多粒度时间戳,则返回 true,否则返回 false。
-
bool is_idmapped_mnt(const struct vfsmount *mnt)¶
检查挂载是否已映射
参数
const struct vfsmount *mnt
要检查的挂载
描述
如果 mnt 附加了非 nop_mnt_idmap,则 mnt 已映射。
返回
如果挂载已映射,则为 true,否则为 false。
-
void kiocb_start_write(struct kiocb *iocb)¶
获取对异步文件 IO 的超级块的写访问权
参数
struct kiocb *iocb
我们想要提交写入的 IO 上下文
描述
这是 sb_start_write()
的变体,用于异步 IO 提交。应与对 kiocb_end_write()
的调用相匹配。
-
void kiocb_end_write(struct kiocb *iocb)¶
在异步文件 IO 之后释放对超级块的写访问权
-
bool is_dot_dotdot(const char *name, size_t len)¶
仅当 name 是“.”或“..”时才返回 true
参数
const char *name
要检查的文件名
size_t len
文件名的长度,以字节为单位
参数
struct inode *inode
直接 I/O 发生的 inode
描述
一旦我们完成了直接 I/O 请求的处理,就会调用此函数,并用于唤醒等待直接 I/O 静止的调用者。
参数
struct inode *inode
直接 I/O 发生的 inode
描述
一旦我们完成了直接 I/O 请求的处理,就会调用此函数,并用于唤醒等待直接 I/O 静止的调用者。
-
bool generic_ci_validate_strict_name(struct inode *dir, struct qstr *name)¶
检查给定的名称是否适合目录
参数
struct inode *dir
将在其中创建新文件的目录的 inode
struct qstr *name
新文件的名称
描述
此函数检查建议的文件名对于父目录是否有效。这意味着对于使用严格编码标志创建的文件系统中区分大小写折叠的目录,将仅接受有效的 UTF-8 文件名。这也意味着对于未启用区分大小写折叠或未严格编码的目录,将接受任何名称。
返回
True:如果文件名适合此目录。如果给定的名称不适合严格编码目录,但正在使用的目录不严格,则可能为 true
False:如果文件名不适合此目录。这仅在目录区分大小写折叠且文件系统对其编码严格时才会发生。
目录缓存¶
参数
struct dentry *dentry
要丢弃的 dentry
描述
d_drop()
从父 dentry 哈希中取消哈希条目,以便通过 VFS 查找不再找到它。请注意,这与删除 dentry 不同 - d_delete 将尝试尽可能将 dentry 标记为负数,从而给出成功的 _negative_ 查找,而 d_drop 只会使缓存查找失败。
d_drop()
主要用于想要因某种原因使 dentry 无效的组件(NFS 超时或 autofs 删除)。
__d_drop 需要 dentry->d_lock
___d_drop 不会将 dentry 标记为“未哈希”(dentry->d_hash.pprev 将是 LIST_POISON2,而不是 NULL)。
参数
struct inode *inode
要查找别名的 inode
描述
如果给定inode存在任何别名,则获取并返回其中一个别名的引用。如果不存在别名,则返回 NULL
。
参数
struct inode *inode
有问题的inode
描述
如果inode有一个哈希别名,或者是一个目录并且有任何别名,则获取对别名的引用并返回它。否则返回NULL。请注意,如果inode是一个目录,则只能有一个别名,并且只有在它没有子目录、或者它是文件系统的根目录、或者目录被重命名且d_revalidate是第一个注意到此点的VFS操作时,它才可能是不哈希的。
如果inode有一个IS_ROOT、DCACHE_DISCONNECTED别名,那么优先选择任何其他的哈希别名而不是该别名。
-
void shrink_dcache_sb(struct super_block *sb)¶
收缩超级块的dcache
参数
struct super_block *sb
超级块
描述
收缩指定超级块的dcache。这用于在卸载文件系统之前释放dcache。
-
int path_has_submounts(const struct path *parent)¶
检查当前命名空间中的dentry上是否存在挂载点。
参数
const struct path *parent
要检查的路径。
描述
如果父路径或其子目录包含当前命名空间中的挂载点,则返回true。
-
void shrink_dcache_parent(struct dentry *parent)¶
修剪dcache
参数
struct dentry *parent
要修剪的条目的父dentry
描述
修剪dcache以删除父dentry未使用的子条目。
参数
struct dentry *dentry
要失效的dentry(也就是分离、修剪和删除)
-
struct dentry *d_alloc(struct dentry *parent, const struct qstr *name)¶
分配一个dcache条目
参数
struct dentry * parent
要分配的条目的父条目
const struct qstr *name
名称的qstr
描述
分配一个dentry。如果可用内存不足,则返回NULL
。成功后,将返回dentry。传入的名称将被复制,并且在此调用后可以重复使用传入的副本。
参数
struct dentry *entry
要完成的dentry
struct inode * inode
要附加到此dentry的inode
描述
填写条目中的inode信息。
这将使负dentry变成社会中有用的完全成员。
注意!这假定inode计数已由调用者递增(或以其他方式设置),以指示它现在正被dcache使用。
参数
struct inode *inode
要为其分配dentry的inode
描述
获取用于NFS文件句柄转换或类似通过句柄操作打开的inode的dentry。返回的dentry可能是匿名的,或者可能具有完整的名称(如果inode已在缓存中)。
当在目录inode上调用时,我们必须确保inode只有一个dentry。如果找到dentry,则返回该dentry而不是分配新的dentry。
在成功返回时,inode的引用已转移到dentry。如果发生错误,则释放inode上的引用。为了更容易在导出操作中使用,可以传入NULL
或IS_ERR的inode,并且错误将传播到返回值,NULL
inode替换为ERR_PTR(-ESTALE)。
参数
struct inode *inode
要为其分配dentry的inode
描述
获取文件系统根的IS_ROOT dentry。
我们必须确保目录inode只有一个dentry。如果找到dentry,则返回该dentry而不是分配新的dentry。
在成功返回时,inode的引用已转移到dentry。如果发生错误,则释放inode上的引用。可以传入NULL
或IS_ERR的inode,并且错误将传播到返回值,NULL
inode替换为ERR_PTR(-ESTALE)。
-
struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode, struct qstr *name)¶
查找或分配具有区分大小写名称的新dentry
参数
struct dentry *dentry
传递给父条目的lookup函数的负dentry
struct inode *inode
不区分大小写查找发现的inode
struct qstr *name
要与返回的dentry关联的区分大小写的名称
描述
这是为了避免用不区分大小写的名称填充dcache到同一个inode,只有实际正确的区分大小写的名称存储在不区分大小写的文件系统的dcache中。
对于不区分大小写的查找匹配,并且如果区分大小写的dentry已存在于dcache中,则使用它并返回它。
如果不存在具有区分大小写的名称的条目,则分配具有区分大小写的名称的新dentry,并返回拼接的条目。
-
bool d_same_name(const struct dentry *dentry, const struct dentry *parent, const struct qstr *name)¶
将dentry名称与区分大小写的名称进行比较
参数
const struct dentry *dentry
传递给父条目的lookup函数的负dentry
const struct dentry *parent
父dentry
const struct qstr *name
要与返回的dentry关联的区分大小写的名称
返回
如果名称相同,则为true,否则为false
-
struct dentry *d_lookup(const struct dentry *parent, const struct qstr *name)¶
搜索dentry
参数
const struct dentry *parent
父dentry
const struct qstr *name
我们希望找到的名称的qstr
返回
dentry或NULL
描述
d_lookup搜索父dentry的子条目以查找有问题的名称。如果找到dentry,则其引用计数将递增并返回dentry。调用者必须使用dput在完成使用后释放该条目。如果dentry不存在,则返回NULL
。
参数
struct dentry * dentry
要删除的dentry
描述
如果可能,将dentry转换为负dentry,否则将其从哈希队列中删除,以便以后可以删除它
-
void d_rehash(struct dentry *entry)¶
将条目添加回哈希
参数
struct dentry * entry
要添加到哈希的dentry
描述
根据dentry的名称将其添加到哈希。
参数
struct dentry *entry
要添加的dentry
struct inode *inode
要附加到此dentry的inode
描述
这会将条目添加到哈希队列并初始化 inode。该条目实际上是在之前的d_alloc()
期间填充的。
参数
struct inode *inode
可能具有断开连接的dentry的inode
struct dentry *dentry
我们希望指向inode的负dentry。
描述
如果inode是一个目录并且具有IS_ROOT别名,则d_move它以代替给定的dentry并返回它,否则只需将inode d_add到dentry并返回NULL。
如果找到非IS_ROOT目录,则文件系统已损坏,我们应该报错:目录不能有多个别名。
任何可导出的文件系统(通过knfsd)的查找例程中都需要此功能,以便我们可以有效地构建到目录的dcache路径。
如果找到并移动了dentry,则返回它。否则返回NULL。这与->lookup的预期返回值匹配。
集群文件系统可以使用已哈希的负dentry调用此函数。在这种情况下,我们知道inode将是一个常规文件,并且这只会发生在atomic_open期间。因此,我们只需要在最后一种情况下检查dentry是否已经哈希。
-
bool is_subdir(struct dentry *new_dentry, struct dentry *old_dentry)¶
new_dentry是否是old_dentry的子目录
参数
struct dentry *new_dentry
新的dentry
struct dentry *old_dentry
旧的dentry
描述
如果new_dentry是父条目的子目录(在任何深度),则返回true。否则返回false。调用者必须确保在调用is_subdir()
之前固定“new_dentry”
参数
struct dentry *dentry
要获取引用的dentry
描述
给定一个活动的dentry,递增引用计数并返回dentry。调用者必须持有 dentry->d_lock。确保dentry处于活动状态是调用者的责任。有很多条件足以保证这一点;例如,任何具有非负引用计数的条目都是活动的,任何哈希的条目、任何正条目、任何条目的父条目等等。
参数
struct dentry *dentry
要获取引用的dentry
描述
给定一个dentry或NULL
指针,如果合适,则递增引用计数并返回dentry。当dentry具有引用时,不会销毁dentry。相反,没有引用的dentry可能会因多种原因而消失,从内存压力开始。换句话说,该原语用于克隆现有引用;在引用计数为零的对象上使用它是bug。
注意
如果持有 dentry->d_lock,它将旋转。从避免死锁的角度来看,它等同于spin_lock()/递增引用计数/spin_unlock(),因此在 dentry->d_lock下调用它始终是bug;在它的任何子条目上在->d_lock下调用它也是如此。
参数
const struct dentry *dentry
要检查的条目
描述
如果传递的 dentry 当前未哈希,则返回 true。
参数
const struct dentry *dentry
有问题的 dentry
描述
如果 dentry 表示一个不存在的名称或一个不映射到 inode 的名称(即 ->d_inode 为 NULL),则返回 true。dentry 可以表示一个真正的未命中,一个不由 0,0 chardev 表示的 whiteout,或者一个不透明目录中的 fallthrough 标记。
注意!(1)这应该仅由文件系统使用来检查它自己的 dentry。不应该用于查看其他文件系统的 dentry。(2)它也应该与 d_inode()
结合使用来获取 inode。(3)dentry 可能有一些东西附加到 ->d_lower,并且标志的类型字段可能被设置为除 miss 或 whiteout 之外的其他东西。
参数
const struct dentry *dentry
有问题的 dentry
描述
如果 dentry 表示一个映射到 inode 的名称(即 ->d_inode 不为 NULL),则返回 true。如果 whiteout 在介质上表示为 0,0 chardev,则 dentry 仍然可能表示一个 whiteout。
注意!(1)这应该仅由文件系统使用来检查它自己的 dentry。不应该用于查看其他文件系统的 dentry。(2)它也应该与 d_inode()
结合使用来获取 inode。
参数
const struct dentry *dentry
要查询的 dentry
描述
这是普通文件系统应该用来获取它们自己的 inode 在它们自己的 dentry 中的助手函数,并忽略叠加在它们之上的分层。
参数
const struct dentry *dentry
要查询的 dentry
描述
这是普通文件系统应该用来获取它们自己的 inode 在它们自己的 dentry 中的助手函数,并忽略叠加在它们之上的分层。
-
struct inode *d_backing_inode(const struct dentry *upper)¶
获取我们应该使用的上层或下层 inode
参数
const struct dentry *upper
上层
描述
这是应该用来获取 inode 的助手函数,如果这个 dentry 要作为文件打开,将会使用该 inode。inode 可能在上层 dentry 上,也可能在由上层固定的下层 dentry 上。
普通文件系统不应该使用它来访问它们自己的 inode。
参数
struct dentry *dentry
要查询的 dentry
enum d_real_type type
真实 dentry 的类型(数据或元数据)
描述
如果 dentry 在 union/overlay 上,则返回底层的真实 dentry。否则返回 dentry 本身。
另请参阅:Linux 虚拟文件系统概述
参数
const struct dentry *dentry
要查询的 dentry
描述
如果 dentry 在 union/overlay 上,则返回底层的真实 inode。否则返回 d_inode()
。
Inode 处理¶
参数
struct super_block *sb
inode 所属的超级块
struct inode *inode
要初始化的 inode
gfp_t gfp
分配标志
描述
这些是在每次 inode 分配时都需要完成的初始化,因为这些字段没有被 slab 分配初始化。如果需要额外的分配,则使用 gfp。
参数
struct inode *inode
inode
描述
这是一个低级文件系统助手,用于替换任何对 i_nlink 的直接文件系统操作。在我们尝试跟踪对文件系统的写入的情况下,减为零意味着当文件被截断并在文件系统上实际取消链接时,即将进行写入。
参数
struct inode *inode
inode
描述
这是一个低级文件系统助手,用于替换任何对 i_nlink 的直接文件系统操作。有关我们为什么关心 i_nlink 达到零的信息,请参阅 drop_nlink()
。
参数
struct inode *inode
inode
unsigned int nlink
新的 nlink(应为非零)
描述
这是一个低级文件系统助手,用于替换任何对 i_nlink 的直接文件系统操作。
参数
struct inode *inode
inode
描述
这是一个低级文件系统助手,用于替换任何对 i_nlink 的直接文件系统操作。目前,它只是为了与 dec_nlink() 保持一致。
参数
struct inode *inode
要添加的 inode
参数
struct inode *inode
未哈希的 inode
unsigned long hashval
用于在 inode_hashtable 中定位此对象的 unsigned long 值。
将 inode 添加到此超级块的 inode 哈希中。
参数
struct inode *inode
要取消哈希的 inode
从超级块中删除一个 inode。
-
void evict_inodes(struct super_block *sb)¶
逐出超级块的所有可逐出的 inode
参数
struct super_block *sb
要操作的超级块
描述
确保不保留任何具有零引用计数的 inode。这在移除 SB_ACTIVE 标志后由超级块关闭调用,因此在此调用期间或之后达到零引用计数的任何 inode 将立即被逐出。
-
struct inode *new_inode(struct super_block *sb)¶
获取一个 inode
参数
struct super_block *sb
超级块
为给定的超级块分配一个新的 inode。与 inode->i_mapping 相关的分配的默认 gfp_mask 是 GFP_HIGHUSER_MOVABLE。如果 HIGHMEM 页面不合适,或者已知为页面缓存分配的页面不可回收或不可迁移,则必须使用新创建的 inode 映射上的适当标志调用 mapping_set_gfp_mask()
参数
struct inode *inode
要解锁的新 inode
描述
当 inode 完全初始化时调用,以清除 inode 的新状态并唤醒任何等待 inode 完成初始化的人。
-
void lock_two_nondirectories(struct inode *inode1, struct inode *inode2)¶
在非目录对象上获取两个 i_mutex
参数
struct inode *inode1
要锁定的第一个 inode
struct inode *inode2
要锁定的第二个 inode
描述
锁定任何非 NULL 参数。传递的对象不能是目录。此函数可以锁定零个、一个或两个对象。
-
void unlock_two_nondirectories(struct inode *inode1, struct inode *inode2)¶
参数
struct inode *inode1
要解锁的第一个 inode
struct inode *inode2
要解锁的第二个 inode
-
struct inode *inode_insert5(struct inode *inode, unsigned long hashval, int (*test)(struct inode*, void*), int (*set)(struct inode*, void*), void *data)¶
从已挂载的文件系统获取一个 inode
参数
struct inode *inode
用于插入到缓存的预分配 inode
unsigned long hashval
要获取的哈希值(通常是 inode 编号)
int (*test)(struct inode *, void *)
用于比较 inode 之间的回调
int (*set)(struct inode *, void *)
用于初始化新 struct inode 的回调函数
void *data
传递给 test 和 set 的不透明数据指针
描述
在 inode 缓存中搜索由 hashval 和 data 指定的 inode,如果存在,则返回它并增加引用计数。 这是 iget5_locked()
的一个变体,它不分配 inode。
如果 inode 不在缓存中,则插入预先分配的 inode 并返回它,此时它是被锁定的、已哈希的,并且设置了 I_NEW 标志。文件系统可以在通过 unlock_new_inode()
解锁它之前填充它。
请注意,test 和 set 都是在持有 inode_hash_lock 的情况下调用的,因此它们无法睡眠。
-
struct inode *iget5_locked(struct super_block *sb, unsigned long hashval, int (*test)(struct inode*, void*), int (*set)(struct inode*, void*), void *data)¶
从已挂载的文件系统获取一个 inode
参数
struct super_block *sb
文件系统的超级块
unsigned long hashval
要获取的哈希值(通常是 inode 编号)
int (*test)(struct inode *, void *)
用于比较 inode 之间的回调
int (*set)(struct inode *, void *)
用于初始化新 struct inode 的回调函数
void *data
传递给 test 和 set 的不透明数据指针
描述
在 inode 缓存中搜索由 hashval 和 data 指定的 inode,如果存在,则返回它并增加引用计数。 这是 iget_locked()
的一个通用版本,用于 inode 编号不足以唯一标识 inode 的文件系统。
如果 inode 不在缓存中,则分配并插入一个新的 inode 并返回它,此时它是被锁定的、已哈希的,并且设置了 I_NEW 标志。文件系统可以在通过 unlock_new_inode()
解锁它之前填充它。
请注意,test 和 set 都是在持有 inode_hash_lock 的情况下调用的,因此它们无法睡眠。
-
struct inode *iget5_locked_rcu(struct super_block *sb, unsigned long hashval, int (*test)(struct inode*, void*), int (*set)(struct inode*, void*), void *data)¶
从已挂载的文件系统获取一个 inode
参数
struct super_block *sb
文件系统的超级块
unsigned long hashval
要获取的哈希值(通常是 inode 编号)
int (*test)(struct inode *, void *)
用于比较 inode 之间的回调
int (*set)(struct inode *, void *)
用于初始化新 struct inode 的回调函数
void *data
传递给 test 和 set 的不透明数据指针
描述
这等效于 iget5_locked,但 test 回调必须容忍 inode 不稳定,包括正在拆卸过程中。
-
struct inode *iget_locked(struct super_block *sb, unsigned long ino)¶
从已挂载的文件系统获取一个 inode
参数
struct super_block *sb
文件系统的超级块
unsigned long ino
要获取的 inode 编号
描述
在 inode 缓存中搜索由 ino 指定的 inode,如果存在,则返回它并增加引用计数。 这适用于 inode 编号足以唯一标识 inode 的文件系统。
如果 inode 不在缓存中,则分配一个新的 inode 并返回它,此时它是被锁定的、已哈希的,并且设置了 I_NEW 标志。文件系统可以在通过 unlock_new_inode()
解锁它之前填充它。
-
ino_t iunique(struct super_block *sb, ino_t max_reserved)¶
获取唯一的 inode 编号
参数
struct super_block *sb
超级块
ino_t max_reserved
最高保留的 inode 编号
获取对于给定的超级块在系统上唯一的 inode 编号。 这适用于没有自然永久 inode 编号系统的文件系统。 返回的 inode 编号高于保留限制但唯一。
错误:如果文件系统上有大量 inode,则此函数目前会变得非常慢。
-
struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval, int (*test)(struct inode*, void*), void *data)¶
在 inode 缓存中搜索 inode
参数
struct super_block *sb
要搜索的文件系统的超级块
unsigned long hashval
要搜索的哈希值(通常是 inode 编号)
int (*test)(struct inode *, void *)
用于比较 inode 之间的回调
void *data
传递给 test 的不透明数据指针
描述
在 inode 缓存中搜索由 hashval 和 data 指定的 inode。 如果 inode 在缓存中,则返回该 inode 并增加引用计数。
注意2:test 是在持有 inode_hash_lock 的情况下调用的,因此无法睡眠。
注意
I_NEW 不会被等待,因此您必须非常小心如何处理返回的 inode。 您可能应该使用 ilookup5()
来代替。
-
struct inode *ilookup5(struct super_block *sb, unsigned long hashval, int (*test)(struct inode*, void*), void *data)¶
在 inode 缓存中搜索 inode
参数
struct super_block *sb
要搜索的文件系统的超级块
unsigned long hashval
要搜索的哈希值(通常是 inode 编号)
int (*test)(struct inode *, void *)
用于比较 inode 之间的回调
void *data
传递给 test 的不透明数据指针
描述
在 inode 缓存中搜索由 hashval 和 data 指定的 inode,如果 inode 在缓存中,则返回该 inode 并增加引用计数。 在返回 inode 之前等待 I_NEW。 返回的 inode 增加引用计数。
这是 ilookup()
的一个通用版本,用于 inode 编号不足以唯一标识 inode 的文件系统。
注意
test 是在持有 inode_hash_lock 的情况下调用的,因此无法睡眠。
-
struct inode *ilookup(struct super_block *sb, unsigned long ino)¶
在 inode 缓存中搜索 inode
参数
struct super_block *sb
要搜索的文件系统的超级块
unsigned long ino
要搜索的 inode 编号
描述
在 inode 缓存中搜索 inode ino,如果 inode 在缓存中,则返回该 inode 并增加引用计数。
-
struct inode *find_inode_nowait(struct super_block *sb, unsigned long hashval, int (*match)(struct inode*, unsigned long, void*), void *data)¶
在 inode 缓存中查找 inode
参数
struct super_block *sb
要搜索的文件系统的超级块
unsigned long hashval
要搜索的哈希值(通常是 inode 编号)
int (*match)(struct inode *, unsigned long, void *)
用于比较 inode 之间的回调
void *data
传递给 match 的不透明数据指针
描述
在 inode 缓存中搜索由 hashval 和 data 指定的 inode,其中辅助函数 match 将在 inode 不匹配时返回 0,在 inode 匹配时返回 1,在应停止搜索时返回 -1。 match 函数必须负责获取 i_lock 自旋锁并检查 i_state 以查找正在释放或正在初始化的 inode,并在返回 1 之前增加引用计数。 它也不能睡眠,因为它是在持有 inode_hash_lock 自旋锁的情况下调用的。
这是 ilookup5()
的更通用版本,当该函数绝不能阻塞时 --- find_inode() 可以在 __wait_on_freeing_inode() 中阻塞 --- 或者当调用者无法增加引用计数时,因为生成的 iput()
可能会导致 inode 逐出。 权衡之处在于,match 函数必须非常小心地实现。
-
struct inode *find_inode_rcu(struct super_block *sb, unsigned long hashval, int (*test)(struct inode*, void*), void *data)¶
在 inode 缓存中查找 inode
参数
struct super_block *sb
要搜索的文件系统的超级块
unsigned long hashval
要哈希的键
int (*test)(struct inode *, void *)
用于测试 inode 上的匹配项的函数
void *data
测试函数的数据
描述
在 inode 缓存中搜索由 hashval 和 data 指定的 inode,其中辅助函数 test 将在 inode 不匹配时返回 0,匹配时返回 1。 test 函数必须负责获取 i_lock 自旋锁并检查 i_state 以查找正在释放或正在初始化的 inode。
如果成功,这将返回 test 函数返回 1 的 inode,否则返回 NULL。
不允许 test 函数获取呈现的任何 inode 的引用。 也不允许睡眠。
调用者必须持有 RCU 读锁。
-
struct inode *find_inode_by_ino_rcu(struct super_block *sb, unsigned long ino)¶
在 inode 缓存中查找 inode
参数
struct super_block *sb
要搜索的文件系统的超级块
unsigned long ino
要匹配的 inode 编号
描述
在 inode 缓存中搜索由 hashval 和 data 指定的 inode,其中辅助函数 test 将在 inode 不匹配时返回 0,匹配时返回 1。 test 函数必须负责获取 i_lock 自旋锁并检查 i_state 以查找正在释放或正在初始化的 inode。
如果成功,这将返回 test 函数返回 1 的 inode,否则返回 NULL。
不允许 test 函数获取呈现的任何 inode 的引用。 也不允许睡眠。
调用者必须持有 RCU 读锁。
参数
struct inode *inode
要释放的 inode
释放一个 inode,删除其使用计数。 如果 inode 使用计数达到零,则释放该 inode,也可能被销毁。
因此,
iput()
可以睡眠。
参数
struct inode *inode
拥有所请求的块编号的 inode
sector_t *block
包含要查找的块的指针
将
*block
中的值替换为设备上保存与文件中所请求的块编号相对应的块的块编号。 也就是说,要求 inode 1 的块 4,该函数将*block
中的 4 替换为相对于磁盘开始处,保存该文件的块的磁盘块。如果发生错误,则返回 -EINVAL,否则返回 0。 如果映射落入一个空洞,则返回 0,并且
*block
也设置为 0。
参数
struct inode *inode
要更新的 inode
int flags
需要更新的 S_* 标志
描述
当需要为读取或写入操作更新 inode 的时间戳时,调用 update_time 函数。 此函数处理更新实际时间戳。 由调用者负责确保 inode 已被适当标记为脏。
在任何 S_MTIME、S_CTIME 或 S_VERSION 需要更新的情况下,尝试更新所有三个时间戳。 S_ATIME 更新可以独立于其余更新处理。
返回一组指示哪些值已更改的 S_* 标志。
参数
struct inode *inode
要更新的 inode
int flags
需要更新的 S_* 标志
描述
当需要为读取或写入操作更新 inode 的时间戳时,将调用 update_time 函数。 如果需要更新 S_MTIME、S_CTIME 或 S_VERSION 中的任何一个,我们将尝试更新所有这三个。 S_ATIME 的更新可以独立于其余部分进行处理。
返回一个 S_* 掩码,指示哪些字段已更新。
参数
struct file *file
要移除权限的文件
描述
当文件被写入或截断修改时,确保移除特殊文件权限。
返回
成功时返回 0,失败时返回负的 errno。
参数
struct inode *inode
inode。
描述
返回截断到文件系统支持的时间粒度的当前时间,适用于 ctime/mtime 更改。 如果 ctime 被标记为已 QUERIED,则获取细粒度的时间戳,但不要更新 floor。
对于 multigrain inode,这实际上是文件将收到的时间戳的估计值。 实际的更新必须通过 inode_set_ctime_current()
。
参数
struct file *file
访问的文件
描述
更新 inode 的 mtime 和 ctime 成员,并将 inode 标记为写回。 请注意,此函数专门用于文件系统的文件写入路径,并且文件系统可以选择使用 _NOCMTIME inode 标志显式忽略通过此函数进行的更新,例如,对于网络文件系统,这些时间戳由服务器处理。 对于需要分配空间才能更新 inode 的文件系统,这可能会返回错误。
返回
成功时返回 0,失败时返回负的 errno。
参数
struct file *file
已修改的文件
描述
当文件被修改时,确保移除特殊文件权限并更新时间设置。
上下文
调用者必须持有文件的 inode 锁。
返回
成功时返回 0,失败时返回负的 errno。
-
int kiocb_modified(struct kiocb *iocb)¶
处理修改文件时强制执行的 vfs 更改
参数
struct kiocb *iocb
已修改的 iocb
描述
当文件被修改时,确保移除特殊文件权限并更新时间设置。
上下文
调用者必须持有文件的 inode 锁。
返回
成功时返回 0,失败时返回负的 errno。
-
void inode_init_owner(struct mnt_idmap *idmap, struct inode *inode, const struct inode *dir, umode_t mode)¶
根据 posix 标准初始化新 inode 的 uid、gid、mode
参数
struct mnt_idmap *idmap
创建 inode 的挂载的 idmap
struct inode *inode
新的 inode
const struct inode *dir
目录 inode
umode_t mode
新 inode 的模式
描述
如果 inode 是通过 idmapped 挂载创建的,则必须通过 idmap 传递 vfsmount 的 idmap。 然后,此函数将负责根据 idmap 映射 inode,然后再检查权限并初始化 i_uid 和 i_gid。 在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
const struct inode *inode
正在检查的 inode
描述
如果当前用户在具有映射的 inode 所有者 uid 的命名空间中具有 CAP_FOWNER,或者拥有该文件,则返回 true。
如果 inode 是通过 idmapped 挂载找到的,则必须通过 idmap 传递 vfsmount 的 idmap。 然后,此函数将负责根据 idmap 映射 inode,然后再检查权限。 在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
参数
struct inode *inode
要等待的 inode
描述
等待所有挂起的直接 I/O 请求完成,以便我们可以继续进行截断或等效操作。
必须在序列化获取对 i_dio_count 的新引用的锁下调用,通常通过 inode->i_mutex。
参数
struct timespec64 t
Timespec
struct inode *inode
正在更新的 inode
描述
将 timespec 截断为包含 inode 的文件系统支持的粒度。 始终向下舍入。 gran 不得为 0,也不得大于 1 秒(NSEC_PER_SEC 或 10^9 纳秒)。
参数
struct inode *inode
inode
描述
将 inode 的 ctime 设置为 inode 的当前值。 返回已分配的当前值。 如果这不是 multigrain inode,则我们将其设置为粗略时间和 floor 值的较晚者。
如果是 multigrain,则我们首先查看粗粒度时间戳是否与已有的时间戳不同。 如果是,则使用它。 否则,获取细粒度时间戳。
之后,尝试将新值交换到 i_ctime_nsec 中。 接受结果 ctime,无论交换结果如何。 如果它已经被替换,则该时间戳晚于早期不可接受的时间戳,因此是可以接受的。
-
struct timespec64 inode_set_ctime_deleg(struct inode *inode, struct timespec64 update)¶
尝试更新委托 inode 上的 ctime
参数
struct inode *inode
要更新的 inode
struct timespec64 update
用于设置 ctime 的 timespec64
描述
尝试代表委托持有者原子地更新 ctime。
nfs 服务器可以回调委托的持有者以获取更新的 inode 属性,包括 mtime。 更新 mtime 时,将 ctime 更新为至少等于该值的值。
这可能会与对 inode 的并发更新竞争,在这种情况下,更新将被跳过。
请注意,即使未启用 multigrain 时间戳,这也可以工作,因此在任何一种情况下都会使用它。
-
bool in_group_or_capable(struct mnt_idmap *idmap, const struct inode *inode, vfsgid_t vfsgid)¶
检查调用方是否具有 CAP_FSETID 权限
参数
struct mnt_idmap *idmap
从 inode 中找到的挂载的 idmap
const struct inode *inode
要检查的 inode
vfsgid_t vfsgid
inode 的新/当前 vfsgid
描述
检查 vfsgid 是否在调用方的组列表中,或者调用方是否对 inode 具有 CAP_FSETID 权限。 这可以用于确定是否可以保留 setgid 位或必须删除它。
返回
如果调用方具有足够的权限,则为 true,否则为 false。
-
umode_t mode_strip_sgid(struct mnt_idmap *idmap, const struct inode *dir, umode_t mode)¶
处理非目录的 sgid 位
参数
struct mnt_idmap *idmap
创建 inode 的挂载的 idmap
const struct inode *dir
父目录 inode
umode_t mode
要在 dir 中创建的文件的模式
描述
如果新文件的 mode 同时提高了 S_ISGID 和 S_IXGRP 位,并且 dir 提高了 S_ISGID 位,则确保调用方要么在父目录的组中,要么在其用户命名空间中具有 CAP_FSETID 权限,并且对父目录具有权限。 在所有其他情况下,从 mode 中删除 S_ISGID 位。
返回
用于文件的新模式
参数
struct inode *inode
要标记为坏的 Inode
当由于介质或远程网络故障而无法读取 inode 时,此函数会使 inode “损坏”,并导致从此开始对其进行的 I/O 操作失败。
参数
struct inode *inode
要测试的 inode
如果问题中的 inode 已被标记为坏,则返回 true。
参数
struct inode *inode
要丢弃的 inode
描述
将正在构建的 inode 标记为死并释放它。
注册和超级块¶
-
void deactivate_locked_super(struct super_block *s)¶
删除对超级块的活动引用
参数
struct super_block *s
要停用的超级块
删除对超级块的活动引用,如果没有其他活动引用,则将其转换为临时引用。 在这种情况下,我们告诉 fs 驱动程序将其关闭并删除我们刚刚获得的临时引用。
调用方持有对超级块的独占锁; 该锁将被释放。
-
void deactivate_super(struct super_block *s)¶
删除对超级块的活动引用
参数
struct super_block *s
要停用的超级块
deactivate_locked_super()
的变体,不同之处在于超级块未被调用方锁定。 如果我们要删除最终的活动引用,则会在删除之前获取锁。
-
void retire_super(struct super_block *sb)¶
防止超级块被重用
参数
struct super_block *sb
要停用的超级块
该函数将超级块标记为在超级块测试中被忽略,这可以防止它被重用于任何新的挂载。 如果超级块具有私有 bdi,它也会注销它,但不会减少超级块的引用计数以防止潜在的竞争。 引用计数由
generic_shutdown_super()
减少。 该函数不能与generic_shutdown_super()
并发调用。 多次调用该函数是安全的,后续调用无效。该标记只会影响基于块设备的超级块的重用。 如果使用此函数,其他超级块仍将被标记,但这不会影响它们的可重用性。
-
void generic_shutdown_super(struct super_block *sb)¶
用于 ->kill_sb() 的常见助手
参数
struct super_block *sb
要终止的超级块
generic_shutdown_super()
在超级块关闭时执行所有 fs 独立的工作。 典型的 ->kill_sb() 应该从超级块中挑选出所有需要销毁的 fs 特定对象,调用generic_shutdown_super()
并释放上述对象。 注意:dentry 和 inode _已_得到处理,不需要特定的处理。调用此函数后,文件系统可能不再更改或重新排列属于此 super_block 的 dentry 集合,也不得更改 dentry 到 inode 的连接。
-
struct super_block *sget_fc(struct fs_context *fc, int (*test)(struct super_block*, struct fs_context*), int (*set)(struct super_block*, struct fs_context*))¶
查找或创建超级块
参数
struct fs_context *fc
文件系统上下文。
int (*test)(struct super_block *, struct fs_context *)
比较回调函数
int (*set)(struct super_block *, struct fs_context *)
设置回调函数
描述
创建一个新的超级块或查找一个已存在的超级块。
test 回调函数用于查找匹配的现有超级块。fc 中请求的参数是否被考虑取决于所使用的 test 回调函数。它们甚至可能被完全忽略。
如果匹配到一个现有的超级块,它将被返回,除非
文件系统上下文 fc 和现有超级块的命名空间不同
文件系统上下文 fc 已经请求不允许重用现有的超级块
在这两种情况下,都会返回 EBUSY。
如果没有找到匹配项,将分配一个新的超级块并执行基本的初始化(s_type、s_fs_info 和 s_id 将被设置,并且 set 回调函数将被调用),超级块将被发布,并且它将在部分构建的状态下返回,SB_BORN 和 SB_ACTIVE 尚未设置。
返回
- 成功时,返回一个已存在的或新创建的超级块。
失败时,返回一个错误指针。
-
struct super_block *sget(struct file_system_type *type, int (*test)(struct super_block*, void*), int (*set)(struct super_block*, void*), int flags, void *data)¶
查找或创建一个超级块
参数
struct file_system_type *type
超级块所属的文件系统类型
int (*test)(struct super_block *,void *)
比较回调函数
int (*set)(struct super_block *,void *)
设置回调函数
int flags
挂载标志
void *data
传递给每个回调函数的参数
-
void iterate_supers_type(struct file_system_type *type, void (*f)(struct super_block*, void*), void *arg)¶
为给定类型的所有超级块调用函数
参数
struct file_system_type *type
文件系统类型
void (*f)(struct super_block *, void *)
要调用的函数
void *arg
传递给函数的参数
扫描超级块列表并调用给定函数,传递锁定的超级块和给定参数。
-
int get_anon_bdev(dev_t *p)¶
为没有块设备的文件系统分配一个块设备。
参数
dev_t *p
指向 dev_t 的指针。
描述
不使用真实块设备的文件系统可以调用此函数来分配一个虚拟块设备。
上下文
任何上下文。经常在持有 sb_lock 时调用。
返回
成功时返回 0,如果没有剩余的匿名 bdevs,则返回 -EMFILE,如果内存分配失败,则返回 -ENOMEM。
-
struct super_block *sget_dev(struct fs_context *fc, dev_t dev)¶
通过设备号查找或创建超级块
参数
struct fs_context *fc
文件系统上下文。
dev_t dev
设备号
描述
使用提供的设备号查找或创建超级块,该设备号将存储在 fc->sget_key 中。
如果匹配到一个现有的超级块,则将返回该超级块,并增加其引用计数,调用者必须传输或丢弃该引用计数。
如果没有找到匹配项,将分配一个新的超级块并执行基本的初始化(s_type、s_fs_info、s_id、s_dev 将被设置)。超级块将被发布,并且它将在部分构建的状态下返回,SB_BORN 和 SB_ACTIVE 尚未设置。
返回
- 成功时,返回一个已存在的或新创建的超级块,失败时返回一个错误指针。
失败时返回指针。
-
int get_tree_bdev_flags(struct fs_context *fc, int (*fill_super)(struct super_block *sb, struct fs_context *fc), unsigned int flags)¶
基于单个块设备获取超级块
参数
struct fs_context *fc
包含参数的文件系统上下文
int (*fill_super)(struct super_block *sb, struct fs_context *fc)
用于初始化新超级块的辅助函数
unsigned int flags
GET_TREE_BDEV_* 标志
-
int get_tree_bdev(struct fs_context *fc, int (*fill_super)(struct super_block*, struct fs_context*))¶
基于单个块设备获取超级块
参数
struct fs_context *fc
包含参数的文件系统上下文
int (*fill_super)(struct super_block *, struct fs_context *)
用于初始化新超级块的辅助函数
-
int vfs_get_tree(struct fs_context *fc)¶
获取可挂载的根
参数
struct fs_context *fc
超级块配置上下文。
描述
调用文件系统以获取或创建超级块,然后可以将其用于挂载。文件系统将指向要用于挂载的根的指针放置在 fc->root 中。
-
int freeze_super(struct super_block *sb, enum freeze_holder who, const void *freeze_owner)¶
锁定文件系统并强制其进入一致状态
参数
struct super_block *sb
要锁定的超级块
enum freeze_holder who
想要冻结的上下文
const void *freeze_owner
冻结的所有者
描述
同步超级块以确保文件系统一致,并调用文件系统的 freeze_fs。在没有首先解冻文件系统的情况下,后续的调用可能会返回 -EBUSY。
who 应该是:* 如果用户空间想要冻结文件系统,则为 FREEZE_HOLDER_USERSPACE
;* 如果内核想要冻结文件系统,则为 FREEZE_HOLDER_KERNEL
。* FREEZE_MAY_NEST
是否允许嵌套冻结和解冻请求。
who 参数区分了内核和用户空间尝试冻结文件系统。虽然在任何给定时间都不能有多个内核冻结或多个用户空间冻结生效,但内核和用户空间都可以保持文件系统冻结。文件系统保持冻结状态,直到没有内核或用户空间冻结生效。
一个文件系统可能持有多个设备,因此可以通过块层通过多个块设备冻结文件系统。在这种情况下,通过传递 FREEZE_MAY_NEST 将该请求标记为允许嵌套。文件系统保持冻结状态,直到所有块设备都被解冻。如果在没有 FREEZE_MAY_NEST 的情况下尝试多个冻结,则会返回 -EBUSY。
在此函数期间,sb->s_writers.frozen 经历以下值
SB_UNFROZEN:文件系统正常,所有写入照常进行。
SB_FREEZE_WRITE:文件系统正在被冻结的过程中。应该阻止新的写入,但仍然允许页面错误。我们等待所有写入完成,然后进行到下一个阶段。
SB_FREEZE_PAGEFAULT:冻结继续。现在页面错误也被阻止了,但是内部 fs 线程仍然可以修改文件系统(尽管它们不应该修改新的脏页面或 inode),回写可以运行等等。在等待所有正在运行的页面错误后,我们同步文件系统,这将清理所有脏页面和 inode(当同步运行时,无法创建新的脏页面或 inode)。
SB_FREEZE_FS:文件系统已冻结。现在,所有文件系统修改的内部来源都被阻止(例如,XFS 预分配在 inode 回收时截断)。这通常是通过阻止具有它们并需要此额外保护的文件系统的新事务来实现的。在所有内部写入器完成后,我们调用 ->freeze_fs() 以完成文件系统的冻结。然后我们转换到 SB_FREEZE_COMPLETE 状态。此状态主要用于文件系统验证它们是否不修改冻结的 fs。
sb->s_writers.frozen 受 sb->s_umount 保护。
返回
- 如果冻结成功,则返回零。如果冻结失败,则返回负错误代码。
如果失败,则返回一个负的错误代码。
-
int thaw_super(struct super_block *sb, enum freeze_holder who, const void *freeze_owner)¶
解锁文件系统
参数
struct super_block *sb
要解冻的超级块
enum freeze_holder who
想要冻结的上下文
const void *freeze_owner
冻结的所有者
描述
在 freeze_super()
之后,如果文件系统上没有剩余的冻结,则解锁文件系统并将其标记为可再次写入。
who 应该是:* 如果用户空间想要解冻文件系统,则为 FREEZE_HOLDER_USERSPACE
;* 如果内核想要解冻文件系统,则为 FREEZE_HOLDER_KERNEL
。* FREEZE_MAY_NEST
是否允许嵌套冻结和解冻请求。
一个文件系统可能持有多个设备,因此可以通过块层通过多个块设备冻结文件系统。文件系统保持冻结状态,直到所有块设备都被解冻。
文件锁¶
-
bool locks_owner_has_blockers(struct file_lock_context *flctx, fl_owner_t owner)¶
检查是否存在阻塞锁请求
参数
struct file_lock_context *flctx
文件锁上下文
fl_owner_t owner
锁所有者
描述
- 返回值
true
:owner 至少有一个阻塞者false
:owner 没有阻塞者
-
int locks_delete_block(struct file_lock *waiter)¶
停止等待文件锁
参数
struct file_lock *waiter
正在等待的锁
lockd/nfsd 需要在处理锁时断开连接。
-
int posix_lock_file(struct file *filp, struct file_lock *fl, struct file_lock *conflock)¶
将 POSIX 风格的锁应用于文件
参数
struct file *filp
要应用锁的文件
struct file_lock *fl
要应用的锁
struct file_lock *conflock
如果找到冲突锁,则返回冲突锁的副本的位置。
描述
将 POSIX 风格的锁添加到文件。我们尽可能地合并相邻和重叠的锁。POSIX 锁按所有者任务排序,然后按起始地址排序
请注意,如果使用 FL_EXISTS 参数调用,则调用者可以通过测试返回值是否为 -ENOENT 来确定是否成功释放了锁。
参数
struct inode *inode
要返回的文件的 inode
unsigned int mode
O_RDONLY: 仅中断写租约;O_WRONLY 或 O_RDWR: 中断所有租约
unsigned int type
FL_LEASE: 中断租约和委托;FL_DELEG: 仅中断委托
break_lease(为了速度内联)已经检查过此文件上至少存在某种类型的锁(可能是租约)。租约在调用 open() 或 truncate() 时中断。除非您在 open() 中指定了
O_NONBLOCK
,否则此函数可以休眠。
参数
struct inode *inode
inode
struct timespec64 *time
指向包含上次修改时间的 timespec 的指针
描述
这是为了强制 NFS 客户端刷新具有独占租约的文件的缓存。理由是如果有人拥有独占租约,那么他们可能会修改它。
参数
struct file *filp
文件指针
int arg
要获得的租约的类型
struct file_lease **flp
输入 - 要使用的 file_lock,输出 - 插入的 file_lock
void **priv
lm_setup 的私有数据(如果 lm_setup 不需要,则可以为 NULL)
(输入) flp->fl_lmops->lm_break 函数是 break_lease() 所必需的。
参数
struct file *filp
文件指针
int arg
要获得的租约的类型
struct file_lease **lease
添加租约时要使用的 file_lock
void **priv
添加租约时 lm_setup 的私有信息(如果 lm_setup 不需要,则可以为 NULL)
描述
调用此函数以在文件上建立租约。 “lease”参数不用于 F_UNLCK 请求,可以为 NULL。 对于设置或更改现有租约的命令,必须设置 (*lease)->fl_lmops->lm_break
操作; 如果没有,此函数将返回 -ENOLCK(并生成一个看起来很可怕的堆栈跟踪)。
“priv”指针直接传递给 lm_setup 函数,并且按原样传递。 如果 lm_setup 操作不需要,则可以为 NULL。
参数
struct inode *inode
要应用到的文件的 inode
struct file_lock *fl
要应用的锁
描述
将 POSIX 或 FLOCK 样式的锁请求应用于 inode。
参数
struct file *filp
要测试锁定的文件
struct file_lock *fl
要测试的锁; 也用于保存结果
描述
失败时返回 -ERRNO。 通过将 conf->fl_type 设置为 F_UNLCK 以外的值来指示是否存在冲突锁。
-
int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl, struct file_lock *conf)¶
文件字节范围锁
参数
struct file *filp
要应用锁的文件
unsigned int cmd
锁定操作的类型 (F_SETLK、F_GETLK 等)
struct file_lock *fl
要应用的锁
struct file_lock *conf
如果找到冲突锁,则返回冲突锁的副本的位置。
描述
不关心冲突锁的调用者可以将 NULL 作为最后一个参数传递。
如果文件系统定义了一个私有的 ->lock() 方法,那么 conf 将保持不变;因此,关心的调用者应将其初始化为一些可接受的默认值。
为了避免阻塞需要获取 POSIX 锁的内核守护进程(例如 lockd),如果设置了 lm_grant,则 ->lock() 接口可能会异步返回,在底层文件系统授予或拒绝锁之前。(并且只有在这种情况下) 此外,需要设置 export_operations 标志中的 EXPORT_OP_ASYNC_LOCK。
期望 ->lock() 异步返回的调用者将只使用 F_SETLK,而不是 F_SETLKW; 如果(并且只有在这种情况下)该请求用于阻塞锁,它们将设置 FL_SLEEP。 当 ->lock() 异步返回时,它必须返回 FILE_LOCK_DEFERRED,并在锁请求完成时调用 ->lm_grant()。 如果请求用于非阻塞锁,则文件系统应返回 FILE_LOCK_DEFERRED,然后尝试获取锁并使用结果调用回调例程。 如果请求超时,则回调例程将返回一个非零的返回码,并且文件系统应释放该锁。 文件系统还有责任在授予锁时保持相应的 posix 锁,以便 VFS 可以找出哪些锁在本地持有,并在需要时进行正确的锁清理。 在以 FILE_LOCK_DEFERRED 返回码返回到调用者之前,底层文件系统不得删除内核锁或调用 ->lm_grant()。
参数
struct file *filp
要应用取消阻塞的文件
struct file_lock *fl
要取消阻塞的锁
描述
锁管理器使用此功能来取消阻塞的请求
参数
struct inode *inode
要检查锁的 inode
描述
如果当前在 inode 上设置了任何 FL_POSIX 或 FL_FLOCK 锁,则返回 true。
参数
struct inode *inode
应向其应用锁请求的文件的 inode
struct file_lock *fl
要应用的锁
描述
将 POSIX 样式的锁请求应用于 inode。
参数
struct file *filp
文件
此函数返回的值将是以下之一(如果未挂起任何租约中断)
F_RDLCK
指示持有共享租约。F_WRLCK
指示持有独占租约。F_UNLCK
指示未持有任何租约。(如果挂起租约中断)
F_RDLCK
指示独占租约需要更改为共享租约(或删除)。
F_UNLCK
指示需要删除租约。XXX:sfr & willy 对是否应将 F_INPROGRESS 返回给用户空间存在分歧。
-
int check_conflicting_open(struct file *filp, const int arg, int flags)¶
查看给定文件是否指向一个现有的打开的 inode,该 inode 会与所需的租约冲突。
参数
struct file *filp
要检查的文件
const int arg
我们正在尝试获得的租约的类型
int flags
当前锁定标志
描述
检查此文件上是否存在现有的打开的 fd,该 fd 会与我们尝试设置的租约冲突。
参数
unsigned int fd
打开的文件描述符
struct file *filp
文件指针
int arg
要获得的租约的类型
调用此 fcntl 以在文件上建立租约。 请注意,您还需要调用
F_SETSIG
以在租约中断时收到信号。
参数
struct inode *inode
要应用到的文件的 inode
struct file_lock *fl
要应用的锁
描述
将 FLOCK 样式的锁请求应用于 inode。
-
long sys_flock(unsigned int fd, unsigned int cmd)¶
flock() 系统调用。
参数
unsigned int fd
要锁定的文件描述符。
unsigned int cmd
要应用的锁的类型。
将
FL_FLOCK
样式的锁应用于打开的文件描述符。 cmd 可以是以下之一LOCK_SH
-- 共享锁。LOCK_EX
-- 独占锁。LOCK_UN
-- 删除现有锁。LOCK_MAND
-- “强制” flock。(已弃用)
LOCK_MAND
支持已从内核中删除。
-
pid_t locks_translate_pid(struct file_lock_core *fl, struct pid_namespace *ns)¶
将 file_lock 的 fl_pid 编号转换为命名空间
参数
struct file_lock_core *fl
应该转换其 fl_pid 的 file_lock
struct pid_namespace *ns
应该将 pid 转换成的命名空间
描述
用于将 fl_pid 转换为命名空间虚拟 pid 编号
其他函数¶
-
void mpage_readahead(struct readahead_control *rac, get_block_t get_block)¶
针对页面启动读取
参数
struct readahead_control *rac
描述要读取的页面。
get_block_t get_block
文件系统的块映射器函数。
描述
此函数遍历页面和每个页面中的块,构建和发出大型 BIO。
如果发生任何不寻常的事情,例如
遇到一个带有缓冲区的页面
在孔之后遇到一个没有孔的页面
遇到一个带有非连续块的页面
然后,此代码只是放弃并调用基于 buffer_head 的读取函数。 它可以处理在末尾有孔的页面 - 这是一种常见情况:blocksize < PAGE_SIZE 设置上的文件结尾。
BH_Boundary 解释
存在一个问题。 mpage 读取代码组装多个页面,获取它们的所有磁盘映射,然后提交它们。 这很好,但是获取磁盘映射可能需要 I/O。 例如,读取间接块。
因此,读取 ext2 文件的前 16 个块的 mpage 将导致按以下顺序提交 I/O
12 0 1 2 3 4 5 6 7 8 9 10 11 13 14 15 16
因为必须读取间接块才能获取块 13、14、15、16 的映射。 显然,这会影响性能。
因此,我们所做的是允许文件系统的 get_block() 函数在映射块 11 时设置 BH_Boundary。 BH_Boundary 说:此块之后的块的映射将需要针对可能与此块接近的块进行 I/O。 因此,您应该推送当前已累积的 I/O。
所有这些都会导致按正确的顺序发出磁盘请求。
-
int mpage_writepages(struct address_space *mapping, struct writeback_control *wbc, get_block_t get_block)¶
遍历给定地址空间的脏页列表并对所有页执行 writepage()
参数
struct address_space *mapping
要写入的地址空间结构
struct writeback_control *wbc
从 *wbc->nr_to_write 中减去已写入页面的数量
get_block_t get_block
文件系统的块映射函数。
描述
这是一个库函数,实现了 writepages() address_space_operation。
-
int generic_permission(struct mnt_idmap *idmap, struct inode *inode, int mask)¶
检查类 Posix 文件系统上的访问权限
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
struct inode *inode
要检查访问权限的 inode
int mask
要检查的权限(
MAY_READ
、MAY_WRITE
、MAY_EXEC
、MAY_NOT_BLOCK
...)
描述
用于检查文件上的读/写/执行权限。我们使用 "fsuid" 来实现这一点,允许我们在不更改用于其他事物的 "normal" uid 的情况下,为文件系统访问设置任意权限。
generic_permission 知道 rcu-walk。 如果无法满足 rcu-walk 请求(例如,需要阻塞或过于复杂),则返回 -ECHILD。 然后将在 ref-walk 模式下再次调用它。
如果 inode 是通过 idmapped 挂载找到的,则必须通过 idmap 传递 vfsmount 的 idmap。 然后,此函数将负责根据 idmap 映射 inode,然后再检查权限。 在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
struct inode *inode
要检查权限的 Inode
int mask
要检查的权限(
MAY_READ
,MAY_WRITE
,MAY_EXEC
)
描述
检查 inode 上的读/写/执行权限。我们使用 fs[ug]id 来实现这一点,允许我们在不更改用于其他事物的“normal”UID 的情况下,为文件系统访问设置任意权限。
在检查 MAY_APPEND 时,mask 中也必须设置 MAY_WRITE。
参数
const struct path *path
要获取引用的路径
描述
给定一个路径,递增对 dentry 和 vfsmount 的引用计数。
参数
const struct path *path
要释放引用的路径
描述
给定一个路径,递减对 dentry 和 vfsmount 的引用计数。
-
int vfs_path_parent_lookup(struct filename *filename, unsigned int flags, struct path *parent, struct qstr *last, int *type, const struct path *root)¶
查找相对于 dentry-vfsmount 对的父路径
参数
struct filename *filename
文件名结构
unsigned int flags
查找标志
struct path *parent
指向要填充的 struct path 的指针
struct qstr *last
最后一个组件
int *type
最后一个组件的类型
const struct path *root
指向基本目录的 struct path 的指针
-
int vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt, const char *name, unsigned int flags, struct path *path)¶
查找相对于 dentry-vfsmount 对的文件路径
参数
struct dentry *dentry
指向基本目录的 dentry 的指针
struct vfsmount *mnt
指向基本目录的 vfs mount 的指针
const char *name
指向文件名的指针
unsigned int flags
查找标志
struct path *path
指向要填充的 struct path 的指针
-
struct dentry *try_lookup_noperm(struct qstr *name, struct dentry *base)¶
文件系统帮助程序,用于查找单个路径名组件
参数
struct qstr *name
qstr 存储要查找的路径名组件
struct dentry *base
要从中查找的基本目录
描述
按名称在 dcache 中查找 dentry,如果当前不存在,则返回 NULL。 该函数不尝试创建 dentry,如果找到 dentry,也不会尝试重新验证它。
请注意,此例程纯粹是文件系统使用的帮助程序,不应由通用代码调用。 它不进行任何权限检查。
不需要持有锁 - 只需要对 base 的计数引用。
-
struct dentry *lookup_noperm(struct qstr *name, struct dentry *base)¶
文件系统帮助程序,用于查找单个路径名组件
参数
struct qstr *name
qstr 存储要查找的路径名组件
struct dentry *base
要从中查找的基本目录
描述
请注意,此例程纯粹是文件系统使用的帮助程序,不应由通用代码调用。 它不进行任何权限检查。
调用者必须持有 base->i_mutex。
-
struct dentry *lookup_one(struct mnt_idmap *idmap, struct qstr *name, struct dentry *base)¶
查找单个路径名组件
参数
struct mnt_idmap *idmap
执行查找的挂载的 idmap
struct qstr *name
qstr 存储要查找的路径名组件
struct dentry *base
要从中查找的基本目录
描述
这可以用于内核文件系统客户端,例如文件服务器。
调用者必须持有 base->i_mutex。
-
struct dentry *lookup_one_unlocked(struct mnt_idmap *idmap, struct qstr *name, struct dentry *base)¶
查找单个路径名组件
参数
struct mnt_idmap *idmap
执行查找的挂载的 idmap
struct qstr *name
qstr olding 要查找的路径名组件
struct dentry *base
要从中查找的基本目录
描述
这可以用于内核文件系统客户端,例如文件服务器。
与 lookup_one 不同,它应该在没有持有父 i_rwsem 的情况下调用,并且如果需要,它将获取 i_rwsem 本身。
-
struct dentry *lookup_one_positive_unlocked(struct mnt_idmap *idmap, struct qstr *name, struct dentry *base)¶
查找单个路径名组件
参数
struct mnt_idmap *idmap
执行查找的挂载的 idmap
struct qstr *name
qstr 存储要查找的路径名组件
struct dentry *base
要从中查找的基本目录
描述
如果为负数,此帮助程序将产生 ERR_PTR(-ENOENT)。 帮助程序返回已知的正数或 ERR_PTR()
。 这是大多数用户想要的。
请注意,带有未锁定父级的已固定的负数_可以_随时变为正数,因此 lookup_one_unlocked()
的调用者需要非常小心; 已固定的正数具有 >d_inode 稳定,因此这一个避免了此类问题。
这可以用于内核文件系统客户端,例如文件服务器。
该帮助程序应在未持有 i_rwsem 的情况下调用。
-
struct dentry *lookup_noperm_unlocked(struct qstr *name, struct dentry *base)¶
文件系统帮助程序,用于查找单个路径名组件
参数
struct qstr *name
要查找的路径名组件
struct dentry *base
要从中查找的基本目录
描述
请注意,此例程纯粹是文件系统使用的帮助程序,不应由通用代码调用。 它不进行任何权限检查。
与 lookup_noperm()
不同,它应该在没有持有父 i_rwsem 的情况下调用,并且如果需要,它将获取 i_rwsem 本身。
与 try_lookup_noperm()
不同,如果 dentry 已经存在,它会重新验证 dentry。
-
int vfs_create(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode, bool want_excl)¶
创建新文件
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
struct inode *dir
父目录的 inode
struct dentry *dentry
子文件的 dentry
umode_t mode
子文件的模式
bool want_excl
该文件是否必须尚不存在
描述
创建一个新文件。
如果 inode 是通过 idmapped 挂载找到的,则必须通过 idmap 传递 vfsmount 的 idmap。 然后,此函数将负责根据 idmap 映射 inode,然后再检查权限。 在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
-
struct file *kernel_tmpfile_open(struct mnt_idmap *idmap, const struct path *parentpath, umode_t mode, int open_flag, const struct cred *cred)¶
为内核内部使用打开一个 tmpfile
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
const struct path *parentpath
基本目录的路径
umode_t mode
新 tmpfile 的模式
int open_flag
flags
const struct cred *cred
用于打开的凭据
描述
创建并打开一个临时文件。该文件未在 nr_files 中进行核算,因此这仅用于内核内部使用,并且不得安装到文件表等中。
-
int vfs_mknod(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)¶
创建设备节点或文件
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
struct inode *dir
父目录的 inode
struct dentry *dentry
子设备节点的 dentry
umode_t mode
子设备节点的模式
dev_t dev
要创建的设备的设备编号
描述
创建一个设备节点或文件。
如果 inode 是通过 idmapped 挂载找到的,则必须通过 idmap 传递 vfsmount 的 idmap。 然后,此函数将负责根据 idmap 映射 inode,然后再检查权限。 在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
-
struct dentry *vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, umode_t mode)¶
创建目录,如果可能,返回正确的dentry
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
struct inode *dir
父目录的 inode
struct dentry *dentry
子目录的dentry
umode_t mode
子目录的模式
描述
创建一个目录。
如果 inode 是通过 idmapped 挂载找到的,则必须通过 idmap 传递 vfsmount 的 idmap。 然后,此函数将负责根据 idmap 映射 inode,然后再检查权限。 在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
如果文件系统不使用**dentry**,而是将其保留为负值或取消散列,并可能拼接一个不同的dentry并返回,则原始dentry将被dput(),并返回备用dentry。
如果发生错误,则dentry将被dput(),并返回一个ERR_PTR()
。
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
struct inode *dir
父目录的 inode
struct dentry *dentry
子目录的dentry
描述
删除一个目录。
如果 inode 是通过 idmapped 挂载找到的,则必须通过 idmap 传递 vfsmount 的 idmap。 然后,此函数将负责根据 idmap 映射 inode,然后再检查权限。 在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
-
int vfs_unlink(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, struct inode **delegated_inode)¶
取消链接一个文件系统对象
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
struct inode *dir
父目录
struct dentry *dentry
受害者
struct inode **delegated_inode
如果 inode 被委托,则返回受害者的 inode。
描述
调用者必须持有 dir->i_mutex。
如果 vfs_unlink 发现一个委托,它将返回 -EWOULDBLOCK 并在 delegated_inode 中返回一个指向 inode 的引用。然后,调用者应该在该 inode 上打破委托并重试。由于打破委托可能需要很长时间,因此调用者应该在这样做之前释放 dir->i_mutex。
或者,调用者可以为 delegated_inode 传递 NULL。这可能适用于期望底层文件系统不被 NFS 导出的调用者。
如果 inode 是通过 idmapped 挂载找到的,则必须通过 idmap 传递 vfsmount 的 idmap。 然后,此函数将负责根据 idmap 映射 inode,然后再检查权限。 在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
-
int vfs_symlink(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, const char *oldname)¶
创建符号链接
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
struct inode *dir
父目录的 inode
struct dentry *dentry
子符号链接文件的dentry
const char *oldname
要链接到的文件的名称
描述
创建一个符号链接。
如果 inode 是通过 idmapped 挂载找到的,则必须通过 idmap 传递 vfsmount 的 idmap。 然后,此函数将负责根据 idmap 映射 inode,然后再检查权限。 在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
-
int vfs_link(struct dentry *old_dentry, struct mnt_idmap *idmap, struct inode *dir, struct dentry *new_dentry, struct inode **delegated_inode)¶
创建一个新链接
参数
struct dentry *old_dentry
要链接的对象
struct mnt_idmap *idmap
挂载的 idmap
struct inode *dir
新的父目录
struct dentry *new_dentry
在哪里创建新的链接
struct inode **delegated_inode
返回需要委托中断的 inode
描述
调用者必须持有 dir->i_mutex
如果 vfs_link 在需要中断的待链接文件上发现委托,它将返回 -EWOULDBLOCK 并在 delegated_inode 中返回一个指向 inode 的引用。然后,调用者应该中断委托并重试。由于打破委托可能需要很长时间,因此调用者应该在这样做之前释放 i_mutex。
或者,调用者可以为 delegated_inode 传递 NULL。这可能适用于期望底层文件系统不被 NFS 导出的调用者。
如果 inode 是通过 idmapped 挂载找到的,则必须通过 idmap 传递 vfsmount 的 idmap。 然后,此函数将负责根据 idmap 映射 inode,然后再检查权限。 在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
-
int vfs_rename(struct renamedata *rd)¶
重命名一个文件系统对象
参数
struct renamedata *rd
指向
struct renamedata
信息的指针
描述
调用者必须持有多个互斥锁--请参见 lock_rename()。
如果 vfs_rename 在源或目标上发现需要中断的委托,它将返回 -EWOULDBLOCK 并在 delegated_inode 中返回一个指向 inode 的引用。然后,调用者应该中断委托并重试。由于打破委托可能需要很长时间,因此调用者应该在这样做之前释放所有锁。
或者,调用者可以为 delegated_inode 传递 NULL。这可能适用于期望底层文件系统不被 NFS 导出的调用者。
所有命名空间操作中最糟糕的 - 重命名目录。“变态”甚至不足以形容它。UCB 中的某个人度过了一段糟糕的旅程... 问题
我们可以进入循环创建。
竞争潜力 - 两个无辜的重命名可以一起创建一个循环。这就是 4.4BSD 搞砸的地方。目前的修复:sb->s_vfs_rename_mutex 上的序列化。我们可能会更准确,但那是另一个故事。
我们可能必须锁定多达 _四个_ 对象 - 父目录和受害者(如果存在),以及源(如果它是一个非目录或移动到不同父目录的子目录)。而且是在我们获取父母的 ->i_mutex 之后(在此之前我们不知道目标是否存在)。解决方案:尝试在 inode 的锁定顺序方面变得聪明。我们依赖于树拓扑只能在 ->s_vfs_rename_mutex _和_ 我们移动的对象的父目录将被锁定的事实。因此,我们可以按树对目录进行排序(祖先优先),并将所有非目录排在它们之后。这之所以有效,是因为除了重命名之外的每个人都执行“锁定父目录,查找,锁定子目录”,并且重命名在 ->s_vfs_rename_mutex 下。但是,它依赖于这样一个假设:任何具有 ->lookup() 的对象都只有一个 dentry。如果“混合”对象将来出现,我们最好确保它们没有 link(2)。
从 fhandle 到 dentry 的转换可能会在错误的时刻发生 - 当我们删除目标时。解决方案:我们必须在 fhandle_to_dentry 代码中获取 ->i_mutex。[FIXME - 当前的 nfsfh.c 依赖于父母的 ->i_mutex,这虽然有效,但会导致一些真正过度的锁定]。
参数
struct dentry *dentry
要在其上获取符号链接的 dentry
char __user *buffer
用户内存指针
int buflen
缓冲区大小
描述
不接触 atime。如有必要,这取决于调用者
不调用安全钩子。
参数
struct dentry *dentry
要在其上获取符号链接的 dentry
struct delayed_call *done
调用者需要使用它来释放返回的数据
描述
在提供的 inode 上调用安全钩子和 i_op->get_link()。
它不接触 atime。如有必要,这取决于调用者。
不适用于“特殊”符号链接,如 /proc/$$/fd/N
-
const char *page_get_link(struct dentry *dentry, struct inode *inode, struct delayed_call *callback)¶
get_link inode_operation 的一个实现。
参数
struct dentry *dentry
作为符号链接的目录条目。
struct inode *inode
符号链接的 inode。
struct delayed_call *callback
用于删除对符号链接的引用。
描述
将其符号链接存储在页面缓存中的文件系统应使用此方法来实现其 inode_operations 的 get_link() 成员。
返回
指向以 NUL 结尾的符号链接的指针。
-
void page_put_link(void *arg)¶
删除对符号链接的引用。
参数
void *arg
包含符号链接的区域。
描述
这是 page_get_link()
内部使用的。导出它是为了供需要实现 page_get_link()
变体本身的文件系统使用。尽管表面上对称,但使用 page_get_link()
的文件系统不需要调用 page_put_link()
。
参数虽然具有 void 指针类型,但必须是指向从页面缓存中检索的区域的指针。delayed_call 基础设施用于在调用者完成符号链接后删除引用计数。
参数
struct bio *bio
要重置的 bio
struct block_device *bdev
要使用 bio 的块设备
blk_opf_t opf
bio 的操作和标志
描述
在调用
bio_reset()
之后,**bio** 将处于与 biobio_alloc_bioset()
返回的全新分配的 bio 相同的状态 - 唯一保留的字段是由bio_alloc_bioset()
初始化的字段。请参阅 struct bio 中的注释。
参数
struct bio *bio
目标 bio
struct bio *parent
**bio** 的父 bio
描述
当 **bio** 完成时,不会调用调用者的 bi_end_io - 相反,在 **parent** 和 **bio** 都完成之前,不会调用 **parent** 的 bi_end_io;链接的 bio 也将在完成时被释放。
调用者不得在 **bio** 中设置 bi_private 或 bi_end_io。
-
struct bio *bio_alloc_bioset(struct block_device *bdev, unsigned short nr_vecs, blk_opf_t opf, gfp_t gfp_mask, struct bio_set *bs)¶
为 I/O 分配一个 bio
参数
struct block_device *bdev
为其分配 bio 的块设备(可以为
NULL
)unsigned short nr_vecs
要预分配的 bvecs 的数量
blk_opf_t opf
bio 的操作和标志
gfp_t gfp_mask
提供给 slab 分配器的 GFP_* 掩码
struct bio_set *bs
要从中分配的 bio_set。
描述
从 **bs** 中的内存池分配一个 bio。
如果设置了 __GFP_DIRECT_RECLAIM
,则 bio_alloc 将始终能够分配一个 bio。这是由于内存池保证。为了使这项工作能够正常进行,调用者绝不能一次从通用池中分配超过 1 个 bio。需要分配超过 1 个 bio 的调用者必须始终在尝试分配新 bio 之前提交先前分配的 bio 以进行 IO。否则可能会导致内存压力下的死锁。
请注意,在 submit_bio_noacct()
下运行时(即任何块驱动程序),bio 不会被提交,直到您返回之后 - 请参见 submit_bio_noacct()
中的代码,该代码将递归转换为迭代,以防止堆栈溢出。
这通常意味着在 submit_bio_noacct()
下分配多个 bio 容易发生死锁,但我们有死锁避免代码,该代码从救援线程重新提交任何被阻止的 bio。
但是,我们不保证从其他内存池进行分配能够取得进展。应避免在 submit_bio_noacct()
下从同一内存池进行多次分配 - 而应使用 bio_set 的 front_pad 进行每个 bio 的分配。
返回
成功时指向新 bio 的指针,失败时为 NULL。
-
struct bio *bio_kmalloc(unsigned short nr_vecs, gfp_t gfp_mask)¶
kmalloc 一个 bio
参数
unsigned short nr_vecs
要分配的 bio_vecs 的数量
gfp_t gfp_mask
提供给 slab 分配器的 GFP_* 掩码
描述
使用 kmalloc 分配一个 bio(包括 bvecs)。在使用前,必须使用 bio_init() 初始化 bio。要释放从此函数返回的 bio,在使用 bio_uninit() 之后使用 kfree()
。可以通过在再次调用 bio_init() 之前调用 bio_uninit() 来重用从此函数返回的 bio。
请注意,与 bio_alloc() 或 bio_alloc_bioset()
不同,从此函数分配的内存没有 mempool 支持,可能会失败。不要在文件系统 I/O 路径中使用此函数进行分配。
返回
成功时指向新 bio 的指针,失败时为 NULL。
参数
struct bio *bio
要释放引用的 bio
描述
释放对
struct bio
的引用,这个 bio 可以是你通过 bio_alloc、bio_get 或 bio_clone_* 获取的。对 bio 的最后一次 put 操作将会释放它。
-
struct bio *bio_alloc_clone(struct block_device *bdev, struct bio *bio_src, gfp_t gfp, struct bio_set *bs)¶
克隆一个 bio,该 bio 共享原始 bio 的 biovec
参数
struct block_device *bdev
要克隆到的 block_device
struct bio *bio_src
要克隆的 bio
gfp_t gfp
分配优先级
struct bio_set *bs
要从中分配的 bio_set
描述
分配一个新的 bio,它是 bio_src 的克隆。调用者拥有返回的 bio,但不拥有它指向的实际数据。
调用者必须确保在 bio_src 之前不要释放返回的 bio。
-
int bio_init_clone(struct block_device *bdev, struct bio *bio, struct bio *bio_src, gfp_t gfp)¶
克隆一个 bio,该 bio 共享原始 bio 的 biovec
参数
struct block_device *bdev
要克隆到的 block_device
struct bio *bio
要克隆到的 bio
struct bio *bio_src
要克隆的 bio
gfp_t gfp
分配优先级
描述
在调用者提供的内存中初始化一个新的 bio,它是 bio_src 的克隆。调用者拥有返回的 bio,但不拥有它指向的实际数据。
调用者必须确保在 bio 之前不要释放 bio_src。
-
void __bio_add_page(struct bio *bio, struct page *page, unsigned int len, unsigned int off)¶
将页面添加到新段中的 bio
参数
struct bio *bio
目标 bio
struct page *page
要添加的起始页
unsigned int len
要添加的数据的长度,可能跨越多个页面
unsigned int off
数据相对于 page 的偏移量,可能跨越多个页面
描述
将 page + off 处的数据作为新的 bvec 添加到 bio。调用者必须确保 bio 有足够的空间容纳另一个 bvec。
参数
struct bio *bio
目标 bio
void *vaddr
要添加的数据
unsigned len
要添加的数据的长度,可能跨越多个页面
描述
将 vaddr 处的数据添加到 bio。调用者必须确保有一个段可用于添加的数据。不会执行与现有段的合并。
-
int bio_add_page(struct bio *bio, struct page *page, unsigned int len, unsigned int offset)¶
尝试将页面添加到 bio
参数
struct bio *bio
目标 bio
struct page *page
要添加的起始页
unsigned int len
vec 条目长度,可能跨越多个页面
unsigned int offset
vec 条目相对于 page 的偏移量,可能跨越多个页面
尝试将页面添加到 bio_vec maplist。只有当 bio->bi_vcnt == bio->bi_max_vecs 或它是克隆的 bio 时,此操作才会失败。
-
bool bio_add_folio(struct bio *bio, struct folio *folio, size_t len, size_t off)¶
尝试将 folio 的一部分添加到 bio。
参数
struct bio *bio
要添加到的 BIO。
struct folio *folio
要添加的 Folio。
size_t len
要从 folio 添加多少字节。
size_t off
要添加的此 folio 中的第一个字节。
描述
使用 folio 的文件系统可以调用此函数,而不是为 folio 中的每个页面调用 bio_add_page()
。如果 off 大于 PAGE_SIZE,则此函数可以创建一个 bio_vec,它从 bv_page 之后的页面开始。BIO 不支持 4GiB 或更大的 folio。
返回
添加是否成功。
参数
struct bio *bio
目标 bio
void *vaddr
要添加的 vmalloc 地址
unsigned len
要添加的数据的总长度(以字节为单位)
描述
将从 vaddr 开始的数据添加到 bio 并返回已添加的字节数。这可能小于最初要求的数量。如果无法将数据添加到 bio,则返回 0。
此 helper 函数为添加的范围调用 flush_kernel_vmap_range()。对于读取,调用者仍然需要在完成处理程序中手动调用 invalidate_kernel_vmap_range()。
参数
struct bio *bio
目标 bio
void *vaddr
要添加的 vmalloc 地址
unsigned int len
要添加的数据的总长度(以字节为单位)
描述
将从 vaddr 开始的数据添加到 bio。如果成功,则返回 true
,如果 bio 没有足够的空间容纳有效负载,则返回 false
。
此 helper 函数为添加的范围调用 flush_kernel_vmap_range()。对于读取,调用者仍然需要在完成处理程序中手动调用 invalidate_kernel_vmap_range()。
参数
struct bio *bio
要添加页面的 bio
struct iov_iter *iter
描述要添加区域的 iov 迭代器
描述
这需要一个指向用户内存的迭代器,或者一个指向内核页面(BVEC 迭代器)的迭代器。 如果我们正在添加用户页面,我们会固定它们并将它们映射到内核中。 在 IO 完成时,调用者应该 put 那些页面。 对于基于 bvec 的迭代器,bio_iov_iter_get_pages()
使用提供的 bvecs 而不是复制它们。 因此,任何发出基于 kiocb 的 IO 的人都需要确保 bvecs 和页面保持引用状态,直到提交的 I/O 通过调用 ->ki_complete() 完成,或者返回一个错误(除了 -EIOCBQUEUED)。 调用者需要在 IO 完成时检查 bio 是否标记了 BIO_NO_PAGE_REF。 如果没有,则应该释放页面。
该函数尝试但不能保证固定尽可能多的页面,这些页面可以放入 bio 中,或者在 iter 中请求,无论哪个更小。 如果 MM 在固定请求的页面时遇到错误,它会停止。 仅当无法固定 0 个页面时,才会返回错误。
参数
struct bio *bio
描述 I/O 的
struct bio
描述
围绕 submit_bio()
的简单包装器。 成功时返回 0,失败时返回来自 bio_endio()
的错误。
警告:与通常使用 submit_bio()
的方式不同,此函数不会导致 bio 引用被消耗。 调用者必须自行释放引用。
-
int bdev_rw_virt(struct block_device *bdev, sector_t sector, void *data, size_t len, enum req_op op)¶
同步读取到/写入到内核映射
参数
struct block_device *bdev
要访问的块设备
sector_t sector
要访问的扇区
void *data
要读取/写入的数据
size_t len
要读取/写入的长度(以字节为单位)
enum req_op op
操作(例如,REQ_OP_READ/REQ_OP_WRITE)
描述
对 bdev 执行同步 I/O 以处理 data/len。 data 必须位于内核直接映射中,而不是 vmalloc 地址。
-
void bio_copy_data(struct bio *dst, struct bio *src)¶
将数据缓冲区的内容从一个 bio 复制到另一个 bio
参数
struct bio *dst
目标 bio
struct bio *src
源 bio
描述
当到达 src 或 dst 的末尾时停止 - 即,复制 min(src->bi_size, dst->bi_size) 字节(或 bio 列表的等效字节数)。
参数
struct bio *bio
bio
描述
bio_endio()
将结束整个 bio 上的 I/O。bio_endio()
是结束 bio 上的 I/O 的首选方式。 除非他们拥有 bio 并因此知道它具有 end_io 函数,否则任何人都不能直接在 bio 上调用 bi_end_io()。可以在使用
bio_chain()
链接的 bio 上多次调用bio_endio()
。 ->bi_end_io() 函数只会在最后一次调用。
参数
struct bio *bio
bio 分割
int sectors
从 bio 前面分割的扇区数
gfp_t gfp
gfp 掩码
struct bio_set *bs
用于分配的 bio 集
描述
分配并返回一个新的 bio,它表示从 bio 开始的 sectors 扇区,并更新 bio 以表示剩余的扇区。
除非这是一个丢弃请求,否则新分配的 bio 将指向 bio 的 bi_io_vec。调用者有责任确保在拆分 bio 之前,bio 和 bs 都不会被释放。
参数
struct bio *bio
要修剪的 bio
sector_t offset
要从 bio 前面修剪的扇区数
sector_t size
我们希望将 bio 修剪到的尺寸,以扇区为单位
描述
此函数通常用于克隆并以部分形式提交给底层设备的 bio。
-
int bioset_init(struct bio_set *bs, unsigned int pool_size, unsigned int front_pad, int flags)¶
初始化 bio_set
参数
struct bio_set *bs
要初始化的池
unsigned int pool_size
要在内存池中缓存的 bio 和 bio_vecs 的数量
unsigned int front_pad
要在返回的 bio 前面分配的字节数
int flags
修改行为的标志,当前为
BIOSET_NEED_BVECS
和BIOSET_NEED_RESCUER
描述
设置一个 bio_set 以与 bio_alloc_bioset 一起使用。允许调用者请求在 bio 前面分配一定数量的字节。 前端填充分配对于将 bio 嵌入到另一个结构中非常有用,以避免分配额外的与 bio 一起使用的数据。 请注意,bio 必须始终嵌入到该结构的末尾,否则会严重损坏。 如果在 flags 中设置了
BIOSET_NEED_BVECS
,则将分配一个单独的池来分配 iovec。 例如,对于bio_init_clone()
,不需要此池。 如果设置了BIOSET_NEED_RESCUER
,则会创建一个工作队列,该队列可用于在内存池空间不足时调度排队的请求。
参数
struct file *file
我们初始化的文件
const struct seq_operations *op
描述序列的方法表
seq_open()
设置 file,将其与由 op 描述的序列相关联。 op->start()
设置迭代器并返回序列的第一个元素。 op->stop()
关闭它。 op->next() 返回序列的下一个元素。 op->show() 将元素打印到缓冲区中。 如果出现错误,->start()
和 ->next() 返回 ERR_PTR(错误)。 在序列的末尾,它们返回NULL
。 ->show() 在成功时返回 0,在出错时返回负数。 返回 SEQ_SKIP 表示“放弃此元素并继续”。
注意
- seq_open() 将分配一个 struct seq_file 并将其存储在
file->private_data 中。 不应修改此指针。
-
ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos)¶
顺序文件的 ->read() 方法。
参数
struct file *file
要从中读取的文件
char __user *buf
要读取到的缓冲区
size_t size
要读取的最大字节数
loff_t *ppos
文件中的当前位置
现成的 ->f_op->read()
参数
struct file *file
有问题的文件
loff_t offset
新位置
int whence
0 表示绝对位置,1 表示相对位置
现成的 ->f_op->llseek()
参数
struct inode *inode
它的 inode
struct file *file
有问题的文件
释放与顺序文件关联的结构; 如果您没有要销毁的私有数据,则可以用作 ->f_op->release()。
-
void seq_escape_mem(struct seq_file *m, const char *src, size_t len, unsigned int flags, const char *esc)¶
将数据打印到缓冲区中,转义某些字符
参数
struct seq_file *m
目标缓冲区
const char *src
源缓冲区
size_t len
源缓冲区的大小
unsigned int flags
要传递给
string_escape_mem()
的标志const char *esc
需要转义的字符集
描述
将数据放入缓冲区,将给定类(由 flags 和 esc 定义)中每个字符的出现替换为可打印的转义序列。
使用 seq_has_overflowed() 检查错误。
-
char *mangle_path(char *s, const char *p, const char *esc)¶
处理并将路径复制到缓冲区开头
参数
char *s
缓冲区开始
const char *p
上述缓冲区中路径的开头
const char *esc
需要转义的字符集
将路径从 p 复制到 s,将 esc 中每个字符的出现替换为常用的八进制转义。 返回指向 s 中最后一个写入字符之后的指针,如果失败则返回 NULL。
参数
struct seq_file *m
seq_file 句柄
const struct path *path
要打印的结构路径
const char *esc
要在输出中转义的字符集
描述
返回 'path' 的绝对路径,由路径参数中的 dentry / mnt 对表示。
参数
struct seq_file *m
seq_file 句柄
struct file *file
要打印的
struct file
const char *esc
要在输出中转义的字符集
描述
返回文件的绝对路径。
-
int seq_write(struct seq_file *seq, const void *data, size_t len)¶
将任意数据写入缓冲区
参数
struct seq_file *seq
标识应在其中写入数据的缓冲区的 seq_file
const void *data
数据地址
size_t len
字节数
描述
成功时返回 0,否则返回非零值。
-
void seq_pad(struct seq_file *m, char c)¶
将填充空格写入缓冲区
参数
struct seq_file *m
标识应在其中写入数据的缓冲区的 seq_file
char c
如果非零,则在填充后追加的字节
-
struct hlist_node *seq_hlist_start(struct hlist_head *head, loff_t pos)¶
开始 hlist 的迭代
-
struct hlist_node *seq_hlist_start_head(struct hlist_head *head, loff_t pos)¶
开始 hlist 的迭代
参数
struct hlist_head *head
hlist 的头
loff_t pos
序列的起始位置
描述
在 seq_file->op->start()
处调用。 如果您想在输出顶部打印标题,请调用此函数。
-
struct hlist_node *seq_hlist_next(void *v, struct hlist_head *head, loff_t *ppos)¶
移动到 hlist 的下一个位置
参数
void *v
当前迭代器
struct hlist_head *head
hlist 的头
loff_t *ppos
当前位置
描述
在 seq_file->op->next() 处调用。
-
struct hlist_node *seq_hlist_start_rcu(struct hlist_head *head, loff_t pos)¶
开始由 RCU 保护的 hlist 的迭代
参数
struct hlist_head *head
hlist 的头
loff_t pos
序列的起始位置
描述
在 seq_file->op->start()
处调用。
只要遍历受 rcu_read_lock()
的保护,此列表遍历原语就可以与 _rcu 列表修改原语(例如 hlist_add_head_rcu()
)安全地并发运行。
-
struct hlist_node *seq_hlist_start_head_rcu(struct hlist_head *head, loff_t pos)¶
开始由 RCU 保护的 hlist 的迭代
参数
struct hlist_head *head
hlist 的头
loff_t pos
序列的起始位置
描述
在 seq_file->op->start()
处调用。 如果您想在输出顶部打印标题,请调用此函数。
只要遍历受 rcu_read_lock()
的保护,此列表遍历原语就可以与 _rcu 列表修改原语(例如 hlist_add_head_rcu()
)安全地并发运行。
-
struct hlist_node *seq_hlist_next_rcu(void *v, struct hlist_head *head, loff_t *ppos)¶
移动到受 RCU 保护的 hlist 的下一个位置
参数
void *v
当前迭代器
struct hlist_head *head
hlist 的头
loff_t *ppos
当前位置
描述
在 seq_file->op->next() 处调用。
只要遍历受 rcu_read_lock()
的保护,此列表遍历原语就可以与 _rcu 列表修改原语(例如 hlist_add_head_rcu()
)安全地并发运行。
-
struct hlist_node *seq_hlist_start_percpu(struct hlist_head __percpu *head, int *cpu, loff_t pos)¶
启动一个 percpu hlist 数组的迭代
参数
struct hlist_head __percpu *head
指向 struct hlist_heads 的 percpu 数组的指针
int *cpu
指向 cpu “光标” 的指针
loff_t pos
序列的起始位置
描述
在 seq_file->op->start()
处调用。
-
struct hlist_node *seq_hlist_next_percpu(void *v, struct hlist_head __percpu *head, int *cpu, loff_t *pos)¶
移动到 percpu hlist 数组的下一个位置
参数
void *v
指向当前 hlist_node 的指针
struct hlist_head __percpu *head
指向 struct hlist_heads 的 percpu 数组的指针
int *cpu
指向 cpu “光标” 的指针
loff_t *pos
序列的起始位置
描述
在 seq_file->op->next() 处调用。
-
int register_filesystem(struct file_system_type *fs)¶
注册一个新的文件系统
参数
struct file_system_type * fs
文件系统结构
将传递的文件系统添加到内核知道的用于挂载和其他系统调用的文件系统列表中。成功时返回 0,错误时返回负 errno 代码。
传递的
struct file_system_type
链接到内核结构中,并且在文件系统注销之前不得释放。
-
int unregister_filesystem(struct file_system_type *fs)¶
注销一个文件系统
参数
struct file_system_type * fs
要注销的文件系统
删除先前已成功向内核注册的文件系统。如果未找到文件系统,则返回错误。成功时返回零。
一旦此函数返回,
struct file_system_type
结构就可以释放或重用。
-
void wbc_attach_fdatawrite_inode(struct writeback_control *wbc, struct inode *inode)¶
关联 wbc 和 inode 以进行 fdatawrite
参数
struct writeback_control *wbc
感兴趣的 writeback_control
struct inode *inode
目标 inode
描述
此函数由 __filemap_fdatawrite_range() 使用,它是写入代码的备用入口点,并且首先确保 inode 与 bdi_writeback 关联并将其附加到 wbc。
-
void wbc_detach_inode(struct writeback_control *wbc)¶
将 wbc 与 inode 分离并执行外部检测
参数
struct writeback_control *wbc
刚刚完成的回写的 writeback_control
描述
在 inode 的回写尝试完成后调用,并撤消 wbc_attach_and_unlock_inode()。可以在任何上下文中调用。
由于 inode 的并发写入共享预计非常罕见,并且 memcg 仅根据首次使用情况跟踪页面所有权,严重限制了此类共享的有用性,因此 cgroup 回写跟踪每个 inode 的所有权。虽然对 inode 的并发写入共享的支持被认为是不必要的,但在不同时间点由不同 cgroup 写入 inode 更为常见,而且更重要的是,仅根据首次使用情况收费很容易导致严重不正确的行为(单个外部页面可能导致千兆字节的回写被错误地归因)。
为了解决这个问题,cgroup 回写检测 inode 的主要脏页者,并将所有权转移给它。为了避免不必要的振荡,检测机制会跟踪历史记录,并且仅当外部使用模式在一定时间内和/或回写尝试中保持稳定时才给出切换判断。
在每次回写尝试时,wbc 尝试使用 Boyer-Moore 多数投票算法检测主要写入者。除了来自多数投票的字节数之外,它还计算当前 wb 和上一轮获胜者 wb 的写入字节数(上一轮当前 wb 的最大值、两个轮次之前的获胜者以及上一轮的多数候选者)。跟踪历史获胜者有助于该算法半可靠地检测最活跃的写入者,即使它不是绝对多数。
一旦确定了该轮的获胜者,无论获胜者是外部的还是否,以及该轮消耗了多少 IO 时间,都会记录在 inode->i_wb_frn_history 中。如果记录的外部 IO 时间量超过某个阈值,则给出切换判断。
-
void wbc_account_cgroup_owner(struct writeback_control *wbc, struct folio *folio, size_t bytes)¶
记账回写以更新 inode cgroup 所有权
参数
struct writeback_control *wbc
正在进行的回写的 writeback_control
struct folio *folio
正在写出的 folio
size_t bytes
正在写出的字节数
描述
来自 folio 的 bytes 将要在由 wbc 控制的回写期间写出。保留外部 inode 检测的账本。请参阅 wbc_detach_inode()
。
参数
struct inode *inode
要标记的 inode
int flags
什么样的脏,例如 I_DIRTY_SYNC。这可以是多个 I_DIRTY_* 标志的组合,但 I_DIRTY_TIME 不能与 I_DIRTY_PAGES 组合。
描述
将 inode 标记为脏。我们通知文件系统,然后更新 inode 的脏标志。然后,如果需要,我们将 inode 添加到相应的脏列表中。
大多数调用者应使用 mark_inode_dirty() 或 mark_inode_dirty_sync() 而不是直接调用此函数。
小心!我们仅在 inode 被散列或引用 blockdev 时才将其添加到脏列表中。未散列的 inode 永远不会被添加到脏列表中,即使它们稍后被散列,因为它们已经被标记为脏。
简而言之,请确保在开始将任何 inode 标记为脏_之前_对其进行散列。
请注意,对于 blockdev,inode->dirtied_when 表示块特殊 inode (/dev/hda1) 本身的脏时间。内核内部 blockdev inode 的 ->dirtied_when 字段表示 blockdev 页面的脏时间。这就是为什么对于 I_DIRTY_PAGES,我们总是使用 page->mapping->host,因此页面脏时间记录在内部 blockdev inode 中。
-
void writeback_inodes_sb_nr(struct super_block *sb, unsigned long nr, enum wb_reason reason)¶
从给定的超级块回写脏 inode
参数
struct super_block *sb
超级块
unsigned long nr
要写入的页面数
enum wb_reason reason
启动某些回写工作的原因
描述
在此超级块上启动某些 inode 的回写。不保证将写入多少(如果有的话),并且此函数不会等待提交 IO 的 IO 完成。
-
void writeback_inodes_sb(struct super_block *sb, enum wb_reason reason)¶
从给定的超级块回写脏 inode
参数
struct super_block *sb
超级块
enum wb_reason reason
启动某些回写工作的原因
描述
在此超级块上启动某些 inode 的回写。不保证将写入多少(如果有的话),并且此函数不会等待提交 IO 的 IO 完成。
-
void try_to_writeback_inodes_sb(struct super_block *sb, enum wb_reason reason)¶
如果没有正在进行的回写,则尝试启动回写
参数
struct super_block *sb
超级块
enum wb_reason reason
启动某些回写工作的原因
描述
如果没有正在进行的回写,则调用 __writeback_inodes_sb_nr。
-
void sync_inodes_sb(struct super_block *sb)¶
同步 sb inode 页面
参数
struct super_block *sb
超级块
描述
此函数写入并等待属于此超级块的任何脏 inode。
参数
struct inode *inode
要写入磁盘的 inode
int sync
写入是否应该是同步的
描述
如果 inode 是脏的,此函数会立即将其提交到磁盘。这主要是 knfsd 所需的。
调用者必须对 inode 具有引用,或者必须已设置 I_WILL_FREE。
参数
struct inode *inode
要同步的 inode
int wait
等待 I/O 完成。
描述
将 inode 写入磁盘并在完成后调整其脏状态。
注意
仅写入实际的 inode,不写入任何关联的数据或其他元数据。
-
struct file *anon_inode_getfile(const char *name, const struct file_operations *fops, void *priv, int flags)¶
通过将其连接到匿名 inode 和描述文件“类”的 dentry 来创建一个新的文件实例
参数
const char *name
[in] 新文件“类”的名称
const struct file_operations *fops
[in] 新文件的文件操作
void *priv
[in] 新文件的私有数据(将是文件的 private_data)
int flags
[in] 标志
描述
通过将其连接到单个 inode 来创建一个新文件。这对于不需要具有完整的 inode 才能正确操作的文件非常有用。所有使用 anon_inode_getfile()
创建的文件将共享单个 inode,从而节省内存并避免文件/inode/dentry 设置的代码重复。返回新创建的 file* 或错误指针。
-
struct file *anon_inode_getfile_fmode(const char *name, const struct file_operations *fops, void *priv, int flags, fmode_t f_mode)¶
通过将其连接到匿名 inode 和描述文件“类”的 dentry 来创建一个新的文件实例
参数
const char *name
[in] 新文件“类”的名称
const struct file_operations *fops
[in] 新文件的文件操作
void *priv
[in] 新文件的私有数据(将是文件的 private_data)
int flags
[in] 标志
fmode_t f_mode
[in] fmode
描述
通过将其连接到单个 inode 来创建一个新文件。这对于不需要具有完整的 inode 才能正确操作的文件非常有用。所有使用 anon_inode_getfile()
创建的文件将共享单个 inode,从而节省内存并避免文件/inode/dentry 设置的代码重复。允许设置 fmode。返回新创建的 file* 或错误指针。
-
struct file *anon_inode_create_getfile(const char *name, const struct file_operations *fops, void *priv, int flags, const struct inode *context_inode)¶
类似于
anon_inode_getfile()
,但会创建一个新的 !S_PRIVATE 匿名 inode,而不是重用单例匿名 inode,并调用 inode_init_security_anon() LSM 钩子。
参数
const char *name
[in] 新文件“类”的名称
const struct file_operations *fops
[in] 新文件的文件操作
void *priv
[in] 新文件的私有数据(将是文件的 private_data)
int flags
[in] 标志
const struct inode *context_inode
[in] 与新 inode 的逻辑关系(可选)
描述
创建新的匿名 inode 和文件对。这可以出于两个原因完成
为了使 inode 具有自己的安全上下文,以便 LSM 可以强制执行对 inode 创建的策略;
如果调用者需要唯一的 inode,例如为了自定义 fstat() 返回的大小
LSM 可能会在 inode_init_security_anon() 中使用 context_inode,但不会持有对它的引用。
返回新创建的 file* 或错误指针。
-
int anon_inode_getfd(const char *name, const struct file_operations *fops, void *priv, int flags)¶
通过将其连接到匿名 inode 和描述文件“类”的 dentry 来创建新的文件实例
参数
const char *name
[in] 新文件“类”的名称
const struct file_operations *fops
[in] 新文件的文件操作
void *priv
[in] 新文件的私有数据(将是文件的 private_data)
int flags
[in] 标志
描述
通过将其连接到单个 inode 来创建新文件。这对于不需要具有完整 inode 才能正确操作的文件很有用。使用 anon_inode_getfd()
创建的所有文件将使用相同的单例 inode,从而减少内存使用并避免文件/inode/dentry 设置的代码重复。返回新创建的文件描述符或错误代码。
参数
struct mnt_idmap *idmap
从 inode 中找到的挂载的 idmap
const struct inode *inode
要检查的 inode
描述
此函数确定是否需要删除 setgid 位。我们保留向后兼容性,并且如果设置了 S_IXGRP,则需要无条件删除 setgid 位。否则,我们具有与 setattr_prepare()
和 setattr_copy()
完全相同的要求。
返回
如果需要删除 setgid 位,则为 ATTR_KILL_SGID,否则为 0。
-
int setattr_should_drop_suidgid(struct mnt_idmap *idmap, struct inode *inode)¶
确定是否需要删除 set{g,u}id 位
参数
struct mnt_idmap *idmap
从 inode 中找到的挂载的 idmap
struct inode *inode
要检查的 inode
描述
此函数确定是否需要删除 set{g,u}id 位。如果需要删除 setuid 位,则返回 ATTR_KILL_SUID。如果需要删除 setgid 位,则返回 ATTR_KILL_SGID。如果需要删除 set{g,u}id 位,则返回两个标志的相应掩码。
返回
指示要删除哪些 setid 位(如果有)的 ATTR_KILL_S{G,U}ID 的掩码,否则为 0。
-
int setattr_prepare(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *attr)¶
检查是否允许更改 dentry 的属性
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
struct dentry *dentry
要检查的 dentry
struct iattr *attr
要更改的属性
描述
检查是否允许更改给定 dentry 中包含在 attr 中的属性。这包括正常的 unix 访问权限检查,以及对 rlimit 和其他内容的检查。如果用户无权设置 SGID 位,该函数还会从模式中清除该位。如果设置了 ATTR_KILL_PRIV,还会清除文件功能和 IMA 扩展属性。
如果 inode 是通过 idmapped 挂载找到的,则必须通过 idmap 传递 vfsmount 的 idmap。 然后,此函数将负责根据 idmap 映射 inode,然后再检查权限。 在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
应在 ->setattr 实现中作为第一件事调用,可能在获取其他锁之后。
参数
const struct inode *inode
要截断的 inode
loff_t offset
要分配给 inode 的新大小
描述
必须在持有 i_mutex 的情况下调用 inode_newsize_ok。
inode_newsize_ok 将检查文件系统限制和 ulimit,以检查新的 inode 大小是否在限制范围内。inode_newsize_ok 还将在必要时发送 SIGXFSZ。如果返回失败,调用者不得继续进行 inode 大小更改。inode 必须是文件(而不是目录),并且具有允许截断的适当权限(inode_newsize_ok 不检查这些条件)。
返回
成功时为 0,失败时为 -ve errno
-
void setattr_copy(struct mnt_idmap *idmap, struct inode *inode, const struct iattr *attr)¶
将简单的元数据更新复制到通用 inode 中
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
struct inode *inode
要更新的 inode
const struct iattr *attr
新属性
描述
必须在持有 i_mutex 的情况下调用 setattr_copy。
setattr_copy 使用 attr 中指定的元数据更新 idmapped 挂载上的 inode 元数据。使用正确的 idmapped 挂载权限助手执行必要的权限检查,以确定是否需要删除 S_ISGID 属性。明显缺少的是 inode 大小更新,因为它需要更复杂的 pagecache 更新。
如果 inode 是通过 idmapped 挂载找到的,则必须通过 idmap 传递 vfsmount 的 idmap。 然后,此函数将负责根据 idmap 映射 inode,然后再检查权限。 在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
此操作后,inode 不会标记为脏。理由是对于“简单”文件系统,struct inode 是 inode 存储。如果需要,调用者可以随意在之后将 inode 标记为脏。
-
int notify_change(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *attr, struct inode **delegated_inode)¶
修改文件系统对象的属性
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
struct dentry *dentry
受影响的对象
struct iattr *attr
新属性
struct inode **delegated_inode
如果 inode 已委托,则返回 inode
描述
调用者必须持有受影响对象上的 i_mutex。
如果 notify_change 发现需要中断的委托,它将返回 -EWOULDBLOCK 并在 delegated_inode 中返回对 inode 的引用。然后,调用者应中断委托并重试。由于中断委托可能需要很长时间,因此调用者应在执行此操作之前释放 i_mutex。
或者,调用者可以为 delegated_inode 传递 NULL。这可能适用于期望底层文件系统未导出 NFS 的调用者。此外,对于为写入打开文件的调用者来说,传递 NULL 是可以的,因为在这种情况下不可能存在冲突的委托。
如果 inode 是通过 idmapped 挂载找到的,则必须通过 idmap 传递 vfsmount 的 idmap。 然后,此函数将负责根据 idmap 映射 inode,然后再检查权限。 在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
参数
const struct path *path
要报告的路径
char *buf
用于在其中返回值的缓冲区
int buflen
缓冲区长度
描述
将 dentry 转换为 ASCII 路径名。如果条目已被删除,则会附加字符串“ (已删除)”。请注意,这不明确。
如果路径太长,则返回指向缓冲区中的指针或错误代码。注意:调用者应使用返回的指针,而不是传入的缓冲区,来使用名称!该实现通常从缓冲区中的偏移量开始,并且可能会在开头留下 0 个字节。
“buflen”应为正数。
-
struct page *dax_layout_busy_page_range(struct address_space *mapping, loff_t start, loff_t end)¶
在 mapping 中查找第一个固定的页面
参数
struct address_space *mapping
要扫描引用计数 > 1 的页面的地址空间
loff_t start
起始偏移量。包含“start”的页面包含在内。
loff_t end
结束偏移量。包含“end”的页面包含在内。如果“end”为 LLONG_MAX,则包含从“start”到文件结尾的页面。
描述
DAX 需要 ZONE_DEVICE 映射的页面。这些页面从未“联机”到页面分配器,因此当 page->count == 1 时,它们被认为是空闲的。文件系统使用此接口来确定映射中的任何页面是否繁忙,即用于 DMA 或其他 get_user_pages() 用法。
预期文件系统持有锁以阻止在此 address_space 中建立新映射。即,它期望能够运行 unmap_mapping_range()
,随后不会竞争 mapping_mapped() 变为 true。
-
ssize_t dax_iomap_rw(struct kiocb *iocb, struct iov_iter *iter, const struct iomap_ops *ops)¶
对 DAX 文件执行 I/O
参数
struct kiocb *iocb
此 I/O 的控制块
struct iov_iter *iter
从或向其执行 I/O 的地址
const struct iomap_ops *ops
从文件系统传递的 iomap ops
描述
此函数对直接映射的持久内存执行读取和写入操作。调用者需要注意读取/写入排除以及驱逐 I/O 下区域中的任何页面缓存页面。
-
vm_fault_t dax_iomap_fault(struct vm_fault *vmf, unsigned int order, pfn_t *pfnp, int *iomap_errp, const struct iomap_ops *ops)¶
处理 DAX 文件上的页面错误
参数
struct vm_fault *vmf
错误的描述
unsigned int order
要错误获取的页面的顺序
pfn_t *pfnp
如果需要 fsync,则为同步错误的要插入的 PFN
int *iomap_errp
用于在发生错误时存储详细错误代码的存储
const struct iomap_ops *ops
从文件系统传递的 Iomap ops
描述
发生页面错误时,文件系统可能会在其 DAX 文件的错误处理程序中调用此帮助程序。dax_iomap_fault()
假定调用者已完成所有必要的锁定,以便页面错误成功进行。
-
vm_fault_t dax_finish_sync_fault(struct vm_fault *vmf, unsigned int order, pfn_t pfn)¶
完成同步页面错误
参数
struct vm_fault *vmf
错误的描述
unsigned int order
要插入的条目的顺序
pfn_t pfn
要插入的 PFN
描述
此函数确保页面错误触及的文件范围持久存储在介质上,并处理插入适当的页表条目。
-
void simple_rename_timestamp(struct inode *old_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry)¶
更新重命名的各种 inode 时间戳
参数
struct inode *old_dir
旧的父目录
struct dentry *old_dentry
正在重命名的 dentry
struct inode *new_dir
新的父目录
struct dentry *new_dentry
重命名的目标
描述
POSIX 规定旧的和新的父目录都需要更新其 ctime 和 mtime,并且 old_dentry 和 new_dentry 的 inode(如果有)需要更新其 ctime。
-
int simple_setattr(struct mnt_idmap *idmap, struct dentry *dentry, struct iattr *iattr)¶
为简单文件系统设置属性
参数
struct mnt_idmap *idmap
目标挂载的idmap
struct dentry *dentry
目录项(dentry)
struct iattr *iattr
iattr 结构体
描述
成功时返回 0,失败时返回 -error。
simple_setattr 是一个简单的 ->setattr 实现,没有正确实现大小更改。
它既可以用于内存文件系统,也可以用于简单常规文件系统上的特殊文件。任何需要在大小更改时更改磁盘上或网络状态的内容都需要自己的 setattr 方法。
-
ssize_t simple_read_from_buffer(void __user *to, size_t count, loff_t *ppos, const void *from, size_t available)¶
将数据从缓冲区复制到用户空间
参数
void __user *to
要读取到的用户空间缓冲区
size_t count
要读取的最大字节数
loff_t *ppos
缓冲区中的当前位置
const void *from
要从中读取的缓冲区
size_t available
缓冲区的大小
描述
simple_read_from_buffer()
函数从 from 缓冲区的 ppos 偏移量处读取最多 count 个字节到从 to 开始的用户空间地址。
成功时,返回读取的字节数,并且偏移量 ppos 会增加此数字;出错时,返回负值。
-
ssize_t simple_write_to_buffer(void *to, size_t available, loff_t *ppos, const void __user *from, size_t count)¶
将数据从用户空间复制到缓冲区
参数
void *to
要写入的缓冲区
size_t available
缓冲区的大小
loff_t *ppos
缓冲区中的当前位置
const void __user *from
要从中读取的用户空间缓冲区
size_t count
要读取的最大字节数
描述
simple_write_to_buffer()
函数从 from 开始的用户空间地址读取最多 count 个字节到 to 缓冲区中的 ppos 偏移量处。
成功时,返回写入的字节数,并且偏移量 ppos 会增加此数字;出错时,返回负值。
-
ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos, const void *from, size_t available)¶
从缓冲区复制数据
参数
void *to
要读取到的内核空间缓冲区
size_t count
要读取的最大字节数
loff_t *ppos
缓冲区中的当前位置
const void *from
要从中读取的缓冲区
size_t available
缓冲区的大小
描述
memory_read_from_buffer()
函数从 from 缓冲区的 ppos 偏移量处读取最多 count 个字节到从 to 开始的内核空间地址。
成功时,返回读取的字节数,并且偏移量 ppos 会增加此数字;出错时,返回负值。
-
int generic_encode_ino32_fh(struct inode *inode, __u32 *fh, int *max_len, struct inode *parent)¶
通用的 export_operations->encode_fh 函数
参数
struct inode *inode
要编码的对象
__u32 *fh
文件句柄片段的存储位置
int *max_len
存储的最大长度(以 4 字节为单位)
struct inode *parent
父目录 inode(如果需要)
描述
此通用 encode_fh 函数假定 32 位 inode 编号适合用于定位 inode,并且可以使用生成号来检查它是否仍然有效。它将它们放置在 export_decode_fh 期望找到它们的 filehandle 片段中。
-
struct dentry *generic_fh_to_dentry(struct super_block *sb, struct fid *fid, int fh_len, int fh_type, struct inode *(*get_inode)(struct super_block *sb, u64 ino, u32 gen))¶
fh_to_dentry 导出操作的通用助手函数
参数
struct super_block *sb
要在其上执行文件句柄转换的文件系统
struct fid *fid
要转换的文件句柄
int fh_len
文件句柄的长度(以字节为单位)
int fh_type
文件句柄的类型
struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen)
文件系统回调,用于检索 inode
描述
只要 fid 具有已知的 Linux 文件句柄类型之一,此函数就会解码 fid,并在其上调用 get_inode 以检索文件句柄中指定的对象的 inode。
-
struct dentry *generic_fh_to_parent(struct super_block *sb, struct fid *fid, int fh_len, int fh_type, struct inode *(*get_inode)(struct super_block *sb, u64 ino, u32 gen))¶
fh_to_parent 导出操作的通用助手函数
参数
struct super_block *sb
要在其上执行文件句柄转换的文件系统
struct fid *fid
要转换的文件句柄
int fh_len
文件句柄的长度(以字节为单位)
int fh_type
文件句柄的类型
struct inode *(*get_inode) (struct super_block *sb, u64 ino, u32 gen)
文件系统回调,用于检索 inode
描述
只要 fid 具有已知的 Linux 文件句柄类型之一,此函数就会解码 fid,并在其上调用 get_inode 以检索文件句柄中指定的 _parent_ 对象的 inode(如果在文件句柄中指定),否则返回 NULL。
-
int __generic_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)¶
简单文件系统的通用 fsync 实现
参数
struct file *file
要同步的文件
loff_t start
起始偏移量(以字节为单位)
loff_t end
结束偏移量(包含)
int datasync
如果为 true,则仅同步基本元数据
描述
这是简单文件系统的 fsync 方法的通用实现,它在 address_space 结构挂起的缓冲区列表中跟踪所有非 inode 元数据。
-
int generic_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)¶
带有 flush 的简单文件系统的通用 fsync 实现
参数
struct file *file
要同步的文件
loff_t start
起始偏移量(以字节为单位)
loff_t end
结束偏移量(包含)
int datasync
如果为 true,则仅同步基本元数据
-
int generic_check_addressable(unsigned blocksize_bits, u64 num_blocks)¶
检查文件系统的可寻址性
参数
unsigned blocksize_bits
文件系统块大小的对数
u64 num_blocks
文件系统中的块数
描述
确定具有 num_blocks 个块(以及 2****blocksize_bits** 的块大小)的文件系统是否可由系统的 sector_t 和页面缓存寻址。如果是,则返回 0;否则返回 -EFBIG。
-
int simple_nosetlease(struct file *filp, int arg, struct file_lease **flp, void **priv)¶
禁止租约的通用助手函数
参数
struct file *filp
文件指针
int arg
要获得的租约的类型
struct file_lease **flp
提供插入的新租约
void **priv
lm_setup 操作的私有数据
描述
用于不希望允许设置租约的文件系统的通用助手函数。所有参数都将被忽略,它只返回 -EINVAL。
-
const char *simple_get_link(struct dentry *dentry, struct inode *inode, struct delayed_call *done)¶
用于获取“快速”符号链接目标的通用助手函数
参数
struct dentry *dentry
此处未使用
struct inode *inode
符号链接 inode
struct delayed_call *done
此处未使用
描述
用于文件系统的通用助手函数,用于符号链接 inode,其中指向符号链接目标的指针存储在 ->i_link 中。注意:这通常不会被调用,因为作为一种优化,路径查找代码直接使用任何非 NULL ->i_link,而不调用 ->get_link()。但是 ->get_link() 仍然必须设置,以将 inode_operations 标记为用于符号链接。
返回
符号链接目标
-
int generic_ci_d_compare(const struct dentry *dentry, unsigned int len, const char *str, const struct qstr *name)¶
区分大小写的文件系统的通用 d_compare 实现
参数
const struct dentry *dentry
要检查其名称的目录项
unsigned int len
目录项名称的长度
const char *str
指向目录项名称的 str 指针
const struct qstr *name
要比较的名称
返回
如果名称匹配,则为 0;如果名称不匹配,则为 1;或者为 -ERRNO
参数
const struct dentry *dentry
父目录的目录项
struct qstr *str
需要填充哈希值的名称的 qstr
返回
如果哈希成功或未更改,则为 0;如果发生错误,则为 -EINVAL
-
int generic_ci_match(const struct inode *parent, const struct qstr *name, const struct qstr *folded_name, const u8 *de_name, u32 de_name_len)¶
将名称(不区分大小写)与目录项进行匹配。这是用于与目录条目进行比较的文件系统辅助函数。在 VFS 的 ->d_compare 中应使用 generic_ci_d_compare。
参数
const struct inode *parent
正在比较的目录项的父 inode
const struct qstr *name
查找下的名称。
const struct qstr *folded_name
查找下可选的预折叠名称
const u8 *de_name
目录项名称。
u32 de_name_len
目录项名称长度。
描述
测试不区分大小写的目录项是否与正在搜索的文件名匹配。如果提供了 folded_name,则使用它而不是重新计算 name 的 casefold。
返回
> 如果目录项匹配,则为 0;如果不匹配,则为 0;如果出错,则 < 0。
-
void generic_set_sb_d_ops(struct super_block *sb)¶
用于为已启用的特性选择文件系统范围的目录项操作集的辅助函数
参数
struct super_block *sb
要配置的超级块
描述
支持 casefolding 和/或 fscrypt 的文件系统可以在挂载时调用此辅助函数,以配置 sb->s_d_op 为已启用特性所需的最佳目录项操作集。必须在配置这些特性之后,但在创建根目录项之前调用此辅助函数。
参数
struct inode *inode
带有应更新的 i_version 的 inode
bool force
即使没有必要,也要递增计数器?
描述
每次修改 inode 时,任何观察者都必须看到 i_version 字段已更改。
如果设置了“force”或设置了 QUERIED 标志,则确保我们递增该值并清除 queried 标志。
在未设置两者的一般情况下,我们可以返回“false”而不更新 i_version。
如果此函数返回 false 并且没有其他元数据已更改,则我们可以避免记录元数据。
参数
struct inode *inode
从中读取 i_version 的 inode
描述
读取 inode i_version 计数器。希望存储返回的 i_version 以供以后比较的调用方应使用此计数器。这将保证如果任何内容发生更改,则以后对 i_version 的查询将产生不同的值。
在此实现中,我们获取当前值,设置 QUERIED 标志,然后尝试使用 cmpxchg 将其交换到位,如果尚未设置。如果失败,我们将使用来自 cmpxchg 的新获取的值重试。
参数
struct inode *inode
要初始化的 inode
描述
创建新 inode 时,大多数文件系统会将时间戳设置为当前时间。添加一个辅助函数来执行此操作。
-
int posix_acl_chmod(struct mnt_idmap *idmap, struct dentry *dentry, umode_t mode)¶
chmod 一个 posix acl
参数
struct mnt_idmap *idmap
从 inode 中找到的挂载的 idmap
struct dentry *dentry
在其上检查权限的 dentry
umode_t mode
inode 的新模式
描述
如果通过 idmapped 挂载找到了该目录项,则必须通过 idmap 传递 vfsmount 的 idmap。然后,此函数将负责根据 idmap 映射 inode,然后再检查权限。在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
-
int posix_acl_update_mode(struct mnt_idmap *idmap, struct inode *inode, umode_t *mode_p, struct posix_acl **acl)¶
更新 set_acl 中的模式
参数
struct mnt_idmap *idmap
从 inode 中找到的挂载的 idmap
struct inode *inode
目标 inode
umode_t *mode_p
用于更新的模式(指针)
struct posix_acl **acl
acl 指针
描述
设置 ACL 时更新文件模式:基于 ACL 计算新的文件权限位。此外,如果 ACL 等效于新的文件模式,则将 *acl 设置为 NULL,以指示不应设置任何 ACL。
与 chmod 一样,如果调用方不在拥有的组中,或者没有 CAP_FSETID 的功能,则清除 setgid 位(请参阅 inode_change_ok)。
如果 inode 是通过 idmapped 挂载找到的,则必须通过 idmap 传递 vfsmount 的 idmap。 然后,此函数将负责根据 idmap 映射 inode,然后再检查权限。 在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
从 set_acl inode 操作调用。
-
struct posix_acl *posix_acl_from_xattr(struct user_namespace *userns, const void *value, size_t size)¶
将 POSIX ACL 从后备存储转换为 VFS 格式
参数
struct user_namespace *userns
文件系统的 idmapping
const void *value
POSIX ACL 的 uapi 表示形式
size_t size
void 的大小
描述
以未更改的 uapi 格式存储 POSIX ACL 的文件系统应在从后备存储读取 POSIX ACL 并将其转换为 struct posix_acl VFS 格式时使用 posix_acl_from_xattr()
。该辅助函数专门用于从 acl inode 操作中调用。
posix_acl_from_xattr()
函数会将存储在 ACL_{GROUP,USER} 条目中的原始 {g,u}id 值映射到 userns 中的 idmapping。
请注意,posix_acl_from_xattr()
不考虑 idmapped 挂载。如果考虑了,则从 get acl inode 操作调用它将返回根据 idmapped 挂载映射的 POSIX ACL,这意味着该值无法为文件系统缓存。Idmapped 挂载在权限检查期间或在将它们报告给用户之前就在 VFS - 用户空间边界上动态考虑。
返回
- 成功时分配的 struct posix_acl,对于有效的标头为 NULL,但
没有实际的 POSIX ACL 条目,或
ERR_PTR()
编码的错误代码。
-
int vfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name, struct posix_acl *kacl)¶
设置 posix acls
参数
struct mnt_idmap *idmap
挂载的 idmap
struct dentry *dentry
在其上设置 posix acls 的 dentry
const char *acl_name
posix acl 的名称
struct posix_acl *kacl
采用适当 VFS 格式的 posix acls
描述
此函数设置 kacl。调用方必须在此后对 kacl 调用 posix_acl_release()。
返回
成功时为 0,出错时为负 errno。
-
struct posix_acl *vfs_get_acl(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name)¶
获取 posix acls
参数
struct mnt_idmap *idmap
挂载的 idmap
struct dentry *dentry
在其上检索 posix acls 的 dentry
const char *acl_name
posix acl 的名称
描述
此函数从文件系统检索 kacl。调用方必须对 kacl 调用 posix_acl_release()。
返回
成功时为 VFS 格式的 POSIX ACL,出错时为负 errno。
-
int vfs_remove_acl(struct mnt_idmap *idmap, struct dentry *dentry, const char *acl_name)¶
删除 posix acls
参数
struct mnt_idmap *idmap
挂载的 idmap
struct dentry *dentry
在其上检索 posix acls 的 dentry
const char *acl_name
posix acl 的名称
描述
此函数删除 posix acls。
返回
成功时为 0,出错时为负 errno。
-
void fill_mg_cmtime(struct kstat *stat, u32 request_mask, struct inode *inode)¶
填充 mtime 和 ctime 并将 ctime 标记为 QUERIED
参数
struct kstat *stat
在何处存储结果值
u32 request_mask
请求的 STATX_* 值
struct inode *inode
从中抓取 c/mtime 的 inode
描述
给定 inode,如果存在,则从中抓取 ctime 和 mtime,并将结果存储在 stat 中。在获取该值时,将其标记为 QUERIED(如果尚未标记),以便下次写入将记录不同的时间戳。
注意:QUERIED 标志在 ctime 中进行跟踪,但即使仅请求了 mtime,我们也会在此处设置它,因为这可以确保下次 mtime 更改将是不同的。
-
void generic_fillattr(struct mnt_idmap *idmap, u32 request_mask, struct inode *inode, struct kstat *stat)¶
从 inode 结构填充基本属性
参数
struct mnt_idmap *idmap
找到 inode 的挂载点的 idmap
u32 request_mask
statx request_mask
struct inode *inode
用作源的 Inode
struct kstat *stat
在何处填充属性
描述
从 VFS inode 结构上可以找到的数据填充 kstat 结构中的基本属性。如果没有提供 getattr inode 操作,则这是默认值。
如果通过 idmapped 挂载找到了该 inode,则必须通过 idmap 传递 vfsmount 的 idmap。然后,此函数将负责根据 idmap 映射 inode,然后再填充 uid 和 gid filds。在非 idmapped 挂载上,或者如果要在原始 inode 上执行权限检查,只需传递 nop_mnt_idmap。
参数
struct inode *inode
用作源的 Inode
struct kstat *stat
在何处填充属性标志
描述
填充 kstat 结构中的 STATX_ATTR_* 标志,以表示在 i_flags 上发布并由 VFS 强制执行的 inode 的属性。
-
void generic_fill_statx_atomic_writes(struct kstat *stat, unsigned int unit_min, unsigned int unit_max, unsigned int unit_max_opt)¶
填充原子写入 statx 属性
参数
struct kstat *stat
在何处填充属性标志
unsigned int unit_min
支持的最小原子写入长度(以字节为单位)
unsigned int unit_max
支持的最大原子写入长度(以字节为单位)
unsigned int unit_max_opt
优化的最大支持原子写入长度(以字节为单位)
描述
从原子写入 unit_min 和 unit_max 值填充 kstat 结构中的 STATX{_ATTR}_WRITE_ATOMIC 标志。
-
int vfs_getattr_nosec(const struct path *path, struct kstat *stat, u32 request_mask, unsigned int query_flags)¶
获取属性但不进行安全检查
参数
const struct path *path
从中获取属性的文件
struct kstat *stat
用于返回属性的结构
u32 request_mask
指示调用者需要什么的STATX_xxx 标志
unsigned int query_flags
查询模式 (AT_STATX_SYNC_TYPE)
描述
获取属性而不调用 security_inode_getattr。
目前,除了 vfs_getattr 之外,唯一的调用者是文件句柄查找代码内部,它仅使用 inode 编号,不向任何用户返回任何属性。任何其他代码可能需要 vfs_getattr。
-
int vfs_fsync_range(struct file *file, loff_t start, loff_t end, int datasync)¶
用于将一定范围的数据和元数据同步到磁盘的辅助函数
参数
struct file *file
要同步的文件
loff_t start
要同步的数据范围起点的字节偏移量
loff_t end
数据范围终点的字节偏移量(包含)
int datasync
仅执行 datasync
描述
将范围 **start**..**end** 中的数据和 **file** 的元数据写回磁盘。如果设置了 **datasync**,则仅写入访问修改的文件数据所需的元数据。
参数
struct file *file
要同步的文件
int datasync
仅执行 fdatasync 操作
描述
将 **file** 的数据和元数据写回磁盘。如果设置了 **datasync**,则仅写入访问修改的文件数据所需的元数据。
-
int __vfs_setxattr_locked(struct mnt_idmap *idmap, struct dentry *dentry, const char *name, const void *value, size_t size, int flags, struct inode **delegated_inode)¶
在持有 inode 锁时设置扩展属性
参数
struct mnt_idmap *idmap
目标 inode 的挂载的 idmap
struct dentry *dentry
要在其上执行 setxattr 的对象
const char *name
要设置的 xattr 名称
const void *value
要将 **name** 设置为的值
size_t size
**value** 的大小
int flags
要传递到文件系统操作的标志
struct inode **delegated_inode
返回时,将包含一个委派被破坏的 inode 指针,如果没有,则为 NULL。
参数
struct dentry *dentry
从中检索 xattr 名称的 inode 的 dentry
char *list
用于存储 xattr 名称的缓冲区
size_t size
缓冲区的大小
描述
此函数返回与 **dentry** 的 inode 关联的所有 xattr 的名称。
请注意,由于历史原因,vfs_listxattr()
函数也列出了 POSIX ACL。由于 POSIX ACL 与 IOP_XATTR 解耦,因此 vfs_listxattr()
函数不检查此标志,因为文件系统可以在不实现任何其他 xattr 的情况下实现 POSIX ACL。
但是,由于所有删除 IOP_XATTR 的代码路径也分配了不实现或实现存根 ->listxattr() 操作的 inode 操作。
返回
- 成功时,使用缓冲区的字节大小。出错时,返回一个
负错误代码。
-
int __vfs_removexattr_locked(struct mnt_idmap *idmap, struct dentry *dentry, const char *name, struct inode **delegated_inode)¶
在持有 inode 锁时设置扩展属性
参数
struct mnt_idmap *idmap
目标 inode 的挂载的 idmap
struct dentry *dentry
要在其上执行 setxattr 的对象
const char *name
要删除的 xattr 的名称
struct inode **delegated_inode
返回时,将包含一个委派被破坏的 inode 指针,如果没有,则为 NULL。
-
ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)¶
运行通过 dentry 的 xattr list() 操作
参数
struct dentry *dentry
要列出 xattr 的 dentry
char *buffer
结果缓冲区
size_t buffer_size
**buffer** 的大小
描述
合并来自 xattr_handler 堆栈中每个 xattr_handler 的 list() 操作的结果。
请注意,这不包括 POSIX ACL 的条目。
-
const char *xattr_full_name(const struct xattr_handler *handler, const char *name)¶
从后缀计算完整属性名称
参数
const struct xattr_handler *handler
xattr_handler 操作的处理程序
const char *name
传递给 xattr_handler 操作的名称
描述
get 和 set xattr 处理程序操作在跳过处理程序的前缀后,使用属性名称的其余部分调用:例如,“foo”传递给具有前缀“user.”的处理程序的 get 操作,以获取属性“user.foo”。完整名称仍然在名称中“存在”。
注意
当从 vfs 调用时,list xattr 处理程序操作会传递一个 NULL 名称;一些文件系统在内部使用此操作,语义各不相同。
-
int mnt_get_write_access(struct vfsmount *m)¶
获取对挂载的写入权限,没有冻结保护
参数
struct vfsmount *m
要在其上进行写入的挂载
描述
这告诉底层文件系统即将对其执行写入操作,并确保允许写入(mnt 是读写),然后才返回成功。此操作不防止文件系统被冻结。写入操作完成后,必须调用 mnt_put_write_access()
。这实际上是一个引用计数。
-
int mnt_want_write(struct vfsmount *m)¶
获取对挂载的写入权限
参数
struct vfsmount *m
要在其上进行写入的挂载
描述
这告诉底层文件系统即将对其执行写入操作,并确保允许写入(挂载是读写,文件系统未冻结),然后才返回成功。写入操作完成后,必须调用 mnt_drop_write()
。这实际上是一个引用计数。
参数
struct file *file
要在其上进行写入的文件的挂载
描述
这类似于 mnt_want_write,但如果该文件已经打开以进行写入,它将跳过递增 mnt_writers(因为打开的文件已经具有引用),而是仅执行冻结保护和紧急 r/o 重新挂载检查。这必须与 mnt_drop_write_file 配对。
-
void mnt_put_write_access(struct vfsmount *mnt)¶
放弃对挂载的写入权限
-
void mnt_drop_write(struct vfsmount *mnt)¶
放弃对挂载的写入权限
参数
struct vfsmount *mnt
要放弃写入权限的挂载
描述
告诉底层文件系统,我们已完成对其执行写入操作,并且还允许再次冻结文件系统。必须与上面的 mnt_want_write()
调用匹配。
-
struct vfsmount *vfs_create_mount(struct fs_context *fc)¶
为已配置的超级块创建挂载
参数
struct fs_context *fc
带有附加的超级块的配置上下文
描述
创建到已配置的超级块的挂载。如有必要,调用者应在调用此函数之前调用 vfs_get_tree()
。
请注意,这不会将挂载附加到任何内容。
参数
const struct path *path
要检查的路径
d_mountpoint() 只能可靠地用于确定 dentry 是否未挂载在任何命名空间中,并且内联处理了常见的这种情况。d_mountpoint() 不知道可能存在多个在不同命名空间中使用给定 dentry 的挂载。此函数检查传入的路径是否为挂载点,而不是仅检查 dentry。
-
int may_umount_tree(struct vfsmount *m)¶
检查挂载树是否繁忙
参数
struct vfsmount *m
挂载树的根
描述
调用此函数是为了检查挂载树是否具有任何打开的文件、pwds、chroot 或繁忙的子挂载。
-
int may_umount(struct vfsmount *mnt)¶
检查挂载点是否繁忙
参数
struct vfsmount *mnt
挂载的根
描述
调用此函数是为了检查挂载点是否具有任何打开的文件、pwds、chroot 或子挂载。如果挂载具有子挂载,则无论子挂载是否繁忙,此函数都将返回繁忙。
不考虑配额和其他内容。换句话说,在某些情况下,它会给出错误的否定结果。它存在的主要原因是我们需要一种非破坏性的方式来查找易于卸载的文件系统。
参数
const struct path *path
要克隆的路径
描述
这将创建一个新的 vfsmount,它将是 **path** 的克隆。新的挂载将不会附加到命名空间中的任何位置,并且将是私有的(即,对原始挂载的更改将不会传播到此挂载中)。
这假定调用者已调用或执行了与 may_mount() 等效的操作。
使用 mntput() 释放。
-
void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list)¶
将挂载放在到期列表中
参数
struct vfsmount *mnt
要列出的挂载。
struct list_head *expiry_list
要将挂载添加到的列表。
proc 文件系统¶
sysctl 接口¶
-
int proc_dostring(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos)¶
读取一个字符串 sysctl
参数
const struct ctl_table *table
sysctl 表
int write
如果这是对 sysctl 文件的写入,则为
TRUE
void *buffer
用户缓冲区
size_t *lenp
用户缓冲区的大小
loff_t *ppos
文件位置
描述
从用户缓冲区读取/写入字符串。如果内核缓冲区不够大,无法容纳字符串,则字符串将被截断。复制的字符串以 NULL
结尾。如果字符串正在被用户进程读取,则会被复制并添加换行符“n”。如果缓冲区不够大,则会被截断。
成功时返回 0。
-
int proc_dobool(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos)¶
读取/写入一个布尔值
参数
const struct ctl_table *table
sysctl 表
int write
如果这是对 sysctl 文件的写入,则为
TRUE
void *buffer
用户缓冲区
size_t *lenp
用户缓冲区的大小
loff_t *ppos
文件位置
描述
从/向用户缓冲区读取/写入一个整数值,将其视为 ASCII 字符串。
table->data 必须指向一个 bool 变量,并且 table->maxlen 必须为 sizeof(bool)。
成功时返回 0。
-
int proc_dointvec(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos)¶
读取一个整数向量
参数
const struct ctl_table *table
sysctl 表
int write
如果这是对 sysctl 文件的写入,则为
TRUE
void *buffer
用户缓冲区
size_t *lenp
用户缓冲区的大小
loff_t *ppos
文件位置
描述
从/向用户缓冲区读取/写入最多 table->maxlen/sizeof(unsigned int) 个整数值,将其视为 ASCII 字符串。
成功时返回 0。
-
int proc_douintvec(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos)¶
读取一个无符号整数向量
参数
const struct ctl_table *table
sysctl 表
int write
如果这是对 sysctl 文件的写入,则为
TRUE
void *buffer
用户缓冲区
size_t *lenp
用户缓冲区的大小
loff_t *ppos
文件位置
描述
从/向用户缓冲区读取/写入最多 table->maxlen/sizeof(unsigned int) 个无符号整数值,将其视为 ASCII 字符串。
成功时返回 0。
-
int proc_dointvec_minmax(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos)¶
读取具有最小值/最大值的整数向量
参数
const struct ctl_table *table
sysctl 表
int write
如果这是对 sysctl 文件的写入,则为
TRUE
void *buffer
用户缓冲区
size_t *lenp
用户缓冲区的大小
loff_t *ppos
文件位置
描述
从/向用户缓冲区读取/写入最多 table->maxlen/sizeof(unsigned int) 个整数值,将其视为 ASCII 字符串。
此例程将确保这些值在 table->extra1(最小值)和 table->extra2(最大值)指定的范围内。
成功时返回 0,如果写入时范围检查失败,则返回 -EINVAL。
-
int proc_douintvec_minmax(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos)¶
读取具有最小值/最大值的无符号整数向量
参数
const struct ctl_table *table
sysctl 表
int write
如果这是对 sysctl 文件的写入,则为
TRUE
void *buffer
用户缓冲区
size_t *lenp
用户缓冲区的大小
loff_t *ppos
文件位置
描述
从/向用户缓冲区读取/写入最多 table->maxlen/sizeof(unsigned int) 个无符号整数值,将其视为 ASCII 字符串。不允许使用负字符串。
此例程将确保这些值在 table->extra1(最小值)和 table->extra2(最大值)指定的范围内。最终会对 UINT_MAX 进行健全性检查,以避免不得不支持来自用户空间的环绕使用。
成功时返回 0,如果写入时范围检查失败,则返回 -ERANGE。
-
int proc_dou8vec_minmax(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos)¶
读取具有最小值/最大值的无符号字符向量
参数
const struct ctl_table *table
sysctl 表
int write
如果这是对 sysctl 文件的写入,则为
TRUE
void *buffer
用户缓冲区
size_t *lenp
用户缓冲区的大小
loff_t *ppos
文件位置
描述
从/向用户缓冲区读取/写入最多 table->maxlen/sizeof(u8) 个无符号字符值,将其视为 ASCII 字符串。不允许使用负字符串。
此例程将确保这些值在 table->extra1(最小值)和 table->extra2(最大值)指定的范围内。
成功时返回 0,如果写入时范围检查失败,则返回错误。
-
int proc_doulongvec_minmax(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos)¶
读取具有最小值/最大值的长整数向量
参数
const struct ctl_table *table
sysctl 表
int write
如果这是对 sysctl 文件的写入,则为
TRUE
void *buffer
用户缓冲区
size_t *lenp
用户缓冲区的大小
loff_t *ppos
文件位置
描述
从/向用户缓冲区读取/写入最多 table->maxlen/sizeof(unsigned long) 个无符号长整数值,将其视为 ASCII 字符串。
此例程将确保这些值在 table->extra1(最小值)和 table->extra2(最大值)指定的范围内。
成功时返回 0。
-
int proc_doulongvec_ms_jiffies_minmax(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos)¶
读取具有最小值/最大值的毫秒值向量
参数
const struct ctl_table *table
sysctl 表
int write
如果这是对 sysctl 文件的写入,则为
TRUE
void *buffer
用户缓冲区
size_t *lenp
用户缓冲区的大小
loff_t *ppos
文件位置
描述
从/向用户缓冲区读取/写入最多 table->maxlen/sizeof(unsigned long) 个无符号长整数值,将其视为 ASCII 字符串。这些值被视为毫秒,并在存储时转换为节拍数。
此例程将确保这些值在 table->extra1(最小值)和 table->extra2(最大值)指定的范围内。
成功时返回 0。
-
int proc_dointvec_jiffies(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos)¶
将整数向量读取为秒
参数
const struct ctl_table *table
sysctl 表
int write
如果这是对 sysctl 文件的写入,则为
TRUE
void *buffer
用户缓冲区
size_t *lenp
用户缓冲区的大小
loff_t *ppos
文件位置
描述
从/向用户缓冲区读取/写入最多 table->maxlen/sizeof(unsigned int) 个整数值,将其视为 ASCII 字符串。假定读取的值以秒为单位,并转换为节拍数。
成功时返回 0。
-
int proc_dointvec_userhz_jiffies(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos)¶
将整数向量读取为 1/USER_HZ 秒
参数
const struct ctl_table *table
sysctl 表
int write
如果这是对 sysctl 文件的写入,则为
TRUE
void *buffer
用户缓冲区
size_t *lenp
用户缓冲区的大小
loff_t *ppos
指向文件位置的指针
描述
从/向用户缓冲区读取/写入最多 table->maxlen/sizeof(unsigned int) 个整数值,将其视为 ASCII 字符串。假定读取的值以 1/USER_HZ 秒为单位,并转换为节拍数。
成功时返回 0。
-
int proc_dointvec_ms_jiffies(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos)¶
将整数向量读取为 1 毫秒
参数
const struct ctl_table *table
sysctl 表
int write
如果这是对 sysctl 文件的写入,则为
TRUE
void *buffer
用户缓冲区
size_t *lenp
用户缓冲区的大小
loff_t *ppos
文件中的当前位置
描述
从/向用户缓冲区读取/写入最多 table->maxlen/sizeof(unsigned int) 个整数值,将其视为 ASCII 字符串。假定读取的值以 1/1000 秒为单位,并转换为节拍数。
成功时返回 0。
-
int proc_do_large_bitmap(const struct ctl_table *table, int write, void *buffer, size_t *lenp, loff_t *ppos)¶
从/向大型位图读取/写入
参数
const struct ctl_table *table
sysctl 表
int write
如果这是对 sysctl 文件的写入,则为
TRUE
void *buffer
用户缓冲区
size_t *lenp
用户缓冲区的大小
loff_t *ppos
文件位置
描述
位图存储在 table->data 中,位图长度(以位为单位)存储在 table->maxlen 中。
我们使用范围逗号分隔格式(例如 1,3-4,10-10),以便大型位图可以以紧凑的方式表示。写入文件将清除位图,然后使用给定的输入更新它。
成功时返回 0。
proc 文件系统接口¶
参数
struct pid *pid
应该刷新的 pid。
描述
此函数遍历附加到 pid 的 inode 列表(属于任何 proc 文件系统),并将它们从目录项缓存中刷新。
在任务退出之前缓存该任务的 /proc 条目是安全合理的。在此之后,它们只会用无用的条目阻塞目录项缓存,可能会导致有用的目录项缓存条目被刷新。提供此例程是为了在重新获得进程时刷新这些无用的目录项缓存条目。
注意
- 此例程只是一种优化,因此不保证
在重新获得进程后不存在任何目录项缓存条目,它只是使任何条目持续存在的可能性很小。
基于文件描述符的事件¶
-
void eventfd_signal_mask(struct eventfd_ctx *ctx, __poll_t mask)¶
递增事件计数器
参数
struct eventfd_ctx *ctx
[in] 指向 eventfd 上下文的指针。
__poll_t mask
[in] 轮询掩码
描述
此函数应该由内核在不允许睡眠的路径中调用。在此函数中,我们允许计数器达到 ULLONG_MAX 值,并通过向 poll(2) 返回 EPOLLERR 来指示此溢出情况。
-
void eventfd_ctx_put(struct eventfd_ctx *ctx)¶
释放对内部 eventfd 上下文的引用。
参数
struct eventfd_ctx *ctx
[in] 指向 eventfd 上下文的指针。
描述
eventfd 上下文引用必须先前已通过 eventfd_ctx_fdget()
或 eventfd_ctx_fileget()
获取。
-
int eventfd_ctx_remove_wait_queue(struct eventfd_ctx *ctx, wait_queue_entry_t *wait, __u64 *cnt)¶
读取当前计数器并删除等待队列。
参数
struct eventfd_ctx *ctx
[in] 指向 eventfd 上下文的指针。
wait_queue_entry_t *wait
[输入] 要移除的等待队列。
__u64 *cnt
[输出] 指向 64 位计数器值的指针。
描述
如果成功,返回 0
,否则返回以下错误代码
- -EAGAIN
: 操作将会阻塞。
此函数用于从 eventfd 等待队列头原子性地移除一个等待队列条目,并读取/重置计数器值。
参数
int fd
[输入] Eventfd 文件描述符。
描述
如果成功,返回指向 eventfd 文件结构的指针,否则返回以下错误指针
- -EBADF
: 无效的 fd 文件描述符。
- -EINVAL
: fd 文件描述符不是 eventfd 文件。
-
struct eventfd_ctx *eventfd_ctx_fdget(int fd)¶
获取对内部 eventfd 上下文的引用。
参数
int fd
[输入] Eventfd 文件描述符。
描述
返回指向内部 eventfd 上下文的指针,否则返回以下函数返回的错误指针
eventfd_fget
参数
struct file *file
[输入] Eventfd 文件指针。
描述
返回指向内部 eventfd 上下文的指针,否则返回错误指针
- -EINVAL
: fd 文件描述符不是 eventfd 文件。
eventpoll (epoll) 接口¶
-
int ep_events_available(struct eventpoll *ep)¶
检查是否有准备好的事件可用。
参数
struct eventpoll *ep
指向 eventpoll 上下文的指针。
返回
- 如果准备好的事件可用,则返回一个不同于
zero
的值, 否则返回
zero
。
-
bool busy_loop_ep_timeout(unsigned long start_time, struct eventpoll *ep)¶
检查忙轮询是否超时。优先使用 epoll 实例 ep 中的超时值,但如果未设置,则回退到通过 busy_loop_timeout 设置的全系统全局超时值。
参数
unsigned long start_time
用于计算到超时剩余时间的开始时间。
struct eventpoll *ep
指向 eventpoll 上下文的指针。
返回
如果超时已过期,则为 true,否则为 false。
-
int reverse_path_check(void)¶
tfile_check_list 是 epitem_head 的列表,其中包含提议新添加的链接。我们需要确保这些添加的链接不会添加过多的路径,以免我们花费所有时间唤醒 eventpoll 对象。
参数
void
无参数
返回
- 如果提议的链接没有创建过多的路径,则返回
zero
, 否则返回
-1
。
-
int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, int maxevents, struct timespec64 *timeout)¶
检索就绪事件,并将它们传递给调用者提供的事件缓冲区。
参数
struct eventpoll *ep
指向 eventpoll 上下文的指针。
struct epoll_event __user *events
指向用户空间缓冲区的指针,就绪事件应存储在该缓冲区中。
int maxevents
调用者事件缓冲区的大小(以事件数为单位)。
struct timespec64 *timeout
用于获取就绪事件的最大超时时间(以 timespec 为单位)。如果超时时间为零,则该函数不会阻塞;如果 timeout 指针为 NULL,则该函数将阻塞,直到至少检索到一个事件(或发生错误)。
返回
- 已获取的就绪事件数,或一个
错误代码(如果发生错误)。
-
int ep_loop_check_proc(struct eventpoll *ep, int depth)¶
验证将一个 epoll 文件添加到另一个 epoll 结构中是否违反了约束,包括闭环或过深的链(可能导致过多的堆栈使用)。
参数
struct eventpoll *ep
要当前检查的
struct eventpoll
。int depth
正在检查的路径的当前深度。
返回
- 如果将 epoll file 添加到当前 epoll
结构 ep 中没有违反约束,则返回
zero
,否则返回-1
。
-
int ep_loop_check(struct eventpoll *ep, struct eventpoll *to)¶
执行检查以验证将一个 epoll 文件 (to) 添加到另一个 epoll 文件(由 ep 表示)中是否会创建闭环或过深的链。
参数
struct eventpoll *ep
指向要插入到的 epoll。
struct eventpoll *to
指向要插入的 epoll。
返回
如果将 epoll to 添加到 epoll from 中没有违反约束,则返回 zero
,否则返回 -1
。
用于导出内核对象的文件系统¶
-
int sysfs_create_file_ns(struct kobject *kobj, const struct attribute *attr, const void *ns)¶
为具有自定义 ns 的对象创建属性文件
参数
struct kobject *kobj
我们正在为其创建的对象
const struct attribute *attr
属性描述符
const void *ns
新文件应属于的命名空间
-
int sysfs_add_file_to_group(struct kobject *kobj, const struct attribute *attr, const char *group)¶
将属性文件添加到预先存在的组。
参数
struct kobject *kobj
我们正在操作的对象。
const struct attribute *attr
属性描述符。
const char *group
组名。
-
int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr, umode_t mode)¶
更新对象属性上的修改后的模式值。
参数
struct kobject *kobj
我们正在操作的对象。
const struct attribute *attr
属性描述符。
umode_t mode
文件权限。
-
struct kernfs_node *sysfs_break_active_protection(struct kobject *kobj, const struct attribute *attr)¶
打破“活动”保护
参数
struct kobject *kobj
与内核对象 attr 关联。
const struct attribute *attr
要打破“活动”保护的属性。
描述
与 kernfs 一样,使用 sysfs 时,属性的删除将推迟到所有活动的 .show() 和 .store() 回调完成之后,除非调用此函数。因此,此函数在实现自删除的方法中很有用。
-
void sysfs_unbreak_active_protection(struct kernfs_node *kn)¶
恢复“活动”保护
参数
struct kernfs_node *kn
由
sysfs_break_active_protection()
返回的指针。
描述
撤消 sysfs_break_active_protection()
的效果。由于此函数在与传递给 sysfs_break_active_protection()
的 'attr' 参数对应的 kernfs 节点上调用 kernfs_put(),因此在该属性已被删除,所以在 sysfs_break_active_protection()
和 sysfs_unbreak_active_protection()
调用之间访问 kn 是不安全的。
-
void sysfs_remove_file_ns(struct kobject *kobj, const struct attribute *attr, const void *ns)¶
删除具有自定义 ns 标签的对象属性
参数
struct kobject *kobj
我们正在操作的对象
const struct attribute *attr
属性描述符
const void *ns
要删除的文件的命名空间标签
描述
哈希属性名称和命名空间标签,然后杀死目标。
-
bool sysfs_remove_file_self(struct kobject *kobj, const struct attribute *attr)¶
从其自身的方法中删除对象属性
参数
struct kobject *kobj
我们正在操作的对象
const struct attribute *attr
属性描述符
描述
有关详细信息,请参阅 kernfs_remove_self()。
-
void sysfs_remove_file_from_group(struct kobject *kobj, const struct attribute *attr, const char *group)¶
从组中删除属性文件。
参数
struct kobject *kobj
我们正在操作的对象。
const struct attribute *attr
属性描述符。
const char *group
组名。
-
int sysfs_create_bin_file(struct kobject *kobj, const struct bin_attribute *attr)¶
为对象创建二进制文件。
参数
struct kobject *kobj
对象。
const struct bin_attribute *attr
属性描述符。
-
void sysfs_remove_bin_file(struct kobject *kobj, const struct bin_attribute *attr)¶
删除对象的二进制文件。
参数
struct kobject *kobj
对象。
const struct bin_attribute *attr
属性描述符。
-
int sysfs_file_change_owner(struct kobject *kobj, const char *name, kuid_t kuid, kgid_t kgid)¶
更改 sysfs 文件的所有者。
参数
struct kobject *kobj
对象。
const char *name
要更改的文件的名称。
kuid_t kuid
新所有者的 kuid
kgid_t kgid
新所有者的 kgid
描述
此函数查找 kobj 下的 sysfs 条目 name,并将所有权更改为 kuid/kgid。
成功时返回 0,失败时返回错误代码。
-
int sysfs_change_owner(struct kobject *kobj, kuid_t kuid, kgid_t kgid)¶
更改给定对象的所有者。
参数
struct kobject *kobj
对象。
kuid_t kuid
新所有者的 kuid
kgid_t kgid
新所有者的 kgid
描述
将 kobj 的默认目录、文件、组和属性的所有者更改为 kuid/kgid。请注意,sysfs_change_owner 反映了驱动程序核心如何添加 kobject 的 sysfs 条目。总之,sysfs_change_owner()
负责 kobj 的默认目录条目、与 kobj 的 ktype 关联的默认属性以及与 kobj 的 ktype 关联的默认属性。驱动程序核心未添加的其他属性必须由创建它们的驱动程序或子系统更改。这类似于删除特定于驱动程序/子系统的条目的方式。
成功时返回 0,失败时返回错误代码。
-
int sysfs_emit(char *buf, const char *fmt, ...)¶
scnprintf 等效项,了解 PAGE_SIZE 缓冲区。
参数
char *buf
PAGE_SIZE 缓冲区的开始。
const char *fmt
格式
...
format 的可选参数
描述
返回写入 buf 的字符数。
-
int sysfs_emit_at(char *buf, int at, const char *fmt, ...)¶
scnprintf 等效项,了解 PAGE_SIZE 缓冲区。
参数
char *buf
PAGE_SIZE 缓冲区的开始。
int at
buf 中的偏移量,以字节为单位开始写入。at 必须 >= 0 && < PAGE_SIZE
const char *fmt
格式
...
fmt 的可选参数
描述
返回从 &**buf**[at] 开始写入的字符数。
-
ssize_t sysfs_bin_attr_simple_read(struct file *file, struct kobject *kobj, const struct bin_attribute *attr, char *buf, loff_t off, size_t count)¶
读取回调以简单地从内存复制。
参数
struct file *file
正在读取的属性文件。
struct kobject *kobj
属性所属的对象。
const struct bin_attribute *attr
属性描述符。
char *buf
目标缓冲区。
loff_t off
要从中读取的字节偏移量。
size_t count
要读取的最大字节数。
描述
由内存中的缓冲区支持的 bin_attributes 的简单 ->read() 回调。在 sysfs 中创建 bin_attribute 之前,必须将 struct bin_attribute 中的 private 和 size 成员设置为缓冲区的位置和大小。
off 和 count 的边界检查在 sysfs_kf_bin_read() 中完成。off 的负值检查在 vfs_setpos() 和 default_llseek() 中完成。
返回写入 buf 的字节数。
-
int sysfs_create_link(struct kobject *kobj, struct kobject *target, const char *name)¶
在两个对象之间创建符号链接。
参数
struct kobject *kobj
我们要在其中创建链接的目录的对象。
struct kobject *target
我们要指向的对象。
const char *name
符号链接的名称。
-
int sysfs_create_link_nowarn(struct kobject *kobj, struct kobject *target, const char *name)¶
在两个对象之间创建符号链接。
参数
struct kobject *kobj
我们要在其中创建链接的目录的对象。
struct kobject *target
我们要指向的对象。
const char *name
符号链接的名称。
此函数与
sysfs_create_link()
的作用相同,但如果链接已存在,则不会发出警告。
-
void sysfs_remove_link(struct kobject *kobj, const char *name)¶
删除对象目录中的符号链接。
参数
struct kobject *kobj
我们正在操作的对象。
const char *name
要删除的符号链接的名称。
-
int sysfs_rename_link_ns(struct kobject *kobj, struct kobject *targ, const char *old, const char *new, const void *new_ns)¶
重命名对象目录中的符号链接。
参数
struct kobject *kobj
我们正在操作的对象。
struct kobject *targ
我们要指向的对象。
const char *old
符号链接的先前名称。
const char *new
符号链接的新名称。
const void *new_ns
符号链接的新命名空间。
用于常见重命名符号链接习惯用法的辅助函数。
debugfs 文件系统¶
debugfs 接口¶
-
struct dentry *debugfs_lookup(const char *name, struct dentry *parent)¶
查找现有 debugfs 文件
参数
const char *name
指向包含要查找的文件的名称的字符串的指针。
struct dentry *parent
指向文件的父 dentry 的指针。
描述
如果此函数成功,将返回指向 dentry 的指针。如果文件不存在或发生错误,将返回 NULL
。不再需要时,必须将返回的 dentry 传递给 dput()。
如果内核中未启用 debugfs,将返回值 -ENODEV
。
-
struct dentry *debugfs_create_file_unsafe(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops)¶
在 debugfs 文件系统中创建一个文件
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限。
struct dentry *parent
指向此文件的父 dentry 的指针。如果设置,这应为目录 dentry。如果此参数为 NULL,则将在 debugfs 文件系统的根目录中创建该文件。
void *data
指向调用方稍后想要访问的内容的指针。inode.i_private 指针将在 open() 调用时指向此值。
const struct file_operations *fops
指向应用于此文件的 struct file_operations 的指针。
描述
debugfs_create_file_unsafe()
与 debugfs_create_file() 完全类似,唯一的区别是传递给它的 fops 不会受到 debugfs 核心的文件删除的保护。
您有责任通过 debugfs_file_get()
和 debugfs_file_put()
来保护您的 struct file_operation 方法免受文件删除。但是,->open() 仍然受到 debugfs 的保护。
任何通过 DEFINE_DEBUGFS_ATTRIBUTE() 定义的 struct file_operations 都受到文件删除的保护,因此,可以在此处使用。
-
void debugfs_create_file_size(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops, loff_t file_size)¶
在 debugfs 文件系统中创建一个文件
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限。
struct dentry *parent
指向此文件的父 dentry 的指针。如果设置,这应为目录 dentry。如果此参数为 NULL,则将在 debugfs 文件系统的根目录中创建该文件。
void *data
指向调用方稍后想要访问的内容的指针。inode.i_private 指针将在 open() 调用时指向此值。
const struct file_operations *fops
指向应用于此文件的 struct file_operations 的指针。
loff_t file_size
初始文件大小
描述
这是 debugfs 的基本“创建文件”函数。它允许在创建文件或目录时具有广泛的灵活性(如果要创建目录,建议使用 debugfs_create_dir()
函数)。
-
struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)¶
在 debugfs 文件系统中创建一个目录
参数
const char *name
指向包含要创建的目录的名称的字符串的指针。
struct dentry *parent
指向此文件的父 dentry 的指针。如果设置,这应为目录 dentry。如果此参数为 NULL,则将在 debugfs 文件系统的根目录中创建该目录。
描述
此函数使用给定的名称在 debugfs 中创建一个目录。
如果此函数成功,将返回指向 dentry 的指针。删除文件时,必须将此指针传递给 debugfs_remove()
函数(如果您的模块已卸载,则不会自动清理,您在此处负责。)如果发生错误,将返回 ERR_PTR(-ERROR)。
如果内核中未启用 debugfs,将返回值 -ENODEV
。
注意
期望大多数调用方应 _ignore_ 此函数返回的错误。其他 debugfs 函数会处理传递给它们的“dentry”可能是错误的事实,并且它们在这种情况下不会崩溃。即使 debugfs 无法初始化,驱动程序通常也能正常工作。
-
struct dentry *debugfs_create_automount(const char *name, struct dentry *parent, debugfs_automount_t f, void *data)¶
在 debugfs 文件系统中创建自动挂载点
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
struct dentry *parent
指向此文件的父 dentry 的指针。如果设置,这应为目录 dentry。如果此参数为 NULL,则将在 debugfs 文件系统的根目录中创建该文件。
debugfs_automount_t f
当路径名解析步骤执行该步骤时要调用的函数。
void *data
要传递给 f() 的不透明参数。
描述
f 应返回 ->d_automount() 将返回的内容。
-
struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent, const char *target)¶
在 debugfs 文件系统中创建符号链接
参数
const char *name
指向包含要创建的符号链接的名称的字符串的指针。
struct dentry *parent
指向此符号链接的父 dentry 的指针。如果设置,这应为目录 dentry。如果此参数为 NULL,则将在 debugfs 文件系统的根目录中创建符号链接。
const char *target
指向包含符号链接目标的路径的字符串的指针。
描述
此函数使用给定的名称在 debugfs 中创建一个链接到给定目标路径的符号链接。
如果此函数成功,将返回指向 dentry 的指针。删除符号链接时,必须将此指针传递给 debugfs_remove()
函数(如果您的模块已卸载,则不会自动清理,您在此处负责。)如果发生错误,将返回 ERR_PTR(-ERROR)。
如果内核中未启用 debugfs,将返回值 -ENODEV
。
参数
struct dentry *dentry
指向要删除的目录的 dentry 的指针。如果此参数为 NULL 或错误值,则不执行任何操作。
描述
此函数递归删除 debugfs 中的目录树,该目录树先前通过调用另一个 debugfs 函数(如 debugfs_create_file() 或其变体)创建。
需要调用此函数才能删除文件,当模块被删除时,不会自动清理文件,您在此处负责。
-
void debugfs_lookup_and_remove(const char *name, struct dentry *parent)¶
查找目录或文件并递归地删除它
参数
const char *name
指向包含要查找项目名称的字符串的指针。
struct dentry *parent
指向项目的父 dentry 的指针。
描述
这相当于执行类似 debugfs_remove(debugfs_lookup(..)) 的操作,但为正在查找的目录处理了正确的引用计数。
参数
struct dentry *dentry
要重命名的对象的 dentry。
const char *fmt
新名称的格式
...
可变参数
描述
此函数在 debugfs 中重命名文件/目录。目标必须不存在才能成功重命名。
此函数成功时返回 0,失败时返回 -E...
如果内核中未启用 debugfs,将返回值 -ENODEV
。
-
bool debugfs_initialized(void)¶
告知 debugfs 是否已注册
参数
void
无参数
参数
struct dentry *dentry
正在访问数据的 dentry 对象。
描述
直到匹配的 debugfs_file_put()
调用为止,对文件删除函数 debugfs_remove()
和 debugfs_remove_recursive() 的任何后续调用都将阻塞。 由于关联的私有文件数据可能仅在任何删除函数成功返回后才能释放,因此您可以在成功调用 debugfs_file_get()
后安全地访问它,而不必担心生存期问题。
如果返回 -EIO
,则该文件已被删除,因此访问其任何数据都是不安全的。 另一方面,如果允许访问文件数据,则返回零。
参数
struct dentry *dentry
先前传递给
debugfs_file_get()
的 dentry 对象。
描述
允许任何正在进行的并发调用 debugfs_remove()
或 debugfs_remove_recursive() 被先前调用 debugfs_file_get()
阻止,以便继续并返回其调用方。
-
void debugfs_enter_cancellation(struct file *file, struct debugfs_cancellation *cancellation)¶
进入 debugfs 取消
参数
struct file *file
正在访问的文件
struct debugfs_cancellation *cancellation
取消对象,其中的取消回调必须已初始化
描述
删除 debugfs 文件时,它需要等待所有活动操作完成。 但是,操作本身可能需要等待硬件或某些异步进程的完成或类似情况。 因此,可能需要取消它以避免长时间的等待甚至死锁。
此函数可以在可能需要取消的 debugfs 处理程序中使用。 一旦调用此函数,就可以调用 cancellation 的“cancel”回调,此时调用者应继续调用 debugfs_leave_cancellation()
并尽快离开 debugfs 处理程序函数。 请注意,“cancel”回调仅在某种 debugfs_remove()
的上下文中调用。
此函数必须与 debugfs_leave_cancellation()
配对使用。
-
void debugfs_leave_cancellation(struct file *file, struct debugfs_cancellation *cancellation)¶
离开取消部分
参数
struct file *file
正在访问的文件
struct debugfs_cancellation *cancellation
先前使用
debugfs_enter_cancellation()
注册的取消
描述
请参阅 debugfs_enter_cancellation()
的文档。
-
void debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent, u8 *value)¶
创建一个 debugfs 文件,用于读取和写入无符号 8 位值
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。u8 *value
指向文件应从中读取和写入的变量的指针。
描述
此函数在 debugfs 中创建一个具有给定名称的文件,其中包含变量 **value** 的值。 如果设置了 **mode** 变量,则可以从中读取和写入。
-
void debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent, u16 *value)¶
创建一个 debugfs 文件,用于读取和写入无符号 16 位值
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。u16 *value
指向文件应从中读取和写入的变量的指针。
描述
此函数在 debugfs 中创建一个具有给定名称的文件,其中包含变量 **value** 的值。 如果设置了 **mode** 变量,则可以从中读取和写入。
-
void debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent, u32 *value)¶
创建一个 debugfs 文件,用于读取和写入无符号 32 位值
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。u32 *value
指向文件应从中读取和写入的变量的指针。
描述
此函数在 debugfs 中创建一个具有给定名称的文件,其中包含变量 **value** 的值。 如果设置了 **mode** 变量,则可以从中读取和写入。
-
void debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent, u64 *value)¶
创建一个 debugfs 文件,用于读取和写入无符号 64 位值
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。u64 *value
指向文件应从中读取和写入的变量的指针。
描述
此函数在 debugfs 中创建一个具有给定名称的文件,其中包含变量 **value** 的值。 如果设置了 **mode** 变量,则可以从中读取和写入。
-
void debugfs_create_ulong(const char *name, umode_t mode, struct dentry *parent, unsigned long *value)¶
创建一个 debugfs 文件,用于读取和写入无符号长整型值。
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。unsigned long *value
指向文件应从中读取和写入的变量的指针。
描述
此函数在 debugfs 中创建一个具有给定名称的文件,其中包含变量 **value** 的值。 如果设置了 **mode** 变量,则可以从中读取和写入。
-
void debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, u8 *value)¶
创建一个 debugfs 文件,用于读取和写入无符号 8 位值
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。u8 *value
指向文件应从中读取和写入的变量的指针。
-
void debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, u16 *value)¶
创建一个 debugfs 文件,用于读取和写入无符号 16 位值
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。u16 *value
指向文件应从中读取和写入的变量的指针。
-
void debugfs_create_x32(const char *name, umode_t mode, struct dentry *parent, u32 *value)¶
创建一个 debugfs 文件,用于读取和写入无符号 32 位值
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。u32 *value
指向文件应从中读取和写入的变量的指针。
-
void debugfs_create_x64(const char *name, umode_t mode, struct dentry *parent, u64 *value)¶
创建一个 debugfs 文件,用于读取和写入无符号 64 位值
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。u64 *value
指向文件应从中读取和写入的变量的指针。
-
void debugfs_create_size_t(const char *name, umode_t mode, struct dentry *parent, size_t *value)¶
创建一个 debugfs 文件,用于读取和写入 size_t 值
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。size_t *value
指向文件应从中读取和写入的变量的指针。
-
void debugfs_create_atomic_t(const char *name, umode_t mode, struct dentry *parent, atomic_t *value)¶
创建一个 debugfs 文件,用于读取和写入 atomic_t 值
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。atomic_t *value
指向文件应从中读取和写入的变量的指针。
-
void debugfs_create_bool(const char *name, umode_t mode, struct dentry *parent, bool *value)¶
创建一个 debugfs 文件,用于读取和写入布尔值
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。bool *value
指向文件应从中读取和写入的变量的指针。
描述
此函数在 debugfs 中创建一个具有给定名称的文件,其中包含变量 **value** 的值。 如果设置了 **mode** 变量,则可以从中读取和写入。
-
void debugfs_create_str(const char *name, umode_t mode, struct dentry *parent, char **value)¶
创建一个 debugfs 文件,用于读取和写入字符串值
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。char **value
指向文件应从中读取和写入的变量的指针。
描述
此函数在 debugfs 中创建一个具有给定名称的文件,其中包含变量 **value** 的值。 如果设置了 **mode** 变量,则可以从中读取和写入。
-
struct dentry *debugfs_create_blob(const char *name, umode_t mode, struct dentry *parent, struct debugfs_blob_wrapper *blob)¶
创建一个 debugfs 文件,用于读写二进制 blob
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。struct debugfs_blob_wrapper *blob
指向 struct debugfs_blob_wrapper 的指针,该结构包含指向 blob 数据的指针和数据大小。
描述
此函数在 debugfs 中创建一个具有给定名称的文件,该文件将 blob->data 导出为二进制 blob。如果设置了 mode 变量,则可以对其进行读取和写入。
如果此函数成功,将返回指向 dentry 的指针。删除文件时,必须将此指针传递给 debugfs_remove()
函数(如果您的模块已卸载,则不会自动清理,您在此处负责。)如果发生错误,将返回 ERR_PTR(-ERROR)。
如果内核中未启用 debugfs,则将返回 ERR_PTR(-ENODEV) 值。
-
void debugfs_create_u32_array(const char *name, umode_t mode, struct dentry *parent, struct debugfs_u32_array *array)¶
创建一个 debugfs 文件,用于读取 u32 数组。
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限。
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。struct debugfs_u32_array *array
包含数据指针和数组大小的包装结构体。
描述
此函数在 debugfs 中创建一个具有给定名称的文件,该文件将 array 导出为数据。如果设置了 mode 变量,则可以读取该数据。不支持写入。也不支持在文件中搜索。一旦创建了数组,就无法更改其大小。
-
void debugfs_print_regs32(struct seq_file *s, const struct debugfs_reg32 *regs, int nregs, void __iomem *base, char *prefix)¶
使用 seq_print 来描述一组寄存器
参数
struct seq_file *s
用于生成输出的 seq_file 结构
const struct debugfs_reg32 *regs
struct debugfs_reg32 结构体的数组
int nregs
上述数组的长度
void __iomem *base
用于读取寄存器的基地址
char *prefix
要添加到每个输出行前面的字符串
描述
此函数输出一个文本块,描述一些 32 位硬件寄存器的当前值。 它旨在用于基于 seq_file 的 debugfs 文件中,这些文件需要显示与其他信息混合的寄存器。 prefix 参数可用于指定前导字符串,因为某些外围设备具有多个相同的寄存器块,例如 dma 通道的配置
-
void debugfs_create_regset32(const char *name, umode_t mode, struct dentry *parent, struct debugfs_regset32 *regset)¶
创建一个 debugfs 文件,该文件返回寄存器值
参数
const char *name
指向包含要创建的文件的名称的字符串的指针。
umode_t mode
文件应具有的权限
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。struct debugfs_regset32 *regset
指向 struct debugfs_regset32 的指针,该结构包含指向寄存器定义数组的指针、数组大小和要查找寄存器组的基地址。
描述
此函数在 debugfs 中创建一个具有给定名称的文件,该文件报告一组 32 位寄存器的名称和值。如果设置了 mode 变量,则可以从中读取。不支持写入。
-
void debugfs_create_devm_seqfile(struct device *dev, const char *name, struct dentry *parent, int (*read_fn)(struct seq_file *s, void *data))¶
创建一个绑定到设备的 debugfs 文件。
参数
struct device *dev
与此 debugfs 文件相关的设备。
const char *name
debugfs 文件的名称。
struct dentry *parent
指向此文件的父 dentry 的指针。 如果设置,这应该是目录 dentry。 如果此参数为
NULL
,则将在 debugfs 文件系统的根目录中创建该文件。int (*read_fn)(struct seq_file *s, void *data)
用于打印 seq_file 内容的函数指针。