1*55491Sbostic /*
2*55491Sbostic  * The LFS user-level library will be used when writing cleaners and
3*55491Sbostic  * checkers for LFS file systems.  It will have facilities
4*55491Sbostic  * for finding and parsing LFS segments.
5*55491Sbostic  */
6*55491Sbostic 
7*55491Sbostic #define IFILE_NAME "ifile"
8*55491Sbostic 
9*55491Sbostic #ifndef TRUE
10*55491Sbostic #define TRUE	(1)
11*55491Sbostic #define FALSE	(0)
12*55491Sbostic #endif
13*55491Sbostic 
14*55491Sbostic typedef struct fs_info {
15*55491Sbostic 	struct	statfs	*fi_statfsp;	/* fsstat info from getfsstat */
16*55491Sbostic 	struct	lfs	*fi_lfsp;	/* superblock */
17*55491Sbostic 					/*
18*55491Sbostic 					 * shared cleaner info data
19*55491Sbostic 					 * (from top of ifile)
20*55491Sbostic 					 */
21*55491Sbostic 	CLEANERINFO	*fi_cip;
22*55491Sbostic 	SEGUSE	*fi_segusep;		/* segment usage table (from ifile) */
23*55491Sbostic 	IFILE	*fi_ifilep;		/* ifile table (from ifile) */
24*55491Sbostic 	u_long	fi_daddr_shift;		/* shift to get byte offset of daddr */
25*55491Sbostic 	u_long	fi_ifile_count;		/* # entries in the ifile table */
26*55491Sbostic 	u_long	fi_ifile_length;	/* length of the ifile */
27*55491Sbostic } FS_INFO;
28*55491Sbostic 
29*55491Sbostic 
30*55491Sbostic #define fsid		(fsp->fi_statfsp->f_fsid)
31*55491Sbostic #define statfsp		(fsp->fi_statfsp)
32*55491Sbostic #define lfsp		(fsp->fi_lfsp)
33*55491Sbostic #define cip		(fsp->fi_cip)
34*55491Sbostic #define segusep		(fsp->fi_segusep)
35*55491Sbostic #define ifilep		(fsp->fi_ifilep)
36*55491Sbostic #define ifile_count	(fsp->fi_ifile_count)
37*55491Sbostic #define ifile_length	(fsp->fi_ifile_length)
38*55491Sbostic 
39*55491Sbostic /*
40*55491Sbostic  * XXX: size (in bytes) of a segment
41*55491Sbostic  *	should lfs_bsize be fsbtodb(fs,1), blksize(fs), or lfs_dsize?
42*55491Sbostic  */
43*55491Sbostic #define seg_size(fs) ((fs)->lfs_ssize<<(fs)->lfs_bshift)
44*55491Sbostic 
45*55491Sbostic /* daddr -> byte offset */
46*55491Sbostic #define datobyte(fs, da) ((da)<<(fs)->fi_daddr_shift)
47*55491Sbostic #define bytetoda(fs, byte) ((byte)>>(fs)->fi_daddr_shift)
48*55491Sbostic 
49*55491Sbostic #define CLEANSIZE(fs)	(CLEANSIZE_SU(fs) << fs->lfs_bshift)
50*55491Sbostic #define SEGTABSIZE(fs)	(SEGTABSIZE_SU(fs) << fs->lfs_bshift)
51*55491Sbostic 
52*55491Sbostic #define IFILE_ENTRY(fs, if, i)	((IFILE*)((caddr_t)(if) + \
53*55491Sbostic 	(fs)->lfs_bsize*((i)/(fs)->lfs_ifpb) + \
54*55491Sbostic 	sizeof(IFILE)*((i)%(fs)->lfs_ifpb)))
55*55491Sbostic #define SEGUSE_ENTRY(fs, su, i) ((SEGUSE*)((caddr_t)(su) + \
56*55491Sbostic 	(fs)->lfs_bsize*((i)/(fs)->lfs_sepb) + \
57*55491Sbostic 	sizeof(IFILE)*((i)%(fs)->lfs_sepb)))
58*55491Sbostic 
59*55491Sbostic /*
60*55491Sbostic  * fs_getmntinfo:
61*55491Sbostic  *
62*55491Sbostic  *    This function will get information on all mounted file systems
63*55491Sbostic  * with the given type.  It will return the number of mounted file
64*55491Sbostic  * systems with the right type.  It will return in *buf a pointer to
65*55491Sbostic  * the array of statfs structures.
66*55491Sbostic  */
67*55491Sbostic extern int
68*55491Sbostic fs_getmntinfo __P((struct statfs **buf, int type));
69*55491Sbostic 
70*55491Sbostic /*
71*55491Sbostic  * get_fs_info:
72*55491Sbostic  *
73*55491Sbostic  * get all the information available on a file system
74*55491Sbostic  */
75*55491Sbostic extern int
76*55491Sbostic get_fs_info __P((struct statfs *lstatfsp, FS_INFO **fspp, int count));
77*55491Sbostic 
78*55491Sbostic extern void
79*55491Sbostic free_fs_info __P((FS_INFO *fsp, int count));
80*55491Sbostic 
81*55491Sbostic /*
82*55491Sbostic  * get_superblock:
83*55491Sbostic  *    gets the superblock from disk (possibly in face of errors)
84*55491Sbostic  */
85*55491Sbostic extern int
86*55491Sbostic get_superblock __P((FS_INFO *fsp, struct lfs *sbp));
87*55491Sbostic 
88*55491Sbostic 
89*55491Sbostic /*
90*55491Sbostic  * get_ifile:
91*55491Sbostic  *    This function will map the ifile into memory.  It returns
92*55491Sbostic  * NULL on failure.
93*55491Sbostic  */
94*55491Sbostic extern int
95*55491Sbostic get_ifile __P((FS_INFO *fsp));
96*55491Sbostic 
97*55491Sbostic /*
98*55491Sbostic  * segmapv:
99*55491Sbostic  *
100*55491Sbostic  *   This function will scan a segment and return a list of
101*55491Sbostic  * <inode, blocknum> pairs which indicate which blocks were
102*55491Sbostic  * contained as live data within the segment at some point
103*55491Sbostic  * (it may have "died" since then).  Any given pair will be
104*55491Sbostic  * listed at most once.
105*55491Sbostic  */
106*55491Sbostic extern int
107*55491Sbostic lfs_segmapv __P((FS_INFO *fsp, int seg, caddr_t seg_buf,
108*55491Sbostic 		BLOCK_INFO **blocks, int *bcount,
109*55491Sbostic 		INODE_INFO **inodes, int *icount));
110*55491Sbostic 
111*55491Sbostic /*
112*55491Sbostic  * this will parse a partial segment and create a vector of block_info's
113*55491Sbostic  * for live data blocks for live inodes.  It will not include blocks or
114*55491Sbostic  * inodes from files with new version numbers.
115*55491Sbostic  */
116*55491Sbostic extern void
117*55491Sbostic pseg_blocks __P((FS_INFO *fsp, int seg, SEGSUM *s, caddr_t seg_buf,
118*55491Sbostic 		BLOCK_INFO **blocks, int *count));
119*55491Sbostic 
120*55491Sbostic /*
121*55491Sbostic  * this will parse a partial segment and create a vector of inode_info's
122*55491Sbostic  * for live inodes.  It will not include blocks or inodes from files
123*55491Sbostic  * with new version numbers.
124*55491Sbostic  */
125*55491Sbostic extern void
126*55491Sbostic pseg_inodes __P((FS_INFO *fsp, int seg, SEGSUM *s, caddr_t seg_buf,
127*55491Sbostic 		INODE_INFO **inodes, int *count));
128*55491Sbostic 
129*55491Sbostic /*
130*55491Sbostic  * return the size of the partial segment in bytes.
131*55491Sbostic  */
132*55491Sbostic extern u_long
133*55491Sbostic pseg_size __P((FS_INFO *fsp, SEGSUM *s));
134*55491Sbostic 
135*55491Sbostic 
136*55491Sbostic /*
137*55491Sbostic  * join block list b with list a (eliminating duplicates), leaving result
138*55491Sbostic  * in list a.
139*55491Sbostic  */
140*55491Sbostic extern void
141*55491Sbostic pseg_bjoin __P((FS_INFO *fsp, BLOCK_INFO **ablocks, int *acount,
142*55491Sbostic 		BLOCK_INFO *bblocks, int bcount));
143*55491Sbostic 
144*55491Sbostic 
145*55491Sbostic /*
146*55491Sbostic  * join inode list b with list a (eliminating duplicates), leaving result
147*55491Sbostic  * in list a.
148*55491Sbostic  */
149*55491Sbostic extern void
150*55491Sbostic pseg_ijoin __P((FS_INFO *fsp, INODE_INFO **ainodes, int *acount,
151*55491Sbostic 		INODE_INFO *binodes, int bcount));
152*55491Sbostic 
153*55491Sbostic 
154*55491Sbostic /* is the segsum block valid? return TRUE if it is, FALSE otherwise */
155*55491Sbostic extern int
156*55491Sbostic segsum_valid __P((FS_INFO *fsp, SEGSUM *ssp));
157*55491Sbostic 
158*55491Sbostic 
159*55491Sbostic /*
160*55491Sbostic  * pseg_valid:
161*55491Sbostic  *
162*55491Sbostic  * returns 1 if the partial segment is valid, and 0 if it is invalid.
163*55491Sbostic  * it uses the checksums to verify validity.
164*55491Sbostic  */
165*55491Sbostic extern int
166*55491Sbostic pseg_valid __P((FS_INFO *fsp, SEGSUM *ssp));
167*55491Sbostic 
168*55491Sbostic 
169*55491Sbostic /*
170*55491Sbostic  * pseg_finfos:
171*55491Sbostic  *
172*55491Sbostic  * get array of FINFO pointers for partial segment
173*55491Sbostic  * return the array in finfos, and the size of the array in count
174*55491Sbostic  */
175*55491Sbostic extern void
176*55491Sbostic pseg_finfos __P((FS_INFO *fsp, SEGSUM *ssp, FINFO ***finfos, int *count));
177*55491Sbostic 
178*55491Sbostic /*
179*55491Sbostic  * blocksize:
180*55491Sbostic  *
181*55491Sbostic  * returns the size (in bytes) of a (logical) block.
182*55491Sbostic  * this is used because lfs uses different block sizes, depending
183*55491Sbostic  * on the logical # of the block.  Lfs uses various sizes so
184*55491Sbostic  * it doesn't need fragments.
185*55491Sbostic  */
186*55491Sbostic extern u_long
187*55491Sbostic blocksize __P((FS_INFO *fsp, int index));
188*55491Sbostic 
189*55491Sbostic /*
190*55491Sbostic  * finfo_size:
191*55491Sbostic  *
192*55491Sbostic  * returns the size in bytes of an FINFO structure
193*55491Sbostic  */
194*55491Sbostic extern u_long
195*55491Sbostic finfo_size __P((FINFO *finfop));
196*55491Sbostic 
197*55491Sbostic /*
198*55491Sbostic  * Simple, general purpose, fast checksum.  Data must be short-aligned.
199*55491Sbostic  * Returns a u_long in case we ever want to do something more rigorous.
200*55491Sbostic  *
201*55491Sbostic  * XXX
202*55491Sbostic  * Use the TCP/IP checksum instead.
203*55491Sbostic  */
204*55491Sbostic extern u_long
205*55491Sbostic cksum __P((register void *str, register size_t len));
206*55491Sbostic 
207*55491Sbostic /*
208*55491Sbostic  * read a segment into a memory buffer
209*55491Sbostic  */
210*55491Sbostic extern int
211*55491Sbostic mmap_segment __P((FS_INFO *fsp, int segment, caddr_t *seg_buf));
212*55491Sbostic 
213*55491Sbostic extern void
214*55491Sbostic munmap_segment __P((FS_INFO *fsp, caddr_t seg_buf));
215*55491Sbostic 
216*55491Sbostic 
217*55491Sbostic /*
218*55491Sbostic  * USEFUL DEBUGGING TOOLS:
219*55491Sbostic  */
220*55491Sbostic 
221*55491Sbostic extern void
222*55491Sbostic print_IFILE __P((IFILE *p));
223*55491Sbostic 
224*55491Sbostic extern void
225*55491Sbostic print_SEGUSE __P((SEGUSE *p));
226*55491Sbostic 
227*55491Sbostic extern void
228*55491Sbostic print_CLEANERINFO __P((CLEANERINFO *p));
229*55491Sbostic 
230*55491Sbostic extern void
231*55491Sbostic print_SEGSUM __P((SEGSUM *p));
232*55491Sbostic 
233*55491Sbostic extern void
234*55491Sbostic print_time_t __P((time_t t));
235*55491Sbostic 
236*55491Sbostic extern void
237*55491Sbostic print_BLOCK_INFO __P((BLOCK_INFO *p));
238*55491Sbostic 
239*55491Sbostic extern void
240*55491Sbostic print_INODE_INFO __P((INODE_INFO *p));
241*55491Sbostic 
242*55491Sbostic extern void
243*55491Sbostic print_FINFO __P((FINFO *p));
244*55491Sbostic 
245*55491Sbostic extern void
246*55491Sbostic print_lfs __P((struct lfs *p));
247*55491Sbostic 
248