Menu

#187 sqlite_indexer.c:384:17: error: 'struct ext2_inode_large' has no member named

None
closed
nobody
None
2
2026-02-01
2025-08-16
noa body
No

manjaro [arch-like], Linux kernel 6.12, gcc 15.1.1, makepkg/pkgbuild dependencies:
depends=(util-linux-libs zlib bzip2 lzo readline ncurses e2fsprogs)
makedepends=(util-linux sqlite openssl)

ext2_inode_large is defined in:

ext2_fs.h

and referenced in:
indexer_test.c

gcc offers suggestions as to the correct member name and, with a bit of sleuthing:

sqlite_indexer.c:384:17: error: 'struct ext2_inode_large' has no member named 'di_atime'; did you mean 'i_atime'?
sqlite_indexer.c:386:17: error: 'struct ext2_inode_large' has no member named 'di_mtime'; did you mean 'i_mtime'?
sqlite_indexer.c:388:17: error: 'struct ext2_inode_large' has no member named 'di_ctime'; did you mean 'i_ctime'?
sqlite_indexer.c:397:31: error: 'struct ext2_inode_large' has no member named 'di_mode'; did you mean 'i_mode'?
sqlite_indexer.c:397:42: error: 'struct ext2_inode_large' has no member named 'di_nlink' (indexer_test.c references dinode.i_links_count = buf->st_nlink; which suggests member name 'i_links_count' is equivalent to 'nlink')
sqlite_indexer.c:397:58: error: 'struct ext2_inode_large' has no member named 'di_uid'; did you mean 'i_uid'?
sqlite_indexer.c:397:70: error: 'struct ext2_inode_large' has no member named 'di_gid'; did you mean 'i_gid'?
sqlite_indexer.c:397:80: error: 'struct ext2_inode_large' has no member named 'di_rdev' (indexer_test.c references dinode.i_block[0] = buf->st_rdev; which suggests member name 'i_block' is equivalent to 'rdev')
sqlite_indexer.c:397:95: error: 'struct ext2_inode_large' has no member named 'di_size'; did you mean 'i_size'?
sqlite_indexer.c:397:124: error: 'struct ext2_inode_large' has no member named 'di_extraisize'; did you mean 'i_extra_isize'?
sqlite_indexer.c:397:162: error: 'struct ext2_inode_large' has no member named 'di_file_acl'; did you mean 'i_file_acl'?
diff a/common/sqlite_indexer.c b/common/sqlite_indexer.c
index 8ce80f8..10b77e8 100644
--- a/common/sqlite_indexer.c
+++ b/common/sqlite_indexer.c
@@ -381,20 +381,20 @@ sqlite_addInode(struct ext2_inode_large *dp, dump_ino_t ino, int metadata_only)
    mts[0] = 0;
    cts[0] = 0;


-   t = dp->di_atime;
+   t = dp->i_atime;
    strftime(ats, sizeof ats, "%FT%T", gmtime(&t));
-   t = dp->di_mtime;
+   t = dp->i_mtime;
    strftime(mts, sizeof ats, "%FT%T", gmtime(&t));
-   t = dp->di_ctime;
+   t = dp->i_ctime;
    strftime(cts, sizeof ats, "%FT%T", gmtime(&t));


-   // xattr: dp->di_extraisize != 0
-   // acl: dp->di_file_acl (inode?)
+   // xattr: dp->i_extra_isize != 0
+   // acl: dp->i_file_acl (inode?)
    // se linux?...

    snprintf(buffer, sizeof buffer,
        "insert into inode(backup_id, ino, is_deleted, mode, nlink, uid, gid, rdev, size, atime, mtime, ctime, has_xattr, has_acl, volume, recno) values(1, %d, '%s', %d, %d, %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %lld)\n",

-       ino, "N", dp->di_mode, dp->di_nlink, dp->di_uid, dp->di_gid, dp->di_rdev, dp->di_size, ats, mts, cts, (dp->di_extraisize == 0) ? "N" : "Y", (dp->di_file_acl != 0) ? "Y" : "N", spcl.c_volume, u_spcl_c_tapea());
+       ino, "N", dp->i_mode, dp->i_links_count, dp->i_uid, dp->i_gid, dp->i_block, dp->i_size, ats, mts, cts, (dp->i_extra_isize == 0) ? "N" : "Y", (dp->i_file_acl != 0) ? "Y" : "N", spcl.c_volume, u_spcl_c_tapea());

    EXEC(db, buffer);

