我正在运行 openSUSE Tumbleweed,并在安装 btrfs 子卷时发现奇怪的行为。我在 btrfs 文件系统上有两个子卷:@media
和@migration
。我的/etc/fstab
设置是这样的:
UUID=<UUID> /mnt/media btrfs subvol=/@media,noatime,noexec,nodev,nosuid 0 0
UUID=<UUID> /mnt/migration btrfs subvol=/@migration,noatime,noexec,nodev,nosuid 0 0
但是,当我运行时mount -a
,我得到以下信息:
/dev/sdb1 on /mnt/media type btrfs (rw,nosuid,nodev,noexec,noatime,space_cache=v2,subvolid=278,subvol=/@media)
/dev/sdb1 on /mnt/migration type btrfs (rw,relatime,space_cache=v2,subvolid=279,subvol=/@migration)
如您所见,安装选项nosuid,nodev,noexec,noatime
似乎仅应用于安装的第一个子卷。第二个只有relatime
.
当我尝试重新安装第二个子卷,它显示正确:
:~> sudo mount -o remount,noatime /dev/sdb1 /mnt/migration
:~> mount | tail -n 2
/dev/sdb1 on /mnt/media type btrfs (rw,nosuid,nodev,noexec,noatime,space_cache=v2,subvolid=278,subvol=/@media)
/dev/sdb1 on /mnt/migration type btrfs (rw,noatime,space_cache=v2,subvolid=279,subvol=/@migration)
所以我的问题是:
- 后续子卷上的挂载选项重要吗? (也就是说,这只是一个视觉错误吗?)
- 有什么方法可以验证挂载选项是否真正生效?
答案1
子卷挂载实际上遵循 noatime。这是在新的 btrfs 文档中明确指出的(尽管不清楚)。https://btrfs.readthedocs.io/en/latest/btrfs-subvolume.html#mount-options
(他们还支持 noexec,这就是我的目的。)
$ sudo mount -o subvolid=257,noatime /dev/sdd1 test
$ touch -a -t 9001010101 test/foo
$ stat test/foo
Access: 1990-01-01 01:01:00.000000000 -0700
$ cat test/foo # noatime: atime unchanged
$ stat test/foo
Access: 1990-01-01 01:01:00.000000000 -0700
$ sudo umount test
$ sudo mount -o subvolid=257 /dev/sdd1 test
$ cat test/foo # default (relatime): atime changed
$ stat test/foo
Access: 2023-09-20 03:50:37.919732794 -0600
(为了简洁起见,已剪掉 stat 的其他输出行)
答案2
我的声望还不到50,所以我无法评论squircle的自我回答。但测试是有缺陷的。touch -a
无论安装点选项如何,都会更新 atime。
/tmp
32% ❯ sudo mount -t tmpfs -o noatime none noatime
/tmp
32% ❯ cd noatime/
/tmp/noatime
32% ❯ touch banana
/tmp/noatime
32% ❯ stat banana
File: banana
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 0,116 Inode: 2 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/vytautas) Gid: ( 100/ users)
Access: 2022-04-14 00:03:14.714042647 +0300
Modify: 2022-04-14 00:03:14.714042647 +0300
Change: 2022-04-14 00:03:14.714042647 +0300
Birth: -
/tmp/noatime
32% ❯ cat banana
/tmp/noatime
32% ❯ stat banana
File: banana
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 0,116 Inode: 2 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/vytautas) Gid: ( 100/ users)
Access: 2022-04-14 00:03:14.714042647 +0300
Modify: 2022-04-14 00:03:14.714042647 +0300
Change: 2022-04-14 00:03:14.714042647 +0300
Birth: -
/tmp/noatime
32% ❯ touch -a -t 1212121212 banana
/tmp/noatime
32% ❯ stat banana
File: banana
Size: 0 Blocks: 0 IO Block: 4096 regular empty file
Device: 0,116 Inode: 2 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 1000/vytautas) Gid: ( 100/ users)
Access: 2012-12-12 12:12:00.000000000 +0200
Modify: 2022-04-14 00:03:14.714042647 +0300
Change: 2022-04-14 00:03:39.030547903 +0300
Birth: -
答案3
我设法使用 btrfs wiki 和一些简单的实验来回答我的问题。
后续子卷上的挂载选项重要吗?
不。根据维基百科:
笔记:大多数挂载选项适用于整个文件系统,并且只有第一个挂载的子卷中的选项才会生效。这是由于缺乏实施造成的,并且将来可能会发生变化。这意味着(例如)您无法使用安装选项设置每个子卷的 nodatacow、nodatasum 或压缩。这个问题最终应该得到解决,但事实证明很难在 Linux VFS 框架内正确实现。
有什么方法可以验证挂载选项是否真正生效?
是的。我用atime
/noatime
参数做到了这一点:
atime
使用选项挂载子卷 1noatime
使用选项挂载子卷 2- 在子卷 2 上创建测试文件
- 用于
touch
将 atime 设置为任意值(例如touch -a -t 12121212 test_file
) - 验证 atime 是否设置为测试值
ls -lu
此实验将显示,尽管子卷 2 是使用该选项挂载的,但其 atime 已在子卷 2 上更新noatime
。这是因为子卷 1 是首先使用该atime
选项挂载的。