Как создать 64-битный индекс?

Мне нужно протестировать 64-битную версию файловых API-интерфейсов ввода-вывода (открыть, создать статистику и т. д.). В этом процессе мне нужно создать файл с 64-битным индексным узлом, чтобы тестировались внутренние 64-битные структуры/переменные данных и, следовательно, API. Как создать 64-битный индекс?

Я написал сценарий, в котором я пытаюсь создать вложенный массив каталогов с 1024 файлами в каждом каталоге. Скрипт занимает огромное количество времени для выполнения и внезапно завершается. Я не могу продолжить, есть ли другой способ добиться этого?


person user1045419    schedule 14.11.2011    source источник
comment
Вы можете создать файловую систему с fuse, которая будет делать то, что вы хотите. Хотя не уверен, что это возможно.   -  person Mat    schedule 14.11.2011
comment
@Mat: я думаю, что это правильный ответ, вы можете опубликовать: напишите свою собственную фиктивную файловую систему, которая возвращает 64-битный индексный дескриптор.   -  person Jörg W Mittag    schedule 14.11.2011
comment
@JörgWMittag: перед публикацией хотел убедиться, что это действительно возможно - не знал, обрабатывает ли FUSE номера инодов внутри или нет. Похоже, это работает, поэтому отправил ответ.   -  person Mat    schedule 14.11.2011


Ответы (3)


Вы можете имитировать любой номер инода, используя FUSE.

Посмотрите на пример hello_ll.c, поставляемый с FUSE. Он создает файловую систему с одним файлом с номером индекса 2. Вы можете довольно легко изменить этот файл, чтобы создавать файлы с любым номером индекса, который вы хотите.

Быстрый тест с 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, я не знаю практического способа принудительно указать номер инода в «настоящих» файловых системах.


Вот минимальный патч, используемый для этого:

--- 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);
 }
person Mat    schedule 14.11.2011
comment
Спасибо, Мэт, за быстрый ответ, я проверил документы FUSE и понял, что он работает только для ядер Linux. Я работаю над AIX, мне нужно посмотреть, как это работает для меня. - person user1045419; 15.11.2011

Вам нужно будет создать 4294967296 файлов или каталогов.

Для этого вы должны подготовить свою файловую систему, чтобы было место для этого. В зависимости от того, какую файловую систему вы используете, это может быть или не быть возможным. (Я только что пытался сделать это с файловой системой ext4, и это не сработало.)

person glglgl    schedule 14.11.2011
comment
Я создал несколько каталогов, и каждый каталог содержит 1024 файла. Это было сделано для того, чтобы команда ls работала без проблем, иначе ls будет списывать количество аргументов. - person user1045419; 15.11.2011

Вы можете использовать сценарий systemtap, чтобы просто увеличить номер инода, возвращаемый вызовом stat.

На ext4 что-то вроде:

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

probe begin { log("starting probe") }

поможет (вам, возможно, придется настроить смещение «21», если ext4_getattr отличается в вашем дереве).

person Eric Sandeen    schedule 15.09.2013