Discussion

  • noa body

    noa body - 2025-08-17

    OpenAi chatGPT offered, and gave me permission, to post its analysis:
    Yep — with just the link and the compiler output, that’s enough to fix it.

    Your file is using old UFS-style di_ member names on an ext2_inode_large. In e2fsprogs’ headers the members are i_ (and one of them changes name entirely: links → i_links_count). Here’s the authoritative struct so you can see the field names you actually have: i_atime, i_mtime, i_ctime, i_mode, i_uid, i_gid, i_links_count, i_size, i_file_acl, i_extra_isize, etc.
    git.osdyson.ru

    Also: ext2/3/4 inodes don’t have an rdev field. For character/block device nodes, the device number is stored in the inode’s first direct block pointer (i_block[0]); otherwise it’s just 0.
    tldp.org f.osdev.org

    Below is a minimal, working patch against your current sqlite_indexer.c that:

    • Maps every di_ to the correct i_ name (and di_nlink → i_links_count).
    • Computes rdev from i_block[0] when the mode says “device”.
    • Leaves the SQLite schema alone (it already expects rdev as an integer).
    • (Optional) silences the two “unused variable” warnings you showed.

    I used your raw file to anchor line numbers/surrounding code.
    SourceForge

    --- a/common/sqlite_indexer.c
    +++ b/common/sqlite_indexer.c
    @@ -1,6 +1,8 @@
     /* ... existing includes ... */
    +/* for S_ISCHR/S_ISBLK */
    +#include <sys/stat.h>
    
     /* ... */
    
    @@ -306,7 +308,7 @@ static int sqlite_addDirEntry(struct direct *dp, dump_ino_t parent_ino) {
    
    -        const char *tail;
    +        /* const char *tail; */ /* not used here */
             if (db == NULL) { return -1; }
             /* don't include backlink */
             if (!strcmp(dp->d_name, "..")) { return -1; }
    @@ -327,7 +329,7 @@ static int sqlite_addDirEntry(struct direct *dp, dump_ino_t parent_ino) {
             if (rc != SQLITE_DONE) {
    -                int i;
    +                /* int i; */ /* unused */
                     msg("(%s:%d) SQL error: %s\n", __FILE__, __LINE__, sqlite3_errmsg(db));
                     msg("(%s:%d) %s\n", __FILE__, __LINE__, sqlite3_sql(stmt));
                     sqlite3_free(errMsg);
    @@ -373,32 +375,46 @@ static int sqlite_addInode(struct ext2_inode_large *dp, dump_ino_t ino, int metadata_only) {
             char ats[40]; char mts[40]; char cts[40];
             time_t t;
             if (db == NULL) { return -1; }
             ats[0] = mts[0] = cts[0] = 0;
    -        t = dp->di_atime; strftime(ats, sizeof ats, "%FT%T", gmtime(&t));
    -        t = dp->di_mtime; strftime(mts, sizeof ats, "%FT%T", gmtime(&t));
    -        t = dp->di_ctime; strftime(cts, sizeof ats, "%FT%T", gmtime(&t));
    -        // xattr: dp->di_extraisize != 0
    -        // acl: dp->di_file_acl (inode?)
    +        t = dp->i_atime; strftime(ats, sizeof ats, "%FT%T", gmtime(&t));
    +        t = dp->i_mtime; strftime(mts, sizeof ats, "%FT%T", gmtime(&t));
    +        t = dp->i_ctime; strftime(cts, sizeof ats, "%FT%T", gmtime(&t));
    +        // xattr: dp->i_extra_isize != 0
    +        // acl:   dp->i_file_acl (nonzero means present)
    +
    +        /* ext2/3/4 store device numbers in i_block[0] for device inodes */
    +        unsigned int rdev = 0;
    +        if (S_ISCHR(dp->i_mode) || S_ISBLK(dp->i_mode)) {
    +                rdev = dp->i_block[0];
    +        }
    
    
    -        snprintf(buffer, sizeof buffer,
    -                 "insert into inode(backup_id, ino, is_deleted, mode, nlink, uid, gid, rdev, size, atime, mtime, ctime, has_xattr, has_acl, volume, recno) "
    -                 "values(1, %d, '%s', %d, %d, %d, %d, %d, %d, '%s', '%s', '%s', '%s', '%s', %d, %lld)\n",
    -                 ino, "N",
    -                 dp->di_mode, dp->di_nlink, dp->di_uid, dp->di_gid, dp->di_rdev, dp->di_size,
    -                 ats, mts, cts,
    -                 (dp->di_extraisize == 0) ? "N" : "Y",
    -                 (dp->di_file_acl != 0) ? "Y" : "N",
    -                 spcl.c_volume, u_spcl_c_tapea());
    +        snprintf(buffer, sizeof buffer,
    +                 "insert into inode(backup_id, ino, is_deleted, mode, nlink, uid, gid, rdev, size, atime, mtime, ctime, has_xattr, has_acl, volume, recno) "
    +                 "values(1, %d, '%s', %u, %u, %u, %u, %u, %u, '%s', '%s', '%s', '%s', '%s', %d, %lld)\n",
    +                 ino, "N",
    +                 (unsigned)dp->i_mode,
    +                 (unsigned)dp->i_links_count,
    +                 (unsigned)dp->i_uid,
    +                 (unsigned)dp->i_gid,
    +                 rdev,
    +                 (unsigned)dp->i_size,
    +                 ats, mts, cts,
    +                 (dp->i_extra_isize == 0) ? "N" : "Y",
    +                 (dp->i_file_acl != 0) ? "Y" : "N",
    +                 spcl.c_volume, u_spcl_c_tapea());
             EXEC(db, buffer);
             return 0;
     }
    

    Why this is correct:

    • The failing identifiers (di_atime, di_mtime, di_ctime, di_mode, di_nlink, di_uid, di_gid, di_size, di_extraisize, di_file_acl) don’t exist on struct ext2_inode_large; the modern, correct identifiers are the i_* names shown above, and links are i_links_count. git.osdyson.ru
    • There is no di_rdev (or i_rdev) in ext2/3/4 on-disk inodes. For device nodes, major/minor is packed into the first direct block pointer, which you can read directly as a 32-bit integer; for non-device inodes, it stays 0. tldp.org f.osdev.org
    • Everything else (timestamps as __u32 seconds since epoch, ACL low word in i_file_acl, extra inode size in i_extra_isize) lines up with the header. git.osdyson.ru
     
  • Tim Woodall

    Tim Woodall - 2025-08-18

    Thanks. The easiest thing is just to build with --disable-sqlite I'm not sure how useful this sql indexer stuff is, there's absolutely nothing to use what gets written to the db! I've just pushed my wip branch so you can get my fix here:
    https://sourceforge.net/p/dump/code/ci/6e1ec6d65c3dc7d57640fa55b4d541d262ae6aca/

    My branch needs some minor cleanups, and removing some of the commits that drag in some large binary images for my testing but addresses a number of open bugs and feature requests.

    My goal with the 0.4b53 release was to move to having tests that don't require root. However, I'm waiting on upstream to review/import a patch that supports SEEK_DATA/SEEK_HOLE for the ext4 fuse implementation as most of the tests can't work without that so it's been stalled for a while.

     
  • Tim Woodall

    Tim Woodall - 2026-02-01
    • status: open --> closed
    • Group: -->
     
  • Tim Woodall

    Tim Woodall - 2026-02-01

    Fixed in v0.4b53

     

Log in to post a comment.

MongoDB Logo MongoDB