151139Sbostic /*- 251139Sbostic * Copyright (c) 1991 The Regents of the University of California. 351139Sbostic * All rights reserved. 451139Sbostic * 551139Sbostic * %sccs.include.redist.c% 651139Sbostic * 7*51481Sbostic * @(#)lfs.h 5.8 (Berkeley) 11/01/91 851139Sbostic */ 951139Sbostic 1051183Sbostic typedef struct buf BUF; 1151183Sbostic typedef struct dinode DINODE; 1251183Sbostic typedef struct inode INODE; 1351183Sbostic typedef struct mount MOUNT; 1451183Sbostic typedef struct ucred UCRED; 1551183Sbostic typedef struct ufsmount UFSMOUNT; 1651183Sbostic typedef struct vnode VNODE; 1751183Sbostic 1851140Sbostic #define LFS_LABELPAD 8192 /* LFS label size */ 1951140Sbostic #define LFS_SBPAD 8192 /* LFS superblock size */ 2051140Sbostic #define MAXMNTLEN 512 /* XXX move from fs.h to mount.h */ 2151139Sbostic 2251155Sbostic /* On-disk and in-memory checkpoint segment usage structure. */ 2351183Sbostic typedef struct segusage SEGUSE; 2451183Sbostic struct segusage { 2551155Sbostic u_long su_nbytes; /* number of live bytes */ 2651350Sbostic u_long su_lastmod; /* SEGUSE last modified timestamp */ 2751183Sbostic #define SEGUSE_DIRTY 0x1 /* XXX fill in comment */ 2851155Sbostic u_long su_flags; 2951183Sbostic }; 3051155Sbostic 3151183Sbostic /* On-disk file information. One per file with data blocks in the segment. */ 3251183Sbostic typedef struct finfo FINFO; 3351183Sbostic struct finfo { 3451183Sbostic u_long fi_nblocks; /* number of blocks */ 3551183Sbostic u_long fi_version; /* version number */ 3651215Sbostic u_long fi_ino; /* inode number */ 3751183Sbostic long fi_blocks[1]; /* array of logical block numbers */ 3851183Sbostic }; 3951183Sbostic 4051183Sbostic /* In-memory description of a segment about to be written */ 4151183Sbostic typedef struct segment SEGMENT; 4251183Sbostic struct segment { 4351303Sbostic SEGMENT *nextp; /* links segments together */ 4451303Sbostic BUF **bpp; /* pointer to buffer array */ 4551303Sbostic BUF **cbpp; /* pointer to next available bp */ 4651303Sbostic BUF *ibp; /* buffer pointer to inode page */ 4751303Sbostic BUF *sbp; /* segment summary buffer pointer */ 4851303Sbostic void *segsum; /* segment Summary info */ 4951303Sbostic u_long seg_bytes_left; /* bytes left in segment */ 5051350Sbostic u_long sum_bytes_left; /* bytes left in summary block */ 5151303Sbostic daddr_t saddr; /* current disk address */ 5251303Sbostic daddr_t sum_addr; /* address of current summary */ 5351303Sbostic u_long ninodes; /* number of inodes in this segment */ 5451350Sbostic u_long nsums; /* number of SEGSUMs in this segment */ 5551303Sbostic u_long seg_number; /* number of this segment */ 5651303Sbostic FINFO *fip; /* current fileinfo pointer */ 5751183Sbostic }; 5851183Sbostic 5951155Sbostic /* On-disk and in-memory super block. */ 6051183Sbostic typedef struct lfs LFS; 6151183Sbostic struct lfs { 6251155Sbostic #define LFS_MAGIC 0xbedead 6351139Sbostic u_long lfs_magic; /* magic number */ 6451140Sbostic #define LFS_VERSION 1 6551139Sbostic u_long lfs_version; /* version number */ 6651139Sbostic 6751139Sbostic u_long lfs_size; /* number of blocks in fs */ 6851139Sbostic u_long lfs_ssize; /* number of blocks per segment */ 6951139Sbostic u_long lfs_dsize; /* number of data blocks in fs */ 7051139Sbostic u_long lfs_bsize; /* size of basic blocks in fs */ 7151139Sbostic u_long lfs_fsize; /* size of frag blocks in fs */ 7251139Sbostic u_long lfs_frag; /* number of frags in a block in fs */ 7351139Sbostic 7451139Sbostic /* Checkpoint region. */ 7551139Sbostic ino_t lfs_free; /* start of the free list */ 7651155Sbostic u_long lfs_bfree; /* number of free blocks */ 7751155Sbostic u_long lfs_nfiles; /* number of allocated inodes */ 7851139Sbostic daddr_t lfs_idaddr; /* inode file disk address */ 7951139Sbostic ino_t lfs_ifile; /* inode file inode number */ 8051303Sbostic daddr_t lfs_lastseg; /* address of last segment written */ 8151303Sbostic daddr_t lfs_nextseg; /* address of next segment to write */ 8251139Sbostic u_long lfs_tstamp; /* time stamp */ 8351139Sbostic 8451139Sbostic /* These are configuration parameters. */ 8551139Sbostic u_long lfs_minfree; /* minimum percentage of free blocks */ 8651139Sbostic 8751139Sbostic /* These fields can be computed from the others. */ 8851139Sbostic u_long lfs_inopb; /* inodes per block */ 8951139Sbostic u_long lfs_ifpb; /* IFILE entries per block */ 9051139Sbostic u_long lfs_nindir; /* indirect pointers per block */ 9151139Sbostic u_long lfs_nseg; /* number of segments */ 9251139Sbostic u_long lfs_nspf; /* number of sectors per fragment */ 9351139Sbostic u_long lfs_segtabsz; /* segment table size in blocks */ 9451139Sbostic 9551139Sbostic u_long lfs_segmask; /* calculate offset within a segment */ 9651139Sbostic u_long lfs_segshift; /* fast mult/div for segments */ 9751139Sbostic u_long lfs_bmask; /* calc block offset from file offset */ 9851139Sbostic u_long lfs_bshift; /* calc block number from file offset */ 9951139Sbostic u_long lfs_ffmask; /* calc frag offset from file offset */ 10051139Sbostic u_long lfs_ffshift; /* fast mult/div for frag from file */ 10151139Sbostic u_long lfs_fbmask; /* calc frag offset from block offset */ 10251139Sbostic u_long lfs_fbshift; /* fast mult/div for frag from block */ 10351139Sbostic u_long lfs_fsbtodb; /* fsbtodb and dbtofsb shift constant */ 10451139Sbostic 10551155Sbostic #define LFS_MIN_SBINTERVAL 5 /* minimum superblock segment spacing */ 10651155Sbostic #define LFS_MAXNUMSB 10 /* superblock disk offsets */ 10751155Sbostic daddr_t lfs_sboffs[LFS_MAXNUMSB]; 10851139Sbostic 10951155Sbostic /* These fields are set at mount time and are meaningless on disk. */ 11051183Sbostic VNODE *lfs_ivnode; /* vnode for the ifile */ 11151155Sbostic SEGUSE *lfs_segtab; /* in-memory segment usage table */ 11251183Sbostic SEGMENT *lfs_seglist; /* list of segments being written */ 11351303Sbostic u_long lfs_iocount; /* number of ios pending */ 11451155Sbostic u_char lfs_fmod; /* super block modified flag */ 11551155Sbostic u_char lfs_clean; /* file system is clean flag */ 11651155Sbostic u_char lfs_ronly; /* mounted read-only flag */ 11751155Sbostic u_char lfs_flags; /* currently unused flag */ 11851155Sbostic u_char lfs_fsmnt[MAXMNTLEN]; /* name mounted on */ 11951155Sbostic u_char pad[3]; /* long-align */ 12051139Sbostic 12151155Sbostic /* Checksum; valid on disk. */ 12251155Sbostic u_long lfs_cksum; /* checksum for superblock checking */ 12351183Sbostic }; 12451139Sbostic 12551155Sbostic /* 12651155Sbostic * The root inode is the root of the file system. Inode 0 is the out-of-band 12751155Sbostic * inode, and inode 1 is the inode number for the ifile. Thus the root inode 12851155Sbostic * is 2. 12951155Sbostic */ 13051155Sbostic #define ROOTINO ((ino_t)2) 13151155Sbostic #define LOSTFOUNDINO ((ino_t)3) 13251139Sbostic 13351140Sbostic /* Fixed inode numbers. */ 13451303Sbostic #define LFS_UNUSED_INUM 0 /* out of band inode number */ 13551303Sbostic #define LFS_IFILE_INUM 1 /* inode number of the ifile */ 13651303Sbostic /* first free inode number */ 13751155Sbostic #define LFS_FIRST_INUM (LOSTFOUNDINO + 1) 13851139Sbostic 13951155Sbostic /* 14051140Sbostic * Used to access the first spare of the dinode which we use to store 14151140Sbostic * the ifile number so we can identify them 14251140Sbostic */ 14351140Sbostic #define di_inum di_spare[0] 14451140Sbostic 14551350Sbostic /* Logical block numbers of indirect blocks. */ 14651183Sbostic #define S_INDIR -1 14751183Sbostic #define D_INDIR -2 14851183Sbostic #define T_INDIR -3 14951183Sbostic 15051350Sbostic /* Unassigned disk address. */ 15151350Sbostic #define UNASSIGNED -1 15251350Sbostic 15351183Sbostic typedef struct ifile IFILE; 15451183Sbostic struct ifile { 15551139Sbostic u_long if_version; /* inode version number */ 15651155Sbostic #define LFS_UNUSED_DADDR 0 /* out-of-band daddr */ 15751139Sbostic daddr_t if_daddr; /* inode disk address */ 15851139Sbostic union { 15951139Sbostic ino_t nextfree; /* next-unallocated inode */ 16051139Sbostic time_t st_atime; /* access time */ 16151139Sbostic } __ifile_u; 16251140Sbostic #define if_st_atime __ifile_u.st_atime 16351140Sbostic #define if_nextfree __ifile_u.nextfree 16451183Sbostic }; 16551139Sbostic 16651139Sbostic /* Segment table size, in blocks. */ 16751139Sbostic #define SEGTABSIZE(fs) \ 16851155Sbostic (((fs)->fs_nseg * sizeof(SEGUSE) + \ 16951155Sbostic ((fs)->fs_bsize - 1)) >> (fs)->fs_bshift) 17051139Sbostic 17151140Sbostic #define SEGTABSIZE_SU(fs) \ 17251155Sbostic (((fs)->lfs_nseg * sizeof(SEGUSE) + \ 17351140Sbostic ((fs)->lfs_bsize - 1)) >> (fs)->lfs_bshift) 17451140Sbostic 17551140Sbostic /* 17651140Sbostic * All summary blocks are the same size, so we can always read a summary 17751303Sbostic * block easily from a segment. 17851140Sbostic */ 17951140Sbostic #define LFS_SUMMARY_SIZE 512 18051140Sbostic 18151139Sbostic /* On-disk segment summary information */ 18251183Sbostic typedef struct segsum SEGSUM; 18351183Sbostic struct segsum { 18451155Sbostic u_long ss_cksum; /* check sum */ 18551139Sbostic daddr_t ss_next; /* next segment */ 18651139Sbostic daddr_t ss_prev; /* next segment */ 18751139Sbostic daddr_t ss_nextsum; /* next summary block */ 18851139Sbostic u_long ss_create; /* creation time stamp */ 18951139Sbostic u_long ss_nfinfo; /* number of file info structures */ 19051155Sbostic u_long ss_ninos; /* number of inode blocks */ 19151155Sbostic /* FINFO's... */ 19251183Sbostic }; 19351139Sbostic 19451155Sbostic /* NINDIR is the number of indirects in a file system block. */ 19551155Sbostic #define NINDIR(fs) ((fs)->lfs_nindir) 19651155Sbostic 19751155Sbostic /* INOPB is the number of inodes in a secondary storage block. */ 19851155Sbostic #define INOPB(fs) ((fs)->lfs_inopb) 19951155Sbostic 20051155Sbostic /* IFPB -- IFILE's per block */ 20151155Sbostic #define IFPB(fs) ((fs)->lfs_ifpb) 20251155Sbostic 20351155Sbostic #define blksize(fs) ((fs)->lfs_bsize) 20451155Sbostic #define blkoff(fs, loc) ((loc) & (fs)->lfs_bmask) 20551155Sbostic #define fsbtodb(fs, b) ((b) << (fs)->lfs_fsbtodb) 20651155Sbostic #define lblkno(fs, loc) ((loc) >> (fs)->lfs_bshift) 20751155Sbostic #define lblktosize(fs, blk) ((blk) << (fs)->lfs_bshift) 20851183Sbostic #define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \ 20951183Sbostic ((loc) >> (fs)->lfs_bshift) 21051350Sbostic 21151350Sbostic #define datosn(fs, daddr) /* disk address to segment number */ \ 21251350Sbostic (((daddr) - (fs)->lfs_sboffs[0]) / fsbtodb((fs), (fs)->lfs_ssize)) 21351350Sbostic #define sntoda(fs, sn) /* segment number to disk address */ \ 21451350Sbostic ((daddr_t)((sn) * ((fs)->lfs_ssize << (fs)->lfs_fsbtodb) + \ 21551350Sbostic (fs)->lfs_sboffs[0])) 216*51481Sbostic 217*51481Sbostic /* Read in the block containing a specific inode from the ifile. */ 218*51481Sbostic #define LFS_IENTRY(I, F, IN, BP) { \ 219*51481Sbostic if (bread((F)->lfs_ivnode, (IN) / IFPB(F) + (F)->lfs_segtabsz, \ 220*51481Sbostic (F)->lfs_bsize, NOCRED, &BP)) \ 221*51481Sbostic panic("lfs: ifile read"); \ 222*51481Sbostic (I) = (IFILE *)BP->b_un.b_addr + IN % IFPB(F); \ 223*51481Sbostic } 224*51481Sbostic 225