【问题标题】:How to create 64 bit inode?如何创建 64 位 inode?
【发布时间】:2013-09-16 00:31:10
【问题描述】:

我需要测试 64 位版本的文件 IO API(打开、创建统计等)。在这个过程中,我需要创建一个具有 64 位 inode 的文件,以便测试内部 64 位数据结构/变量以及 API。如何创建 64 位 inode ?

我编写了一个脚本,其中我试图创建一个嵌套的目录数组,每个目录中有 1024 个文件。该脚本需要大量时间来执行并突然终止。我无法继续,还有其他方法可以实现吗?

【问题讨论】:

  • 您也许可以使用fuse 创建一个文件系统来满足您的需求。不确定它是否可能。
  • @Mat:我认为这是正确的答案,您可能想发布:编写您自己的模拟文件系统,它返回一个 64 位 inode。
  • @JörgWMittag:想在发布之前确保它实际上是可能的——不知道 FUSE 是否在内部处理了 inode 编号。似乎它有效,所以发布了一个答案。

标签: linux filesystems inode


【解决方案1】:

您可以使用FUSE 模拟您想要的任何inode 编号。

查看 FUSE 附带的 hello_ll.c 示例。它创建了一个文件系统,其中包含一个 inode 编号为 2 的文件。您可以很容易地修改该文件以创建具有您想要的任何 inode 编号的文件。

使用0x10000000FFFFFFL 进行快速测试:

 $ stat fuse/hello 
  File: `fuse/hello'
  Size: 13          Blocks: 0          IO Block: 4096   regular file
Device: 11h/17d Inode: 4503599644147711  Links: 1
Access: (0444/-r--r--r--)  Uid: (    0/    root)   Gid: (    0/    root)

除了 FUSE,我不知道在“真实”文件系统上强制使用 inode 编号的实用方法。


这里有一个用于生成它的最小补丁:

--- hello_ll.c.orig 2011-11-14 13:22:19.000000000 +0100
+++ hello_ll.c  2011-11-14 13:20:27.000000000 +0100
@@ -9,6 +9,7 @@
 */

 #define FUSE_USE_VERSION 26
+#define MYINO   0x10000000FFFFFFL

 #include <fuse_lowlevel.h>
 #include <stdio.h>
@@ -31,7 +32,7 @@
        stbuf->st_nlink = 2;
        break;

-   case 2:
+   case MYINO:
        stbuf->st_mode = S_IFREG | 0444;
        stbuf->st_nlink = 1;
        stbuf->st_size = strlen(hello_str);
@@ -65,7 +66,7 @@
        fuse_reply_err(req, ENOENT);
    else {
        memset(&e, 0, sizeof(e));
-       e.ino = 2;
+       e.ino = MYINO;
        e.attr_timeout = 1.0;
        e.entry_timeout = 1.0;
        hello_stat(e.ino, &e.attr);
@@ -117,7 +118,7 @@
        memset(&b, 0, sizeof(b));
        dirbuf_add(req, &b, ".", 1);
        dirbuf_add(req, &b, "..", 1);
-       dirbuf_add(req, &b, hello_name, 2);
+       dirbuf_add(req, &b, hello_name, MYINO);
        reply_buf_limited(req, b.p, b.size, off, size);
        free(b.p);
    }
@@ -126,7 +127,7 @@
 static void hello_ll_open(fuse_req_t req, fuse_ino_t ino,
              struct fuse_file_info *fi)
 {
-   if (ino != 2)
+   if (ino != MYINO)
        fuse_reply_err(req, EISDIR);
    else if ((fi->flags & 3) != O_RDONLY)
        fuse_reply_err(req, EACCES);
@@ -139,7 +140,7 @@
 {
    (void) fi;

-   assert(ino == 2);
+   assert(ino == MYINO);
    reply_buf_limited(req, hello_str, strlen(hello_str), off, size);
 }

【讨论】:

  • 感谢 Mat 的快速响应,我查看了 FUSE 文档并意识到它仅适用于 Linux 内核。我在 AIX 上工作,我需要看看它是如何为我工作的。
【解决方案2】:

您必须创建 4294967296 个文件或目录。

为了做到这一点,您必须准备好您的文件系统,以便为它留出空间。根据您使用的文件系统,它可能会也可能不会。 (我只是尝试使用 ext4 文件系统这样做,但没有成功。)

【讨论】:

  • 我创建了多个目录,每个目录包含 1024 个文件。这样做是为了让“ls”命令可以正常工作,否则“ls”将为参数数量提供便利。
【解决方案3】:

您可以使用 systemtap 脚本来简单地增加 stat 调用返回的 inode 编号。

在 ext4 上,类似:

probe kernel.statement("ext4_getattr@fs/ext4/inode.c+21")
{
  $stat->ino = $stat->ino + 4294967295;
}

probe begin { log("starting probe") }

可以解决问题(如果您的树中的 ext4_getattr 不同,您可能需要调整“21”偏移量)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-04
    • 2014-09-22
    • 2019-10-19
    • 2020-07-31
    • 2017-06-01
    • 2013-06-08
    • 1970-01-01
    相关资源
    最近更新 更多