NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/40936: ext2fs: add support for inodes > 128 bytes



>Number:         40936
>Category:       kern
>Synopsis:       ext2fs: add support for inodes > 128 bytes
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sun Mar 01 14:55:00 +0000 2009
>Originator:     Frederik Sausmikat
>Release:        4.0.1
>Organization:
>Environment:
>Description:
In recent Linux distributions it has become common practice to create ext2/ext3 
filesystems with inode sizes of 256 bytes (or more) which NetBSD doesn't 
support since the ext2fs code is fixed to 128 bytes/inode.

I'm not aware what the additional space in the inode actually is used for but a 
quick search on Google indicated this had been done in preparation for the 
upcoming ext4 filesystem.

The attached patch, which applies against CURRENT, is essentially copy & pasted 
(with minor adjustments) from a patch that was commited to the OpenBSD source 
tree about three months ago which in turn had been posted in a PR for FreeBSD.

I've tested it with a 4.0.1 and CURRENT kernel and it seems to work without 
problems so far.

For some more information on the patch see:
<http://www.nabble.com/ext2-with-inode-size-other-than-128b-td20550369.html>
and
<http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/124621>

>How-To-Repeat:
Try to mount an ext2/ext3 filesystem whose inode size is greater than 128 bytes.
>Fix:
Index: ext2fs_dinode.h
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_dinode.h,v
retrieving revision 1.17
diff -u -r1.17 ext2fs_dinode.h
--- ext2fs_dinode.h     23 Nov 2008 10:09:25 -0000      1.17
+++ ext2fs_dinode.h     1 Mar 2009 11:04:16 -0000
@@ -154,7 +154,7 @@
 #define EXT2_NODUMP            0x00000040      /* do not dump file */
 
 /* Size of on-disk inode. */
-#define        EXT2_DINODE_SIZE        (sizeof(struct ext2fs_dinode))  /* 128 
*/
+#define EXT2_DINODE_SIZE(s)    (s)->e2fs.e2fs_inode_size
 
 /*
  * The e2di_blocks fields may be overlaid with other information for
Index: ext2fs_inode.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_inode.c,v
retrieving revision 1.67
diff -u -r1.67 ext2fs_inode.c
--- ext2fs_inode.c      17 Dec 2008 20:51:38 -0000      1.67
+++ ext2fs_inode.c      1 Mar 2009 11:04:16 -0000
@@ -221,7 +221,7 @@
        }
        ip->i_flag &= ~(IN_MODIFIED | IN_ACCESSED);
        cp = (char *)bp->b_data +
-           (ino_to_fsbo(fs, ip->i_number) * EXT2_DINODE_SIZE);
+           (ino_to_fsbo(fs, ip->i_number) * EXT2_DINODE_SIZE(fs));
        e2fs_isave(ip->i_din.e2fs_din, (struct ext2fs_dinode *)cp);
        if ((updflags & (UPDATE_WAIT|UPDATE_DIROP)) != 0 &&
            (flags & IN_MODIFIED) != 0 &&
Index: ext2fs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vfsops.c,v
retrieving revision 1.141
diff -u -r1.141 ext2fs_vfsops.c
--- ext2fs_vfsops.c     8 Dec 2008 11:34:30 -0000       1.141
+++ ext2fs_vfsops.c     1 Mar 2009 11:04:17 -0000
@@ -572,7 +572,7 @@
        fs->e2fs_bmask = ~fs->e2fs_qbmask;
        fs->e2fs_ngdb =
            howmany(fs->e2fs_ncg, fs->e2fs_bsize / sizeof(struct ext2_gd));
-       fs->e2fs_ipb = fs->e2fs_bsize / EXT2_DINODE_SIZE;
+       fs->e2fs_ipb = fs->e2fs_bsize / EXT2_DINODE_SIZE(fs);
        fs->e2fs_itpg = fs->e2fs.e2fs_ipg / fs->e2fs_ipb;
 
        /*
@@ -640,7 +640,7 @@
                        break;
                }
                cp = (char *)bp->b_data +
-                   (ino_to_fsbo(fs, ip->i_number) * EXT2_DINODE_SIZE);
+                   (ino_to_fsbo(fs, ip->i_number) * EXT2_DINODE_SIZE(fs));
                e2fs_iload((struct ext2fs_dinode *)cp, ip->i_din.e2fs_din);
                ext2fs_set_inode_guid(ip);
                brelse(bp, 0);
@@ -690,8 +690,7 @@
        ump = NULL;
 
 #ifdef DEBUG_EXT2
-       printf("sb size: %d ino size %d\n", sizeof(struct ext2fs),
-           EXT2_DINODE_SIZE);
+       printf("ext2 sb size: %d\n", sizeof(struct ext2fs));
 #endif
        error = bread(devvp, (SBOFF / size), SBSIZE, cred, 0, &bp);
        if (error)
@@ -711,6 +710,10 @@
        bp = NULL;
        m_fs = ump->um_e2fs;
        m_fs->e2fs_ronly = ronly;
+
+#ifdef DEBUG_EXT2
+       printf("ext2 ino size %d\n", EXT2_DINODE_SIZE(m_fs));
+#endif
        if (ronly == 0) {
                if (m_fs->e2fs.e2fs_state == E2FS_ISCLEAN)
                        m_fs->e2fs.e2fs_state = 0;
@@ -731,7 +734,7 @@
        m_fs->e2fs_bmask = ~m_fs->e2fs_qbmask;
        m_fs->e2fs_ngdb =
            howmany(m_fs->e2fs_ncg, m_fs->e2fs_bsize / sizeof(struct ext2_gd));
-       m_fs->e2fs_ipb = m_fs->e2fs_bsize / EXT2_DINODE_SIZE;
+       m_fs->e2fs_ipb = m_fs->e2fs_bsize / EXT2_DINODE_SIZE(m_fs);
        m_fs->e2fs_itpg = m_fs->e2fs.e2fs_ipg / m_fs->e2fs_ipb;
 
        m_fs->e2fs_gd = malloc(m_fs->e2fs_ngdb * m_fs->e2fs_bsize,
@@ -1072,7 +1075,7 @@
                *vpp = NULL;
                return (error);
        }
-       cp = (char *)bp->b_data + (ino_to_fsbo(fs, ino) * EXT2_DINODE_SIZE);
+       cp = (char *)bp->b_data + (ino_to_fsbo(fs, ino) * EXT2_DINODE_SIZE(fs));
        ip->i_din.e2fs_din = pool_get(&ext2fs_dinode_pool, PR_WAITOK);
        e2fs_iload((struct ext2fs_dinode *)cp, ip->i_din.e2fs_din);
        ext2fs_set_inode_guid(ip);
@@ -1253,9 +1256,8 @@
                return (EINVAL);           /* XXX needs translation */
        }
        if (fs2h32(fs->e2fs_rev) > E2FS_REV0) {
-               if (fs2h32(fs->e2fs_first_ino) != EXT2_FIRSTINO ||
-                   fs2h16(fs->e2fs_inode_size) != EXT2_DINODE_SIZE) {
-                       printf("Ext2 fs: unsupported inode size\n");
+               if (fs2h32(fs->e2fs_first_ino) != EXT2_FIRSTINO) {
+                       printf("Ext2 fs: unsupported first inode position\n");
                        return (EINVAL);      /* XXX needs translation */
                }
                if (fs2h32(fs->e2fs_features_incompat) &



Home | Main Index | Thread Index | Old Index