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;