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.7 (Berkeley) 12/14/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; /* 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 0xbedead 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, and inode 1 is the inode number for the 119 * ifile. Thus the root inode is 2, and the lost+found inode is 3. 120 */ 121 #define LOSTFOUNDINO ((ino_t)3) 122 123 /* Fixed inode numbers. */ 124 #define LFS_UNUSED_INUM 0 /* out of band inode number */ 125 #define LFS_IFILE_INUM 1 /* inode number of the ifile */ 126 /* first free inode number */ 127 #define LFS_FIRST_INUM (LOSTFOUNDINO + 1) 128 129 /* 130 * Used to access the first spare of the dinode which we use to store 131 * the ifile number so we can identify them 132 */ 133 #define di_inum di_spare[0] 134 135 /* Address calculations for metadata located in the inode */ 136 #define S_INDIR(fs) -NDADDR 137 #define D_INDIR(fs) (S_INDIR - NINDIR(fs) - 1) 138 #define T_INDIR(fs) (D_INDIR - NINDIR(fs) * NINDIR(fs) - 1) 139 140 /* Structure used to pass around logical block paths. */ 141 typedef struct _indir { 142 long in_lbn; /* logical block number */ 143 int in_off; /* offset in buffer */ 144 } INDIR; 145 146 /* Unassigned disk address. */ 147 #define UNASSIGNED -1 148 149 typedef struct ifile IFILE; 150 struct ifile { 151 u_long if_version; /* inode version number */ 152 #define LFS_UNUSED_DADDR 0 /* out-of-band daddr */ 153 daddr_t if_daddr; /* inode disk address */ 154 union { 155 ino_t nextfree; /* next-unallocated inode */ 156 time_t st_atime; /* access time */ 157 } __ifile_u; 158 #define if_st_atime __ifile_u.st_atime 159 #define if_nextfree __ifile_u.nextfree 160 }; 161 162 /* 163 * Cleaner information structure. This resides in the ifile and is used 164 * to pass information between the cleaner and the kernel. 165 */ 166 typedef struct _cleanerinfo { 167 u_long clean; /* K: number of clean segments */ 168 u_long dirty; /* K: number of dirty segments */ 169 } CLEANERINFO; 170 171 #define CLEANSIZE_SU(fs) \ 172 ((sizeof(CLEANERINFO) + (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_sumsum; /* check sum of summary block */ 184 u_long ss_datasum; /* check sum of data */ 185 daddr_t ss_next; /* next segment */ 186 u_long ss_create; /* creation time stamp */ 187 u_long ss_nfinfo; /* number of file info structures */ 188 u_long ss_ninos; /* number of inodes in summary */ 189 /* FINFO's... */ 190 }; 191 192 /* NINDIR is the number of indirects in a file system block. */ 193 #define NINDIR(fs) ((fs)->lfs_nindir) 194 195 /* INOPB is the number of inodes in a secondary storage block. */ 196 #define INOPB(fs) ((fs)->lfs_inopb) 197 198 #define blksize(fs) ((fs)->lfs_bsize) 199 #define blkoff(fs, loc) ((loc) & (fs)->lfs_bmask) 200 #define fsbtodb(fs, b) ((b) << (fs)->lfs_fsbtodb) 201 #define lblkno(fs, loc) ((loc) >> (fs)->lfs_bshift) 202 #define lblktosize(fs, blk) ((blk) << (fs)->lfs_bshift) 203 #define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \ 204 ((loc) >> (fs)->lfs_bshift) 205 206 /* Read in the block with the cleaner info from the ifile. */ 207 #define LFS_CLEANERINFO(CP, F, BP) { \ 208 if (bread((F)->lfs_ivnode, (daddr_t)0, (F)->lfs_bsize, NOCRED, &(BP))) \ 209 panic("lfs: ifile read"); \ 210 (CP) = (CLEANERINFO *)(BP)->b_un.b_addr; \ 211 } 212 213 /* Read in the block with a specific inode from the ifile. */ 214 #define LFS_IENTRY(IP, F, IN, BP) { \ 215 VTOI((F)->lfs_ivnode)->i_flag |= IACC; \ 216 if (bread((F)->lfs_ivnode, \ 217 (IN) / (F)->lfs_ifpb + (F)->lfs_cleansz + (F)->lfs_segtabsz, \ 218 (F)->lfs_bsize, NOCRED, &(BP))) \ 219 panic("lfs: ifile read"); \ 220 (IP) = (IFILE *)(BP)->b_un.b_addr + (IN) % (F)->lfs_ifpb; \ 221 } 222 223 /* Read in the block with a specific segment usage entry from the ifile. */ 224 #define LFS_SEGENTRY(SP, F, IN, BP) { \ 225 VTOI((F)->lfs_ivnode)->i_flag |= IACC; \ 226 if (bread((F)->lfs_ivnode, (IN) / (F)->lfs_sepb + (F)->lfs_cleansz, \ 227 (F)->lfs_bsize, NOCRED, &(BP))) \ 228 panic("lfs: ifile read"); \ 229 (SP) = (SEGUSE *)(BP)->b_un.b_addr + (IN) % (F)->lfs_sepb; \ 230 } 231 232 /* Release the ifile block, updating the access time. */ 233 #define LFS_IRELEASE(F, BP) { \ 234 VTOI((F)->lfs_ivnode)->i_flag |= IACC; \ 235 brelse((BP)); \ 236 } 237 238 /* Release the ifile block, scheduling it for writing. */ 239 #define LFS_IWRITE(F, BP) { \ 240 VTOI((F)->lfs_ivnode)->i_flag |= ICHG | IUPD; \ 241 lfs_bwrite((BP)); \ 242 } 243 244 /* 245 * Structures used by lfs_bmapv and lfs_markv to communicate information 246 * about inodes and data blocks. 247 */ 248 typedef struct block_info { 249 ino_t bi_inode; /* inode # */ 250 off_t bi_lbn; /* logical block w/in file */ 251 daddr_t bi_daddr; /* disk address of block */ 252 time_t bi_segcreate; /* origin segment create time */ 253 void *bi_bp; /* data buffer */ 254 } BLOCK_INFO; 255 256 typedef struct inode_info { 257 ino_t ii_inode; /* inode # */ 258 daddr_t ii_daddr; /* disk address of block */ 259 time_t ii_segcreate; /* origin segment create time */ 260 struct dinode *ii_dinode; /* data buffer */ 261 } INODE_INFO; 262