Commit 5d75e455 authored by Jonathan Corbet's avatar Jonathan Corbet
Browse files

Merge tag 'Chinese-docs-6.18' of gitolite.kernel.org:pub/scm/linux/kernel/git/alexs/linux into alex

Chinese translation docs for 6.18

This is the Chinese translation subtree for 6.18. It includes
the following changes:
        - docs/zh_CN: Add rust Chinese translations
        - docs/zh_CN: Add scsi Chinese translations
        - docs/zh_CN: Add gfs2 Chinese translations
        - Add some other Chinese translations and fixes

Above patches are tested by 'make htmldocs'
parents 2c62e2e8 6fc05a14
Loading
Loading
Loading
Loading
+67 −0
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0

.. include:: ../disclaimer-zh_CN.rst

:Original: Documentation/filesystems/dnotify.rst

:翻译:

   王龙杰 Wang Longjie <wang.longjie1@zte.com.cn>

==============
Linux 目录通知
==============

	   Stephen Rothwell <sfr@canb.auug.org.au>

目录通知的目的是使用户应用程序能够在目录或目录中的任何文件发生变更时收到通知。基本机制包括应用程序
通过 fcntl(2) 调用在目录上注册通知,通知本身则通过信号传递。

应用程序可以决定希望收到哪些 “事件” 的通知。当前已定义的事件如下:

	=========	=====================================
	DN_ACCESS	目录中的文件被访问(read)
	DN_MODIFY	目录中的文件被修改(write,truncate)
	DN_CREATE	目录中创建了文件
	DN_DELETE	目录中的文件被取消链接
	DN_RENAME	目录中的文件被重命名
	DN_ATTRIB	目录中的文件属性被更改(chmod,chown)
	=========	=====================================

通常,应用程序必须在每次通知后重新注册,但如果将 DN_MULTISHOT 与事件掩码进行或运算,则注册
将一直保持有效,直到被显式移除(通过注册为不接收任何事件)。

默认情况下,SIGIO 信号将被传递给进程,且不附带其他有用的信息。但是,如果使用 F_SETSIG fcntl(2)
调用让内核知道要传递哪个信号,一个 siginfo 结构体将被传递给信号处理程序,该结构体的 si_fd 成员将
包含与发生事件的目录相关联的文件描述符。

应用程序最好选择一个实时信号(SIGRTMIN + <n>),以便通知可以被排队。如果指定了 DN_MULTISHOT,
这一点尤为重要。注意,SIGRTMIN 通常是被阻塞的,因此最好使用(至少)SIGRTMIN + 1。

实现预期(特性与缺陷 :-))
--------------------------

对于文件的任何本地访问,通知都应能正常工作,即使实际文件系统位于远程服务器上。这意味着,对本地用户
模式服务器提供的文件的远程访问应能触发通知。同样的,对本地内核 NFS 服务器提供的文件的远程访问
也应能触发通知。

为了尽可能减小对文件系统代码的影响,文件硬链接的问题已被忽略。因此,如果一个文件(x)存在于两个
目录(a 和 b)中,通过名称”a/x”对该文件进行的更改应通知给期望接收目录“a”通知的程序,但不会
通知给期望接收目录“b”通知的程序。

此外,取消链接的文件仍会在它们链接到的最后一个目录中触发通知。

配置
----

Dnotify 由 CONFIG_DNOTIFY 配置选项控制。禁用该选项时,fcntl(fd, F_NOTIFY, ...) 将返
回 -EINVAL。

示例
----
具体示例可参见 tools/testing/selftests/filesystems/dnotify_test.c。

注意
----
从 Linux 2.6.13 开始,dnotify 已被 inotify 取代。有关 inotify 的更多信息,请参见
Documentation/filesystems/inotify.rst。
+211 −0
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0

.. include:: ../disclaimer-zh_CN.rst

:Original: Documentation/filesystems/gfs2-glocks.rst

:翻译:

 邵明寅 Shao Mingyin <shao.mingyin@zte.com.cn>

:校译:

 杨涛 yang tao <yang.tao172@zte.com.cn>

==================
Glock 内部加锁规则
==================

本文档阐述 glock 状态机内部运作的基本原理。每个 glock(即
fs/gfs2/incore.h 中的 struct gfs2_glock)包含两把主要的内部锁:

 1. 自旋锁(gl_lockref.lock):用于保护内部状态(如
    gl_state、gl_target)和持有者列表(gl_holders)
 2. 非阻塞的位锁(GLF_LOCK):用于防止其他线程同时调用
    DLM 等操作。若某线程获取此锁,则在释放时必须调用
    run_queue(通常通过工作队列),以确保所有待处理任务
    得以完成。

gl_holders 列表包含与该 glock 关联的所有排队锁请求(不
仅是持有者)。若存在已持有的锁,它们将位于列表开头的连
续条目中。锁的授予严格遵循排队顺序。

