【问题标题】:Distinguishing file on the filesystem区分文件系统上的文件
【发布时间】:2019-01-15 11:58:45
【问题描述】:

我试图通过以下要求来区分文件系统上的文件(假设所有文件都在同一个文件系统中):

  1. 如果文件 A 被重命名为文件 B,它应该看起来是一样的
  2. 如果文件 A 被删除然后创建它应该看起来不同

由于我假设所有文件都在同一个文件系统中,因此我倾向于使用inode_number。但它不满足2.这一点。其实:

root@spc:~/test# touch test
root@spc:~/test# ls -li
total 0
2098203 -rw-r--r-- 1 root root 0 Jan 15 14:55 test
root@spc:~/test# rm test
root@spc:~/test# touch test
root@spc:~/test# ls -li
total 0
2098203 -rw-r--r-- 1 root root 0 Jan 15 14:55 test

因此,这两个不同的文件似乎具有相同的 inode 编号。有没有办法为linux/ext4 做到这一点?也许我们可以使用一些文件系统特定的api来存储一些元uid

【问题讨论】:

  • (st_dev, st_ino, st_gen) 元组就足够了,但不幸的是 st_gen (inode generation number) 没有被内核导出。 statx() 调用时考虑过它,但它似乎没有进入它。
  • 也就是说,statx() 提供的 (st_dev, st_ino, st_btime) 可能有效。您需要使用来自<sys/syscall.h>syscall(),并从内核include/linux/uapi/stat.h:struct statx 复制struct statx

标签: c linux filesystems


【解决方案1】:

您可以设置扩展文件系统属性(在支持的情况下,即使用选项 user_xattr 挂载时使用 ext4):

#include <sys/types.h>
#include <attr/xattr.h>

int main (void) {
    setxattr("test", "user.fileguid", "someuniqueguid", 15, 0);
}

然后读回来

char uuid[100];
int len = getxattr("test", "user.fileguid", uuid, sizeof(uuid), 0);

如果该属性只能由特权进程修改,您可以使用security 命名空间而不是user(即属性名称security.fileguid)。在这种情况下,文件所有者本身不能自己修改属性。如果您不使用 user 命名空间,则甚至不需要挂载选项 user_xattr

但是,这些属性不会在文件创建后立即设置。但在第一次使用您的工具访问文件时(即尚未设置 guid 时)设置一个随机 guid 就足够了。

这些文件属性与 inode 一起保存,因此重命名文件或(硬)链接它将保留这些属性。但是,删除并重新创建它不会。

【讨论】:

    【解决方案2】:

    唉,这是不可能的,因为:

    1. 对于用户控制的所有数据/元数据(包括扩展属性等),可以将它们的值/内容设置为与“原始”文件完全相同的值。

    2. 对于 inode 编号,它取决于内核中的文件系统支持,其中许多 (FS) 回收 inode 编号。

    【讨论】:

    • 您能举一些用户可以设置的元数据示例吗?
    • @SomeName 时间戳、文件长度(间接)、ID、链接数等
    猜你喜欢
    • 2011-12-14
    • 2021-08-06
    • 2011-04-08
    • 2019-02-28
    • 2020-01-16
    • 2023-04-09
    • 2015-12-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多