]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
Bump version for 32-bit awareness.
authorEric Sandeen <sandeen@sgi.com>
Fri, 31 Aug 2001 20:08:21 +0000 (20:08 +0000)
committerEric Sandeen <sandeen@sgi.com>
Fri, 31 Aug 2001 20:08:21 +0000 (20:08 +0000)
VERSION
doc/CHANGES
growfs/xfs_growfs.c
man/man8/mkfs.xfs.8
man/man8/xfs_growfs.8
mkfs/xfs_mkfs.c
mkfs/xfs_mkfs.h

diff --git a/VERSION b/VERSION
index 2bb55de7060c3c73cb820f04c18d4c5813001f13..4de6827344c81c8d89403e4efa6de84b22a68720 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -3,5 +3,5 @@
 #
 PKG_MAJOR=1
 PKG_MINOR=3
-PKG_REVISION=5
+PKG_REVISION=6
 PKG_BUILD=0
index b9fce592680538e5fa14e333f5dc3a33761ea605..28ac50cc328f1004ecc3f5eb616e885fbefd4f15 100644 (file)
@@ -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 <tanglb@sina.com> for fixing this)
        - fix mkfs.xfs core dump when attemping to run on devices
index 25341cdab207cbfab57d88b31523d7b63bf99649..138f03c334bae0e6e74e917a1e5e509842e3f122 100644 (file)
 #include <mntent.h>
 #include <sys/ioctl.h>
 
+/*
+ * 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);
+                       }
                }
        }
 
index aff3cc4552b1d7c31ee8e213bf5e91a39686cbe1..c2f27e0f3dc65078e5f4e9aaa45585f23cde081d 100644 (file)
@@ -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%.
index 5a2496c551c42a271e31852cc16c4218cc1f87be..bf624b25a97ca2cf482c8557f7a72fc7e66c0b3d 100644 (file)
@@ -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),
index 45e159c146ee2f072ca48acccd08a31dc466e0f1..c6a287b886749d84ba616d0657f27349d910f0d5 100644 (file)
@@ -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,
index 6dcd004d097996b6b5ce4c479d46f64f5c904046..5d0babe6a5169713b06eea549e9efda8de6e14f3 100644 (file)
 #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);