BSD 4_4_Lite1 release
[unix-history] / usr / src / sys / ufs / ffs / fs.h
index 2ca006c..bef052f 100644 (file)
@@ -1,10 +1,36 @@
 /*
 /*
- * Copyright (c) 1982, 1986 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1982, 1986, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  *
- * %sccs.include.redist.c%
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
  *
- *     @(#)fs.h        7.13 (Berkeley) %G%
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *     @(#)fs.h        8.7 (Berkeley) 4/19/94
  */
 
 /*
  */
 
 /*
  *
  * The first boot and super blocks are given in absolute disk addresses.
  * The byte-offset forms are preferred, as they don't imply a sector size.
  *
  * The first boot and super blocks are given in absolute disk addresses.
  * The byte-offset forms are preferred, as they don't imply a sector size.
- * The byte-offset forms are preferred, as they don't imply a sector size.
  */
 #define BBSIZE         8192
 #define SBSIZE         8192
 #define        BBOFF           ((off_t)(0))
 #define        SBOFF           ((off_t)(BBOFF + BBSIZE))
  */
 #define BBSIZE         8192
 #define SBSIZE         8192
 #define        BBOFF           ((off_t)(0))
 #define        SBOFF           ((off_t)(BBOFF + BBSIZE))
-#define        BBOFF           ((off_t)(0))
-#define        SBOFF           ((off_t)(BBOFF + BBSIZE))
-#ifndef SECSIZE
 #define        BBLOCK          ((daddr_t)(0))
 #define        SBLOCK          ((daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE))
 #define        BBLOCK          ((daddr_t)(0))
 #define        SBLOCK          ((daddr_t)(BBLOCK + BBSIZE / DEV_BSIZE))
-#endif SECSIZE
 
 /*
  * Addresses stored in inodes are capable of addressing fragments
 
 /*
  * Addresses stored in inodes are capable of addressing fragments
 #define MAXMNTLEN 512
 #define MAXCSBUFS 32
 
 #define MAXMNTLEN 512
 #define MAXCSBUFS 32
 
+/*
+ * A summary of contiguous blocks of various sizes is maintained
+ * in each cylinder group. Normally this is set by the initial
+ * value of fs_maxcontig. To conserve space, a maximum summary size
+ * is set by FS_MAXCONTIG.
+ */
+#define FS_MAXCONTIG   16
+
+/*
+ * MINFREE gives the minimum acceptable percentage of file system
+ * blocks which may be free. If the freelist drops below this level
+ * only the superuser may continue to allocate blocks. This may
+ * be set to 0 if no reserve of free blocks is deemed necessary,
+ * however throughput drops by fifty percent if the file system
+ * is run at between 95% and 100% full; thus the minimum default
+ * value of fs_minfree is 5%. However, to get good clustering
+ * performance, 10% is a better choice. hence we use 10% as our
+ * default value. With 10% free space, fragmentation is not a
+ * problem, so we choose to optimize for time.
+ */
+#define MINFREE                5
+#define DEFAULTOPT     FS_OPTTIME
+
 /*
  * Per cylinder group information; summarized in blocks allocated
  * from first cylinder group data blocks.  These blocks have to be
 /*
  * Per cylinder group information; summarized in blocks allocated
  * from first cylinder group data blocks.  These blocks have to be
@@ -103,10 +147,7 @@ struct csum {
 /*
  * Super block for a file system.
  */
 /*
  * Super block for a file system.
  */
-#define        FS_MAGIC        0x011954
-#define        FSOKAY          0x7c269d38
-struct fs
-{
+struct fs {
        struct  fs *fs_link;            /* linked list of file systems */
        struct  fs *fs_rlink;           /*     used for incore super blocks */
        daddr_t fs_sblkno;              /* addr of super-block in filesys */
        struct  fs *fs_link;            /* linked list of file systems */
        struct  fs *fs_rlink;           /*     used for incore super blocks */
        daddr_t fs_sblkno;              /* addr of super-block in filesys */
@@ -173,25 +214,34 @@ struct    fs
        char    fs_ronly;               /* mounted read-only flag */
        char    fs_flags;               /* currently unused flag */
        char    fs_fsmnt[MAXMNTLEN];    /* name mounted on */
        char    fs_ronly;               /* mounted read-only flag */
        char    fs_flags;               /* currently unused flag */
        char    fs_fsmnt[MAXMNTLEN];    /* name mounted on */
-       long    fs_dbsize;              /* hardware sector size */
-       long    fs_sparecon[31];        /* reserved for future constants */
 /* these fields retain the current block allocation info */
        long    fs_cgrotor;             /* last cg searched */
        struct  csum *fs_csp[MAXCSBUFS];/* list of fs_cs info buffers */
        long    fs_cpc;                 /* cyl per cycle in postbl */
        short   fs_opostbl[16][8];      /* old rotation block list head */
 /* these fields retain the current block allocation info */
        long    fs_cgrotor;             /* last cg searched */
        struct  csum *fs_csp[MAXCSBUFS];/* list of fs_cs info buffers */
        long    fs_cpc;                 /* cyl per cycle in postbl */
        short   fs_opostbl[16][8];      /* old rotation block list head */
-       long    fs_sparecon[55];        /* reserved for future constants */
+       long    fs_sparecon[50];        /* reserved for future constants */
+       long    fs_contigsumsize;       /* size of cluster summary array */ 
+       long    fs_maxsymlinklen;       /* max length of an internal symlink */
+       long    fs_inodefmt;            /* format of on-disk inodes */
+       u_quad_t fs_maxfilesize;        /* maximum representable file size */
+       quad_t  fs_qbmask;              /* ~fs_bmask - for use with quad size */
+       quad_t  fs_qfmask;              /* ~fs_fmask - for use with quad size */
        long    fs_state;               /* validate fs_clean field */
        long    fs_state;               /* validate fs_clean field */
-       quad    fs_qbmask;              /* ~fs_bmask - for use with quad size */
-       quad    fs_qfmask;              /* ~fs_fmask - for use with quad size */
        long    fs_postblformat;        /* format of positional layout tables */
        long    fs_postblformat;        /* format of positional layout tables */
-       long    fs_nrpos;               /* number of rotaional positions */
+       long    fs_nrpos;               /* number of rotational positions */
        long    fs_postbloff;           /* (short) rotation block list head */
        long    fs_rotbloff;            /* (u_char) blocks for each rotation */
        long    fs_magic;               /* magic number */
        u_char  fs_space[1];            /* list of blocks for each rotation */
 /* actually longer */
 };
        long    fs_postbloff;           /* (short) rotation block list head */
        long    fs_rotbloff;            /* (u_char) blocks for each rotation */
        long    fs_magic;               /* magic number */
        u_char  fs_space[1];            /* list of blocks for each rotation */
 /* actually longer */
 };
+/*
+ * Filesystem idetification
+ */
+#define        FS_MAGIC        0x011954        /* the fast filesystem magic number */
+#define        FS_OKAY         0x7c269d38      /* superblock checksum */
+#define FS_42INODEFMT  -1              /* 4.2BSD inode format */
+#define FS_44INODEFMT  2               /* 4.4BSD inode format */
 /*
  * Preference for optimization.
  */
 /*
  * Preference for optimization.
  */
@@ -215,6 +265,22 @@ struct     fs
     ? ((fs)->fs_space) \
     : ((u_char *)((char *)(fs) + (fs)->fs_rotbloff)))
 
     ? ((fs)->fs_space) \
     : ((u_char *)((char *)(fs) + (fs)->fs_rotbloff)))
 
