checkpoint, but not because it's working
[unix-history] / usr / src / sys / ufs / lfs / lfs.h
index 34d34c8..c0e8306 100644 (file)
@@ -4,17 +4,60 @@
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)lfs.h       5.2 (Berkeley) %G%
+ *     @(#)lfs.h       5.4 (Berkeley) %G%
  */
 
  */
 
+typedef struct buf     BUF;
+typedef struct dinode  DINODE;
+typedef struct inode   INODE;
+typedef struct mount   MOUNT;
+typedef struct ucred   UCRED;
+typedef struct ufsmount        UFSMOUNT;
+typedef struct vnode   VNODE;
+
 #define        LFS_LABELPAD    8192            /* LFS label size */
 #define        LFS_SBPAD       8192            /* LFS superblock size */
 #define MAXMNTLEN      512             /* XXX move from fs.h to mount.h */
 #define        LFS_LABELPAD    8192            /* LFS label size */
 #define        LFS_SBPAD       8192            /* LFS superblock size */
 #define MAXMNTLEN      512             /* XXX move from fs.h to mount.h */
-#define        LFS_BLKSIZE     4096            /* LFS block size */
 
 
-/* On-disk super block. */
-typedef struct lfs_super {
-#define        LFS_MAGIC       0xdeadbeef
+/* On-disk and in-memory checkpoint segment usage structure. */
+typedef struct segusage SEGUSE;
+struct segusage {
+       u_long  su_nbytes;              /* number of live bytes */
+       u_long  su_lastmod;             /* last modified timestamp */
+#define        SEGUSE_DIRTY    0x1             /* XXX fill in comment */
+       u_long  su_flags;
+};
+
+/* On-disk file information.  One per file with data blocks in the segment. */
+typedef struct finfo FINFO;
+struct finfo {
+       u_long  fi_nblocks;             /* number of blocks */
+       u_long  fi_version;             /* version number */
+       ino_t   fi_ino;                 /* inode number */
+       long    fi_blocks[1];           /* array of logical block numbers */
+};
+
+/* In-memory description of a segment about to be written */
+typedef struct segment SEGMENT;
+struct segment {
+       SEGMENT *nextp;                 /* Links segments together */
+       BUF     **bpp;                  /* Pointer to buffer array */
+       BUF     **cbpp;                 /* Pointer to next available bp */
+       void    *segsum;                /* Segment Summary info */
+       u_long  sum_bytes_left;         /* Bytes left in summary */
+       u_long  seg_bytes_left;         /* Bytes left in segment */
+       daddr_t saddr;                  /* Current disk address */
+       daddr_t sum_addr;               /* Address of current summary */
+       u_long  ninodes;                /* Number of inodes in this segment */
+       u_long  sum_num;                /* Number of current summary block */
+       u_long  seg_number;             /* Number of this segment */
+       FINFO   *fip;                   /* Current fileinfo pointer */
+};
+
+/* On-disk and in-memory super block. */
+typedef struct lfs LFS;
+struct lfs {
+#define        LFS_MAGIC       0xbedead
        u_long  lfs_magic;              /* magic number */
 #define        LFS_VERSION     1
        u_long  lfs_version;            /* version number */
        u_long  lfs_magic;              /* magic number */
 #define        LFS_VERSION     1
        u_long  lfs_version;            /* version number */
@@ -25,13 +68,15 @@ typedef struct lfs_super {
        u_long  lfs_bsize;              /* size of basic blocks in fs */
        u_long  lfs_fsize;              /* size of frag blocks in fs */
        u_long  lfs_frag;               /* number of frags in a block in fs */
        u_long  lfs_bsize;              /* size of basic blocks in fs */
        u_long  lfs_fsize;              /* size of frag blocks in fs */
        u_long  lfs_frag;               /* number of frags in a block in fs */
-       u_long  lfs_sbsize;             /* actual size of super block */
 
 /* Checkpoint region. */
        ino_t   lfs_free;               /* start of the free list */
 
 /* Checkpoint region. */
        ino_t   lfs_free;               /* start of the free list */
+       u_long  lfs_bfree;              /* number of free blocks */
+       u_long  lfs_nfiles;             /* number of allocated inodes */
        daddr_t lfs_idaddr;             /* inode file disk address */
        ino_t   lfs_ifile;              /* inode file inode number */
        daddr_t lfs_lastseg;            /* last segment written */
        daddr_t lfs_idaddr;             /* inode file disk address */
        ino_t   lfs_ifile;              /* inode file inode number */
        daddr_t lfs_lastseg;            /* last segment written */
+       daddr_t lfs_nextseg;            /* next segment to write */
        u_long  lfs_tstamp;             /* time stamp */
 
 /* These are configuration parameters. */
        u_long  lfs_tstamp;             /* time stamp */
 
 /* These are configuration parameters. */
@@ -55,83 +100,57 @@ typedef struct lfs_super {
        u_long  lfs_fbshift;            /* fast mult/div for frag from block */
        u_long  lfs_fsbtodb;            /* fsbtodb and dbtofsb shift constant */
 
        u_long  lfs_fbshift;            /* fast mult/div for frag from block */
        u_long  lfs_fsbtodb;            /* fsbtodb and dbtofsb shift constant */
 
-#define        LFS_MAXNUMSB            10
-#define        LFS_MIN_SBINTERVAL      5
-       daddr_t lfs_sboffs[LFS_MAXNUMSB];       /* super-block disk offsets */
-} LFS_SUPER;
-
-#define        blksize(fs, ip, lbn)    LFSBLKSIZE
-#define        blkoff(fs, loc)         /* calculates (loc % fs->fs_bsize) */ \
-       ((loc) & ~(fs)->fs_bmask)
-#define        fsbtodb(fs, b)          ((b) << (fs)->fs_fsbtodb)
-#define        lblkno(fs, loc)         /* calculates (loc / fs->fs_bsize) */ \
-       ((loc) >> (fs)->fs_bshift)
-#define        itoo(fs, x)             ((x) % INOPB(fs))
-#define        itod(fs, x)             LFS -- IMPLEMENT
-
-/* In-memory super block. */
-typedef struct lfs {
-       struct  fs *fs_link;            /* linked list of file systems */
-       struct  fs *fs_rlink;           /*     used for incore super blocks */
-       time_t  fs_time;                /* last time written */
-
-/* These fields are cleared at mount time. */
-       u_char  fs_fmod;                /* super block modified flag */
-       u_char  fs_clean;               /* file system is clean flag */
-       u_char  fs_ronly;               /* mounted read-only flag */
-       u_char  fs_flags;               /* currently unused flag */
-       u_char  fs_fsmnt[MAXMNTLEN];    /* name mounted on */
-
-/* On-disk structure. */
-       LFS_SUPER fs_super;
-} LFS;
-
-#define        fs_bmask        fs_super.lfs_bmask
-#define        fs_bshift       fs_super.lfs_bshift
-#define        fs_bsize        fs_super.lfs_bsize
-#define        fs_dsize        fs_super.lfs_dsize
-#define        fs_fbmask       fs_super.lfs_fbmask
-#define        fs_fbshift      fs_super.lfs_fbshift
-#define        fs_ffmask       fs_super.lfs_ffmask
-#define        fs_ffshift      fs_super.lfs_ffshift
-#define        fs_frag         fs_super.lfs_frag
-#define        fs_free         fs_super.lfs_free
-#define        fs_fsbtodb      fs_super.lfs_fsbtodb
-#define        fs_fsize        fs_super.lfs_fsize
-#define        fs_idaddr       fs_super.lfs_idaddr
-#define        fs_ifile        fs_super.lfs_ifile
-#define        fs_ifpb         fs_super.lfs_ifpb
-#define        fs_inopb        fs_super.lfs_inopb
-#define        fs_lastseg      fs_super.lfs_lastseg
-#define        fs_magic        fs_super.lfs_magic
-#define        fs_minfree      fs_super.lfs_minfree
-#define        fs_nindir       fs_super.lfs_nindir
-#define        fs_nseg         fs_super.lfs_nseg
-#define        fs_nspf         fs_super.lfs_nspf
-#define        fs_sboffs       fs_super.lfs_sboffs
-#define        fs_sbsize       fs_super.lfs_sbsize
-#define        fs_segmask      fs_super.lfs_segmask
-#define        fs_segshift     fs_super.lfs_segshift
-#define        fs_segtabsz     fs_super.lfs_segtabsz
-#define        fs_size         fs_super.lfs_size
-#define        fs_ssize        fs_super.lfs_ssize
-#define        fs_tstamp       fs_super.lfs_tstamp
-#define        fs_version      fs_super.lfs_version
+#define        LFS_MIN_SBINTERVAL      5       /* minimum superblock segment spacing */
+#define        LFS_MAXNUMSB            10      /* superblock disk offsets */
+       daddr_t lfs_sboffs[LFS_MAXNUMSB];
+
+/* These fields are set at mount time and are meaningless on disk. */
+       VNODE   *lfs_ivnode;            /* vnode for the ifile */
+       SEGUSE  *lfs_segtab;            /* in-memory segment usage table */
+       SEGMENT *lfs_seglist;           /* list of segments being written */
+       u_long  lfs_iocount;            /* Number of ios pending */
+       u_char  lfs_fmod;               /* super block modified flag */
+       u_char  lfs_clean;              /* file system is clean flag */
+       u_char  lfs_ronly;              /* mounted read-only flag */
+       u_char  lfs_flags;              /* currently unused flag */
+       u_char  lfs_fsmnt[MAXMNTLEN];   /* name mounted on */
+       u_char  pad[3];                 /* long-align */
+
+/* Checksum; valid on disk. */
+       u_long  lfs_cksum;              /* checksum for superblock checking */
+};
+
+/*
+ * The root inode is the root of the file system.  Inode 0 is the out-of-band
+ * inode, and inode 1 is the inode number for the ifile.  Thus the root inode
+ * is 2.
+ */
+#define ROOTINO         ((ino_t)2)
+#define        LOSTFOUNDINO    ((ino_t)3)
 
 /* Fixed inode numbers. */
 #define        LFS_UNUSED_INUM 0               /* Out of band inode number. */
 #define        LFS_IFILE_INUM  1               /* Inode number of the ifile. */
 
 /* Fixed inode numbers. */
 #define        LFS_UNUSED_INUM 0               /* Out of band inode number. */
 #define        LFS_IFILE_INUM  1               /* Inode number of the ifile. */
-#define        LFS_FIRST_INUM  2               /* First free inode number. */
+                                       /* First free inode number. */
+#define        LFS_FIRST_INUM  (LOSTFOUNDINO + 1)
 
 
-/* 
+/*
  * Used to access the first spare of the dinode which we use to store
  * the ifile number so we can identify them
  */
 #define        di_inum di_spare[0]
 
  * Used to access the first spare of the dinode which we use to store
  * the ifile number so we can identify them
  */
 #define        di_inum di_spare[0]
 
-typedef struct ifile {
+/*
+ * Logical block numbers of indirect blocks.
+ */
+#define S_INDIR        -1
+#define D_INDIR -2
+#define T_INDIR -3
+
+typedef struct ifile IFILE;
+struct ifile {
        u_long  if_version;             /* inode version number */
        u_long  if_version;             /* inode version number */
-#define        UNUSED_DADDR    0               /* out-of-band daddr */
+#define        LFS_UNUSED_DADDR        0       /* out-of-band daddr */
        daddr_t if_daddr;               /* inode disk address */
        union {
                ino_t   nextfree;       /* next-unallocated inode */
        daddr_t if_daddr;               /* inode disk address */
        union {
                ino_t   nextfree;       /* next-unallocated inode */
@@ -139,25 +158,17 @@ typedef struct ifile {
        } __ifile_u;
 #define        if_st_atime     __ifile_u.st_atime
 #define        if_nextfree     __ifile_u.nextfree
        } __ifile_u;
 #define        if_st_atime     __ifile_u.st_atime
 #define        if_nextfree     __ifile_u.nextfree
-} IFILE;
+};
 
 /* Segment table size, in blocks. */
 #define        SEGTABSIZE(fs) \
 
 /* Segment table size, in blocks. */
 #define        SEGTABSIZE(fs) \
-       (((fs)->fs_nseg * sizeof(SEGUSAGE) + \
-           ((fs)->fs_bsize - 1)) << (fs)->fs_bshift)
+       (((fs)->fs_nseg * sizeof(SEGUSE) + \
+           ((fs)->fs_bsize - 1)) >> (fs)->fs_bshift)
 
 #define        SEGTABSIZE_SU(fs) \
 
 #define        SEGTABSIZE_SU(fs) \
-       (((fs)->lfs_nseg * sizeof(SEGUSAGE) + \
+       (((fs)->lfs_nseg * sizeof(SEGUSE) + \
            ((fs)->lfs_bsize - 1)) >> (fs)->lfs_bshift)
 
            ((fs)->lfs_bsize - 1)) >> (fs)->lfs_bshift)
 
-/* In-memory and on-disk checkpoint segment usage structure. */
-typedef struct segusage {
-       u_long  su_nbytes;              /* number of live bytes */
-       u_long  su_lastmod;             /* last modified timestamp */
-#define        SEGUSAGE_DIRTY                  0x1
-       u_long  su_flags;
-} SEGUSAGE;
-
 /*
  * All summary blocks are the same size, so we can always read a summary
  * block easily from a segment
 /*
  * All summary blocks are the same size, so we can always read a summary
  * block easily from a segment
@@ -165,26 +176,35 @@ typedef struct segusage {
 #define        LFS_SUMMARY_SIZE        512
 
 /* On-disk segment summary information */
 #define        LFS_SUMMARY_SIZE        512
 
 /* On-disk segment summary information */
-typedef struct segsum {
+typedef struct segsum SEGSUM;
+struct segsum {
+       u_long  ss_cksum;               /* check sum */
        daddr_t ss_next;                /* next segment */
        daddr_t ss_prev;                /* next segment */
        daddr_t ss_nextsum;             /* next summary block */
        u_long  ss_create;              /* creation time stamp */
        u_long  ss_nfinfo;              /* number of file info structures */
        daddr_t ss_next;                /* next segment */
        daddr_t ss_prev;                /* next segment */
        daddr_t ss_nextsum;             /* next summary block */
        u_long  ss_create;              /* creation time stamp */
        u_long  ss_nfinfo;              /* number of file info structures */
-       u_long  ss_niinfo;              /* number of inode info structures */
-       u_long  ss_cksum;               /* check sum */
-} SEGSUM;
-
-/* On-disk file information.  One per file with data blocks in the segment. */
-typedef struct finfo {
-       u_long  fi_nblocks;             /* number of blocks */
-       u_long  fi_version;             /* version number */
-       ino_t   fi_ino;                 /* inode number */
-       u_long  fi_blocks[1];           /* array of logical block numbers */
-} FINFO;
-
-/* On-disk inode information.  One per block of inodes in the segment. */
-typedef struct iinfo {
-       u_long  ii_ninodes;             /* number of inodes */
-       ino_t   ii_inodes;              /* array of inode numbers */
-} IINFO;
+       u_long  ss_ninos;               /* number of inode blocks */
+       /* FINFO's... */
+};
+
+/* NINDIR is the number of indirects in a file system block. */
+#define        NINDIR(fs)      ((fs)->lfs_nindir)
+
+/* INOPB is the number of inodes in a secondary storage block. */
+#define        INOPB(fs)       ((fs)->lfs_inopb)
+
+/* IFPB -- IFILE's per block */
+#define        IFPB(fs)        ((fs)->lfs_ifpb)
+
+#define        blksize(fs)             ((fs)->lfs_bsize)
+#define        blkoff(fs, loc)         ((loc) & (fs)->lfs_bmask)
+#define        fsbtodb(fs, b)          ((b) << (fs)->lfs_fsbtodb)
+#define        lblkno(fs, loc)         ((loc) >> (fs)->lfs_bshift)
+#define        lblktosize(fs, blk)     ((blk) << (fs)->lfs_bshift)
+#define numfrags(fs, loc)      /* calculates (loc / fs->fs_fsize) */ \
+       ((loc) >> (fs)->lfs_bshift)
+#define satosn(fs, saddr) \
+       ((int)((saddr - fs->lfs_sboffs[0]) / fsbtodb(fs, fs->lfs_ssize)))
+#define sntosa(fs, sn) \
+       ((daddr_t)(sn * (fs->lfs_ssize << fs->lfs_fsbtodb) + fs->lfs_sboffs[0]))