glock 层用户可请求三种锁状态:共享(SH)、延迟(DF)和
排他(EX)。它们对应以下 DLM 锁模式:

==========	====== =====================================================
Glock 模式       DLM    锁模式
==========	====== =====================================================
    UN          IV/NL  未加锁(无关联的 DLM 锁)或 NL
    SH          PR     受保护读(Protected read)
    DF          CW     并发写(Concurrent write)
    EX          EX     排他(Exclusive)
==========	====== =====================================================

因此,DF 本质上是一种与“常规”共享锁模式(SH)互斥的共
享模式。在 GFS2 中,DF 模式专用于直接 I/O 操作。Glock
本质上是锁加缓存管理例程的组合,其缓存规则如下:

==========      ==============   ==========   ==========   ==============
Glock 模式      缓存元数据       缓存数据      脏数据        脏元数据
==========      ==============   ==========   ==========   ==============
    UN               否            否           否            否
    DF               是            否           否            否
    SH               是            是           否            否
    EX               是            是           是            是
==========      ==============   ==========   ==========   ==============

这些规则通过为每种 glock 定义的操作函数实现。并非所有
glock 类型都使用全部的模式,例如仅 inode glock 使用 DF 模
式。

glock 操作函数及类型常量说明表:

==============     ========================================================
字段                用途
==============     ========================================================
go_sync            远程状态变更前调用(如同步脏数据)
go_xmote_bh        远程状态变更后调用(如刷新缓存)
go_inval           远程状态变更需使缓存失效时调用
go_instantiate     获取 glock 时调用
go_held            每次获取 glock 持有者时调用
go_dump            为 debugfs 文件打印对象内容,或出错时将 glock 转储至日志
go_callback        若 DLM 发送回调以释放此锁时调用
go_unlocked        当 glock 解锁时调用(dlm_unlock())
go_type            glock 类型,``LM_TYPE_*``
go_flags           若 glock 关联地址空间,则设置GLOF_ASPACE 标志
==============     ========================================================

每种锁的最短持有时间是指在远程锁授予后忽略远程降级请求
的时间段。此举旨在防止锁在集群节点间持续弹跳而无实质进
展的情况,此现象常见于多节点写入的共享内存映射文件。通
过延迟响应远程回调的降级操作,为用户空间程序争取页面取
消映射前的处理时间。

未来计划将 glock 的 "EX" 模式设为本地共享,使本地锁通
过 i_mutex 实现而非 glock。

glock 操作函数的加锁规则:

==============   ======================    =============================
操作              GLF_LOCK 位锁持有          gl_lockref.lock 自旋锁持有
==============   ======================    =============================
go_sync              是                         否
go_xmote_bh          是                         否
go_inval             是                         否
go_instantiate       否                         否
go_held              否                         否
go_dump              有时                       是
go_callback          有时(N/A)                 是
go_unlocked          是                         否
==============   ======================    =============================

.. Note::

   若入口处持有锁则操作期间不得释放位锁或自旋锁。
   go_dump 和 do_demote_ok 严禁阻塞。
   仅当 glock 状态指示其缓存最新数据时才会调用 go_dump。

GFS2 内部的 glock 加锁顺序:

 1. i_rwsem(如需要)
 2. 重命名 glock(仅用于重命名)
 3. Inode glock
    (父级优先于子级,同级 inode 按锁编号排序)
 4. Rgrp glock(用于(反)分配操作)
 5. 事务 glock(通过 gfs2_trans_begin,非读操作)
 6. i_rw_mutex(如需要)
 7. 页锁(始终最后,至关重要!)

每个 inode 对应两把 glock:一把管理 inode 本身(加锁顺
序如上),另一把(称为 iopen glock)结合 inode 的
i_nlink 字段决定 inode 生命周期。inode 加锁基于单个
inode,rgrp 加锁基于单个 rgrp。通常优先获取本地锁再获
取集群锁。

Glock 统计
----------

统计分为两类:超级块相关统计和单个 glock 相关统计。超级
块统计按每 CPU 执行以减少收集开销,并进一步按 glock 类
型细分。所有时间单位为纳秒。

超级块和 glock 统计收集相同信息。超级块时序统计为 glock
时序统计提供默认值,使新建 glock 具有合理的初始值。每个
glock 的计数器在创建时初始化为零,当 glock 从内存移除时
统计丢失。

统计包含三组均值/方差对及两个计数器。均值/方差对为平滑
指数估计,算法与网络代码中的往返时间计算类似(参见《
TCP/IP详解 卷1》第21.3节及《卷2》第25.10节)。与 TCP/IP
案例不同,此处均值/方差未缩放且单位为整数纳秒。