+/*
+ * The size of a cylinder group is calculated by CGSIZE. The maximum size
+ * is limited by the fact that cylinder groups are at most one block.
+ * Its size is derived from the size of the maps maintained in the 
+ * cylinder group and the (struct cg) size.
+ */
+#define CGSIZE(fs) \
+    /* base cg */      (sizeof(struct cg) + sizeof(long) + \
+    /* blktot size */  (fs)->fs_cpg * sizeof(long) + \
+    /* blks size */    (fs)->fs_cpg * (fs)->fs_nrpos * sizeof(short) + \
+    /* inode map */    howmany((fs)->fs_ipg, NBBY) + \
+    /* block map */    howmany((fs)->fs_cpg * (fs)->fs_spc / NSPF(fs), NBBY) +\
+    /* if present */   ((fs)->fs_contigsumsize <= 0 ? 0 : \
+    /* cluster sum */  (fs)->fs_contigsumsize * sizeof(long) + \
+    /* cluster map */  howmany((fs)->fs_cpg * (fs)->fs_spc / NSPB(fs), NBBY)))
+
 /*
  * Convert cylinder group to base address of its global summary info.
  *
 /*
  * Convert cylinder group to base address of its global summary info.
  *
@@ -245,7 +311,10 @@ struct     cg {
        long    cg_iusedoff;            /* (char) used inode map */
        long    cg_freeoff;             /* (u_char) free block map */
        long    cg_nextfreeoff;         /* (u_char) next available space */
        long    cg_iusedoff;            /* (char) used inode map */
        long    cg_freeoff;             /* (u_char) free block map */
        long    cg_nextfreeoff;         /* (u_char) next available space */
-       long    cg_sparecon[16];        /* reserved for future use */
+       long    cg_clustersumoff;       /* (long) counts of avail clusters */
+       long    cg_clusteroff;          /* (char) free cluster map */
+       long    cg_nclusterblks;        /* number of clusters this cg */
+       long    cg_sparecon[13];        /* reserved for future use */
        u_char  cg_space[1];            /* space for cylinder group maps */
 /* actually longer */
 };
        u_char  cg_space[1];            /* space for cylinder group maps */
 /* actually longer */
 };
@@ -270,6 +339,10 @@ struct     cg {
     : ((u_char *)((char *)(cgp) + (cgp)->cg_freeoff)))
 #define cg_chkmagic(cgp) \
     ((cgp)->cg_magic == CG_MAGIC || ((struct ocg *)(cgp))->cg_magic == CG_MAGIC)
     : ((u_char *)((char *)(cgp) + (cgp)->cg_freeoff)))
 #define cg_chkmagic(cgp) \
     ((cgp)->cg_magic == CG_MAGIC || ((struct ocg *)(cgp))->cg_magic == CG_MAGIC)
+#define cg_clustersfree(cgp) \
+    ((u_char *)((char *)(cgp) + (cgp)->cg_clusteroff))
+#define cg_clustersum(cgp) \
+    ((long *)((char *)(cgp) + (cgp)->cg_clustersumoff))
 
 /*
  * The following structure is defined
 
 /*
  * The following structure is defined
@@ -308,12 +381,12 @@ struct    ocg {
  * They calc file system addresses of cylinder group data structures.
  */
 #define        cgbase(fs, c)   ((daddr_t)((fs)->fs_fpg * (c)))
  * They calc file system addresses of cylinder group data structures.
  */
 #define        cgbase(fs, c)   ((daddr_t)((fs)->fs_fpg * (c)))
-#define cgstart(fs, c) \
-       (cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask)))
+#define        cgdmin(fs, c)   (cgstart(fs, c) + (fs)->fs_dblkno)      /* 1st data */
+#define        cgimin(fs, c)   (cgstart(fs, c) + (fs)->fs_iblkno)      /* inode blk */
 #define        cgsblock(fs, c) (cgstart(fs, c) + (fs)->fs_sblkno)      /* super blk */
 #define        cgtod(fs, c)    (cgstart(fs, c) + (fs)->fs_cblkno)      /* cg block */
 #define        cgsblock(fs, c) (cgstart(fs, c) + (fs)->fs_sblkno)      /* super blk */
 #define        cgtod(fs, c)    (cgstart(fs, c) + (fs)->fs_cblkno)      /* cg block */
-#define        cgimin(fs, c)   (cgstart(fs, c) + (fs)->fs_iblkno)      /* inode blk */
-#define        cgdmin(fs, c)   (cgstart(fs, c) + (fs)->fs_dblkno)      /* 1st data */
+#define cgstart(fs, c)                                                 \
+       (cgbase(fs, c) + (fs)->fs_cgoffset * ((c) & ~((fs)->fs_cgmask)))
 
 /*
  * Macros for handling inode numbers:
 
 /*
  * Macros for handling inode numbers:
@@ -321,11 +394,11 @@ struct    ocg {
  *     inode number to cylinder group number.
  *     inode number to file system block address.
  */
  *     inode number to cylinder group number.
  *     inode number to file system block address.
  */
