Subject: kern/9088: Patch for NetBSD 1.4.1 to support ext2fs Rev. 1
To: None <gnats-bugs@gnats.netbsd.org>
From: None <sgoel@cyberdialogue.com>
List: netbsd-bugs
Date: 12/31/1999 10:51:58
>Number: 9088
>Category: kern
>Synopsis: Add support for ext2fs Rev. 1 to NetBSD 1.4.1
>Confidential: no
>Severity: critical
>Priority: medium
>Responsible: kern-bug-people (Kernel Bug People)
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Dec 31 10:50:59 1999
>Last-Modified:
>Originator: Shantanu Goel
>Organization:
>Release: NetBSD 1.4.1
>Environment:
System: NetBSD anupama.goel.com 1.4.1 NetBSD 1.4.1 (ANUPAMA) #4: Fri Dec 31 09:45:51 GMT 1999 root@anupama.goel.com:/usr/src/sys/arch/i386/compile/ANUPAMA i386
>Description:
NetBSD 1.4.1 does not support ext2fs Rev. 1. Newer versions
of Linux (version 2.2.13 in my case) create a filesystem with
this revision. The attached patch adds support for this.
>How-To-Repeat:
The kernel refuses to mount a Rev. 1 ext2fs filesystem because
it only supports Rev. 0.
>Fix:
Please see attached patch.
diff -cr ext2fs.orig/ext2fs.h ext2fs/ext2fs.h
*** ext2fs.orig/ext2fs.h Wed Feb 17 13:09:43 1999
--- ext2fs/ext2fs.h Thu Dec 30 12:48:27 1999
***************
*** 152,157 ****
--- 152,159 ----
int32_t e2fs_ngdb; /* number of group descriptor block */
int32_t e2fs_ipb; /* number of inodes per block */
int32_t e2fs_itpg; /* number of inode table per group */
+ u_int32_t e2fs_firstino;/* first non-reserved inode */
+ u_int32_t e2fs_isize; /* inode size */
struct ext2_gd *e2fs_gd; /* group descripors */
};
***************
*** 160,167 ****
/*
* Filesystem identification
*/
! #define E2FS_MAGIC 0xef53 /* the ext2fs magic number */
! #define E2FS_REV 0 /* revision level */
/*
* OS identification
--- 162,171 ----
/*
* Filesystem identification
*/
! #define E2FS_MAGIC 0xef53 /* the ext2fs magic number */
! #define E2FS_OLD_REV 0 /* original version */
! #define E2FS_DYNAMIC_REV 1 /* V2 with dynamic inode sizes */
! #define E2FS_REV E2FS_DYNAMIC_REV
/*
* OS identification
diff -cr ext2fs.orig/ext2fs_alloc.c ext2fs/ext2fs_alloc.c
*** ext2fs.orig/ext2fs_alloc.c Wed Feb 10 13:14:09 1999
--- ext2fs/ext2fs_alloc.c Thu Dec 30 13:00:37 1999
***************
*** 558,564 ****
pip = VTOI(ap->a_pvp);
fs = pip->i_e2fs;
! if ((u_int)ino >= fs->e2fs.e2fs_icount || (u_int)ino < EXT2_FIRSTINO)
panic("ifree: range: dev = 0x%x, ino = %d, fs = %s\n",
pip->i_dev, ino, fs->e2fs_fsmnt);
cg = ino_to_cg(fs, ino);
--- 558,565 ----
pip = VTOI(ap->a_pvp);
fs = pip->i_e2fs;
! if ((u_int)ino >= fs->e2fs.e2fs_icount ||
! (u_int)ino < fs->e2fs_firstino)
panic("ifree: range: dev = 0x%x, ino = %d, fs = %s\n",
pip->i_dev, ino, fs->e2fs_fsmnt);
cg = ino_to_cg(fs, ino);
diff -cr ext2fs.orig/ext2fs_bswap.c ext2fs/ext2fs_bswap.c
*** ext2fs.orig/ext2fs_bswap.c Sun Aug 9 20:15:38 1998
--- ext2fs/ext2fs_bswap.c Thu Dec 30 12:38:33 1999
***************
*** 70,75 ****
--- 70,77 ----
new->e2fs_beh = bswap16(old->e2fs_beh);
new->e2fs_ruid = bswap16(old->e2fs_ruid);
new->e2fs_rgid = bswap16(old->e2fs_rgid);
+ new->e2fs_first_ino = bswap32(old->e2fs_first_ino;
+ new->e2fs_inode_size = bswap16(old->e2fs_inode_size;
}
void e2fs_cg_bswap(old, new, size)
diff -cr ext2fs.orig/ext2fs_inode.c ext2fs/ext2fs_inode.c
*** ext2fs.orig/ext2fs_inode.c Wed Mar 24 05:51:30 1999
--- ext2fs/ext2fs_inode.c Thu Dec 30 13:02:58 1999
***************
*** 155,161 ****
return (error);
}
cp = (caddr_t)bp->b_data +
! (ino_to_fsbo(fs, ip->i_number) * EXT2_DINODE_SIZE);
e2fs_isave(&ip->i_din.e2fs_din, (struct ext2fs_dinode *)cp);
if (ap->a_waitfor && (ap->a_vp->v_mount->mnt_flag & MNT_ASYNC) == 0)
return (bwrite(bp));
--- 155,161 ----
return (error);
}
cp = (caddr_t)bp->b_data +
! (ino_to_fsbo(fs, ip->i_number) * fs->e2fs_isize);
e2fs_isave(&ip->i_din.e2fs_din, (struct ext2fs_dinode *)cp);
if (ap->a_waitfor && (ap->a_vp->v_mount->mnt_flag & MNT_ASYNC) == 0)
return (bwrite(bp));
diff -cr ext2fs.orig/ext2fs_vfsops.c ext2fs/ext2fs_vfsops.c
*** ext2fs.orig/ext2fs_vfsops.c Mon Jun 21 23:03:07 1999
--- ext2fs/ext2fs_vfsops.c Fri Dec 31 13:21:51 1999
***************
*** 369,375 ****
brelse(bp);
return (EIO); /* XXX needs translation */
}
! if (fs2h32(newfs->e2fs_rev) != E2FS_REV) {
#ifdef DIAGNOSTIC
printf("Ext2 fs: unsupported revision number: %x (expected %x)\n",
fs2h32(newfs->e2fs_rev), E2FS_REV);
--- 369,380 ----
brelse(bp);
return (EIO); /* XXX needs translation */
}
!
! #ifdef DEBUG_EXT2
! printf("rev: %x\n", fs2h32(newfs->e2fs_rev));
! #endif
!
! if (fs2h32(newfs->e2fs_rev) > E2FS_REV) {
#ifdef DIAGNOSTIC
printf("Ext2 fs: unsupported revision number: %x (expected %x)\n",
fs2h32(newfs->e2fs_rev), E2FS_REV);
***************
*** 386,397 ****
return (EIO); /* XXX needs translation */
}
-
fs = VFSTOUFS(mountp)->um_e2fs;
/*
* copy in new superblock, and compute in-memory values
*/
e2fs_sbload(newfs, &fs->e2fs);
fs->e2fs_ncg =
howmany(fs->e2fs.e2fs_bcount - fs->e2fs.e2fs_first_dblock,
fs->e2fs.e2fs_bpg);
--- 391,402 ----
return (EIO); /* XXX needs translation */
}
fs = VFSTOUFS(mountp)->um_e2fs;
/*
* copy in new superblock, and compute in-memory values
*/
e2fs_sbload(newfs, &fs->e2fs);
+
fs->e2fs_ncg =
howmany(fs->e2fs.e2fs_bcount - fs->e2fs.e2fs_first_dblock,
fs->e2fs.e2fs_bpg);
***************
*** 403,409 ****
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_itpg = fs->e2fs.e2fs_ipg/fs->e2fs_ipb;
/*
--- 408,432 ----
fs->e2fs_bmask = ~fs->e2fs_qbmask;
fs->e2fs_ngdb = howmany(fs->e2fs_ncg,
fs->e2fs_bsize / sizeof(struct ext2_gd));
! if (fs->e2fs.e2fs_rev == E2FS_OLD_REV) {
! fs->e2fs_isize = EXT2_DINODE_SIZE;
! fs->e2fs_firstino = EXT2_FIRSTINO;
! } else {
! fs->e2fs_isize = fs->e2fs.e2fs_inode_size;
! fs->e2fs_firstino = fs->e2fs.e2fs_first_ino;
! }
! /*
! * Check the inode size.
! */
! if (fs->e2fs_isize != EXT2_DINODE_SIZE) {
! #ifdef DIAGNOSTIC
! printf("Ext2 fs: unsupported inode size: %d (expected %d)\n",
! fs->e2fs_isize, EXT2_DINODE_SIZE);
! #endif
! brelse(bp);
! return (EIO); /* XXX needs translation */
! }
! fs->e2fs_ipb = fs->e2fs_bsize / fs->e2fs_isize;
fs->e2fs_itpg = fs->e2fs.e2fs_ipg/fs->e2fs_ipb;
/*
***************
*** 457,463 ****
return (error);
}
cp = (caddr_t)bp->b_data +
! (ino_to_fsbo(fs, ip->i_number) * EXT2_DINODE_SIZE);
e2fs_iload((struct ext2fs_dinode *)cp, &ip->i_din.e2fs_din);
brelse(bp);
vput(vp);
--- 480,486 ----
return (error);
}
cp = (caddr_t)bp->b_data +
! (ino_to_fsbo(fs, ip->i_number) * fs->e2fs_isize);
e2fs_iload((struct ext2fs_dinode *)cp, &ip->i_din.e2fs_din);
brelse(bp);
vput(vp);
***************
*** 514,531 ****
ump = NULL;
#ifdef DEBUG_EXT2
! printf("sb size: %d ino size %d\n", sizeof(struct ext2fs),
! EXT2_DINODE_SIZE);
#endif
error = bread(devvp, (SBOFF / DEV_BSIZE), SBSIZE, cred, &bp);
if (error)
goto out;
fs = (struct ext2fs *)bp->b_data;
if (fs2h16(fs->e2fs_magic) != E2FS_MAGIC) {
error = EINVAL; /* XXX needs translation */
goto out;
}
! if (fs2h32(fs->e2fs_rev) != E2FS_REV) {
#ifdef DIAGNOSTIC
printf("Ext2 fs: unsupported revision number: %x (expected %x)\n",
fs2h32(fs->e2fs_rev), E2FS_REV);
--- 537,562 ----
ump = NULL;
#ifdef DEBUG_EXT2
! printf("sb size: %d\n", sizeof(struct ext2fs));
#endif
error = bread(devvp, (SBOFF / DEV_BSIZE), SBSIZE, cred, &bp);
if (error)
goto out;
fs = (struct ext2fs *)bp->b_data;
if (fs2h16(fs->e2fs_magic) != E2FS_MAGIC) {
+ #ifdef DEBUG_EXT2
+ printf("bad magic: %x (expected %x)\n",
+ fs2h16(fs->e2fs_magic), E2FS_MAGIC);
+ #endif
error = EINVAL; /* XXX needs translation */
goto out;
}
!
! #ifdef DEBUG_EXT2
! printf("rev: %x\n", fs2h32(fs->e2fs_rev));
! #endif
!
! if (fs2h32(fs->e2fs_rev) > E2FS_REV) {
#ifdef DIAGNOSTIC
printf("Ext2 fs: unsupported revision number: %x (expected %x)\n",
fs2h32(fs->e2fs_rev), E2FS_REV);
***************
*** 571,577 ****
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_itpg = m_fs->e2fs.e2fs_ipg/m_fs->e2fs_ipb;
m_fs->e2fs_gd = malloc(m_fs->e2fs_ngdb * m_fs->e2fs_bsize,
--- 602,632 ----
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));
! if (m_fs->e2fs.e2fs_rev == E2FS_OLD_REV) {
! m_fs->e2fs_isize = EXT2_DINODE_SIZE;
! m_fs->e2fs_firstino = EXT2_FIRSTINO;
! } else {
! m_fs->e2fs_isize = m_fs->e2fs.e2fs_inode_size;
! m_fs->e2fs_firstino = m_fs->e2fs.e2fs_first_ino;
! }
! /*
! * Check the inode size.
! */
! if (m_fs->e2fs_isize != EXT2_DINODE_SIZE) {
! #ifdef DIAGNOSTIC
! printf("Ext2 fs: unsupported inode size: %d (expected %d)\n",
! m_fs->e2fs_isize, EXT2_DINODE_SIZE);
! #endif
! error = EINVAL; /* XXX needs translation */
! goto out;
! }
!
! #ifdef DEBUG_EXT2
! printf("inode size: %d, first inode: %d\n",
! m_fs->e2fs_isize, m_fs->e2fs_firstino);
! #endif
!
! m_fs->e2fs_ipb = m_fs->e2fs_bsize / m_fs->e2fs_isize;
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,
***************
*** 877,883 ****
return (error);
}
cp = (caddr_t)bp->b_data +
! (ino_to_fsbo(fs, ino) * EXT2_DINODE_SIZE);
e2fs_iload((struct ext2fs_dinode *)cp, &ip->i_din.e2fs_din);
brelse(bp);
--- 932,938 ----
return (error);
}
cp = (caddr_t)bp->b_data +
! (ino_to_fsbo(fs, ino) * fs->e2fs_isize);
e2fs_iload((struct ext2fs_dinode *)cp, &ip->i_din.e2fs_din);
brelse(bp);
***************
*** 940,946 ****
ufhp = (struct ufid *)fhp;
fs = VFSTOUFS(mp)->um_e2fs;
! if ((ufhp->ufid_ino < EXT2_FIRSTINO && ufhp->ufid_ino != EXT2_ROOTINO) ||
ufhp->ufid_ino >= fs->e2fs_ncg * fs->e2fs.e2fs_ipg)
return (ESTALE);
--- 995,1002 ----
ufhp = (struct ufid *)fhp;
fs = VFSTOUFS(mp)->um_e2fs;
! if ((ufhp->ufid_ino < fs->e2fs_firstino &&
! ufhp->ufid_ino != EXT2_ROOTINO) ||
ufhp->ufid_ino >= fs->e2fs_ncg * fs->e2fs.e2fs_ipg)
return (ESTALE);
>Audit-Trail:
>Unformatted: