user1045419
user1045419

Reputation: 21

How to create 64 bit inode?

I need to test 64bit version of file IO APIs (open, create stat etc. ). In this process I need to create a file which has a 64 bit inode, so that the internal 64 bit data structures/variables are tested and so the APIs. How do I create a 64 bit inode ?

I have written a script where in I am trying to create a nested array of directories with 1024 files in each directories. The script takes huge amount of time to execute and terminates abruptly. I am not able to proceed, is there any other way to achieve it?

Upvotes: 2

Views: 2284

Answers (3)

Eric Sandeen
Eric Sandeen

Reputation: 1

You could use a systemtap script to simply bump up the inode number returned by a stat call.

On ext4, something like:

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

probe begin { log("starting probe") }

would do the trick (you might have to adjust the "21" offset, if ext4_getattr is different in your tree).

Upvotes: 0

Mat
Mat

Reputation: 206841

You could simulate any inode number you want by using FUSE.

Look at the hello_ll.c example that comes with FUSE. It creates a filesystem with a single file that has inode number 2. You could modify that file pretty easily to create files with whatever inode number you want.

A quick test with 0x10000000FFFFFFL does this:

 $ 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)

Other than FUSE, I know of no practical way of forcing an inode number on "real" filesystems.


Here's a minimal patch used to produce that:

--- 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);
 }

Upvotes: 2

glglgl
glglgl

Reputation: 91109

You would have to create 4294967296 files or directories.

In order to do so, you have to prepare your file system to have space for this. Depending on which file system you use, it may or may not be possible. (I just tried to do so with a ext4 file system, and it didn't work.)

Upvotes: 0

Related Questions