-#define        itoo(fs, x)     ((x) % INOPB(fs))
-#define        itog(fs, x)     ((x) / (fs)->fs_ipg)
-#define        itod(fs, x) \
-       ((daddr_t)(cgimin(fs, itog(fs, x)) + \
-       (blkstofrags((fs), (((x) % (fs)->fs_ipg) / INOPB(fs))))))
+#define        ino_to_cg(fs, x)        ((x) / (fs)->fs_ipg)
+#define        ino_to_fsba(fs, x)                                              \
+       ((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))
 
 /*
  * Give cylinder group number for a file system block.
 
 /*
  * Give cylinder group number for a file system block.
@@ -353,9 +426,9 @@ struct      ocg {
  * modulos and multiplications.
  */
 #define blkoff(fs, loc)                /* calculates (loc % fs->fs_bsize) */ \
  * modulos and multiplications.
  */
 #define blkoff(fs, loc)                /* calculates (loc % fs->fs_bsize) */ \
-       ((loc) & ~(fs)->fs_bmask)
+       ((loc) & (fs)->fs_qbmask)
 #define fragoff(fs, loc)       /* calculates (loc % fs->fs_fsize) */ \
 #define fragoff(fs, loc)       /* calculates (loc % fs->fs_fsize) */ \
-       ((loc) & ~(fs)->fs_fmask)
+       ((loc) & (fs)->fs_qfmask)
 #define lblktosize(fs, blk)    /* calculates (blk * fs->fs_bsize) */ \
        ((blk) << (fs)->fs_bshift)
 #define lblkno(fs, loc)                /* calculates (loc / fs->fs_bsize) */ \
 #define lblktosize(fs, blk)    /* calculates (blk * fs->fs_bsize) */ \
        ((blk) << (fs)->fs_bshift)
 #define lblkno(fs, loc)                /* calculates (loc / fs->fs_bsize) */ \
@@ -363,9 +436,9 @@ struct      ocg {
 #define numfrags(fs, loc)      /* calculates (loc / fs->fs_fsize) */ \
        ((loc) >> (fs)->fs_fshift)
 #define blkroundup(fs, size)   /* calculates roundup(size, fs->fs_bsize) */ \
 #define numfrags(fs, loc)      /* calculates (loc / fs->fs_fsize) */ \
        ((loc) >> (fs)->fs_fshift)
 #define blkroundup(fs, size)   /* calculates roundup(size, fs->fs_bsize) */ \
-       (((size) + (fs)->fs_bsize - 1) & (fs)->fs_bmask)
+       (((size) + (fs)->fs_qbmask) & (fs)->fs_bmask)
 #define fragroundup(fs, size)  /* calculates roundup(size, fs->fs_fsize) */ \
 #define fragroundup(fs, size)  /* calculates roundup(size, fs->fs_fsize) */ \
-       (((size) + (fs)->fs_fsize - 1) & (fs)->fs_fmask)
+       (((size) + (fs)->fs_qfmask) & (fs)->fs_fmask)
 #define fragstoblks(fs, frags) /* calculates (frags / fs->fs_frag) */ \
        ((frags) >> (fs)->fs_fragshift)
 #define blkstofrags(fs, blks)  /* calculates (blks * fs->fs_frag) */ \
 #define fragstoblks(fs, frags) /* calculates (frags / fs->fs_frag) */ \
        ((frags) >> (fs)->fs_fragshift)
 #define blkstofrags(fs, blks)  /* calculates (blks * fs->fs_frag) */ \
@@ -411,3 +484,6 @@ struct      ocg {
  * NINDIR is the number of indirects in a file system block.
  */
 #define        NINDIR(fs)      ((fs)->fs_nindir)
  * NINDIR is the number of indirects in a file system block.
  */
 #define        NINDIR(fs)      ((fs)->fs_nindir)
+
+extern int inside[], around[];
+extern u_char *fragtbl[];