From: Eric Sandeen Date: Fri, 31 Aug 2001 20:08:21 +0000 (+0000) Subject: Bump version for 32-bit awareness. X-Git-Tag: v2.0.0~57 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8e4b2fda03d71336646218976d9e14b3af91d663;p=thirdparty%2Fxfsprogs-dev.git Bump version for 32-bit awareness. --- diff --git a/VERSION b/VERSION index 2bb55de70..4de682734 100644 --- a/VERSION +++ b/VERSION @@ -3,5 +3,5 @@ # PKG_MAJOR=1 PKG_MINOR=3 -PKG_REVISION=5 +PKG_REVISION=6 PKG_BUILD=0 diff --git a/doc/CHANGES b/doc/CHANGES index b9fce5926..28ac50cc3 100644 --- a/doc/CHANGES +++ b/doc/CHANGES @@ -1,4 +1,8 @@ -xfsprogs-current +xfsprogs-1.3.6 (31 August 2001) + - make mkfs.xfs aware of geometries that might cause + inode numbers to exceed 32 significant bits. + - make xfs_growfs warn if new filesystem will have + inode numbers that exceed 32 significant bits. - fix logprint bug in reporting extended attributes (thanks to Tang Lingbo for fixing this) - fix mkfs.xfs core dump when attemping to run on devices diff --git a/growfs/xfs_growfs.c b/growfs/xfs_growfs.c index 25341cdab..138f03c33 100644 --- a/growfs/xfs_growfs.c +++ b/growfs/xfs_growfs.c @@ -34,6 +34,14 @@ #include #include +/* + * When growing a filesystem, this is the most significant + * bits we'll accept in the resulting inode numbers + * without warning the user. + */ + +#define XFS_MAX_INODE_SIG_BITS 32 + static char *fname; /* mount point name */ static char *datadev; /* data device name */ static char *logdev; /* log device name */ @@ -49,6 +57,7 @@ Options:\n\ -l grow log section\n\ -r grow realtime section\n\ -n don't change anything, just show geometry\n\ + -I allow inode numbers to exceed %d significant bits\n\ -i convert log from external to internal format\n\ -t alternate location for mount table (/etc/mtab)\n\ -x convert log from internal to external format\n\ @@ -58,7 +67,7 @@ Options:\n\ -e size set realtime extent size to size blks\n\ -m imaxpct set inode max percent to imaxpct\n\ -V print version information\n", - progname); + progname, XFS_MAX_INODE_SIG_BITS); exit(2); } @@ -70,15 +79,24 @@ report_info( int dirversion, int isint) { + + int inodebits; + + inodebits = (libxfs_highbit32(geo.blocksize/geo.inodesize - 1) + 1) + + (libxfs_highbit64(geo.agblocks - 1) + 1) + + (libxfs_highbit64(geo.agcount - 1) + 1); + printf("meta-data=%-22s isize=%-6d agcount=%d, agsize=%d blks\n" "data =%-22s bsize=%-6d blocks=%lld, imaxpct=%d\n" " =%-22s sunit=%-6d swidth=%d blks, unwritten=%d\n" + " =%-22s imaxbits=%-6d\n" "naming =version %-14d bsize=%-6d\n" "log =%-22s bsize=%-6d blocks=%d\n" "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n", mntpoint, geo.inodesize, geo.agcount, geo.agblocks, "", geo.blocksize, (long long)geo.datablocks, geo.imaxpct, "", geo.sunit, geo.swidth, unwritten, + "", inodebits, dirversion, geo.dirblocksize, isint ? "internal" : "external", geo.blocksize, geo.logblocks, geo.rtblocks ? "external" : "none", @@ -168,6 +186,7 @@ main(int argc, char **argv) long esize; /* new rt extent size */ int ffd; /* mount point file descriptor */ xfs_fsop_geom_t geo; /* current fs geometry */ + int Iflag; /* force flag for big inode numbers */ int iflag; /* -i flag */ int isint; /* log is currently internal */ int lflag; /* -l flag */ @@ -185,10 +204,10 @@ main(int argc, char **argv) mtab = MOUNTED; progname = basename(argv[0]); - aflag = dflag = iflag = lflag = mflag = nflag = rflag = xflag = 0; + aflag = dflag = Iflag = iflag = lflag = mflag = nflag = rflag = xflag = 0; maxpct = esize = 0; dsize = lsize = rsize = 0LL; - while ((c = getopt(argc, argv, "dD:e:ilL:m:np:rR:t:xV")) != EOF) { + while ((c = getopt(argc, argv, "dD:e:IilL:m:np:rR:t:xV")) != EOF) { switch (c) { case 'D': dsize = atoll(optarg); @@ -200,6 +219,9 @@ main(int argc, char **argv) esize = atol(optarg); rflag = 1; break; + case 'I': + Iflag = 1; + break; case 'i': lflag = iflag = 1; break; @@ -311,7 +333,9 @@ main(int argc, char **argv) error = 0; if (dflag | aflag) { xfs_growfs_data_t in; - + int inodebits; + __uint64_t new_agcount; + if (!mflag) maxpct = geo.imaxpct; if (!dsize) @@ -323,6 +347,14 @@ main(int argc, char **argv) (long long)(ddsize/(geo.blocksize/BBSIZE))); error = 1; } + + new_agcount = dsize / geo.agblocks + + (dsize % geo.agblocks != 0); + + inodebits = (libxfs_highbit32(geo.blocksize/geo.inodesize - 1) + 1) + + (libxfs_highbit64(geo.agblocks - 1) + 1) + + (libxfs_highbit64(new_agcount - 1) + 1); + if (!error && dsize < geo.datablocks) { fprintf(stderr, "data size %lld too small," " old size is %lld\n", @@ -336,6 +368,14 @@ main(int argc, char **argv) if (mflag) fprintf(stderr, "inode max pct unchanged, skipping\n"); + } else if (!error && !Iflag + && inodebits > XFS_MAX_INODE_SIG_BITS) { + fprintf(stderr, + "warning: inode numbers would exceed %d " + "significant bits (%d)\n" + " Use -I option to allow this\n", + XFS_MAX_INODE_SIG_BITS, inodebits); + error = 1; } else if (!error && !nflag) { in.newblocks = (__u64)dsize; in.imaxpct = (__u32)maxpct; @@ -350,6 +390,12 @@ main(int argc, char **argv) progname, strerror(errno)); error = 1; } + if (inodebits > XFS_MAX_INODE_SIG_BITS) { + fprintf(stderr, + "inode numbers exceed %d " + "significant bits (%d)\n", + XFS_MAX_INODE_SIG_BITS, inodebits); + } } } diff --git a/man/man8/mkfs.xfs.8 b/man/man8/mkfs.xfs.8 index aff3cc455..c2f27e0f3 100644 --- a/man/man8/mkfs.xfs.8 +++ b/man/man8/mkfs.xfs.8 @@ -264,6 +264,21 @@ The mininum (and default) value is 256 bytes. The maximum value is 2048 (2 KB) subject to the restriction that the inode size cannot exceed one half of the filesystem block size. .IP +XFS uses 64-bit inode numbers internally; however, the number of +significant bits in an inode number +is affected by filesystem geometry. In +practice, filesystem size and inode size are the predominant factors. +The Linux kernel and most applications cannot currently handle +inode numbers greater than 32 significant bits, so if no +inode size is given on the command line, +.I mkfs.xfs +will attempt to choose a size +such that inode numbers will be < 32 bits. If an inode size +is specified, or if a filesystem is sufficently large, +.I mkfs.xfs +will warn if this will create inode numbers > 32 significant +bits. +.IP The option \f3maxpct=\f1\f2value\f1 specifies the maximum percentage of space in the filesystem that can be allocated to inodes. The default value is 25%. diff --git a/man/man8/xfs_growfs.8 b/man/man8/xfs_growfs.8 index 5a2496c55..bf624b25a 100644 --- a/man/man8/xfs_growfs.8 +++ b/man/man8/xfs_growfs.8 @@ -3,7 +3,7 @@ xfs_growfs, xfs_info \- expand an XFS filesystem .SH SYNOPSIS .nf -\f3xfs_growfs\f1 [ \f3\-dilnrxV\f1 ] [ \f3\-D\f1 size ] [ \f3\-e\f1 rtextsize ] +\f3xfs_growfs\f1 [ \f3\-dIilnrxV\f1 ] [ \f3\-D\f1 size ] [ \f3\-e\f1 rtextsize ] [ \f3\-L\f1 size ] [ \f3\-m\f1 maxpct ] [ \f3-t\f1 mtab ] [ \f3\-R\f1 size ] mount-point \f3xfs_info\f1 [ \f3-t\f1 mtab ] mount-point @@ -51,6 +51,10 @@ this is specified with .B \-r .BI extsize= nnnn. .TP +.B \-I +Allow new inode numbers to exceed 32 significant bits. +(See CONSIDERATIONS below.) +.TP .B \-i The new log is an internal log (inside the data section). @@ -129,6 +133,29 @@ Therefore there must be at least one spare new disk partition available. Adding the space is done through the mechanism of logical volumes. +.SH CONSIDERATIONS +XFS uses 64-bit inode numbers internally; however, the number of +significant bits in an inode number is +affected by filesystem geometry. In +practice, filesystem size and inode size are the predominant factors. +The Linux kernel and most applications cannot currently handle +inode numbers greater than 32 significant bits, so +.I xfs_growfs +will issue a warning and fail if growing the filesystem will +cause the significant bits in inode numbers to exceed 32 bits. +This can be overwritten with the +.B \-I +option. +.PP +If you anticipate significantly growing filesystems after using +.I mkfs.xfs +you should take into consideration this inode number growth +as well, +and keep the number of significant digits sufficiently small +to allow for future growth. On average, doubling the size +of the inode will reduce significant bits by one, and doubling +the size of the filesystem will increase significant bits +by one. .SH SEE ALSO mkfs.xfs(8), lvm(8), diff --git a/mkfs/xfs_mkfs.c b/mkfs/xfs_mkfs.c index 45e159c14..c6a287b88 100644 --- a/mkfs/xfs_mkfs.c +++ b/mkfs/xfs_mkfs.c @@ -379,6 +379,7 @@ main(int argc, char **argv) int imaxpct; int imflag; int inodelog; + int inodebits; int inopblock; int ipflag; int isflag; @@ -1515,6 +1516,64 @@ main(int argc, char **argv) } } + /* + * Check to see if inode number will be > 32 significant bits + * Note that libxfs_highbitXX returns 0 -> XX-1, + * so to get the bit count, add one to what we get. + */ + + inodebits = (libxfs_highbit32(blocksize/isize - 1) + 1) + + (libxfs_highbit64(agsize - 1) + 1) + + (libxfs_highbit64(agcount - 1) + 1); + + if (inodebits > XFS_MAX_INODE_SIG_BITS) { + + int new_isize; + int new_isize_ok; + + new_isize = isize << (inodebits - XFS_MAX_INODE_SIG_BITS); + + new_isize_ok = (new_isize <= blocksize / XFS_MIN_INODE_PERBLOCK + && new_isize <= XFS_DINODE_MAX_SIZE); + + if (ilflag + ipflag + isflag == 0) { + /* + * If we didn't specify inode size, just bump it up + * unless we can't go far enough. + */ + + if (new_isize_ok) { + isize = new_isize; + /* re-calc inodebits */ + inodebits = (libxfs_highbit32(blocksize/isize - 1) + 1) + + (libxfs_highbit64(agsize - 1) + 1) + + (libxfs_highbit64(agcount - 1) + 1); + /* Let's not get too chatty, no fprintf here */ + } else { + /* + * Can't do nothin' for ya, man! + * Don't bother changing isize at all, + * one bit over is as bad as 20. + */ + fprintf(stderr, + "warning: inode numbers exceed %d " + " significant bits (%d)\n", + XFS_MAX_INODE_SIG_BITS, inodebits); + } + } else { + /* if isize specified, just warn the user */ + fprintf(stderr, + "warning: inode numbers exceed %d " + "significant bits (%d)\n", + XFS_MAX_INODE_SIG_BITS, inodebits); + if (new_isize_ok) { + fprintf(stderr, + " increase inode size to %d to " + "avoid this\n", new_isize); + } + } + } + protostring = setup_proto(protofile); bsize = 1 << (blocklog - BBSHIFT); buf = libxfs_getbuf(xi.ddev, XFS_SB_DADDR, 1); @@ -1641,12 +1700,14 @@ main(int argc, char **argv) "meta-data=%-22s isize=%-6d agcount=%lld, agsize=%lld blks\n" "data =%-22s bsize=%-6d blocks=%lld, imaxpct=%d\n" " =%-22s sunit=%-6d swidth=%d blks, unwritten=%d\n" + " =%-22s imaxbits=%-6d\n" "naming =version %-14d bsize=%-6d\n" "log =%-22s bsize=%-6d blocks=%lld\n" "realtime =%-22s extsz=%-6d blocks=%lld, rtextents=%lld\n", dfile, isize, (long long)agcount, (long long)agsize, "", blocksize, (long long)dblocks, sbp->sb_imax_pct, "", dsunit, dswidth, extent_flagging, + "", inodebits, dirversion, dirversion == 1 ? blocksize : dirblocksize, logfile, 1 << blocklog, (long long)logblocks, rtfile, rtextblocks << blocklog, diff --git a/mkfs/xfs_mkfs.h b/mkfs/xfs_mkfs.h index 6dcd004d0..5d0babe6a 100644 --- a/mkfs/xfs_mkfs.h +++ b/mkfs/xfs_mkfs.h @@ -44,6 +44,10 @@ #define XFS_MIN_LOG_FACTOR 3 /* min log size factor */ #define XFS_DFL_LOG_FACTOR 16 /* default log size, factor */ /* with max trans reservation */ +#define XFS_MAX_INODE_SIG_BITS 32 /* most significant bits in an + * inode number that we'll + * accept w/o warnings + */ extern void usage (void); extern long long cvtnum (int blocksize, char *s);