151139Sbostic /*- 251139Sbostic * Copyright (c) 1991 The Regents of the University of California. 351139Sbostic * All rights reserved. 451139Sbostic * 551139Sbostic * %sccs.include.redist.c% 651139Sbostic * 7*55546Sbostic * @(#)lfs.h 7.17 (Berkeley) 07/22/92 851139Sbostic */ 951139Sbostic 1051140Sbostic #define LFS_LABELPAD 8192 /* LFS label size */ 1151140Sbostic #define LFS_SBPAD 8192 /* LFS superblock size */ 1251139Sbostic 13*55546Sbostic /* 14*55546Sbostic * XXX 15*55546Sbostic * This is a kluge and NEEDS to go away. 16*55546Sbostic * 17*55546Sbostic * Right now, ufs code handles most of the calls for directory operations 18*55546Sbostic * such as create, mkdir, link, etc. As a result VOP_UPDATE is being 19*55546Sbostic * called with waitfor set (since ffs does these things synchronously). 20*55546Sbostic * Since LFS does not want to do these synchronously, we treat the last 21*55546Sbostic * argument to lfs_update as a set of flags. If LFS_SYNC is set, then 22*55546Sbostic * the update should be synchronous, if not, do it asynchronously. 23*55546Sbostic * Unfortunately, this means that LFS won't work with NFS yet because 24*55546Sbostic * NFS goes through paths that will make normal calls to ufs which will 25*55546Sbostic * call lfs with a last argument of 1. 26*55546Sbostic */ 27*55546Sbostic #define LFS_SYNC 0x02 28*55546Sbostic 2951155Sbostic /* On-disk and in-memory checkpoint segment usage structure. */ 3051183Sbostic typedef struct segusage SEGUSE; 3151183Sbostic struct segusage { 3251155Sbostic u_long su_nbytes; /* number of live bytes */ 3351350Sbostic u_long su_lastmod; /* SEGUSE last modified timestamp */ 3451912Sbostic #define SEGUSE_ACTIVE 0x1 /* segment is currently being written */ 3551912Sbostic #define SEGUSE_DIRTY 0x2 /* segment has data in it */ 3651912Sbostic #define SEGUSE_SUPERBLOCK 0x4 /* segment contains a superblock */ 3754264Sbostic #define SEGUSE_LIVELOG 0x8 /* segment has not been checkpointed */ 3851155Sbostic u_long su_flags; 3951183Sbostic }; 4051155Sbostic 4151850Sbostic #define SEGTABSIZE_SU(fs) \ 4251850Sbostic (((fs)->lfs_nseg * sizeof(SEGUSE) + \ 4351850Sbostic ((fs)->lfs_bsize - 1)) >> (fs)->lfs_bshift) 4451850Sbostic 4551183Sbostic /* On-disk file information. One per file with data blocks in the segment. */ 4651183Sbostic typedef struct finfo FINFO; 4751183Sbostic struct finfo { 4851183Sbostic u_long fi_nblocks; /* number of blocks */ 4951183Sbostic u_long fi_version; /* version number */ 5051215Sbostic u_long fi_ino; /* inode number */ 5151183Sbostic long fi_blocks[1]; /* array of logical block numbers */ 5251183Sbostic }; 5351183Sbostic 5451155Sbostic /* On-disk and in-memory super block. */ 5551183Sbostic struct lfs { 5652149Sbostic #define LFS_MAGIC 0x070162 5751139Sbostic u_long lfs_magic; /* magic number */ 5851140Sbostic #define LFS_VERSION 1 5951139Sbostic u_long lfs_version; /* version number */ 6051139Sbostic 6151139Sbostic u_long lfs_size; /* number of blocks in fs */ 6251139Sbostic u_long lfs_ssize; /* number of blocks per segment */ 6351139Sbostic u_long lfs_dsize; /* number of data blocks in fs */ 6451139Sbostic u_long lfs_bsize; /* size of basic blocks in fs */ 6551139Sbostic u_long lfs_fsize; /* size of frag blocks in fs */ 6651139Sbostic u_long lfs_frag; /* number of frags in a block in fs */ 6751139Sbostic 6851139Sbostic /* Checkpoint region. */ 6951139Sbostic ino_t lfs_free; /* start of the free list */ 7051155Sbostic u_long lfs_bfree; /* number of free blocks */ 7151155Sbostic u_long lfs_nfiles; /* number of allocated inodes */ 7251139Sbostic daddr_t lfs_idaddr; /* inode file disk address */ 7351139Sbostic ino_t lfs_ifile; /* inode file inode number */ 7451303Sbostic daddr_t lfs_lastseg; /* address of last segment written */ 7551303Sbostic daddr_t lfs_nextseg; /* address of next segment to write */ 7651912Sbostic daddr_t lfs_curseg; /* current segment being written */ 7751850Sbostic daddr_t lfs_offset; /* offset in curseg for next partial */ 7854264Sbostic daddr_t lfs_lastpseg; /* address of last partial written */ 7951139Sbostic u_long lfs_tstamp; /* time stamp */ 8051139Sbostic 8151139Sbostic /* These are configuration parameters. */ 8251139Sbostic u_long lfs_minfree; /* minimum percentage of free blocks */ 8351139Sbostic 8451139Sbostic /* These fields can be computed from the others. */ 8555454Sbostic u_quad_t lfs_maxfilesize; /* maximum representable file size */ 8651850Sbostic u_long lfs_dbpseg; /* disk blocks per segment */ 8751139Sbostic u_long lfs_inopb; /* inodes per block */ 8851139Sbostic u_long lfs_ifpb; /* IFILE entries per block */ 8951850Sbostic u_long lfs_sepb; /* SEGUSE 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 */ 9351850Sbostic u_long lfs_cleansz; /* cleaner info size in blocks */ 9451139Sbostic u_long lfs_segtabsz; /* segment table size in blocks */ 9551139Sbostic 9651139Sbostic u_long lfs_segmask; /* calculate offset within a segment */ 9751139Sbostic u_long lfs_segshift; /* fast mult/div for segments */ 9851139Sbostic u_long lfs_bmask; /* calc block offset from file offset */ 9951139Sbostic u_long lfs_bshift; /* calc block number from file offset */ 10051139Sbostic u_long lfs_ffmask; /* calc frag offset from file offset */ 10151139Sbostic u_long lfs_ffshift; /* fast mult/div for frag from file */ 10251139Sbostic u_long lfs_fbmask; /* calc frag offset from block offset */ 10351139Sbostic u_long lfs_fbshift; /* fast mult/div for frag from block */ 10451139Sbostic u_long lfs_fsbtodb; /* fsbtodb and dbtofsb shift constant */ 10551139Sbostic 10651155Sbostic #define LFS_MIN_SBINTERVAL 5 /* minimum superblock segment spacing */ 10751155Sbostic #define LFS_MAXNUMSB 10 /* superblock disk offsets */ 10851155Sbostic daddr_t lfs_sboffs[LFS_MAXNUMSB]; 10951139Sbostic 11051155Sbostic /* These fields are set at mount time and are meaningless on disk. */ 11153146Sbostic struct vnode *lfs_ivnode; /* vnode for the ifile */ 11254685Sbostic u_long lfs_seglock; /* single-thread the segment writer */ 11351303Sbostic u_long lfs_iocount; /* number of ios pending */ 11454264Sbostic u_long lfs_writer; /* don't allow any dirops to start */ 11554264Sbostic u_long lfs_dirops; /* count of active directory ops */ 11654264Sbostic u_long lfs_doifile; /* Write ifile blocks on next write */ 11751155Sbostic u_char lfs_fmod; /* super block modified flag */ 11851155Sbostic u_char lfs_clean; /* file system is clean flag */ 11951155Sbostic u_char lfs_ronly; /* mounted read-only flag */ 12051155Sbostic u_char lfs_flags; /* currently unused flag */ 12154685Sbostic u_char lfs_fsmnt[MNAMELEN]; /* name mounted on */ 12251155Sbostic u_char pad[3]; /* long-align */ 12351139Sbostic 12451155Sbostic /* Checksum; valid on disk. */ 12551155Sbostic u_long lfs_cksum; /* checksum for superblock checking */ 12651183Sbostic }; 12751139Sbostic 12851155Sbostic /* 12952079Sbostic * Inode 0 is the out-of-band inode number, inode 1 is the inode number for 13052079Sbostic * the IFILE, the root inode is 2 and the lost+found inode is 3. 13151155Sbostic */ 13251139Sbostic 13351140Sbostic /* Fixed inode numbers. */ 13451303Sbostic #define LFS_UNUSED_INUM 0 /* out of band inode number */ 13552079Sbostic #define LFS_IFILE_INUM 1 /* IFILE inode number */ 13652079Sbostic #define LOSTFOUNDINO 3 /* lost+found inode number */ 13752079Sbostic #define LFS_FIRST_INUM 4 /* first free inode number */ 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 14551850Sbostic /* Address calculations for metadata located in the inode */ 14651850Sbostic #define S_INDIR(fs) -NDADDR 14752997Sstaelin #define D_INDIR(fs) (S_INDIR(fs) - NINDIR(fs) - 1) 14852997Sstaelin #define T_INDIR(fs) (D_INDIR(fs) - NINDIR(fs) * NINDIR(fs) - 1) 14951183Sbostic 15051850Sbostic /* Structure used to pass around logical block paths. */ 15151850Sbostic typedef struct _indir { 15251850Sbostic long in_lbn; /* logical block number */ 15351850Sbostic int in_off; /* offset in buffer */ 15451850Sbostic } INDIR; 15551850Sbostic 15651350Sbostic /* Unassigned disk address. */ 15751350Sbostic #define UNASSIGNED -1 15851350Sbostic 15951183Sbostic typedef struct ifile IFILE; 16051183Sbostic struct ifile { 16151139Sbostic u_long if_version; /* inode version number */ 16251155Sbostic #define LFS_UNUSED_DADDR 0 /* out-of-band daddr */ 16351139Sbostic daddr_t if_daddr; /* inode disk address */ 16452079Sbostic ino_t if_nextfree; /* next-unallocated inode */ 16551183Sbostic }; 16651139Sbostic 16751850Sbostic /* 16851850Sbostic * Cleaner information structure. This resides in the ifile and is used 16951850Sbostic * to pass information between the cleaner and the kernel. 17051850Sbostic */ 17151850Sbostic typedef struct _cleanerinfo { 17251850Sbostic u_long clean; /* K: number of clean segments */ 17351850Sbostic u_long dirty; /* K: number of dirty segments */ 17451850Sbostic } CLEANERINFO; 17551139Sbostic 17651850Sbostic #define CLEANSIZE_SU(fs) \ 17751850Sbostic ((sizeof(CLEANERINFO) + (fs)->lfs_bsize - 1) >> (fs)->lfs_bshift) 17851140Sbostic 17951140Sbostic /* 18051140Sbostic * All summary blocks are the same size, so we can always read a summary 18151303Sbostic * block easily from a segment. 18251140Sbostic */ 18351140Sbostic #define LFS_SUMMARY_SIZE 512 18451140Sbostic 18551139Sbostic /* On-disk segment summary information */ 18651183Sbostic typedef struct segsum SEGSUM; 18751183Sbostic struct segsum { 18851850Sbostic u_long ss_sumsum; /* check sum of summary block */ 18951850Sbostic u_long ss_datasum; /* check sum of data */ 19051139Sbostic daddr_t ss_next; /* next segment */ 19151139Sbostic u_long ss_create; /* creation time stamp */ 19254264Sbostic u_short ss_nfinfo; /* number of file info structures */ 19354264Sbostic u_short ss_ninos; /* number of inodes in summary */ 19454264Sbostic #define SS_DIROP 0x01 /* segment begins a dirop */ 19554264Sbostic #define SS_CONT 0x02 /* more partials to finish this write*/ 19654264Sbostic u_short ss_flags; /* used for directory operations */ 19754264Sbostic u_short ss_pad; /* extra space */ 19852993Sbostic /* FINFO's and inode daddr's... */ 19951183Sbostic }; 20051139Sbostic 20151155Sbostic /* NINDIR is the number of indirects in a file system block. */ 20251155Sbostic #define NINDIR(fs) ((fs)->lfs_nindir) 20351155Sbostic 20451155Sbostic /* INOPB is the number of inodes in a secondary storage block. */ 20551155Sbostic #define INOPB(fs) ((fs)->lfs_inopb) 20651155Sbostic 20751155Sbostic #define blksize(fs) ((fs)->lfs_bsize) 20851155Sbostic #define blkoff(fs, loc) ((loc) & (fs)->lfs_bmask) 20951155Sbostic #define fsbtodb(fs, b) ((b) << (fs)->lfs_fsbtodb) 21051155Sbostic #define lblkno(fs, loc) ((loc) >> (fs)->lfs_bshift) 21151155Sbostic #define lblktosize(fs, blk) ((blk) << (fs)->lfs_bshift) 21251183Sbostic #define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \ 21351183Sbostic ((loc) >> (fs)->lfs_bshift) 21451350Sbostic 21552079Sbostic #define datosn(fs, daddr) /* disk address to segment number */ \ 21652079Sbostic (((daddr) - (fs)->lfs_sboffs[0]) / fsbtodb((fs), (fs)->lfs_ssize)) 21752079Sbostic #define sntoda(fs, sn) /* segment number to disk address */ \ 21852079Sbostic ((daddr_t)((sn) * ((fs)->lfs_ssize << (fs)->lfs_fsbtodb) + \ 21952079Sbostic (fs)->lfs_sboffs[0])) 22052079Sbostic 22151925Sbostic /* Read in the block with the cleaner info from the ifile. */ 22251925Sbostic #define LFS_CLEANERINFO(CP, F, BP) { \ 22352079Sbostic VTOI((F)->lfs_ivnode)->i_flag |= IACC; \ 22451936Sbostic if (bread((F)->lfs_ivnode, (daddr_t)0, (F)->lfs_bsize, NOCRED, &(BP))) \ 22551925Sbostic panic("lfs: ifile read"); \ 22651936Sbostic (CP) = (CLEANERINFO *)(BP)->b_un.b_addr; \ 22751925Sbostic } 22851925Sbostic 22951850Sbostic /* Read in the block with a specific inode from the ifile. */ 23051925Sbostic #define LFS_IENTRY(IP, F, IN, BP) { \ 23151936Sbostic VTOI((F)->lfs_ivnode)->i_flag |= IACC; \ 23251850Sbostic if (bread((F)->lfs_ivnode, \ 23351850Sbostic (IN) / (F)->lfs_ifpb + (F)->lfs_cleansz + (F)->lfs_segtabsz, \ 23451936Sbostic (F)->lfs_bsize, NOCRED, &(BP))) \ 23551481Sbostic panic("lfs: ifile read"); \ 23651936Sbostic (IP) = (IFILE *)(BP)->b_un.b_addr + (IN) % (F)->lfs_ifpb; \ 23751481Sbostic } 23851481Sbostic 23951850Sbostic /* Read in the block with a specific segment usage entry from the ifile. */ 24051925Sbostic #define LFS_SEGENTRY(SP, F, IN, BP) { \ 24151936Sbostic VTOI((F)->lfs_ivnode)->i_flag |= IACC; \ 24251850Sbostic if (bread((F)->lfs_ivnode, (IN) / (F)->lfs_sepb + (F)->lfs_cleansz, \ 24351936Sbostic (F)->lfs_bsize, NOCRED, &(BP))) \ 24451850Sbostic panic("lfs: ifile read"); \ 24551936Sbostic (SP) = (SEGUSE *)(BP)->b_un.b_addr + (IN) % (F)->lfs_sepb; \ 24651850Sbostic } 24751850Sbostic 24852079Sbostic /* Write a block and update the inode change times. */ 24952079Sbostic #define LFS_UBWRITE(BP) { \ 25052079Sbostic VTOI((BP)->b_vp)->i_flag |= ICHG | IUPD; \ 25153499Sheideman VOP_BWRITE(BP); \ 25251936Sbostic } 25351936Sbostic 25451850Sbostic /* 25551850Sbostic * Structures used by lfs_bmapv and lfs_markv to communicate information 25651850Sbostic * about inodes and data blocks. 25751850Sbostic */ 25851850Sbostic typedef struct block_info { 25951850Sbostic ino_t bi_inode; /* inode # */ 26051850Sbostic off_t bi_lbn; /* logical block w/in file */ 26151850Sbostic daddr_t bi_daddr; /* disk address of block */ 26251850Sbostic time_t bi_segcreate; /* origin segment create time */ 26351850Sbostic void *bi_bp; /* data buffer */ 26451850Sbostic } BLOCK_INFO; 26551850Sbostic 26651850Sbostic typedef struct inode_info { 26751850Sbostic ino_t ii_inode; /* inode # */ 26851850Sbostic daddr_t ii_daddr; /* disk address of block */ 26951850Sbostic time_t ii_segcreate; /* origin segment create time */ 27051850Sbostic struct dinode *ii_dinode; /* data buffer */ 27151850Sbostic } INODE_INFO; 272