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