Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Feb 2010 20:10:35 +0000 (UTC)
From:      Kirk McKusick <mckusick@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r203763 - head/sys/ufs/ffs
Message-ID:  <201002102010.o1AKAZP5095805@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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 <ufs/ffs/fs.h>
 #include <ufs/ffs/ffs_extern.h>
 
-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.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201002102010.o1AKAZP5095805>