三组均值/方差对测量以下内容:

 1. DLM 锁时间(非阻塞请求)
 2. DLM 锁时间(阻塞请求)
 3. 请求间隔时间(指向 DLM)

非阻塞请求指无论目标 DLM 锁处于何种状态均能立即完成的请求。
当前满足条件的请求包括:(a)锁当前状态为互斥(如锁降级)、
(b)请求状态为空置或解锁(同样如锁降级)、或(c)设置"try lock"
标志的请求。其余锁请求均属阻塞请求。

两个计数器分别统计:
 1. 锁请求总数(决定均值/方差计算的数据量)
 2. glock 代码顶层的持有者排队数(通常远大于 DLM 锁请求数)

为什么收集这些统计数据?我们需深入分析时序参数的动因如下:

1. 更精准设置 glock "最短持有时间"
2. 快速识别性能问题
3. 改进资源组分配算法(基于锁等待时间而非盲目 "try lock")

因平滑更新的特性,采样量的阶跃变化需经 8 次采样(方差需
4 次)才能完全体现,解析结果时需审慎考虑。

通过锁请求完成时间和 glock 平均锁请求间隔时间,可计算节
点使用 glock 时长与集群共享时长的占比,对设置锁最短持有
时间至关重要。

我们已采取严谨措施,力求精准测量目标量值。任何测量系统均
存在误差,但我期望当前方案已达到合理精度极限。

超级块状态统计路径::

    /sys/kernel/debug/gfs2/<fsname>/sbstats

Glock 状态统计路径::

    /sys/kernel/debug/gfs2/<fsname>/glstats

(假设 debugfs 挂载于 /sys/kernel/debug,且 <fsname> 替
换为对应 GFS2 文件系统名)

输出缩写说明:

=========  ============================================
srtt       非阻塞 DLM 请求的平滑往返时间
srttvar    srtt 的方差估计
srttb      (潜在)阻塞 DLM 请求的平滑往返时间
srttvarb   srttb 的方差估计
sirt       DLM 请求的平滑请求间隔时间
sirtvar    sirt 的方差估计
dlm        DLM 请求数(glstats 文件中的 dcnt)
queue      排队的 glock 请求数(glstats 文件中的 qcnt)
=========  ============================================

sbstats文件按glock类型(每种类型8行)和CPU核心(每CPU一列)
记录统计数据集。glstats文件则为每个glock提供统计集,其格式
与glocks文件类似,但所有时序统计量均采用均值/方差格式存储。

gfs2_glock_lock_time 跟踪点实时输出目标 glock 的当前统计
值,并附带每次接收到的dlm响应附加信息:

======   ============
status   DLM 请求状态
flags    DLM 请求标志
tdiff    该请求的耗时
======   ============

(其余字段同上表)
+97 −0
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0

.. include:: ../disclaimer-zh_CN.rst

:Original: Documentation/filesystems/gfs2-uevents.rst

:翻译:

   邵明寅 Shao Mingyin <shao.mingyin@zte.com.cn>

:校译:

   杨涛 yang tao <yang.tao172@zte.com.cn>

===============
uevents 与 GFS2
===============

在 GFS2 文件系统的挂载生命周期内,会生成多个 uevent。
本文档解释了这些事件的含义及其用途(被 gfs2-utils 中的 gfs_controld 使用)。

GFS2 uevents 列表
=================

1. ADD
------

ADD 事件发生在挂载时。它始终是新建文件系统生成的第一个 uevent。如果挂载成
功,随后会生成 ONLINE uevent。如果挂载失败,则随后会生成 REMOVE uevent。

ADD uevent 包含两个环境变量:SPECTATOR=[0|1] 和 RDONLY=[0|1],分别用
于指定文件系统的观察者状态(一种未分配日志的只读挂载)和只读状态(已分配日志)。

2. ONLINE
---------

ONLINE uevent 在成功挂载或重新挂载后生成。它具有与 ADD uevent 相同的环
境变量。ONLINE uevent 及其用于标识观察者和 RDONLY 状态的两个环境变量是较
新版本内核引入的功能(2.6.32-rc+ 及以上),旧版本内核不会生成此事件。

3. CHANGE
---------

CHANGE uevent 在两种场景下使用。一是报告第一个节点成功挂载文件系统时
(FIRSTMOUNT=Done)。这作为信号告知 gfs_controld,此时集群中其他节点可以
安全挂载该文件系统。

另一个 CHANGE uevent 用于通知文件系统某个日志的日志恢复已完成。它包含两个
环境变量:JID= 指定刚恢复的日志 ID,RECOVERY=[Done|Failed] 表示操作成
功与否。这些 uevent 会在每次日志恢复时生成,无论是在初始挂载过程中,还是
gfs_controld 通过 /sys/fs/gfs2/<fsname>/lock_module/recovery 文件
请求特定日志恢复的结果。

