From owner-svn-src-all@FreeBSD.ORG Wed Feb 10 20:10:35 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 7E6F21065676; Wed, 10 Feb 2010 20:10:35 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 6BEF88FC08; Wed, 10 Feb 2010 20:10:35 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o1AKAZ1s095808; Wed, 10 Feb 2010 20:10:35 GMT (envelope-from mckusick@svn.freebsd.org) Received: (from mckusick@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o1AKAZP5095805; Wed, 10 Feb 2010 20:10:35 GMT (envelope-from mckusick@svn.freebsd.org) Message-Id: <201002102010.o1AKAZP5095805@svn.freebsd.org> From: Kirk McKusick Date: Wed, 10 Feb 2010 20:10:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r203763 - head/sys/ufs/ffs X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 10 Feb 2010 20:10:35 -0000 Author: mckusick Date: Wed Feb 10 20:10:35 2010 New Revision: 203763 URL: http://svn.freebsd.org/changeset/base/203763 Log: This fix corrects a problem in the file system that treats large inode numbers as negative rather than unsigned. For a default (16K block) file system, this bug began to show up at a file system size above about 16Tb. To fully handle this problem, newfs must be updated to ensure that it will never create a filesystem with more than 2^32 inodes. That patch will be forthcoming soon. Reported by: Scott Burns, John Kilburg, Bruce Evans Followup by: Jeff Roberson PR: 133980 MFC after: 2 weeks Modified: head/sys/ufs/ffs/ffs_alloc.c head/sys/ufs/ffs/fs.h Modified: head/sys/ufs/ffs/ffs_alloc.c ============================================================================== --- head/sys/ufs/ffs/ffs_alloc.c Wed Feb 10 19:03:48 2010 (r203762) +++ head/sys/ufs/ffs/ffs_alloc.c Wed Feb 10 20:10:35 2010 (r203763) @@ -93,24 +93,25 @@ __FBSDID("$FreeBSD$"); #include #include -typedef ufs2_daddr_t allocfcn_t(struct inode *ip, int cg, ufs2_daddr_t bpref, +typedef ufs2_daddr_t allocfcn_t(struct inode *ip, u_int cg, ufs2_daddr_t bpref, int size); -static ufs2_daddr_t ffs_alloccg(struct inode *, int, ufs2_daddr_t, int); +static ufs2_daddr_t ffs_alloccg(struct inode *, u_int, ufs2_daddr_t, int); static ufs2_daddr_t ffs_alloccgblk(struct inode *, struct buf *, ufs2_daddr_t); #ifdef INVARIANTS static int ffs_checkblk(struct inode *, ufs2_daddr_t, long); #endif -static ufs2_daddr_t ffs_clusteralloc(struct inode *, int, ufs2_daddr_t, int); +static ufs2_daddr_t ffs_clusteralloc(struct inode *, u_int, ufs2_daddr_t, int); static void ffs_clusteracct(struct ufsmount *, struct fs *, struct cg *, ufs1_daddr_t, int); static ino_t ffs_dirpref(struct inode *); -static ufs2_daddr_t ffs_fragextend(struct inode *, int, ufs2_daddr_t, int, int); +static ufs2_daddr_t ffs_fragextend(struct inode *, u_int, ufs2_daddr_t, + int, int); static void ffs_fserr(struct fs *, ino_t, char *); static ufs2_daddr_t ffs_hashalloc - (struct inode *, int, ufs2_daddr_t, int, allocfcn_t *); -static ufs2_daddr_t ffs_nodealloccg(struct inode *, int, ufs2_daddr_t, int); + (struct inode *, u_int, ufs2_daddr_t, int, allocfcn_t *); +static ufs2_daddr_t ffs_nodealloccg(struct inode *, u_int, ufs2_daddr_t, int); static ufs1_daddr_t ffs_mapsearch(struct fs *, struct cg *, ufs2_daddr_t, int); static int ffs_reallocblks_ufs1(struct vop_reallocblks_args *); static int ffs_reallocblks_ufs2(struct vop_reallocblks_args *); @@ -145,7 +146,7 @@ ffs_alloc(ip, lbn, bpref, size, flags, c struct fs *fs; struct ufsmount *ump; ufs2_daddr_t bno; - int cg, reclaimed; + u_int cg, reclaimed; static struct timeval lastfail; static int curfail; int64_t delta; @@ -248,7 +249,8 @@ ffs_realloccg(ip, lbprev, bprev, bpref, struct fs *fs; struct buf *bp; struct ufsmount *ump; - int cg, request, error, reclaimed; + u_int cg, request, reclaimed; + int error; ufs2_daddr_t bno; static struct timeval lastfail; static int curfail; @@ -933,7 +935,8 @@ ffs_valloc(pvp, mode, cred, vpp) struct timespec ts; struct ufsmount *ump; ino_t ino, ipref; - int cg, error, error1; + u_int cg; + int error, error1; static struct timeval lastfail; static int curfail; @@ -1043,11 +1046,11 @@ ffs_dirpref(pip) struct inode *pip; { struct fs *fs; - int cg, prefcg, dirsize, cgsize; - int avgifree, avgbfree, avgndir, curdirsize; - int minifree, minbfree, maxndir; - int mincg, minndir; - int maxcontigdirs; + u_int cg, prefcg, dirsize, cgsize; + u_int avgifree, avgbfree, avgndir, curdirsize; + u_int minifree, minbfree, maxndir; + u_int mincg, minndir; + u_int maxcontigdirs; mtx_assert(UFS_MTX(pip->i_ump), MA_OWNED); fs = pip->i_fs; @@ -1171,8 +1174,8 @@ ffs_blkpref_ufs1(ip, lbn, indx, bap) ufs1_daddr_t *bap; { struct fs *fs; - int cg; - int avgbfree, startcg; + u_int cg; + u_int avgbfree, startcg; mtx_assert(UFS_MTX(ip->i_ump), MA_OWNED); fs = ip->i_fs; @@ -1221,8 +1224,8 @@ ffs_blkpref_ufs2(ip, lbn, indx, bap) ufs2_daddr_t *bap; { struct fs *fs; - int cg; - int avgbfree, startcg; + u_int cg; + u_int avgbfree, startcg; mtx_assert(UFS_MTX(ip->i_ump), MA_OWNED); fs = ip->i_fs; @@ -1275,14 +1278,14 @@ ffs_blkpref_ufs2(ip, lbn, indx, bap) static ufs2_daddr_t ffs_hashalloc(ip, cg, pref, size, allocator) struct inode *ip; - int cg; + u_int cg; ufs2_daddr_t pref; int size; /* size for data blocks, mode for inodes */ allocfcn_t *allocator; { struct fs *fs; ufs2_daddr_t result; - int i, icg = cg; + u_int i, icg = cg; mtx_assert(UFS_MTX(ip->i_ump), MA_OWNED); #ifdef INVARIANTS @@ -1333,7 +1336,7 @@ ffs_hashalloc(ip, cg, pref, size, alloca static ufs2_daddr_t ffs_fragextend(ip, cg, bprev, osize, nsize) struct inode *ip; - int cg; + u_int cg; ufs2_daddr_t bprev; int osize, nsize; { @@ -1416,7 +1419,7 @@ fail: static ufs2_daddr_t ffs_alloccg(ip, cg, bpref, size) struct inode *ip; - int cg; + u_int cg; ufs2_daddr_t bpref; int size; { @@ -1586,7 +1589,7 @@ gotit: static ufs2_daddr_t ffs_clusteralloc(ip, cg, bpref, len) struct inode *ip; - int cg; + u_int cg; ufs2_daddr_t bpref; int len; { @@ -1710,7 +1713,7 @@ fail: static ufs2_daddr_t ffs_nodealloccg(ip, cg, ipref, mode) struct inode *ip; - int cg; + u_int cg; ufs2_daddr_t ipref; int mode; { @@ -1811,7 +1814,7 @@ gotit: bdwrite(bp); if (ibp != NULL) bawrite(ibp); - return (cg * fs->fs_ipg + ipref); + return ((ino_t)(cg * fs->fs_ipg + ipref)); } /* @@ -1856,7 +1859,8 @@ ffs_blkfree(ump, fs, devvp, bno, size, i struct buf *bp; ufs1_daddr_t fragno, cgbno; ufs2_daddr_t cgblkno; - int i, cg, blk, frags, bbase; + int i, blk, frags, bbase; + u_int cg; u_int8_t *blksfree; struct cdev *dev; @@ -2054,7 +2058,8 @@ ffs_freefile(ump, fs, devvp, ino, mode) struct cg *cgp; struct buf *bp; ufs2_daddr_t cgbno; - int error, cg; + int error; + u_int cg; u_int8_t *inosused; struct cdev *dev; @@ -2068,7 +2073,7 @@ ffs_freefile(ump, fs, devvp, ino, mode) dev = devvp->v_rdev; cgbno = fsbtodb(fs, cgtod(fs, cg)); } - if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg) + if (ino >= fs->fs_ipg * fs->fs_ncg) panic("ffs_freefile: range: dev = %s, ino = %lu, fs = %s", devtoname(dev), (u_long)ino, fs->fs_fsmnt); if ((error = bread(devvp, cgbno, (int)fs->fs_cgsize, NOCRED, &bp))) { @@ -2085,8 +2090,8 @@ ffs_freefile(ump, fs, devvp, ino, mode) inosused = cg_inosused(cgp); ino %= fs->fs_ipg; if (isclr(inosused, ino)) { - printf("dev = %s, ino = %lu, fs = %s\n", devtoname(dev), - (u_long)ino + cg * fs->fs_ipg, fs->fs_fsmnt); + printf("dev = %s, ino = %u, fs = %s\n", devtoname(dev), + ino + cg * fs->fs_ipg, fs->fs_fsmnt); if (fs->fs_ronly == 0) panic("ffs_freefile: freeing free inode"); } @@ -2121,7 +2126,8 @@ ffs_checkfreefile(fs, devvp, ino) struct cg *cgp; struct buf *bp; ufs2_daddr_t cgbno; - int ret, cg; + int ret; + u_int cg; u_int8_t *inosused; cg = ino_to_cg(fs, ino); @@ -2132,7 +2138,7 @@ ffs_checkfreefile(fs, devvp, ino) /* devvp is a normal disk device */ cgbno = fsbtodb(fs, cgtod(fs, cg)); } - if ((u_int)ino >= fs->fs_ipg * fs->fs_ncg) + if (ino >= fs->fs_ipg * fs->fs_ncg) return (1); if (bread(devvp, cgbno, (int)fs->fs_cgsize, NOCRED, &bp)) { brelse(bp); Modified: head/sys/ufs/ffs/fs.h ============================================================================== --- head/sys/ufs/ffs/fs.h Wed Feb 10 19:03:48 2010 (r203762) +++ head/sys/ufs/ffs/fs.h Wed Feb 10 20:10:35 2010 (r203763) @@ -264,7 +264,7 @@ struct fs { int32_t fs_old_time; /* last time written */ int32_t fs_old_size; /* number of blocks in fs */ int32_t fs_old_dsize; /* number of data blocks in fs */ - int32_t fs_ncg; /* number of cylinder groups */ + u_int32_t fs_ncg; /* number of cylinder groups */ int32_t fs_bsize; /* size of basic blocks in fs */ int32_t fs_fsize; /* size of frag blocks in fs */ int32_t fs_frag; /* number of frags in a block in fs */ @@ -304,7 +304,7 @@ struct fs { int32_t fs_old_spc; /* sectors per cylinder */ int32_t fs_old_ncyl; /* cylinders in filesystem */ int32_t fs_old_cpg; /* cylinders per group */ - int32_t fs_ipg; /* inodes per group */ + u_int32_t fs_ipg; /* inodes per group */ int32_t fs_fpg; /* blocks per group * fs_frag */ /* this data must be re-computed after crashes */ struct csum fs_old_cstotal; /* cylinder summary information */ @@ -335,10 +335,10 @@ struct fs { int64_t fs_dsize; /* number of data blocks in fs */ ufs2_daddr_t fs_csaddr; /* blk addr of cyl grp summary area */ int64_t fs_pendingblocks; /* (u) blocks being freed */ - int32_t fs_pendinginodes; /* (u) inodes being freed */ - int32_t fs_snapinum[FSMAXSNAP];/* list of snapshot inode numbers */ - int32_t fs_avgfilesize; /* expected average file size */ - int32_t fs_avgfpdir; /* expected # of files per directory */ + u_int32_t fs_pendinginodes; /* (u) inodes being freed */ + ino_t fs_snapinum[FSMAXSNAP];/* list of snapshot inode numbers */ + u_int32_t fs_avgfilesize; /* expected average file size */ + u_int32_t fs_avgfpdir; /* expected # of files per directory */ int32_t fs_save_cgsize; /* save real cg size to use fs_bsize */ int32_t fs_sparecon32[26]; /* reserved for future constants */ int32_t fs_flags; /* see FS_ flags below */ @@ -463,26 +463,26 @@ struct cg { int32_t cg_firstfield; /* historic cyl groups linked list */ int32_t cg_magic; /* magic number */ int32_t cg_old_time; /* time last written */ - int32_t cg_cgx; /* we are the cgx'th cylinder group */ + u_int32_t cg_cgx; /* we are the cgx'th cylinder group */ int16_t cg_old_ncyl; /* number of cyl's this cg */ int16_t cg_old_niblk; /* number of inode blocks this cg */ - int32_t cg_ndblk; /* number of data blocks this cg */ - struct csum cg_cs; /* cylinder summary information */ - int32_t cg_rotor; /* position of last used block */ - int32_t cg_frotor; /* position of last used frag */ - int32_t cg_irotor; /* position of last used inode */ - int32_t cg_frsum[MAXFRAG]; /* counts of available frags */ + u_int32_t cg_ndblk; /* number of data blocks this cg */ + struct csum cg_cs; /* cylinder summary information */ + u_int32_t cg_rotor; /* position of last used block */ + u_int32_t cg_frotor; /* position of last used frag */ + u_int32_t cg_irotor; /* position of last used inode */ + u_int32_t cg_frsum[MAXFRAG]; /* counts of available frags */ int32_t cg_old_btotoff; /* (int32) block totals per cylinder */ int32_t cg_old_boff; /* (u_int16) free block positions */ - int32_t cg_iusedoff; /* (u_int8) used inode map */ - int32_t cg_freeoff; /* (u_int8) free block map */ - int32_t cg_nextfreeoff; /* (u_int8) next available space */ - int32_t cg_clustersumoff; /* (u_int32) counts of avail clusters */ - int32_t cg_clusteroff; /* (u_int8) free cluster map */ - int32_t cg_nclusterblks; /* number of clusters this cg */ - int32_t cg_niblk; /* number of inode blocks this cg */ - int32_t cg_initediblk; /* last initialized inode */ - int32_t cg_unrefs; /* number of unreferenced inodes */ + u_int32_t cg_iusedoff; /* (u_int8) used inode map */ + u_int32_t cg_freeoff; /* (u_int8) free block map */ + u_int32_t cg_nextfreeoff; /* (u_int8) next available space */ + u_int32_t cg_clustersumoff; /* (u_int32) counts of avail clusters */ + u_int32_t cg_clusteroff; /* (u_int8) free cluster map */ + u_int32_t cg_nclusterblks; /* number of clusters this cg */ + u_int32_t cg_niblk; /* number of inode blocks this cg */ + u_int32_t cg_initediblk; /* last initialized inode */ + u_int32_t cg_unrefs; /* number of unreferenced inodes */ int32_t cg_sparecon32[2]; /* reserved for future use */ ufs_time_t cg_time; /* time last written */ int64_t cg_sparecon64[3]; /* reserved for future use */ @@ -529,11 +529,11 @@ struct cg { * inode number to cylinder group number. * inode number to filesystem block address. */ -#define ino_to_cg(fs, x) ((x) / (fs)->fs_ipg) +#define ino_to_cg(fs, x) (((ino_t)(x)) / (fs)->fs_ipg) #define ino_to_fsba(fs, x) \ - ((ufs2_daddr_t)(cgimin(fs, ino_to_cg(fs, x)) + \ - (blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs)))))) -#define ino_to_fsbo(fs, x) ((x) % INOPB(fs)) + ((ufs2_daddr_t)(cgimin(fs, ino_to_cg(fs, (ino_t)(x))) + \ + (blkstofrags((fs), ((((ino_t)(x)) % (fs)->fs_ipg) / INOPB(fs)))))) +#define ino_to_fsbo(fs, x) (((ino_t)(x)) % INOPB(fs)) /* * Give cylinder group number for a filesystem block.