Module Name: src
Committed By: jakllsch
Date: Sun Nov 25 19:42:14 UTC 2012
Modified Files:
src/sbin/fsck_ext2fs: dir.c extern.h inode.c pass1.c
Log Message:
Catch up to the kernel with respect to Ext2 huge_file feature.
To generate a diff of this commit:
cvs rdiff -u -r1.24 -r1.25 src/sbin/fsck_ext2fs/dir.c
cvs rdiff -u -r1.7 -r1.8 src/sbin/fsck_ext2fs/extern.h
cvs rdiff -u -r1.31 -r1.32 src/sbin/fsck_ext2fs/inode.c
cvs rdiff -u -r1.21 -r1.22 src/sbin/fsck_ext2fs/pass1.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sbin/fsck_ext2fs/dir.c
diff -u src/sbin/fsck_ext2fs/dir.c:1.24 src/sbin/fsck_ext2fs/dir.c:1.25
--- src/sbin/fsck_ext2fs/dir.c:1.24 Sun Nov 25 19:36:23 2012
+++ src/sbin/fsck_ext2fs/dir.c Sun Nov 25 19:42:14 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: dir.c,v 1.24 2012/11/25 19:36:23 jakllsch Exp $ */
+/* $NetBSD: dir.c,v 1.25 2012/11/25 19:42:14 jakllsch Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@@ -58,7 +58,7 @@
#if 0
static char sccsid[] = "@(#)dir.c 8.5 (Berkeley) 12/8/94";
#else
-__RCSID("$NetBSD: dir.c,v 1.24 2012/11/25 19:36:23 jakllsch Exp $");
+__RCSID("$NetBSD: dir.c,v 1.25 2012/11/25 19:42:14 jakllsch Exp $");
#endif
#endif /* not lint */
@@ -569,8 +569,7 @@ expanddir(struct ext2fs_dinode *dp, char
dp->e2di_blocks[lastbn + 1] = dp->e2di_blocks[lastbn];
dp->e2di_blocks[lastbn] = h2fs32(newblk);
inossize(dp, inosize(dp) + sblock.e2fs_bsize);
- dp->e2di_nblock = h2fs32(fs2h32(dp->e2di_nblock) +
- btodb(sblock.e2fs_bsize));
+ inosnblock(dp, inonblock(dp) + btodb(sblock.e2fs_bsize));
bp = getdirblk(fs2h32(dp->e2di_blocks[lastbn + 1]),
sblock.e2fs_bsize);
if (bp->b_errs)
@@ -604,8 +603,7 @@ bad:
dp->e2di_blocks[lastbn] = dp->e2di_blocks[lastbn + 1];
dp->e2di_blocks[lastbn + 1] = 0;
inossize(dp, inosize(dp) - sblock.e2fs_bsize);
- dp->e2di_nblock = h2fs32(fs2h32(dp->e2di_nblock) -
- btodb(sblock.e2fs_bsize));
+ inosnblock(dp, inonblock(dp) - btodb(sblock.e2fs_bsize));
freeblk(newblk);
return (0);
}
Index: src/sbin/fsck_ext2fs/extern.h
diff -u src/sbin/fsck_ext2fs/extern.h:1.7 src/sbin/fsck_ext2fs/extern.h:1.8
--- src/sbin/fsck_ext2fs/extern.h:1.7 Thu Jun 9 19:57:50 2011
+++ src/sbin/fsck_ext2fs/extern.h Sun Nov 25 19:42:14 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: extern.h,v 1.7 2011/06/09 19:57:50 christos Exp $ */
+/* $NetBSD: extern.h,v 1.8 2012/11/25 19:42:14 jakllsch Exp $ */
/*
* Copyright (c) 1997 Manuel Bouyer.
@@ -71,3 +71,5 @@ int reply(const char *);
void resetinodebuf(void);
int setup(const char *);
struct ext2fs_dinode * getnextinode(ino_t);
+uint64_t inonblock(struct ext2fs_dinode *);
+void inosnblock(struct ext2fs_dinode *, uint64_t);
Index: src/sbin/fsck_ext2fs/inode.c
diff -u src/sbin/fsck_ext2fs/inode.c:1.31 src/sbin/fsck_ext2fs/inode.c:1.32
--- src/sbin/fsck_ext2fs/inode.c:1.31 Thu Feb 4 23:55:42 2010
+++ src/sbin/fsck_ext2fs/inode.c Sun Nov 25 19:42:14 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: inode.c,v 1.31 2010/02/04 23:55:42 christos Exp $ */
+/* $NetBSD: inode.c,v 1.32 2012/11/25 19:42:14 jakllsch Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@@ -58,7 +58,7 @@
#if 0
static char sccsid[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95";
#else
-__RCSID("$NetBSD: inode.c,v 1.31 2010/02/04 23:55:42 christos Exp $");
+__RCSID("$NetBSD: inode.c,v 1.32 2012/11/25 19:42:14 jakllsch Exp $");
#endif
#endif /* not lint */
@@ -97,6 +97,8 @@ static int iblock(struct inodesc *, long
static int setlarge(void);
+static int sethuge(void);
+
static int
setlarge(void)
{
@@ -115,6 +117,24 @@ setlarge(void)
return 1;
}
+static int
+sethuge(void)
+{
+ if (sblock.e2fs.e2fs_rev < E2FS_REV1) {
+ pfatal("HUGE FILES UNSUPPORTED ON REVISION 0 FILESYSTEMS");
+ return 0;
+ }
+ if (!(sblock.e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_HUGE_FILE)) {
+ if (preen)
+ pwarn("SETTING HUGE FILE FEATURE\n");
+ else if (!reply("SET HUGE FILE FEATURE"))
+ return 0;
+ sblock.e2fs.e2fs_features_rocompat |= EXT2F_ROCOMPAT_HUGE_FILE;
+ sbdirty();
+ }
+ return 1;
+}
+
u_int64_t
inosize(struct ext2fs_dinode *dp)
{
@@ -707,7 +727,7 @@ allocino(ino_t request, int type)
dp->e2di_mtime = dp->e2di_ctime = dp->e2di_atime;
dp->e2di_dtime = 0;
inossize(dp, sblock.e2fs_bsize);
- dp->e2di_nblock = h2fs32(btodb(sblock.e2fs_bsize));
+ inosnblock(dp, btodb(sblock.e2fs_bsize));
n_files++;
inodirty();
typemap[ino] = E2IFTODT(type);
@@ -734,3 +754,59 @@ freeino(ino_t ino)
statemap[ino] = USTATE;
n_files--;
}
+
+uint64_t
+inonblock(struct ext2fs_dinode *dp)
+{
+ uint64_t nblock;
+
+ /* XXX check for EXT2_HUGE_FILE without EXT2F_ROCOMPAT_HUGE_FILE? */
+
+ nblock = fs2h32(dp->e2di_nblock);
+
+ if ((sblock.e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_HUGE_FILE)) {
+ nblock |= (uint64_t)fs2h16(dp->e2di_nblock_high) << 32;
+ if (fs2h32(dp->e2di_flags) & EXT2_HUGE_FILE) {
+ nblock = fsbtodb(&sblock, nblock);
+ }
+ }
+
+ return nblock;
+}
+
+void
+inosnblock(struct ext2fs_dinode *dp, uint64_t nblock)
+{
+ uint32_t flags;
+
+ flags = fs2h32(dp->e2di_flags);
+
+ if (nblock <= 0xffffffffULL) {
+ flags &= ~EXT2_HUGE_FILE;
+ dp->e2di_flags = h2fs32(flags);
+ dp->e2di_nblock = h2fs32(nblock);
+ return;
+ }
+
+ sethuge();
+
+ if (nblock <= 0xffffffffffffULL) {
+ flags &= ~EXT2_HUGE_FILE;
+ dp->e2di_flags = h2fs32(flags);
+ dp->e2di_nblock = h2fs32(nblock);
+ dp->e2di_nblock_high = h2fs16((nblock >> 32));
+ return;
+ }
+
+ if (dbtofsb(&sblock, nblock) <= 0xffffffffffffULL) {
+ flags |= EXT2_HUGE_FILE;
+ dp->e2di_flags = h2fs32(flags);
+ dp->e2di_nblock = h2fs32(dbtofsb(&sblock, nblock));
+ dp->e2di_nblock_high = h2fs16((dbtofsb(&sblock, nblock) >> 32));
+ return;
+ }
+
+ pfatal("trying to set nblocks higher than representable");
+
+ return;
+}
Index: src/sbin/fsck_ext2fs/pass1.c
diff -u src/sbin/fsck_ext2fs/pass1.c:1.21 src/sbin/fsck_ext2fs/pass1.c:1.22
--- src/sbin/fsck_ext2fs/pass1.c:1.21 Thu Feb 4 23:55:42 2010
+++ src/sbin/fsck_ext2fs/pass1.c Sun Nov 25 19:42:14 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: pass1.c,v 1.21 2010/02/04 23:55:42 christos Exp $ */
+/* $NetBSD: pass1.c,v 1.22 2012/11/25 19:42:14 jakllsch Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@@ -58,7 +58,7 @@
#if 0
static char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93";
#else
-__RCSID("$NetBSD: pass1.c,v 1.21 2010/02/04 23:55:42 christos Exp $");
+__RCSID("$NetBSD: pass1.c,v 1.22 2012/11/25 19:42:14 jakllsch Exp $");
#endif
#endif /* not lint */
@@ -302,16 +302,17 @@ checkinode(ino_t inumber, struct inodesc
idesc->id_number = inumber;
(void)ckinode(dp, idesc);
idesc->id_entryno *= btodb(sblock.e2fs_bsize);
- if (fs2h32(dp->e2di_nblock) != (uint32_t)idesc->id_entryno) {
- pwarn("INCORRECT BLOCK COUNT I=%llu (%d should be %d)",
- (unsigned long long)inumber, fs2h32(dp->e2di_nblock),
+ if (inonblock(dp) != (uint32_t)idesc->id_entryno) {
+ pwarn("INCORRECT BLOCK COUNT I=%llu (%llu should be %d)",
+ (unsigned long long)inumber,
+ (unsigned long long)inonblock(dp),
idesc->id_entryno);
if (preen)
printf(" (CORRECTED)\n");
else if (reply("CORRECT") == 0)
return;
dp = ginode(inumber);
- dp->e2di_nblock = h2fs32(idesc->id_entryno);
+ inosnblock(dp, idesc->id_entryno);
inodirty();
}
return;