1 /*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)lfs.h 5.5 (Berkeley) 10/02/91 8 */ 9 10 typedef struct buf BUF; 11 typedef struct dinode DINODE; 12 typedef struct inode INODE; 13 typedef struct mount MOUNT; 14 typedef struct ucred UCRED; 15 typedef struct ufsmount UFSMOUNT; 16 typedef struct vnode VNODE; 17 18 #define LFS_LABELPAD 8192 /* LFS label size */ 19 #define LFS_SBPAD 8192 /* LFS superblock size */ 20 #define MAXMNTLEN 512 /* XXX move from fs.h to mount.h */ 21 22 /* On-disk and in-memory checkpoint segment usage structure. */ 23 typedef struct segusage SEGUSE; 24 struct segusage { 25 u_long su_nbytes; /* number of live bytes */ 26 u_long su_lastmod; /* last modified timestamp */ 27 #define SEGUSE_DIRTY 0x1 /* XXX fill in comment */ 28 u_long su_flags; 29 }; 30 31 /* On-disk file information. One per file with data blocks in the segment. */ 32 typedef struct finfo FINFO; 33 struct finfo { 34 u_long fi_nblocks; /* number of blocks */ 35 u_long fi_version; /* version number */ 36 u_long fi_ino; /* inode number */ 37 long fi_blocks[1]; /* array of logical block numbers */ 38 }; 39 40 /* In-memory description of a segment about to be written */ 41 typedef struct segment SEGMENT; 42 struct segment { 43 SEGMENT *nextp; /* Links segments together */ 44 BUF **bpp; /* Pointer to buffer array */ 45 BUF **cbpp; /* Pointer to next available bp */ 46 BUF *ibp; /* Buffer pointer to inode page */ 47 BUF *sbp; /* Segment summary buffer pointer */ 48 void *segsum; /* Segment Summary info */ 49 u_long sum_bytes_left; /* Bytes left in summary */ 50 u_long seg_bytes_left; /* Bytes left in segment */ 51 daddr_t saddr; /* Current disk address */ 52 daddr_t sum_addr; /* Address of current summary */ 53 u_long ninodes; /* Number of inodes in this segment */ 54 u_long sum_num; /* Number of current summary block */ 55 u_long seg_number; /* Number of this segment */ 56 FINFO *fip; /* Current fileinfo pointer */ 57 }; 58 59 /* On-disk and in-memory super block. */ 60 typedef struct lfs LFS; 61 struct lfs { 62 #define LFS_MAGIC 0xbedead 63 u_long lfs_magic; /* magic number */ 64 #define LFS_VERSION 1 65 u_long lfs_version; /* version number */ 66 67 u_long lfs_size; /* number of blocks in fs */ 68 u_long lfs_ssize; /* number of blocks per segment */ 69 u_long lfs_dsize; /* number of data blocks in fs */ 70 u_long lfs_bsize; /* size of basic blocks in fs */ 71 u_long lfs_fsize; /* size of frag blocks in fs */ 72 u_long lfs_frag; /* number of frags in a block in fs */ 73 74 /* Checkpoint region. */ 75 ino_t lfs_free; /* start of the free list */ 76 u_long lfs_bfree; /* number of free blocks */ 77 u_long lfs_nfiles; /* number of allocated inodes */ 78 daddr_t lfs_idaddr; /* inode file disk address */ 79 ino_t lfs_ifile; /* inode file inode number */ 80 daddr_t lfs_lastseg; /* last segment written */ 81 daddr_t lfs_nextseg; /* next segment to write */ 82 u_long lfs_tstamp; /* time stamp */ 83 84 /* These are configuration parameters. */ 85 u_long lfs_minfree; /* minimum percentage of free blocks */ 86 87 /* These fields can be computed from the others. */ 88 u_long lfs_inopb; /* inodes per block */ 89 u_long lfs_ifpb; /* IFILE entries per block */ 90 u_long lfs_nindir; /* indirect pointers per block */ 91 u_long lfs_nseg; /* number of segments */ 92 u_long lfs_nspf; /* number of sectors per fragment */ 93 u_long lfs_segtabsz; /* segment table size in blocks */ 94 95 u_long lfs_segmask; /* calculate offset within a segment */ 96 u_long lfs_segshift; /* fast mult/div for segments */ 97 u_long lfs_bmask; /* calc block offset from file offset */ 98 u_long lfs_bshift; /* calc block number from file offset */ 99 u_long lfs_ffmask; /* calc frag offset from file offset */ 100 u_long lfs_ffshift; /* fast mult/div for frag from file */ 101 u_long lfs_fbmask; /* calc frag offset from block offset */ 102 u_long lfs_fbshift; /* fast mult/div for frag from block */ 103 u_long lfs_fsbtodb; /* fsbtodb and dbtofsb shift constant */ 104 105 #define LFS_MIN_SBINTERVAL 5 /* minimum superblock segment spacing */ 106 #define LFS_MAXNUMSB 10 /* superblock disk offsets */ 107 daddr_t lfs_sboffs[LFS_MAXNUMSB]; 108 109 /* These fields are set at mount time and are meaningless on disk. */ 110 VNODE *lfs_ivnode; /* vnode for the ifile */ 111 SEGUSE *lfs_segtab; /* in-memory segment usage table */ 112 SEGMENT *lfs_seglist; /* list of segments being written */ 113 u_long lfs_iocount; /* Number of ios pending */ 114 u_char lfs_fmod; /* super block modified flag */ 115 u_char lfs_clean; /* file system is clean flag */ 116 u_char lfs_ronly; /* mounted read-only flag */ 117 u_char lfs_flags; /* currently unused flag */ 118 u_char lfs_fsmnt[MAXMNTLEN]; /* name mounted on */ 119 u_char pad[3]; /* long-align */ 120 121 /* Checksum; valid on disk. */ 122 u_long lfs_cksum; /* checksum for superblock checking */ 123 }; 124 125 /* 126 * The root inode is the root of the file system. Inode 0 is the out-of-band 127 * inode, and inode 1 is the inode number for the ifile. Thus the root inode 128 * is 2. 129 */ 130 #define ROOTINO ((ino_t)2) 131 #define LOSTFOUNDINO ((ino_t)3) 132 133 /* Fixed inode numbers. */ 134 #define LFS_UNUSED_INUM 0 /* Out of band inode number. */ 135 #define LFS_IFILE_INUM 1 /* Inode number of the ifile. */ 136 /* First free inode number. */ 137 #define LFS_FIRST_INUM (LOSTFOUNDINO + 1) 138 139 /* 140 * Used to access the first spare of the dinode which we use to store 141 * the ifile number so we can identify them 142 */ 143 #define di_inum di_spare[0] 144 145 /* 146 * Logical block numbers of indirect blocks. 147 */ 148 #define S_INDIR -1 149 #define D_INDIR -2 150 #define T_INDIR -3 151 152 typedef struct ifile IFILE; 153 struct ifile { 154 u_long if_version; /* inode version number */ 155 #define LFS_UNUSED_DADDR 0 /* out-of-band daddr */ 156 daddr_t if_daddr; /* inode disk address */ 157 union { 158 ino_t nextfree; /* next-unallocated inode */ 159 time_t st_atime; /* access time */ 160 } __ifile_u; 161 #define if_st_atime __ifile_u.st_atime 162 #define if_nextfree __ifile_u.nextfree 163 }; 164 165 /* Segment table size, in blocks. */ 166 #define SEGTABSIZE(fs) \ 167 (((fs)->fs_nseg * sizeof(SEGUSE) + \ 168 ((fs)->fs_bsize - 1)) >> (fs)->fs_bshift) 169 170 #define SEGTABSIZE_SU(fs) \ 171 (((fs)->lfs_nseg * sizeof(SEGUSE) + \ 172 ((fs)->lfs_bsize - 1)) >> (fs)->lfs_bshift) 173 174 /* 175 * All summary blocks are the same size, so we can always read a summary 176 * block easily from a segment 177 */ 178 #define LFS_SUMMARY_SIZE 512 179 180 /* On-disk segment summary information */ 181 typedef struct segsum SEGSUM; 182 struct segsum { 183 u_long ss_cksum; /* check sum */ 184 daddr_t ss_next; /* next segment */ 185 daddr_t ss_prev; /* next segment */ 186 daddr_t ss_nextsum; /* next summary block */ 187 u_long ss_create; /* creation time stamp */ 188 u_long ss_nfinfo; /* number of file info structures */ 189 u_long ss_ninos; /* number of inode blocks */ 190 /* FINFO's... */ 191 }; 192 193 /* NINDIR is the number of indirects in a file system block. */ 194 #define NINDIR(fs) ((fs)->lfs_nindir) 195 196 /* INOPB is the number of inodes in a secondary storage block. */ 197 #define INOPB(fs) ((fs)->lfs_inopb) 198 199 /* IFPB -- IFILE's per block */ 200 #define IFPB(fs) ((fs)->lfs_ifpb) 201 202 #define blksize(fs) ((fs)->lfs_bsize) 203 #define blkoff(fs, loc) ((loc) & (fs)->lfs_bmask) 204 #define fsbtodb(fs, b) ((b) << (fs)->lfs_fsbtodb) 205 #define lblkno(fs, loc) ((loc) >> (fs)->lfs_bshift) 206 #define lblktosize(fs, blk) ((blk) << (fs)->lfs_bshift) 207 #define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \ 208 ((loc) >> (fs)->lfs_bshift) 209 #define satosn(fs, saddr) \ 210 ((int)((saddr - fs->lfs_sboffs[0]) / fsbtodb(fs, fs->lfs_ssize))) 211 #define sntosa(fs, sn) \ 212 ((daddr_t)(sn * (fs->lfs_ssize << fs->lfs_fsbtodb) + fs->lfs_sboffs[0])) 213