151139Sbostic /*- 251139Sbostic * Copyright (c) 1991 The Regents of the University of California. 351139Sbostic * All rights reserved. 451139Sbostic * 551139Sbostic * %sccs.include.redist.c% 651139Sbostic * 7*53146Sbostic * @(#)lfs.h 7.12 (Berkeley) 04/08/92 851139Sbostic */ 951139Sbostic 1051140Sbostic #define LFS_LABELPAD 8192 /* LFS label size */ 1151140Sbostic #define LFS_SBPAD 8192 /* LFS superblock size */ 1251140Sbostic #define MAXMNTLEN 512 /* XXX move from fs.h to mount.h */ 1351139Sbostic 1451155Sbostic /* On-disk and in-memory checkpoint segment usage structure. */ 1551183Sbostic typedef struct segusage SEGUSE; 1651183Sbostic struct segusage { 1751155Sbostic u_long su_nbytes; /* number of live bytes */ 1851350Sbostic u_long su_lastmod; /* SEGUSE last modified timestamp */ 1951912Sbostic #define SEGUSE_ACTIVE 0x1 /* segment is currently being written */ 2051912Sbostic #define SEGUSE_DIRTY 0x2 /* segment has data in it */ 2151912Sbostic #define SEGUSE_SUPERBLOCK 0x4 /* segment contains a superblock */ 2251155Sbostic u_long su_flags; 2351183Sbostic }; 2451155Sbostic 2551850Sbostic #define SEGTABSIZE_SU(fs) \ 2651850Sbostic (((fs)->lfs_nseg * sizeof(SEGUSE) + \ 2751850Sbostic ((fs)->lfs_bsize - 1)) >> (fs)->lfs_bshift) 2851850Sbostic 2951183Sbostic /* On-disk file information. One per file with data blocks in the segment. */ 3051183Sbostic typedef struct finfo FINFO; 3151183Sbostic struct finfo { 3251183Sbostic u_long fi_nblocks; /* number of blocks */ 3351183Sbostic u_long fi_version; /* version number */ 3451215Sbostic u_long fi_ino; /* inode number */ 3551183Sbostic long fi_blocks[1]; /* array of logical block numbers */ 3651183Sbostic }; 3751183Sbostic 3851155Sbostic /* On-disk and in-memory super block. */ 3951183Sbostic struct lfs { 4052149Sbostic #define LFS_MAGIC 0x070162 4151139Sbostic u_long lfs_magic; /* magic number */ 4251140Sbostic #define LFS_VERSION 1 4351139Sbostic u_long lfs_version; /* version number */ 4451139Sbostic 4551139Sbostic u_long lfs_size; /* number of blocks in fs */ 4651139Sbostic u_long lfs_ssize; /* number of blocks per segment */ 4751139Sbostic u_long lfs_dsize; /* number of data blocks in fs */ 4851139Sbostic u_long lfs_bsize; /* size of basic blocks in fs */ 4951139Sbostic u_long lfs_fsize; /* size of frag blocks in fs */ 5051139Sbostic u_long lfs_frag; /* number of frags in a block in fs */ 5151139Sbostic 5251139Sbostic /* Checkpoint region. */ 5351139Sbostic ino_t lfs_free; /* start of the free list */ 5451155Sbostic u_long lfs_bfree; /* number of free blocks */ 5551155Sbostic u_long lfs_nfiles; /* number of allocated inodes */ 5651139Sbostic daddr_t lfs_idaddr; /* inode file disk address */ 5751139Sbostic ino_t lfs_ifile; /* inode file inode number */ 5851303Sbostic daddr_t lfs_lastseg; /* address of last segment written */ 5951303Sbostic daddr_t lfs_nextseg; /* address of next segment to write */ 6051912Sbostic daddr_t lfs_curseg; /* current segment being written */ 6151850Sbostic daddr_t lfs_offset; /* offset in curseg for next partial */ 6251139Sbostic u_long lfs_tstamp; /* time stamp */ 6351139Sbostic 6451139Sbostic /* These are configuration parameters. */ 6551139Sbostic u_long lfs_minfree; /* minimum percentage of free blocks */ 6651139Sbostic 6751139Sbostic /* These fields can be computed from the others. */ 6851850Sbostic u_long lfs_dbpseg; /* disk blocks per segment */ 6951139Sbostic u_long lfs_inopb; /* inodes per block */ 7051139Sbostic u_long lfs_ifpb; /* IFILE entries per block */ 7151850Sbostic u_long lfs_sepb; /* SEGUSE entries per block */ 7251139Sbostic u_long lfs_nindir; /* indirect pointers per block */ 7351139Sbostic u_long lfs_nseg; /* number of segments */ 7451139Sbostic u_long lfs_nspf; /* number of sectors per fragment */ 7551850Sbostic u_long lfs_cleansz; /* cleaner info size in blocks */ 7651139Sbostic u_long lfs_segtabsz; /* segment table size in blocks */ 7751139Sbostic 7851139Sbostic u_long lfs_segmask; /* calculate offset within a segment */ 7951139Sbostic u_long lfs_segshift; /* fast mult/div for segments */ 8051139Sbostic u_long lfs_bmask; /* calc block offset from file offset */ 8151139Sbostic u_long lfs_bshift; /* calc block number from file offset */ 8251139Sbostic u_long lfs_ffmask; /* calc frag offset from file offset */ 8351139Sbostic u_long lfs_ffshift; /* fast mult/div for frag from file */ 8451139Sbostic u_long lfs_fbmask; /* calc frag offset from block offset */ 8551139Sbostic u_long lfs_fbshift; /* fast mult/div for frag from block */ 8651139Sbostic u_long lfs_fsbtodb; /* fsbtodb and dbtofsb shift constant */ 8751139Sbostic 8851155Sbostic #define LFS_MIN_SBINTERVAL 5 /* minimum superblock segment spacing */ 8951155Sbostic #define LFS_MAXNUMSB 10 /* superblock disk offsets */ 9051155Sbostic daddr_t lfs_sboffs[LFS_MAXNUMSB]; 9151139Sbostic 9251155Sbostic /* These fields are set at mount time and are meaningless on disk. */ 93*53146Sbostic struct vnode *lfs_ivnode; /* vnode for the ifile */ 9451155Sbostic SEGUSE *lfs_segtab; /* in-memory segment usage table */ 9551850Sbostic /* XXX NOT USED */ 9651850Sbostic void *XXXlfs_seglist; /* list of segments being written */ 9751303Sbostic u_long lfs_iocount; /* number of ios pending */ 9851155Sbostic u_char lfs_fmod; /* super block modified flag */ 9951155Sbostic u_char lfs_clean; /* file system is clean flag */ 10051155Sbostic u_char lfs_ronly; /* mounted read-only flag */ 10151155Sbostic u_char lfs_flags; /* currently unused flag */ 10251155Sbostic u_char lfs_fsmnt[MAXMNTLEN]; /* name mounted on */ 10351155Sbostic u_char pad[3]; /* long-align */ 10451139Sbostic 10551155Sbostic /* Checksum; valid on disk. */ 10651155Sbostic u_long lfs_cksum; /* checksum for superblock checking */ 10751183Sbostic }; 10851139Sbostic 10951155Sbostic /* 11052079Sbostic * Inode 0 is the out-of-band inode number, inode 1 is the inode number for 11152079Sbostic * the IFILE, the root inode is 2 and the lost+found inode is 3. 11251155Sbostic */ 11351139Sbostic 11451140Sbostic /* Fixed inode numbers. */ 11551303Sbostic #define LFS_UNUSED_INUM 0 /* out of band inode number */ 11652079Sbostic #define LFS_IFILE_INUM 1 /* IFILE inode number */ 11752079Sbostic #define LOSTFOUNDINO 3 /* lost+found inode number */ 11852079Sbostic #define LFS_FIRST_INUM 4 /* first free inode number */ 11951139Sbostic 12051155Sbostic /* 12151140Sbostic * Used to access the first spare of the dinode which we use to store 12251140Sbostic * the ifile number so we can identify them 12351140Sbostic */ 12451140Sbostic #define di_inum di_spare[0] 12551140Sbostic 12651850Sbostic /* Address calculations for metadata located in the inode */ 12751850Sbostic #define S_INDIR(fs) -NDADDR 12852997Sstaelin #define D_INDIR(fs) (S_INDIR(fs) - NINDIR(fs) - 1) 12952997Sstaelin #define T_INDIR(fs) (D_INDIR(fs) - NINDIR(fs) * NINDIR(fs) - 1) 13051183Sbostic 13151850Sbostic /* Structure used to pass around logical block paths. */ 13251850Sbostic typedef struct _indir { 13351850Sbostic long in_lbn; /* logical block number */ 13451850Sbostic int in_off; /* offset in buffer */ 13551850Sbostic } INDIR; 13651850Sbostic 13751350Sbostic /* Unassigned disk address. */ 13851350Sbostic #define UNASSIGNED -1 13951350Sbostic 14051183Sbostic typedef struct ifile IFILE; 14151183Sbostic struct ifile { 14251139Sbostic u_long if_version; /* inode version number */ 14351155Sbostic #define LFS_UNUSED_DADDR 0 /* out-of-band daddr */ 14451139Sbostic daddr_t if_daddr; /* inode disk address */ 14552079Sbostic ino_t if_nextfree; /* next-unallocated inode */ 14651183Sbostic }; 14751139Sbostic 14851850Sbostic /* 14951850Sbostic * Cleaner information structure. This resides in the ifile and is used 15051850Sbostic * to pass information between the cleaner and the kernel. 15151850Sbostic */ 15251850Sbostic typedef struct _cleanerinfo { 15351850Sbostic u_long clean; /* K: number of clean segments */ 15451850Sbostic u_long dirty; /* K: number of dirty segments */ 15551850Sbostic } CLEANERINFO; 15651139Sbostic 15751850Sbostic #define CLEANSIZE_SU(fs) \ 15851850Sbostic ((sizeof(CLEANERINFO) + (fs)->lfs_bsize - 1) >> (fs)->lfs_bshift) 15951140Sbostic 16051140Sbostic /* 16151140Sbostic * All summary blocks are the same size, so we can always read a summary 16251303Sbostic * block easily from a segment. 16351140Sbostic */ 16451140Sbostic #define LFS_SUMMARY_SIZE 512 16551140Sbostic 16651139Sbostic /* On-disk segment summary information */ 16751183Sbostic typedef struct segsum SEGSUM; 16851183Sbostic struct segsum { 16951850Sbostic u_long ss_sumsum; /* check sum of summary block */ 17051850Sbostic u_long ss_datasum; /* check sum of data */ 17151139Sbostic daddr_t ss_next; /* next segment */ 17251139Sbostic u_long ss_create; /* creation time stamp */ 17351139Sbostic u_long ss_nfinfo; /* number of file info structures */ 17451850Sbostic u_long ss_ninos; /* number of inodes in summary */ 17552993Sbostic /* FINFO's and inode daddr's... */ 17651183Sbostic }; 17751139Sbostic 17851155Sbostic /* NINDIR is the number of indirects in a file system block. */ 17951155Sbostic #define NINDIR(fs) ((fs)->lfs_nindir) 18051155Sbostic 18151155Sbostic /* INOPB is the number of inodes in a secondary storage block. */ 18251155Sbostic #define INOPB(fs) ((fs)->lfs_inopb) 18351155Sbostic 18451155Sbostic #define blksize(fs) ((fs)->lfs_bsize) 18551155Sbostic #define blkoff(fs, loc) ((loc) & (fs)->lfs_bmask) 18651155Sbostic #define fsbtodb(fs, b) ((b) << (fs)->lfs_fsbtodb) 18751155Sbostic #define lblkno(fs, loc) ((loc) >> (fs)->lfs_bshift) 18851155Sbostic #define lblktosize(fs, blk) ((blk) << (fs)->lfs_bshift) 18951183Sbostic #define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \ 19051183Sbostic ((loc) >> (fs)->lfs_bshift) 19151350Sbostic 19252079Sbostic #define datosn(fs, daddr) /* disk address to segment number */ \ 19352079Sbostic (((daddr) - (fs)->lfs_sboffs[0]) / fsbtodb((fs), (fs)->lfs_ssize)) 19452079Sbostic #define sntoda(fs, sn) /* segment number to disk address */ \ 19552079Sbostic ((daddr_t)((sn) * ((fs)->lfs_ssize << (fs)->lfs_fsbtodb) + \ 19652079Sbostic (fs)->lfs_sboffs[0])) 19752079Sbostic 19851925Sbostic /* Read in the block with the cleaner info from the ifile. */ 19951925Sbostic #define LFS_CLEANERINFO(CP, F, BP) { \ 20052079Sbostic VTOI((F)->lfs_ivnode)->i_flag |= IACC; \ 20151936Sbostic if (bread((F)->lfs_ivnode, (daddr_t)0, (F)->lfs_bsize, NOCRED, &(BP))) \ 20251925Sbostic panic("lfs: ifile read"); \ 20351936Sbostic (CP) = (CLEANERINFO *)(BP)->b_un.b_addr; \ 20451925Sbostic } 20551925Sbostic 20651850Sbostic /* Read in the block with a specific inode from the ifile. */ 20751925Sbostic #define LFS_IENTRY(IP, F, IN, BP) { \ 20851936Sbostic VTOI((F)->lfs_ivnode)->i_flag |= IACC; \ 20951850Sbostic if (bread((F)->lfs_ivnode, \ 21051850Sbostic (IN) / (F)->lfs_ifpb + (F)->lfs_cleansz + (F)->lfs_segtabsz, \ 21151936Sbostic (F)->lfs_bsize, NOCRED, &(BP))) \ 21251481Sbostic panic("lfs: ifile read"); \ 21351936Sbostic (IP) = (IFILE *)(BP)->b_un.b_addr + (IN) % (F)->lfs_ifpb; \ 21451481Sbostic } 21551481Sbostic 21651850Sbostic /* Read in the block with a specific segment usage entry from the ifile. */ 21751925Sbostic #define LFS_SEGENTRY(SP, F, IN, BP) { \ 21851936Sbostic VTOI((F)->lfs_ivnode)->i_flag |= IACC; \ 21951850Sbostic if (bread((F)->lfs_ivnode, (IN) / (F)->lfs_sepb + (F)->lfs_cleansz, \ 22051936Sbostic (F)->lfs_bsize, NOCRED, &(BP))) \ 22151850Sbostic panic("lfs: ifile read"); \ 22251936Sbostic (SP) = (SEGUSE *)(BP)->b_un.b_addr + (IN) % (F)->lfs_sepb; \ 22351850Sbostic } 22451850Sbostic 22552079Sbostic /* Write a block and update the inode change times. */ 22652079Sbostic #define LFS_UBWRITE(BP) { \ 22752079Sbostic VTOI((BP)->b_vp)->i_flag |= ICHG | IUPD; \ 22852079Sbostic lfs_bwrite(BP); \ 22951936Sbostic } 23051936Sbostic 23151850Sbostic /* 23251850Sbostic * Structures used by lfs_bmapv and lfs_markv to communicate information 23351850Sbostic * about inodes and data blocks. 23451850Sbostic */ 23551850Sbostic typedef struct block_info { 23651850Sbostic ino_t bi_inode; /* inode # */ 23751850Sbostic off_t bi_lbn; /* logical block w/in file */ 23851850Sbostic daddr_t bi_daddr; /* disk address of block */ 23951850Sbostic time_t bi_segcreate; /* origin segment create time */ 24051850Sbostic void *bi_bp; /* data buffer */ 24151850Sbostic } BLOCK_INFO; 24251850Sbostic 24351850Sbostic typedef struct inode_info { 24451850Sbostic ino_t ii_inode; /* inode # */ 24551850Sbostic daddr_t ii_daddr; /* disk address of block */ 24651850Sbostic time_t ii_segcreate; /* origin segment create time */ 24751850Sbostic struct dinode *ii_dinode; /* data buffer */ 24851850Sbostic } INODE_INFO; 249