大容量存储设备 (MSG)¶
概述¶
大容量存储设备 (或 MSG) 充当 USB 大容量存储设备,对主机表现为磁盘或 CD-ROM 驱动器。它支持多个逻辑单元 (LUN)。每个 LUN 的后备存储由常规文件或块设备提供,访问可以限制为只读,并且设备可以指示它是可移动的和/或 CD-ROM (后者意味着只读访问)。
它的要求不高;只需要一个批量输入端点和一个批量输出端点。内存要求为两个 16K 缓冲区。支持全速、高速和超高速操作。
请注意,该驱动程序在某种程度上是不可移植的,因为它假设单个内存/DMA 缓冲区可用于批量输入和批量输出端点。对于大多数设备控制器来说,这不是问题,但可能有一些硬件限制阻止缓冲区被多个端点使用。
本文档描述了如何从用户空间使用该设备,它与大容量存储功能 (或 MSF) 的关系以及使用它的不同设备,以及它与文件存储设备 (或 FSG) 的区别 (后者不再包含在 Linux 中)。它将仅简要讨论如何在复合设备中使用 MSF。
模块参数¶
大容量存储设备接受以下特定于大容量存储的模块参数
file=filename[,filename...]
此参数列出用于每个逻辑单元的后备存储的文件或块设备的路径。最多可以设置 FSG_MAX_LUNS (8) 个 LUN。如果指定了更多文件,它们将被静默忽略。另请参阅 “luns” 参数。
注意,如果将文件用作后备存储,则任何其他进程都不得修改它。这是因为主机假设数据不会在其不知情的情况下发生更改。它可以读取,但 (如果逻辑单元是可写的) 由于主机端的缓冲,内容没有明确定义。
逻辑单元的大小将向下舍入为完整的逻辑块。模拟 CD-ROM 的 LUN 的逻辑块大小为 2048 字节,如果后备文件是块设备,则逻辑块大小为设备的块大小,否则为 512 字节。
removable=b[,b...]
此参数指定每个逻辑单元是否应为可移动的。“b” 此处为 “y”、“Y” 或 “1” 表示 true,或 “n”、“N” 或 “0” 表示 false。
如果为逻辑单元设置了此选项,设备将接受 “eject” SCSI 请求 (启动/停止单元)。发送时,后备文件将被关闭以模拟弹出,并且在设备上的用户空间指定新的后备文件之前,主机将无法挂载逻辑单元 (请参阅 “sysfs 条目” 部分)。
如果逻辑单元不可移动 (默认),则在加载模块时必须使用 “file” 参数为其指定后备文件。如果模块是内置的,则相同适用,没有例外。
该标志的默认值为 false,但是它以前是 true。这已更改为更好地匹配文件存储设备,并且毕竟似乎是更合理的默认值。因此,为了保持与旧内核的兼容性,最好指定默认值。此外,如果依赖旧的默认值,现在需要显式指定 “n”。
请注意,“可移动” 是指逻辑单元的介质可以弹出或移除 (CD-ROM 驱动器或读卡器的情况)。它不意味着可以从主机拔下整个设备;该术语的正确说法是 “热插拔”。
cdrom=b[,b...]
此参数指定每个逻辑单元是否应模拟 CD-ROM。默认值为 false。
ro=b[,b...]
此参数指定是否应将每个逻辑单元报告为只读。这将阻止主机修改后备文件。
请注意,如果给定逻辑单元的此标志为 false,但无法以读/写模式打开后备文件,则设备将回退到只读模式。
非 CD-ROM 逻辑单元的默认值为 false;对于模拟 CD-ROM 的逻辑单元,它被强制设置为 true。
nofua=b[,b...]
此参数指定是否应忽略发送到给定逻辑单元的 SCSI Write10 和 Write12 命令中的 FUA 标志。
默认情况下,MS Windows 以 “移除优化模式” 挂载可移动存储。对介质的所有写入都是同步的,这是通过在 SCSI Write(10,12) 命令中设置 FUA (强制单元访问) 位来实现的。这迫使每次写入都等待到数据实际写入后,并防止 I/O 请求在块层中聚合,从而显着降低性能。
请注意,这可能意味着,如果设备通过 USB 供电,并且用户在不卸载设备的情况下拔下设备 (至少某些 Windows 用户会这样做),则数据可能会丢失。
默认值为 false。
luns=N
此参数指定设备将具有的逻辑单元数。它受 FSG_MAX_LUNS (8) 的限制,并且更高的值将被限制。
如果提供了此参数,并且在 “file” 参数中指定的文件数大于 “luns” 的值,则所有多余的文件都将被忽略。
如果不存在此参数,则逻辑单元的数量将从 “file” 参数中指定的文件数推断出来。如果文件参数也丢失,则假定为一个。
stall=b
指定是否允许设备停止批量端点。默认值根据 USB 设备控制器的类型确定,但通常为 true。
除了上述内容之外,该设备还接受复合框架定义的以下参数 (它们对于所有复合设备都是通用的,因此仅列出快速列表)
idVendor -- USB 供应商 ID (16 位整数)
idProduct -- USB 产品 ID (16 位整数)
bcdDevice -- USB 设备版本 (BCD) (16 位整数)
iManufacturer -- USB 制造商字符串 (字符串)
iProduct -- USB 产品字符串 (字符串)
iSerialNumber -- 序列号字符串 (字符串)
sysfs 条目¶
对于每个逻辑单元,该设备都会在 sysfs 层次结构中创建一个目录。在其中创建以下三个文件
file
读取时,它返回给定逻辑单元的后备文件的路径。如果没有后备文件 (仅当逻辑单元是可移动的时才可能),则内容为空。
写入时,它会更改给定逻辑单元的后备文件。即使给定逻辑单元未指定为可移动,也可以执行此更改 (但这对于主机来说可能看起来很奇怪)。但是,如果主机使用 “防止/允许介质移除” SCSI 命令禁止介质移除,则可能会失败。
ro
反映给定逻辑单元的 ro 标志的状态。可以随时读取它,并且可以在没有为给定逻辑单元打开后备文件时写入它。
nofua
反映给定逻辑单元的 nofua 标志的状态。可以读取和写入。
forced_eject
写入时,它会导致后备文件强制从 LUN 分离,而不管主机是否允许这样做。内容无关紧要,写入任何非零字节数都会导致弹出。
无法读取。
除此之外,像往常一样,可以从 /sys/module/g_mass_storage/parameters/* 文件中读取模块参数的值。
使用大容量存储功能的其他设备¶
大容量存储设备使用大容量存储功能来处理大容量存储协议。作为复合功能,MSF 也可以由其他设备使用 (例如 g_multi 和 acm_ms)。
前面章节中的所有信息对于使用 MSF 的其他设备都是有效的,除了可能缺少对大容量存储相关模块参数的支持,或者这些参数可能带有前缀。要弄清楚是否存在这种情况,需要查阅设备的文档或其源代码。
有关如何在设备中包含大容量存储功能的示例,可以查看 mass_storage.c、acm_ms.c 和 multi.c (按复杂性排序)。
与文件存储设备的关系¶
大容量存储功能以及大容量存储设备是基于文件存储设备开发的。两者之间的区别在于 MSG 是一个复合设备 (即使用复合框架),而文件存储设备是一个传统设备。从用户空间的角度来看,这种区别实际上并不重要,但是从内核黑客的角度来看,这意味着 (i) MSG 不会重复处理基本 USB 协议命令所需的代码,并且 (ii) MSF 可以用于任何其他复合设备中。
因此,文件存储设备已在 Linux 3.8 中删除。所有用户都需要过渡到大容量存储设备。从外部来看,这两个设备的行为基本相同,除了
在 FSG 中,“removable” 和 “cdrom” 模块参数为所有逻辑单元设置标志,而在 MSG 中,它们接受每个逻辑单元的 y/n 值列表。如果只使用单个逻辑单元,则无关紧要,但是如果有多个逻辑单元,则需要为每个逻辑单元重复 y/n 值。
FSG的“serial”、“vendor”、“product”和“release”模块参数在MSG中由复合层的参数分别处理,这些参数名为:“iSerialnumber”、“idVendor”、“idProduct”和“bcdDevice”。
MSG不支持FSG的测试模式,因此不支持FSG的“transport”、“protocol”和“buflen”模块参数。 MSG始终使用SCSI协议,仅采用批量传输模式和16 KiB缓冲区。