151139Sbostic /*- 251139Sbostic * Copyright (c) 1991 The Regents of the University of California. 351139Sbostic * All rights reserved. 451139Sbostic * 551139Sbostic * %sccs.include.redist.c% 651139Sbostic * 7*52997Sstaelin * @(#)lfs.h 7.11 (Berkeley) 03/18/92 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 */ 2751912Sbostic #define SEGUSE_ACTIVE 0x1 /* segment is currently being written */ 2851912Sbostic #define SEGUSE_DIRTY 0x2 /* segment has data in it */ 2951912Sbostic #define SEGUSE_SUPERBLOCK 0x4 /* segment contains a superblock */ 3051155Sbostic u_long su_flags; 3151183Sbostic }; 3251155Sbostic 3351850Sbostic #define SEGTABSIZE_SU(fs) \ 3451850Sbostic (((fs)->lfs_nseg * sizeof(SEGUSE) + \ 3551850Sbostic ((fs)->lfs_bsize - 1)) >> (fs)->lfs_bshift) 3651850Sbostic 3751183Sbostic /* On-disk file information. One per file with data blocks in the segment. */ 3851183Sbostic typedef struct finfo FINFO; 3951183Sbostic struct finfo { 4051183Sbostic u_long fi_nblocks; /* number of blocks */ 4151183Sbostic u_long fi_version; /* version number */ 4251215Sbostic u_long fi_ino; /* inode number */ 4351183Sbostic long fi_blocks[1]; /* array of logical block numbers */ 4451183Sbostic }; 4551183Sbostic 4651155Sbostic /* On-disk and in-memory super block. */ 4751183Sbostic struct lfs { 4852149Sbostic #define LFS_MAGIC 0x070162 4951139Sbostic u_long lfs_magic; /* magic number */ 5051140Sbostic #define LFS_VERSION 1 5151139Sbostic u_long lfs_version; /* version number */ 5251139Sbostic 5351139Sbostic u_long lfs_size; /* number of blocks in fs */ 5451139Sbostic u_long lfs_ssize; /* number of blocks per segment */ 5551139Sbostic u_long lfs_dsize; /* number of data blocks in fs */ 5651139Sbostic u_long lfs_bsize; /* size of basic blocks in fs */ 5751139Sbostic u_long lfs_fsize; /* size of frag blocks in fs */ 5851139Sbostic u_long lfs_frag; /* number of frags in a block in fs */ 5951139Sbostic 6051139Sbostic /* Checkpoint region. */ 6151139Sbostic ino_t lfs_free; /* start of the free list */ 6251155Sbostic u_long lfs_bfree; /* number of free blocks */ 6351155Sbostic u_long lfs_nfiles; /* number of allocated inodes */ 6451139Sbostic daddr_t lfs_idaddr; /* inode file disk address */ 6551139Sbostic ino_t lfs_ifile; /* inode file inode number */ 6651303Sbostic daddr_t lfs_lastseg; /* address of last segment written */ 6751303Sbostic daddr_t lfs_nextseg; /* address of next segment to write */ 6851912Sbostic daddr_t lfs_curseg; /* current segment being written */ 6951850Sbostic daddr_t lfs_offset; /* offset in curseg for next partial */ 7051139Sbostic u_long lfs_tstamp; /* time stamp */ 7151139Sbostic 7251139Sbostic /* These are configuration parameters. */ 7351139Sbostic u_long lfs_minfree; /* minimum percentage of free blocks */ 7451139Sbostic 7551139Sbostic /* These fields can be computed from the others. */ 7651850Sbostic u_long lfs_dbpseg; /* disk blocks per segment */ 7751139Sbostic u_long lfs_inopb; /* inodes per block */ 7851139Sbostic u_long lfs_ifpb; /* IFILE entries per block */ 7951850Sbostic u_long lfs_sepb; /* SEGUSE entries per block */ 8051139Sbostic u_long lfs_nindir; /* indirect pointers per block */ 8151139Sbostic u_long lfs_nseg; /* number of segments */ 8251139Sbostic u_long lfs_nspf; /* number of sectors per fragment */ 8351850Sbostic u_long lfs_cleansz; /* cleaner info size in blocks */ 8451139Sbostic u_long lfs_segtabsz; /* segment table size in blocks */ 8551139Sbostic 8651139Sbostic u_long lfs_segmask; /* calculate offset within a segment */ 8751139Sbostic u_long lfs_segshift; /* fast mult/div for segments */ 8851139Sbostic u_long lfs_bmask; /* calc block offset from file offset */ 8951139Sbostic u_long lfs_bshift; /* calc block number from file offset */ 9051139Sbostic u_long lfs_ffmask; /* calc frag offset from file offset */ 9151139Sbostic u_long lfs_ffshift; /* fast mult/div for frag from file */ 9251139Sbostic u_long lfs_fbmask; /* calc frag offset from block offset */ 9351139Sbostic u_long lfs_fbshift; /* fast mult/div for frag from block */ 9451139Sbostic u_long lfs_fsbtodb; /* fsbtodb and dbtofsb shift constant */ 9551139Sbostic 9651155Sbostic #define LFS_MIN_SBINTERVAL 5 /* minimum superblock segment spacing */ 9751155Sbostic #define LFS_MAXNUMSB 10 /* superblock disk offsets */ 9851155Sbostic daddr_t lfs_sboffs[LFS_MAXNUMSB]; 9951139Sbostic 10051155Sbostic /* These fields are set at mount time and are meaningless on disk. */ 10151183Sbostic VNODE *lfs_ivnode; /* vnode for the ifile */ 10251155Sbostic SEGUSE *lfs_segtab; /* in-memory segment usage table */ 10351850Sbostic /* XXX NOT USED */ 10451850Sbostic void *XXXlfs_seglist; /* list of segments being written */ 10551303Sbostic u_long lfs_iocount; /* number of ios pending */ 10651155Sbostic u_char lfs_fmod; /* super block modified flag */ 10751155Sbostic u_char lfs_clean; /* file system is clean flag */ 10851155Sbostic u_char lfs_ronly; /* mounted read-only flag */ 10951155Sbostic u_char lfs_flags; /* currently unused flag */ 11051155Sbostic u_char lfs_fsmnt[MAXMNTLEN]; /* name mounted on */ 11151155Sbostic u_char pad[3]; /* long-align */ 11251139Sbostic 11351155Sbostic /* Checksum; valid on disk. */ 11451155Sbostic u_long lfs_cksum; /* checksum for superblock checking */ 11551183Sbostic }; 11651139Sbostic 11751155Sbostic /* 11852079Sbostic * Inode 0 is the out-of-band inode number, inode 1 is the inode number for 11952079Sbostic * the IFILE, the root inode is 2 and the lost+found inode is 3. 12051155Sbostic */ 12151139Sbostic 12251140Sbostic /* Fixed inode numbers. */ 12351303Sbostic #define LFS_UNUSED_INUM 0 /* out of band inode number */ 12452079Sbostic #define LFS_IFILE_INUM 1 /* IFILE inode number */ 12552079Sbostic #define LOSTFOUNDINO 3 /* lost+found inode number */ 12652079Sbostic #define LFS_FIRST_INUM 4 /* first free inode number */ 12751139Sbostic 12851155Sbostic /* 12951140Sbostic * Used to access the first spare of the dinode which we use to store 13051140Sbostic * the ifile number so we can identify them 13151140Sbostic */ 13251140Sbostic #define di_inum di_spare[0] 13351140Sbostic 13451850Sbostic /* Address calculations for metadata located in the inode */ 13551850Sbostic #define S_INDIR(fs) -NDADDR 136*52997Sstaelin #define D_INDIR(fs) (S_INDIR(fs) - NINDIR(fs) - 1) 137*52997Sstaelin #define T_INDIR(fs) (D_INDIR(fs) - NINDIR(fs) * NINDIR(fs) - 1) 13851183Sbostic 13951850Sbostic /* Structure used to pass around logical block paths. */ 14051850Sbostic typedef struct _indir { 14151850Sbostic long in_lbn; /* logical block number */ 14251850Sbostic int in_off; /* offset in buffer */ 14351850Sbostic } INDIR; 14451850Sbostic 14551350Sbostic /* Unassigned disk address. */ 14651350Sbostic #define UNASSIGNED -1 14751350Sbostic 14851183Sbostic typedef struct ifile IFILE; 14951183Sbostic struct ifile { 15051139Sbostic u_long if_version; /* inode version number */ 15151155Sbostic #define LFS_UNUSED_DADDR 0 /* out-of-band daddr */ 15251139Sbostic daddr_t if_daddr; /* inode disk address */ 15352079Sbostic ino_t if_nextfree; /* next-unallocated inode */ 15451183Sbostic }; 15551139Sbostic 15651850Sbostic /* 15751850Sbostic * Cleaner information structure. This resides in the ifile and is used 15851850Sbostic * to pass information between the cleaner and the kernel. 15951850Sbostic */ 16051850Sbostic typedef struct _cleanerinfo { 16151850Sbostic u_long clean; /* K: number of clean segments */ 16251850Sbostic u_long dirty; /* K: number of dirty segments */ 16351850Sbostic } CLEANERINFO; 16451139Sbostic 16551850Sbostic #define CLEANSIZE_SU(fs) \ 16651850Sbostic ((sizeof(CLEANERINFO) + (fs)->lfs_bsize - 1) >> (fs)->lfs_bshift) 16751140Sbostic 16851140Sbostic /* 16951140Sbostic * All summary blocks are the same size, so we can always read a summary 17051303Sbostic * block easily from a segment. 17151140Sbostic */ 17251140Sbostic #define LFS_SUMMARY_SIZE 512 17351140Sbostic 17451139Sbostic /* On-disk segment summary information */ 17551183Sbostic typedef struct segsum SEGSUM; 17651183Sbostic struct segsum { 17751850Sbostic u_long ss_sumsum; /* check sum of summary block */ 17851850Sbostic u_long ss_datasum; /* check sum of data */ 17951139Sbostic daddr_t ss_next; /* next segment */ 18051139Sbostic u_long ss_create; /* creation time stamp */ 18151139Sbostic u_long ss_nfinfo; /* number of file info structures */ 18251850Sbostic u_long ss_ninos; /* number of inodes in summary */ 18352993Sbostic /* FINFO's and inode daddr's... */ 18451183Sbostic }; 18551139Sbostic 18651155Sbostic /* NINDIR is the number of indirects in a file system block. */ 18751155Sbostic #define NINDIR(fs) ((fs)->lfs_nindir) 18851155Sbostic 18951155Sbostic /* INOPB is the number of inodes in a secondary storage block. */ 19051155Sbostic #define INOPB(fs) ((fs)->lfs_inopb) 19151155Sbostic 19251155Sbostic #define blksize(fs) ((fs)->lfs_bsize) 19351155Sbostic #define blkoff(fs, loc) ((loc) & (fs)->lfs_bmask) 19451155Sbostic #define fsbtodb(fs, b) ((b) << (fs)->lfs_fsbtodb) 19551155Sbostic #define lblkno(fs, loc) ((loc) >> (fs)->lfs_bshift) 19651155Sbostic #define lblktosize(fs, blk) ((blk) << (fs)->lfs_bshift) 19751183Sbostic #define numfrags(fs, loc) /* calculates (loc / fs->fs_fsize) */ \ 19851183Sbostic ((loc) >> (fs)->lfs_bshift) 19951350Sbostic 20052079Sbostic #define datosn(fs, daddr) /* disk address to segment number */ \ 20152079Sbostic (((daddr) - (fs)->lfs_sboffs[0]) / fsbtodb((fs), (fs)->lfs_ssize)) 20252079Sbostic #define sntoda(fs, sn) /* segment number to disk address */ \ 20352079Sbostic ((daddr_t)((sn) * ((fs)->lfs_ssize << (fs)->lfs_fsbtodb) + \ 20452079Sbostic (fs)->lfs_sboffs[0])) 20552079Sbostic 20651925Sbostic /* Read in the block with the cleaner info from the ifile. */ 20751925Sbostic #define LFS_CLEANERINFO(CP, F, BP) { \ 20852079Sbostic VTOI((F)->lfs_ivnode)->i_flag |= IACC; \ 20951936Sbostic if (bread((F)->lfs_ivnode, (daddr_t)0, (F)->lfs_bsize, NOCRED, &(BP))) \ 21051925Sbostic panic("lfs: ifile read"); \ 21151936Sbostic (CP) = (CLEANERINFO *)(BP)->b_un.b_addr; \ 21251925Sbostic } 21351925Sbostic 21451850Sbostic /* Read in the block with a specific inode from the ifile. */ 21551925Sbostic #define LFS_IENTRY(IP, F, IN, BP) { \ 21651936Sbostic VTOI((F)->lfs_ivnode)->i_flag |= IACC; \ 21751850Sbostic if (bread((F)->lfs_ivnode, \ 21851850Sbostic (IN) / (F)->lfs_ifpb + (F)->lfs_cleansz + (F)->lfs_segtabsz, \ 21951936Sbostic (F)->lfs_bsize, NOCRED, &(BP))) \ 22051481Sbostic panic("lfs: ifile read"); \ 22151936Sbostic (IP) = (IFILE *)(BP)->b_un.b_addr + (IN) % (F)->lfs_ifpb; \ 22251481Sbostic } 22351481Sbostic 22451850Sbostic /* Read in the block with a specific segment usage entry from the ifile. */ 22551925Sbostic #define LFS_SEGENTRY(SP, F, IN, BP) { \ 22651936Sbostic VTOI((F)->lfs_ivnode)->i_flag |= IACC; \ 22751850Sbostic if (bread((F)->lfs_ivnode, (IN) / (F)->lfs_sepb + (F)->lfs_cleansz, \ 22851936Sbostic (F)->lfs_bsize, NOCRED, &(BP))) \ 22951850Sbostic panic("lfs: ifile read"); \ 23051936Sbostic (SP) = (SEGUSE *)(BP)->b_un.b_addr + (IN) % (F)->lfs_sepb; \ 23151850Sbostic } 23251850Sbostic 23352079Sbostic /* Write a block and update the inode change times. */ 23452079Sbostic #define LFS_UBWRITE(BP) { \ 23552079Sbostic VTOI((BP)->b_vp)->i_flag |= ICHG | IUPD; \ 23652079Sbostic lfs_bwrite(BP); \ 23751936Sbostic } 23851936Sbostic 23951850Sbostic /* 24051850Sbostic * Structures used by lfs_bmapv and lfs_markv to communicate information 24151850Sbostic * about inodes and data blocks. 24251850Sbostic */ 24351850Sbostic typedef struct block_info { 24451850Sbostic ino_t bi_inode; /* inode # */ 24551850Sbostic off_t bi_lbn; /* logical block w/in file */ 24651850Sbostic daddr_t bi_daddr; /* disk address of block */ 24751850Sbostic time_t bi_segcreate; /* origin segment create time */ 24851850Sbostic void *bi_bp; /* data buffer */ 24951850Sbostic } BLOCK_INFO; 25051850Sbostic 25151850Sbostic typedef struct inode_info { 25251850Sbostic ino_t ii_inode; /* inode # */ 25351850Sbostic daddr_t ii_daddr; /* disk address of block */ 25451850Sbostic time_t ii_segcreate; /* origin segment create time */ 25551850Sbostic struct dinode *ii_dinode; /* data buffer */ 25651850Sbostic } INODE_INFO; 257