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 7.9 (Berkeley) 01/08/92 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; /* SEGUSE last modified timestamp */ 27 #define SEGUSE_ACTIVE 0x1 /* segment is currently being written */ 28 #define SEGUSE_DIRTY 0x2 /* segment has data in it */ 29 #define SEGUSE_SUPERBLOCK 0x4 /* segment contains a superblock */ 30 u_long su_flags; 31 }; 32 33 #define SEGTABSIZE_SU(fs) \ 34 (((fs)->lfs_nseg * sizeof(SEGUSE) + \ 35 ((fs)->lfs_bsize - 1)) >> (fs)->lfs_bshift) 36 37 /* On-disk file information. One per file with data blocks in the segment. */ 38 typedef struct finfo FINFO; 39 struct finfo { 40 u_long fi_nblocks; /* number of blocks */ 41 u_long fi_version; /* version number */ 42 u_long fi_ino; /* inode number */ 43 long fi_blocks[1]; /* array of logical block numbers */ 44 }; 45 46 /* On-disk and in-memory super block. */ 47 struct lfs { 48 #define LFS_MAGIC 0x070162 49 u_long lfs_magic; /* magic number */ 50 #define LFS_VERSION 1 51 u_long lfs_version; /* version number */ 52 53 u_long lfs_size; /* number of blocks in fs */ 54 u_long lfs_ssize; /* number of blocks per segment */ 55 u_long lfs_dsize; /* number of data blocks in fs */ 56 u_long lfs_bsize; /* size of basic blocks in fs */ 57 u_long lfs_fsize; /* size of frag blocks in fs */ 58 u_long lfs_frag; /* number of frags in a block in fs */ 59 60 /* Checkpoint region. */ 61 ino_t lfs_free; /* start of the free list */ 62 u_long lfs_bfree; /* number of free blocks */ 63 u_long lfs_nfiles; /* number of allocated inodes */ 64 daddr_t lfs_idaddr; /* inode file disk address */ 65 ino_t lfs_ifile; /* inode file inode number */ 66 daddr_t lfs_lastseg; /* address of last segment written */ 67 daddr_t lfs_nextseg; /* address of next segment to write */ 68 daddr_t lfs_curseg; /* current segment being written */ 69 daddr_t lfs_offset; /* offset in curseg for next partial */ 70 u_long lfs_tstamp; /* time stamp */ 71 72 /* These are configuration parameters. */ 73 u_long lfs_minfree; /* minimum percentage of free blocks */ 74 75 /* These fields can be computed from the others. */ 76 u_long lfs_dbpseg; /* disk blocks per segment */ 77 u_long lfs_inopb; /* inodes per block */ 78 u_long lfs_ifpb; /* IFILE entries per block */ 79 u_long lfs_sepb; /* SEGUSE entries per block */ 80 u_long lfs_nindir; /* indirect pointers per block */ 81 u_long lfs_nseg; /* number of segments */ 82 u_long lfs_nspf; /* number of sectors per fragment */ 83 u_long lfs_cleansz; /* cleaner info size in blocks */ 84 u_long lfs_segtabsz; /* segment table size in blocks */ 85 86 u_long lfs_segmask; /* calculate offset within a segment */ 87 u_long lfs_segshift; /* fast mult/div for segments */ 88 u_long lfs_bmask; /* calc block offset from file offset */ 89 u_long lfs_bshift; /* calc block number from file offset */ 90 u_long lfs_ffmask; /* calc frag offset from file offset */ 91 u_long lfs_ffshift; /* fast mult/div for frag from file */ 92 u_long lfs_fbmask; /* calc frag offset from block offset */ 93 u_long lfs_fbshift; /* fast mult/div for frag from block */ 94 u_long lfs_fsbtodb; /* fsbtodb and dbtofsb shift constant */ 95 96 #define LFS_MIN_SBINTERVAL 5 /* minimum superblock segment spacing */ 97 #define LFS_MAXNUMSB 10 /* superblock disk offsets */ 98 daddr_t lfs_sboffs[LFS_MAXNUMSB]; 99 100 /* These fields are set at mount time and are meaningless on disk. */ 101 VNODE *lfs_ivnode; /* vnode for the ifile */ 102 SEGUSE *lfs_segtab; /* in-memory segment usage table */ 103 /* XXX NOT USED */ 104 void *XXXlfs_seglist; /* list of segments being written */ 105 u_long lfs_iocount; /* number of ios pending */ 106 u_char lfs_fmod; /* super block modified flag */ 107 u_char lfs_clean; /* file system is clean flag */ 108 u_char lfs_ronly; /* mounted read-only flag */ 109 u_char lfs_flags; /* currently unused flag */ 110 u_char lfs_fsmnt[MAXMNTLEN]; /* name mounted on */ 111 u_char pad[3]; /* long-align */ 112 113 /* Checksum; valid on disk. */ 114 u_long lfs_cksum; /* checksum for superblock checking */ 115 }; 116 117 /* 118 * Inode 0 is the out-of-band inode number, inode 1 is the inode number for 119 * the IFILE, the root inode is 2 and the lost+found inode is 3. 120 */ 121 122 /* Fixed inode numbers. */ 123 #define LFS_UNUSED_INUM 0 /* out of band inode number */ 124 #define LFS_IFILE_INUM 1 /* IFILE inode number */ 125 #define LOSTFOUNDINO 3 /* lost+found inode number */ 126 #define LFS_FIRST_INUM 4 /* first free inode number */ 127 128 /* 129 * Used to access the first spare of the dinode which we use to store 130 * the ifile number so we can identify them 131 */ 132 #define di_inum di_spare[0] 133 134 /* Address calculations for metadata located in the inode */ 135 #define S_INDIR(fs) -NDADDR 136 #define D_INDIR(fs) (S_INDIR - NINDIR(fs) - 1) 137 #define T_INDIR(fs) (D_INDIR - NINDIR(fs) * NINDIR(fs) - 1) 138 139 /* Structure used to pass around logical block paths. */ 140 typedef struct _indir { 141 long in_lbn; /* logical block number */ 142 int in_off; /* offset in buffer */ 143 } INDIR; 144 145 /* Unassigned disk address. */ 146 #define UNASSIGNED -1 147 148 typedef struct ifile IFILE; 149 struct ifile { 150 u_long if_version; /* inode version number */ 151 #define LFS_UNUSED_DADDR 0 /* out-of-band daddr */ 152 daddr_t if_daddr; /* inode disk address */ 153 ino_t if_nextfree; /* next-unallocated inode */ 154 }; 155 156 /* 157 * Cleaner information structure. This resides in the ifile and is used 158 * to pass information between the cleaner and the kernel. 159 */ 160 typedef struct _cleanerinfo { 161 u_long clean; /* K: number of clean segments */ 162 u_long dirty; /* K: number of dirty segments */ 163 } CLEANERINFO; 164 165 #define CLEANSIZE_SU(fs) \ 166 ((sizeof(CLEANERINFO) + (fs)->lfs_bsize - 1) >> (fs)->lfs_bshift) 167 168 /* 169 * All summary blocks are the same size, so we can always read a summary 170 * block easily from a segment. 171 */ 172 #define LFS_SUMMARY_SIZE 512 173 174 /* On-disk segment summary information */ 175 typedef struct segsum SEGSUM; 176 struct segsum { 177 u_long ss_sumsum; /* check sum of summary block */ 178 u_long ss_datasum; /* check sum of data */ 179 daddr_t ss_next; /* next segment */ 180 u_long ss_create; /* creation time stamp */ 181 u_long ss_nfinfo; /* number of file info structures */ 182 u_long ss_ninos; /* number of inodes in summary */ 183 /* FINFO's... */ 184 }; 185 186 /* NINDIR is the number of indirects in a file system block. */ 187 #define NINDIR(fs) ((fs)->lfs_nindir) 188 189 /* INOPB is the number of inodes in a secondary storage block. */ 190 #define INOPB(fs) ((fs)->lfs_inopb) 191 192 #define blksize(fs) ((fs)->lfs_bsize) 193 #define blkoff(fs, loc) ((loc) & (fs)->lfs_bmask) 194 #define fsbtodb(fs, b) ((b) << (fs)->lfs_fsbtodb) 195 #define lblkno(fs, loc) ((loc) >> (fs)->lfs_bshift) 196 #define lblktosize(fs, blk) ((blk) << (fs)->lfs_bshift) 197 #define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \ 198 ((loc) >> (fs)->lfs_bshift) 199 200 #define datosn(fs, daddr) /* disk address to segment number */ \ 201 (((daddr) - (fs)->lfs_sboffs[0]) / fsbtodb((fs), (fs)->lfs_ssize)) 202 #define sntoda(fs, sn) /* segment number to disk address */ \ 203 ((daddr_t)((sn) * ((fs)->lfs_ssize << (fs)->lfs_fsbtodb) + \ 204 (fs)->lfs_sboffs[0])) 205 206 /* Read in the block with the cleaner info from the ifile. */ 207 #define LFS_CLEANERINFO(CP, F, BP) { \ 208 VTOI((F)->lfs_ivnode)->i_flag |= IACC; \ 209 if (bread((F)->lfs_ivnode, (daddr_t)0, (F)->lfs_bsize, NOCRED, &(BP))) \ 210 panic("lfs: ifile read"); \ 211 (CP) = (CLEANERINFO *)(BP)->b_un.b_addr; \ 212 } 213 214 /* Read in the block with a specific inode from the ifile. */ 215 #define LFS_IENTRY(IP, F, IN, BP) { \ 216 VTOI((F)->lfs_ivnode)->i_flag |= IACC; \ 217 if (bread((F)->lfs_ivnode, \ 218 (IN) / (F)->lfs_ifpb + (F)->lfs_cleansz + (F)->lfs_segtabsz, \ 219 (F)->lfs_bsize, NOCRED, &(BP))) \ 220 panic("lfs: ifile read"); \ 221 (IP) = (IFILE *)(BP)->b_un.b_addr + (IN) % (F)->lfs_ifpb; \ 222 } 223 224 /* Read in the block with a specific segment usage entry from the ifile. */ 225 #define LFS_SEGENTRY(SP, F, IN, BP) { \ 226 VTOI((F)->lfs_ivnode)->i_flag |= IACC; \ 227 if (bread((F)->lfs_ivnode, (IN) / (F)->lfs_sepb + (F)->lfs_cleansz, \ 228 (F)->lfs_bsize, NOCRED, &(BP))) \ 229 panic("lfs: ifile read"); \ 230 (SP) = (SEGUSE *)(BP)->b_un.b_addr + (IN) % (F)->lfs_sepb; \ 231 } 232 233 /* Write a block and update the inode change times. */ 234 #define LFS_UBWRITE(BP) { \ 235 VTOI((BP)->b_vp)->i_flag |= ICHG | IUPD; \ 236 lfs_bwrite(BP); \ 237 } 238 239 /* 240 * Structures used by lfs_bmapv and lfs_markv to communicate information 241 * about inodes and data blocks. 242 */ 243 typedef struct block_info { 244 ino_t bi_inode; /* inode # */ 245 off_t bi_lbn; /* logical block w/in file */ 246 daddr_t bi_daddr; /* disk address of block */ 247 time_t bi_segcreate; /* origin segment create time */ 248 void *bi_bp; /* data buffer */ 249 } BLOCK_INFO; 250 251 typedef struct inode_info { 252 ino_t ii_inode; /* inode # */ 253 daddr_t ii_daddr; /* disk address of block */ 254 time_t ii_segcreate; /* origin segment create time */ 255 struct dinode *ii_dinode; /* data buffer */ 256 } INODE_INFO; 257