由于早期版本的 gfs_controld 使用 CHANGE uevent 时未检查环境变量以确定状
态,若为其添加新功能,存在用户工具版本过旧导致集群故障的风险。因此,在新增用
于标识成功挂载或重新挂载的 uevent 时,选择了使用 ONLINE uevent。

4. OFFLINE
----------

OFFLINE uevent 仅在文件系统发生错误时生成,是 "withdraw" 机制的一部分。
当前该事件未提供具体错误信息,此问题有待修复。

5. REMOVE
---------

REMOVE uevent 在挂载失败结束或卸载文件系统时生成。所有 REMOVE uevent
之前都至少存在同一文件系统的 ADD uevent。与其他 uevent 不同,它由内核的
kobject 子系统自动生成。


所有 GFS2 uevents 的通用信息(uevent 环境变量)
===============================================

1. LOCKTABLE=
--------------

LOCKTABLE 是一个字符串,其值来源于挂载命令行(locktable=)或 fstab 文件。
它用作文件系统标签,并为 lock_dlm 类型的挂载提供加入集群所需的信息。

2. LOCKPROTO=
-------------

LOCKPROTO 是一个字符串,其值取决于挂载命令行或 fstab 中的设置。其值将是
lock_nolock 或 lock_dlm。未来可能支持其他锁管理器。

3. JOURNALID=
-------------

如果文件系统正在使用日志(观察者挂载不分配日志),则所有 GFS2 uevent 中都
会包含此变量,其值为数字形式的日志 ID。

4. UUID=
--------

在较新版本的 gfs2-utils 中,mkfs.gfs2 会向文件系统超级块写入 UUID。若存
在 UUID,所有与该文件系统相关的 uevent 中均会包含此信息。
+57 −0
Original line number Diff line number Diff line
.. SPDX-License-Identifier: GPL-2.0

.. include:: ../disclaimer-zh_CN.rst

:Original: Documentation/filesystems/gfs2.rst

:翻译:

   邵明寅 Shao Mingyin <shao.mingyin@zte.com.cn>

:校译:

   杨涛 yang tao <yang.tao172@zte.com.cn>

=====================================
全局文件系统 2 (Global File System 2)
=====================================

GFS2 是一个集群文件系统。它允许一组计算机同时使用在它们之间共享的块设备(通
过 FC、iSCSI、NBD 等)。GFS2 像本地文件系统一样读写块设备,但也使用一个锁
模块来让计算机协调它们的 I/O 操作,从而维护文件系统的一致性。GFS2 的出色特
性之一是完美一致性——在一台机器上对文件系统所做的更改会立即显示在集群中的所
有其他机器上。

GFS2 使用可互换的节点间锁定机制,当前支持的机制有:

  lock_nolock
    - 允许将 GFS2 用作本地文件系统

  lock_dlm
    - 使用分布式锁管理器 (dlm) 进行节点间锁定。
      该 dlm 位于 linux/fs/dlm/

lock_dlm 依赖于在上述 URL 中找到的用户空间集群管理系统。

若要将 GFS2 用作本地文件系统,则不需要外部集群系统,只需::

  $ mkfs -t gfs2 -p lock_nolock -j 1 /dev/block_device
  $ mount -t gfs2 /dev/block_device /dir

在所有集群节点上都需要安装 gfs2-utils 软件包;对于 lock_dlm,您还需要按
照文档配置 dlm 和 corosync 用户空间工具。

gfs2-utils 可在 https://pagure.io/gfs2-utils  找到。

GFS2 在磁盘格式上与早期版本的 GFS 不兼容,但它已相当接近。

以下手册页 (man pages) 可在 gfs2-utils 中找到:

  ============          =============================================
  fsck.gfs2		用于修复文件系统
  gfs2_grow		用于在线扩展文件系统
  gfs2_jadd		用于在线向文件系统添加日志
  tunegfs2		用于操作、检查和调优文件系统
  gfs2_convert		用于将 gfs 文件系统原地转换为 GFS2
  mkfs.gfs2		用于创建文件系统
  ============          =============================================
+16 −1
Original line number Diff line number Diff line
@@ -15,6 +15,16 @@ Linux Kernel中的文件系统
文件系统(VFS)层以及基于其上的各种文件系统如何工作呈现给大家。当前\
可以看到下面的内容。

核心 VFS 文档
=============

有关 VFS 层本身以及其算法工作方式的文档,请参阅这些手册。

.. toctree::
   :maxdepth: 1

   dnotify

文件系统
========

@@ -26,4 +36,9 @@ Linux Kernel中的文件系统
   virtiofs
   debugfs
   tmpfs
   ubifs
   ubifs-authentication
   gfs2
   gfs2-uevents
   gfs2-glocks
   inotify
Loading