root / lab4 / .minix-src / include / ufs / lfs / lfs.h @ 14
History | View | Annotate | Download (47.3 KB)
1 | 13 | up20180614 | /* $NetBSD: lfs.h,v 1.194 2015/10/03 08:29:34 dholland Exp $ */
|
---|---|---|---|
2 | |||
3 | /* from NetBSD: dinode.h,v 1.22 2013/01/22 09:39:18 dholland Exp */
|
||
4 | /* from NetBSD: dir.h,v 1.21 2009/07/22 04:49:19 dholland Exp */
|
||
5 | |||
6 | /*-
|
||
7 | * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
|
||
8 | * All rights reserved.
|
||
9 | *
|
||
10 | * This code is derived from software contributed to The NetBSD Foundation
|
||
11 | * by Konrad E. Schroder <perseant@hhhh.org>.
|
||
12 | *
|
||
13 | * Redistribution and use in source and binary forms, with or without
|
||
14 | * modification, are permitted provided that the following conditions
|
||
15 | * are met:
|
||
16 | * 1. Redistributions of source code must retain the above copyright
|
||
17 | * notice, this list of conditions and the following disclaimer.
|
||
18 | * 2. Redistributions in binary form must reproduce the above copyright
|
||
19 | * notice, this list of conditions and the following disclaimer in the
|
||
20 | * documentation and/or other materials provided with the distribution.
|
||
21 | *
|
||
22 | * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||
23 | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||
24 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||
25 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||
26 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||
27 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||
28 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||
29 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||
30 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||
31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||
32 | * POSSIBILITY OF SUCH DAMAGE.
|
||
33 | */
|
||
34 | /*-
|
||
35 | * Copyright (c) 1991, 1993
|
||
36 | * The Regents of the University of California. All rights reserved.
|
||
37 | *
|
||
38 | * Redistribution and use in source and binary forms, with or without
|
||
39 | * modification, are permitted provided that the following conditions
|
||
40 | * are met:
|
||
41 | * 1. Redistributions of source code must retain the above copyright
|
||
42 | * notice, this list of conditions and the following disclaimer.
|
||
43 | * 2. Redistributions in binary form must reproduce the above copyright
|
||
44 | * notice, this list of conditions and the following disclaimer in the
|
||
45 | * documentation and/or other materials provided with the distribution.
|
||
46 | * 3. Neither the name of the University nor the names of its contributors
|
||
47 | * may be used to endorse or promote products derived from this software
|
||
48 | * without specific prior written permission.
|
||
49 | *
|
||
50 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||
51 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
52 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
53 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||
54 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
55 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||
56 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
57 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
58 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||
59 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
60 | * SUCH DAMAGE.
|
||
61 | *
|
||
62 | * @(#)lfs.h 8.9 (Berkeley) 5/8/95
|
||
63 | */
|
||
64 | /*
|
||
65 | * Copyright (c) 2002 Networks Associates Technology, Inc.
|
||
66 | * All rights reserved.
|
||
67 | *
|
||
68 | * This software was developed for the FreeBSD Project by Marshall
|
||
69 | * Kirk McKusick and Network Associates Laboratories, the Security
|
||
70 | * Research Division of Network Associates, Inc. under DARPA/SPAWAR
|
||
71 | * contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA CHATS
|
||
72 | * research program
|
||
73 | *
|
||
74 | * Copyright (c) 1982, 1989, 1993
|
||
75 | * The Regents of the University of California. All rights reserved.
|
||
76 | * (c) UNIX System Laboratories, Inc.
|
||
77 | * All or some portions of this file are derived from material licensed
|
||
78 | * to the University of California by American Telephone and Telegraph
|
||
79 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||
80 | * the permission of UNIX System Laboratories, Inc.
|
||
81 | *
|
||
82 | * Redistribution and use in source and binary forms, with or without
|
||
83 | * modification, are permitted provided that the following conditions
|
||
84 | * are met:
|
||
85 | * 1. Redistributions of source code must retain the above copyright
|
||
86 | * notice, this list of conditions and the following disclaimer.
|
||
87 | * 2. Redistributions in binary form must reproduce the above copyright
|
||
88 | * notice, this list of conditions and the following disclaimer in the
|
||
89 | * documentation and/or other materials provided with the distribution.
|
||
90 | * 3. Neither the name of the University nor the names of its contributors
|
||
91 | * may be used to endorse or promote products derived from this software
|
||
92 | * without specific prior written permission.
|
||
93 | *
|
||
94 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||
95 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
96 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
97 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||
98 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
99 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||
100 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
101 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
102 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||
103 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
104 | * SUCH DAMAGE.
|
||
105 | *
|
||
106 | * @(#)dinode.h 8.9 (Berkeley) 3/29/95
|
||
107 | */
|
||
108 | /*
|
||
109 | * Copyright (c) 1982, 1986, 1989, 1993
|
||
110 | * The Regents of the University of California. All rights reserved.
|
||
111 | * (c) UNIX System Laboratories, Inc.
|
||
112 | * All or some portions of this file are derived from material licensed
|
||
113 | * to the University of California by American Telephone and Telegraph
|
||
114 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||
115 | * the permission of UNIX System Laboratories, Inc.
|
||
116 | *
|
||
117 | * Redistribution and use in source and binary forms, with or without
|
||
118 | * modification, are permitted provided that the following conditions
|
||
119 | * are met:
|
||
120 | * 1. Redistributions of source code must retain the above copyright
|
||
121 | * notice, this list of conditions and the following disclaimer.
|
||
122 | * 2. Redistributions in binary form must reproduce the above copyright
|
||
123 | * notice, this list of conditions and the following disclaimer in the
|
||
124 | * documentation and/or other materials provided with the distribution.
|
||
125 | * 3. Neither the name of the University nor the names of its contributors
|
||
126 | * may be used to endorse or promote products derived from this software
|
||
127 | * without specific prior written permission.
|
||
128 | *
|
||
129 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||
130 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
131 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
132 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||
133 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
134 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||
135 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
136 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
137 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||
138 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
139 | * SUCH DAMAGE.
|
||
140 | *
|
||
141 | * @(#)dir.h 8.5 (Berkeley) 4/27/95
|
||
142 | */
|
||
143 | |||
144 | /*
|
||
145 | * NOTE: COORDINATE ON-DISK FORMAT CHANGES WITH THE FREEBSD PROJECT.
|
||
146 | */
|
||
147 | |||
148 | #ifndef _UFS_LFS_LFS_H_
|
||
149 | #define _UFS_LFS_LFS_H_
|
||
150 | |||
151 | #if !defined(_KERNEL) && !defined(_STANDALONE)
|
||
152 | #include <stddef.h> /* for offsetof */ |
||
153 | #endif
|
||
154 | |||
155 | #include <sys/rwlock.h> |
||
156 | #include <sys/mutex.h> |
||
157 | #include <sys/queue.h> |
||
158 | #include <sys/condvar.h> |
||
159 | #include <sys/mount.h> |
||
160 | #include <sys/pool.h> |
||
161 | |||
162 | /*
|
||
163 | * Compile-time options for LFS.
|
||
164 | */
|
||
165 | #define LFS_IFIND_RETRIES 16 |
||
166 | #define LFS_LOGLENGTH 1024 /* size of debugging log */ |
||
167 | #define LFS_MAX_ACTIVE 10 /* Dirty segments before ckp forced */ |
||
168 | |||
169 | /*
|
||
170 | * Fixed filesystem layout parameters
|
||
171 | */
|
||
172 | #define LFS_LABELPAD 8192 /* LFS label size */ |
||
173 | #define LFS_SBPAD 8192 /* LFS superblock size */ |
||
174 | |||
175 | #define LFS_UNUSED_INUM 0 /* 0: out of band inode number */ |
||
176 | #define LFS_IFILE_INUM 1 /* 1: IFILE inode number */ |
||
177 | /* 2: Root inode number */
|
||
178 | #define LFS_LOSTFOUNDINO 3 /* 3: lost+found inode number */ |
||
179 | #define LFS_FIRST_INUM 4 /* 4: first free inode number */ |
||
180 | |||
181 | /*
|
||
182 | * The root inode is the root of the file system. Inode 0 can't be used for
|
||
183 | * normal purposes and historically bad blocks were linked to inode 1, thus
|
||
184 | * the root inode is 2. (Inode 1 is no longer used for this purpose, however
|
||
185 | * numerous dump tapes make this assumption, so we are stuck with it).
|
||
186 | */
|
||
187 | #define ULFS_ROOTINO ((ino_t)2) |
||
188 | |||
189 | /*
|
||
190 | * The Whiteout inode# is a dummy non-zero inode number which will
|
||
191 | * never be allocated to a real file. It is used as a place holder
|
||
192 | * in the directory entry which has been tagged as a LFS_DT_WHT entry.
|
||
193 | * See the comments about ULFS_ROOTINO above.
|
||
194 | */
|
||
195 | #define ULFS_WINO ((ino_t)1) |
||
196 | |||
197 | |||
198 | #define LFS_V1_SUMMARY_SIZE 512 /* V1 fixed summary size */ |
||
199 | #define LFS_DFL_SUMMARY_SIZE 512 /* Default summary size */ |
||
200 | |||
201 | #define LFS_MAXNAMLEN 255 /* maximum name length in a dir */ |
||
202 | |||
203 | #define ULFS_NXADDR 2 |
||
204 | #define ULFS_NDADDR 12 /* Direct addresses in inode. */ |
||
205 | #define ULFS_NIADDR 3 /* Indirect addresses in inode. */ |
||
206 | |||
207 | /*
|
||
208 | * Adjustable filesystem parameters
|
||
209 | */
|
||
210 | #ifndef LFS_ATIME_IFILE
|
||
211 | # define LFS_ATIME_IFILE 0 /* Store atime info in ifile (optional in LFSv1) */ |
||
212 | #endif
|
||
213 | #define LFS_MARKV_MAXBLKCNT 65536 /* Max block count for lfs_markv() */ |
||
214 | |||
215 | /*
|
||
216 | * Directories
|
||
217 | */
|
||
218 | |||
219 | /*
|
||
220 | * Directories in LFS are files; they use the same inode and block
|
||
221 | * mapping structures that regular files do. The directory per se is
|
||
222 | * manifested in the file contents: an unordered, unstructured
|
||
223 | * sequence of variable-size directory entries.
|
||
224 | *
|
||
225 | * This format and structure is taken (via what was originally shared
|
||
226 | * ufs-level code) from FFS. Each directory entry is a fixed header
|
||
227 | * followed by a string, the total length padded to a 4-byte boundary.
|
||
228 | * All strings include a null terminator; the maximum string length
|
||
229 | * is LFS_MAXNAMLEN, which is 255.
|
||
230 | *
|
||
231 | * The directory entry header structure (struct lfs_dirheader) is just
|
||
232 | * the header information. A complete entry is this plus a null-
|
||
233 | * terminated name following it, plus some amount of padding. The
|
||
234 | * length of the name (not including the null terminator) is given by
|
||
235 | * the namlen field of the header; the complete record length,
|
||
236 | * including the null terminator and padding, is given by the reclen
|
||
237 | * field of the header. The record length is always 4-byte aligned.
|
||
238 | * (Even on 64-bit volumes, the record length is only 4-byte aligned,
|
||
239 | * not 8-byte.)
|
||
240 | *
|
||
241 | * Historically, FFS directories were/are organized into blocks of
|
||
242 | * size DIRBLKSIZE that can be written atomically to disk at the
|
||
243 | * hardware level. Directory entries are not allowed to cross the
|
||
244 | * boundaries of these blocks. The resulting atomicity is important
|
||
245 | * for the integrity of FFS volumes; however, for LFS it's irrelevant.
|
||
246 | * All we have to care about is not writing out directories that
|
||
247 | * confuse earlier ufs-based versions of the LFS code.
|
||
248 | *
|
||
249 | * This means [to be determined]. (XXX)
|
||
250 | *
|
||
251 | * As DIRBLKSIZE in its FFS sense is hardware-dependent, and file
|
||
252 | * system images do from time to time move to different hardware, code
|
||
253 | * that reads directories should be prepared to handle directories
|
||
254 | * written in a context where DIRBLKSIZE was different (smaller or
|
||
255 | * larger) than its current value. Note however that it is not
|
||
256 | * sensible for DIRBLKSIZE to be larger than the volume fragment size,
|
||
257 | * and not practically possible for it to be larger than the volume
|
||
258 | * block size.
|
||
259 | *
|
||
260 | * Some further notes:
|
||
261 | * - the LFS_DIRSIZ macro provides the minimum space needed to hold
|
||
262 | * a directory entry.
|
||
263 | * - any particular entry may be arbitrarily larger (which is why the
|
||
264 | * header stores both the entry size and the name size) to pad out
|
||
265 | * unused space.
|
||
266 | * - historically the padding in an entry is not necessarily zeroed
|
||
267 | * but may contain trash.
|
||
268 | * - dp->d_reclen is the size of the entry. This is always 4-byte
|
||
269 | * aligned.
|
||
270 | * - dp->d_namlen is the length of the string, and should always be
|
||
271 | * the same as strlen(dp->d_name).
|
||
272 | * - in particular, space available in an entry is given by
|
||
273 | * dp->d_reclen - LFS_DIRSIZ(dp), and all space available within a
|
||
274 | * directory block is tucked away within an existing entry.
|
||
275 | * - all space within a directory block is part of some entry.
|
||
276 | * - therefore, inserting a new entry requires finding and
|
||
277 | * splitting a suitable existing entry, and when entries are
|
||
278 | * removed their space is merged into the entry ahead of them.
|
||
279 | * - an empty/unused entry has d_ino set to 0. This normally only
|
||
280 | * appears in the first entry in a block, as elsewhere the unused
|
||
281 | * entry should have been merged into the one before it. However,
|
||
282 | * fsck leaves such entries behind so they must be tolerated
|
||
283 | * elsewhere.
|
||
284 | * - a completely empty directory block has one entry whose
|
||
285 | * d_reclen is DIRBLKSIZ and whose d_ino is 0.
|
||
286 | *
|
||
287 | * The "old directory format" referenced by the fs->lfs_isolddirfmt
|
||
288 | * flag (and some other things) refers to when the type field was
|
||
289 | * added to directory entries. This change was made to FFS in the 80s,
|
||
290 | * well before LFS was first written; there should be no LFS volumes
|
||
291 | * (and certainly no LFS v2-format volumes or LFS64 volumes) where the
|
||
292 | * old format pertains. All of the related logic should probably be
|
||
293 | * removed; however, it hasn't been yet, and we get to carry it around
|
||
294 | * until we can be conclusively sure it isn't needed.
|
||
295 | *
|
||
296 | * In the "old directory format" there is no type field and the namlen
|
||
297 | * field is correspondingly 16 bits wide. On big-endian volumes this
|
||
298 | * has no effect: namlen cannot exceed 255, so the upper byte is
|
||
299 | * always 0 and this reads back from the type field as LFS_DT_UNKNOWN.
|
||
300 | * On little-endian volumes, the namlen field will always be 0 and
|
||
301 | * the namlen value needs to be read out of the type field. (The type
|
||
302 | * is always LFS_DT_UNKNOWN.) The directory accessor functions take
|
||
303 | * care of this so nothing else needs to be aware of it.
|
||
304 | *
|
||
305 | * LFS_OLDDIRFMT and LFS_NEWDIRFMT are code numbers for the old and
|
||
306 | * new directory format respectively. These codes do not appear on
|
||
307 | * disk; they're generated from a runtime macro called FSFMT() that's
|
||
308 | * cued by other things. This is why (confusingly) LFS_OLDDIRFMT is 1
|
||
309 | * and LFS_NEWDIRFMT is 0.
|
||
310 | *
|
||
311 | * FSFMT(), LFS_OLDDIRFMT, and LFS_NEWDIRFMT should be removed. (XXX)
|
||
312 | */
|
||
313 | |||
314 | /*
|
||
315 | * Directory block size.
|
||
316 | */
|
||
317 | #undef LFS_DIRBLKSIZ
|
||
318 | #define LFS_DIRBLKSIZ DEV_BSIZE
|
||
319 | |||
320 | /*
|
||
321 | * Convert between stat structure type codes and directory entry type codes.
|
||
322 | */
|
||
323 | #define LFS_IFTODT(mode) (((mode) & 0170000) >> 12) |
||
324 | #define LFS_DTTOIF(dirtype) ((dirtype) << 12) |
||
325 | |||
326 | /*
|
||
327 | * Theoretically, directories can be more than 2Gb in length; however, in
|
||
328 | * practice this seems unlikely. So, we define the type doff_t as a 32-bit
|
||
329 | * quantity to keep down the cost of doing lookup on a 32-bit machine.
|
||
330 | */
|
||
331 | #define doff_t int32_t
|
||
332 | #define lfs_doff_t int32_t
|
||
333 | #define LFS_MAXDIRSIZE (0x7fffffff) |
||
334 | |||
335 | /*
|
||
336 | * File types for d_type
|
||
337 | */
|
||
338 | #define LFS_DT_UNKNOWN 0 |
||
339 | #define LFS_DT_FIFO 1 |
||
340 | #define LFS_DT_CHR 2 |
||
341 | #define LFS_DT_DIR 4 |
||
342 | #define LFS_DT_BLK 6 |
||
343 | #define LFS_DT_REG 8 |
||
344 | #define LFS_DT_LNK 10 |
||
345 | #define LFS_DT_SOCK 12 |
||
346 | #define LFS_DT_WHT 14 |
||
347 | |||
348 | /*
|
||
349 | * (See notes above)
|
||
350 | */
|
||
351 | |||
352 | struct lfs_dirheader32 {
|
||
353 | u_int32_t dh_ino; /* inode number of entry */
|
||
354 | u_int16_t dh_reclen; /* length of this record */
|
||
355 | u_int8_t dh_type; /* file type, see below */
|
||
356 | u_int8_t dh_namlen; /* length of string in d_name */
|
||
357 | }; |
||
358 | |||
359 | struct lfs_dirheader64 {
|
||
360 | u_int32_t dh_inoA; /* inode number of entry */
|
||
361 | u_int32_t dh_inoB; /* inode number of entry */
|
||
362 | u_int16_t dh_reclen; /* length of this record */
|
||
363 | u_int8_t dh_type; /* file type, see below */
|
||
364 | u_int8_t dh_namlen; /* length of string in d_name */
|
||
365 | }; |
||
366 | |||
367 | union lfs_dirheader {
|
||
368 | struct lfs_dirheader64 u_64;
|
||
369 | struct lfs_dirheader32 u_32;
|
||
370 | }; |
||
371 | |||
372 | typedef union lfs_dirheader LFS_DIRHEADER; |
||
373 | |||
374 | /*
|
||
375 | * Template for manipulating directories.
|
||
376 | */
|
||
377 | |||
378 | struct lfs_dirtemplate32 {
|
||
379 | struct lfs_dirheader32 dot_header;
|
||
380 | char dot_name[4]; /* must be multiple of 4 */ |
||
381 | struct lfs_dirheader32 dotdot_header;
|
||
382 | char dotdot_name[4]; /* ditto */ |
||
383 | }; |
||
384 | |||
385 | struct lfs_dirtemplate64 {
|
||
386 | struct lfs_dirheader64 dot_header;
|
||
387 | char dot_name[4]; /* must be multiple of 4 */ |
||
388 | struct lfs_dirheader64 dotdot_header;
|
||
389 | char dotdot_name[4]; /* ditto */ |
||
390 | }; |
||
391 | |||
392 | union lfs_dirtemplate {
|
||
393 | struct lfs_dirtemplate64 u_64;
|
||
394 | struct lfs_dirtemplate32 u_32;
|
||
395 | }; |
||
396 | |||
397 | #if 0
|
||
398 | /*
|
||
399 | * This is the old format of directories, sans type element.
|
||
400 | */
|
||
401 | struct lfs_odirtemplate {
|
||
402 | u_int32_t dot_ino;
|
||
403 | int16_t dot_reclen;
|
||
404 | u_int16_t dot_namlen;
|
||
405 | char dot_name[4]; /* must be multiple of 4 */
|
||
406 | u_int32_t dotdot_ino;
|
||
407 | int16_t dotdot_reclen;
|
||
408 | u_int16_t dotdot_namlen;
|
||
409 | char dotdot_name[4]; /* ditto */
|
||
410 | };
|
||
411 | #endif
|
||
412 | |||
413 | /*
|
||
414 | * Inodes
|
||
415 | */
|
||
416 | |||
417 | /*
|
||
418 | * A dinode contains all the meta-data associated with a LFS file.
|
||
419 | * This structure defines the on-disk format of a dinode. Since
|
||
420 | * this structure describes an on-disk structure, all its fields
|
||
421 | * are defined by types with precise widths.
|
||
422 | */
|
||
423 | |||
424 | struct lfs32_dinode {
|
||
425 | u_int16_t di_mode; /* 0: IFMT, permissions; see below. */
|
||
426 | int16_t di_nlink; /* 2: File link count. */
|
||
427 | u_int32_t di_inumber; /* 4: Inode number. */
|
||
428 | u_int64_t di_size; /* 8: File byte count. */
|
||
429 | int32_t di_atime; /* 16: Last access time. */
|
||
430 | int32_t di_atimensec; /* 20: Last access time. */
|
||
431 | int32_t di_mtime; /* 24: Last modified time. */
|
||
432 | int32_t di_mtimensec; /* 28: Last modified time. */
|
||
433 | int32_t di_ctime; /* 32: Last inode change time. */
|
||
434 | int32_t di_ctimensec; /* 36: Last inode change time. */
|
||
435 | int32_t di_db[ULFS_NDADDR]; /* 40: Direct disk blocks. */
|
||
436 | int32_t di_ib[ULFS_NIADDR]; /* 88: Indirect disk blocks. */
|
||
437 | u_int32_t di_flags; /* 100: Status flags (chflags). */
|
||
438 | u_int32_t di_blocks; /* 104: Blocks actually held. */
|
||
439 | int32_t di_gen; /* 108: Generation number. */
|
||
440 | u_int32_t di_uid; /* 112: File owner. */
|
||
441 | u_int32_t di_gid; /* 116: File group. */
|
||
442 | u_int64_t di_modrev; /* 120: i_modrev for NFSv4 */
|
||
443 | }; |
||
444 | |||
445 | struct lfs64_dinode {
|
||
446 | u_int16_t di_mode; /* 0: IFMT, permissions; see below. */
|
||
447 | int16_t di_nlink; /* 2: File link count. */
|
||
448 | u_int32_t di_uid; /* 4: File owner. */
|
||
449 | u_int32_t di_gid; /* 8: File group. */
|
||
450 | u_int32_t di_blksize; /* 12: Inode blocksize. */
|
||
451 | u_int64_t di_size; /* 16: File byte count. */
|
||
452 | u_int64_t di_blocks; /* 24: Bytes actually held. */
|
||
453 | int64_t di_atime; /* 32: Last access time. */
|
||
454 | int64_t di_mtime; /* 40: Last modified time. */
|
||
455 | int64_t di_ctime; /* 48: Last inode change time. */
|
||
456 | int64_t di_birthtime; /* 56: Inode creation time. */
|
||
457 | int32_t di_mtimensec; /* 64: Last modified time. */
|
||
458 | int32_t di_atimensec; /* 68: Last access time. */
|
||
459 | int32_t di_ctimensec; /* 72: Last inode change time. */
|
||
460 | int32_t di_birthnsec; /* 76: Inode creation time. */
|
||
461 | int32_t di_gen; /* 80: Generation number. */
|
||
462 | u_int32_t di_kernflags; /* 84: Kernel flags. */
|
||
463 | u_int32_t di_flags; /* 88: Status flags (chflags). */
|
||
464 | int32_t di_extsize; /* 92: External attributes block. */
|
||
465 | int64_t di_extb[ULFS_NXADDR];/* 96: External attributes block. */
|
||
466 | int64_t di_db[ULFS_NDADDR]; /* 112: Direct disk blocks. */
|
||
467 | int64_t di_ib[ULFS_NIADDR]; /* 208: Indirect disk blocks. */
|
||
468 | u_int64_t di_modrev; /* 232: i_modrev for NFSv4 */
|
||
469 | u_int64_t di_inumber; /* 240: Inode number */
|
||
470 | u_int64_t di_spare[1]; /* 244: Reserved; currently unused */ |
||
471 | }; |
||
472 | |||
473 | union lfs_dinode {
|
||
474 | struct lfs64_dinode u_64;
|
||
475 | struct lfs32_dinode u_32;
|
||
476 | }; |
||
477 | |||
478 | /*
|
||
479 | * The di_db fields may be overlaid with other information for
|
||
480 | * file types that do not have associated disk storage. Block
|
||
481 | * and character devices overlay the first data block with their
|
||
482 | * dev_t value. Short symbolic links place their path in the
|
||
483 | * di_db area.
|
||
484 | */
|
||
485 | #define di_rdev di_db[0] |
||
486 | |||
487 | /* Size of the on-disk inode. */
|
||
488 | //#define LFS_DINODE1_SIZE (sizeof(struct ulfs1_dinode)) /* 128 */
|
||
489 | //#define LFS_DINODE2_SIZE (sizeof(struct ulfs2_dinode))
|
||
490 | |||
491 | /* File types, found in the upper bits of di_mode. */
|
||
492 | #define LFS_IFMT 0170000 /* Mask of file type. */ |
||
493 | #define LFS_IFIFO 0010000 /* Named pipe (fifo). */ |
||
494 | #define LFS_IFCHR 0020000 /* Character device. */ |
||
495 | #define LFS_IFDIR 0040000 /* Directory file. */ |
||
496 | #define LFS_IFBLK 0060000 /* Block device. */ |
||
497 | #define LFS_IFREG 0100000 /* Regular file. */ |
||
498 | #define LFS_IFLNK 0120000 /* Symbolic link. */ |
||
499 | #define LFS_IFSOCK 0140000 /* UNIX domain socket. */ |
||
500 | #define LFS_IFWHT 0160000 /* Whiteout. */ |
||
501 | |||
502 | /*
|
||
503 | * "struct buf" associated definitions
|
||
504 | */
|
||
505 | |||
506 | /* Unassigned disk addresses. */
|
||
507 | #define UNASSIGNED -1 |
||
508 | #define UNWRITTEN -2 |
||
509 | |||
510 | /* Unused logical block number */
|
||
511 | #define LFS_UNUSED_LBN -1 |
||
512 | |||
513 | /*
|
||
514 | * "struct inode" associated definitions
|
||
515 | */
|
||
516 | |||
517 | /* For convenience */
|
||
518 | #define IN_ALLMOD (IN_MODIFIED|IN_ACCESS|IN_CHANGE|IN_UPDATE|IN_MODIFY|IN_ACCESSED|IN_CLEANING)
|
||
519 | |||
520 | /*
|
||
521 | * On-disk and in-memory checkpoint segment usage structure.
|
||
522 | */
|
||
523 | typedef struct segusage SEGUSE; |
||
524 | struct segusage {
|
||
525 | u_int32_t su_nbytes; /* 0: number of live bytes */
|
||
526 | u_int32_t su_olastmod; /* 4: SEGUSE last modified timestamp */
|
||
527 | u_int16_t su_nsums; /* 8: number of summaries in segment */
|
||
528 | u_int16_t su_ninos; /* 10: number of inode blocks in seg */
|
||
529 | |||
530 | #define SEGUSE_ACTIVE 0x01 /* segment currently being written */ |
||
531 | #define SEGUSE_DIRTY 0x02 /* segment has data in it */ |
||
532 | #define SEGUSE_SUPERBLOCK 0x04 /* segment contains a superblock */ |
||
533 | #define SEGUSE_ERROR 0x08 /* cleaner: do not clean segment */ |
||
534 | #define SEGUSE_EMPTY 0x10 /* segment is empty */ |
||
535 | #define SEGUSE_INVAL 0x20 /* segment is invalid */ |
||
536 | u_int32_t su_flags; /* 12: segment flags */
|
||
537 | u_int64_t su_lastmod; /* 16: last modified timestamp */
|
||
538 | }; |
||
539 | |||
540 | typedef struct segusage_v1 SEGUSE_V1; |
||
541 | struct segusage_v1 {
|
||
542 | u_int32_t su_nbytes; /* 0: number of live bytes */
|
||
543 | u_int32_t su_lastmod; /* 4: SEGUSE last modified timestamp */
|
||
544 | u_int16_t su_nsums; /* 8: number of summaries in segment */
|
||
545 | u_int16_t su_ninos; /* 10: number of inode blocks in seg */
|
||
546 | u_int32_t su_flags; /* 12: segment flags */
|
||
547 | }; |
||
548 | |||
549 | /*
|
||
550 | * On-disk file information. One per file with data blocks in the segment.
|
||
551 | *
|
||
552 | * The FINFO structure is a header; it is followed by fi_nblocks block
|
||
553 | * pointers, which are logical block numbers of the file. (These are the
|
||
554 | * blocks of the file present in this segment.)
|
||
555 | */
|
||
556 | |||
557 | typedef struct finfo64 FINFO64; |
||
558 | struct finfo64 {
|
||
559 | u_int32_t fi_nblocks; /* number of blocks */
|
||
560 | u_int32_t fi_version; /* version number */
|
||
561 | u_int64_t fi_ino; /* inode number */
|
||
562 | u_int32_t fi_lastlength; /* length of last block in array */
|
||
563 | u_int32_t fi_pad; /* unused */
|
||
564 | }; |
||
565 | |||
566 | typedef struct finfo32 FINFO32; |
||
567 | struct finfo32 {
|
||
568 | u_int32_t fi_nblocks; /* number of blocks */
|
||
569 | u_int32_t fi_version; /* version number */
|
||
570 | u_int32_t fi_ino; /* inode number */
|
||
571 | u_int32_t fi_lastlength; /* length of last block in array */
|
||
572 | }; |
||
573 | |||
574 | typedef union finfo { |
||
575 | struct finfo64 u_64;
|
||
576 | struct finfo32 u_32;
|
||
577 | } FINFO; |
||
578 | |||
579 | /*
|
||
580 | * inode info (part of the segment summary)
|
||
581 | *
|
||
582 | * Each one of these is just a block number; wrapping the structure
|
||
583 | * around it gives more contextual information in the code about
|
||
584 | * what's going on.
|
||
585 | */
|
||
586 | |||
587 | typedef struct iinfo64 { |
||
588 | uint64_t ii_block; /* block number */
|
||
589 | } IINFO64; |
||
590 | |||
591 | typedef struct iinfo32 { |
||
592 | uint32_t ii_block; /* block number */
|
||
593 | } IINFO32; |
||
594 | |||
595 | typedef union iinfo { |
||
596 | struct iinfo64 u_64;
|
||
597 | struct iinfo32 u_32;
|
||
598 | } IINFO; |
||
599 | |||
600 | /*
|
||
601 | * Index file inode entries.
|
||
602 | */
|
||
603 | |||
604 | /* magic value for daddrs */
|
||
605 | #define LFS_UNUSED_DADDR 0 /* out-of-band daddr */ |
||
606 | /* magic value for if_nextfree */
|
||
607 | #define LFS_ORPHAN_NEXTFREE (~(u_int32_t)0) /* indicate orphaned file */ |
||
608 | |||
609 | typedef struct ifile64 IFILE64; |
||
610 | struct ifile64 {
|
||
611 | u_int32_t if_version; /* inode version number */
|
||
612 | u_int32_t if_atime_nsec; /* and nanoseconds */
|
||
613 | u_int64_t if_atime_sec; /* Last access time, seconds */
|
||
614 | int64_t if_daddr; /* inode disk address */
|
||
615 | u_int64_t if_nextfree; /* next-unallocated inode */
|
||
616 | }; |
||
617 | |||
618 | typedef struct ifile32 IFILE32; |
||
619 | struct ifile32 {
|
||
620 | u_int32_t if_version; /* inode version number */
|
||
621 | int32_t if_daddr; /* inode disk address */
|
||
622 | u_int32_t if_nextfree; /* next-unallocated inode */
|
||
623 | u_int32_t if_atime_sec; /* Last access time, seconds */
|
||
624 | u_int32_t if_atime_nsec; /* and nanoseconds */
|
||
625 | }; |
||
626 | |||
627 | typedef struct ifile_v1 IFILE_V1; |
||
628 | struct ifile_v1 {
|
||
629 | u_int32_t if_version; /* inode version number */
|
||
630 | int32_t if_daddr; /* inode disk address */
|
||
631 | u_int32_t if_nextfree; /* next-unallocated inode */
|
||
632 | #if LFS_ATIME_IFILE
|
||
633 | #error "this cannot work" |
||
634 | struct timespec if_atime; /* Last access time */ |
||
635 | #endif
|
||
636 | }; |
||
637 | |||
638 | /*
|
||
639 | * Note: struct ifile_v1 is often handled by accessing the first three
|
||
640 | * fields of struct ifile32. (XXX: Blah. This should be cleaned up as
|
||
641 | * it may in some cases violate the strict-aliasing rules.)
|
||
642 | */
|
||
643 | typedef union ifile { |
||
644 | struct ifile64 u_64;
|
||
645 | struct ifile32 u_32;
|
||
646 | struct ifile_v1 u_v1;
|
||
647 | } IFILE; |
||
648 | |||
649 | /*
|
||
650 | * Cleaner information structure. This resides in the ifile and is used
|
||
651 | * to pass information from the kernel to the cleaner.
|
||
652 | */
|
||
653 | |||
654 | /* flags for ->flags */
|
||
655 | #define LFS_CLEANER_MUST_CLEAN 0x01 |
||
656 | |||
657 | typedef struct _cleanerinfo32 { |
||
658 | u_int32_t clean; /* 0: number of clean segments */
|
||
659 | u_int32_t dirty; /* 4: number of dirty segments */
|
||
660 | int32_t bfree; /* 8: disk blocks free */
|
||
661 | int32_t avail; /* 12: disk blocks available */
|
||
662 | u_int32_t free_head; /* 16: head of the inode free list */
|
||
663 | u_int32_t free_tail; /* 20: tail of the inode free list */
|
||
664 | u_int32_t flags; /* 24: status word from the kernel */
|
||
665 | } CLEANERINFO32; |
||
666 | |||
667 | typedef struct _cleanerinfo64 { |
||
668 | u_int32_t clean; /* 0: number of clean segments */
|
||
669 | u_int32_t dirty; /* 4: number of dirty segments */
|
||
670 | int64_t bfree; /* 8: disk blocks free */
|
||
671 | int64_t avail; /* 16: disk blocks available */
|
||
672 | u_int64_t free_head; /* 24: head of the inode free list */
|
||
673 | u_int64_t free_tail; /* 32: tail of the inode free list */
|
||
674 | u_int32_t flags; /* 40: status word from the kernel */
|
||
675 | u_int32_t pad; /* 44: must be 64-bit aligned */
|
||
676 | } CLEANERINFO64; |
||
677 | |||
678 | /* this must not go to disk directly of course */
|
||
679 | typedef union _cleanerinfo { |
||
680 | CLEANERINFO32 u_32; |
||
681 | CLEANERINFO64 u_64; |
||
682 | } CLEANERINFO; |
||
683 | |||
684 | /*
|
||
685 | * On-disk segment summary information
|
||
686 | */
|
||
687 | |||
688 | /* magic value for ss_magic */
|
||
689 | #define SS_MAGIC 0x061561 |
||
690 | |||
691 | /* flags for ss_flags */
|
||
692 | #define SS_DIROP 0x01 /* segment begins a dirop */ |
||
693 | #define SS_CONT 0x02 /* more partials to finish this write*/ |
||
694 | #define SS_CLEAN 0x04 /* written by the cleaner */ |
||
695 | #define SS_RFW 0x08 /* written by the roll-forward agent */ |
||
696 | #define SS_RECLAIM 0x10 /* written by the roll-forward agent */ |
||
697 | |||
698 | /* type used for reading checksum signatures from metadata structures */
|
||
699 | typedef uint32_t lfs_checkword;
|
||
700 | |||
701 | typedef struct segsum_v1 SEGSUM_V1; |
||
702 | struct segsum_v1 {
|
||
703 | u_int32_t ss_sumsum; /* 0: check sum of summary block */
|
||
704 | u_int32_t ss_datasum; /* 4: check sum of data */
|
||
705 | u_int32_t ss_magic; /* 8: segment summary magic number */
|
||
706 | int32_t ss_next; /* 12: next segment */
|
||
707 | u_int32_t ss_create; /* 16: creation time stamp */
|
||
708 | u_int16_t ss_nfinfo; /* 20: number of file info structures */
|
||
709 | u_int16_t ss_ninos; /* 22: number of inodes in summary */
|
||
710 | u_int16_t ss_flags; /* 24: used for directory operations */
|
||
711 | u_int16_t ss_pad; /* 26: extra space */
|
||
712 | /* FINFO's and inode daddr's... */
|
||
713 | }; |
||
714 | |||
715 | typedef struct segsum32 SEGSUM32; |
||
716 | struct segsum32 {
|
||
717 | u_int32_t ss_sumsum; /* 0: check sum of summary block */
|
||
718 | u_int32_t ss_datasum; /* 4: check sum of data */
|
||
719 | u_int32_t ss_magic; /* 8: segment summary magic number */
|
||
720 | int32_t ss_next; /* 12: next segment (disk address) */
|
||
721 | u_int32_t ss_ident; /* 16: roll-forward fsid */
|
||
722 | u_int16_t ss_nfinfo; /* 20: number of file info structures */
|
||
723 | u_int16_t ss_ninos; /* 22: number of inodes in summary */
|
||
724 | u_int16_t ss_flags; /* 24: used for directory operations */
|
||
725 | u_int8_t ss_pad[2]; /* 26: extra space */ |
||
726 | u_int32_t ss_reclino; /* 28: inode being reclaimed */
|
||
727 | u_int64_t ss_serial; /* 32: serial number */
|
||
728 | u_int64_t ss_create; /* 40: time stamp */
|
||
729 | /* FINFO's and inode daddr's... */
|
||
730 | }; |
||
731 | |||
732 | typedef struct segsum64 SEGSUM64; |
||
733 | struct segsum64 {
|
||
734 | u_int32_t ss_sumsum; /* 0: check sum of summary block */
|
||
735 | u_int32_t ss_datasum; /* 4: check sum of data */
|
||
736 | u_int32_t ss_magic; /* 8: segment summary magic number */
|
||
737 | u_int32_t ss_ident; /* 12: roll-forward fsid */
|
||
738 | int64_t ss_next; /* 16: next segment (disk address) */
|
||
739 | u_int16_t ss_nfinfo; /* 24: number of file info structures */
|
||
740 | u_int16_t ss_ninos; /* 26: number of inodes in summary */
|
||
741 | u_int16_t ss_flags; /* 28: used for directory operations */
|
||
742 | u_int8_t ss_pad[2]; /* 30: extra space */ |
||
743 | u_int64_t ss_reclino; /* 32: inode being reclaimed */
|
||
744 | u_int64_t ss_serial; /* 40: serial number */
|
||
745 | u_int64_t ss_create; /* 48: time stamp */
|
||
746 | /* FINFO's and inode daddr's... */
|
||
747 | }; |
||
748 | |||
749 | typedef union segsum SEGSUM; |
||
750 | union segsum {
|
||
751 | struct segsum64 u_64;
|
||
752 | struct segsum32 u_32;
|
||
753 | struct segsum_v1 u_v1;
|
||
754 | }; |
||
755 | |||
756 | |||
757 | /*
|
||
758 | * On-disk super block.
|
||
759 | *
|
||
760 | * We have separate superblock structures for the 32-bit and 64-bit
|
||
761 | * LFS, and accessor functions to hide the differences.
|
||
762 | *
|
||
763 | * For lfs64, the format version is always 2; version 1 lfs is old.
|
||
764 | * For both, the inode format version is 0; for lfs32 this selects the
|
||
765 | * same 32-bit inode as always, and for lfs64 this selects the larger
|
||
766 | * 64-bit inode structure we got from ffsv2.
|
||
767 | *
|
||
768 | * In lfs64:
|
||
769 | * - inode numbers are still 32 bit
|
||
770 | * - segments may not be larger than 4G (counted in bytes)
|
||
771 | * - there may not be more than 2^32 (or perhaps 2^31) segments
|
||
772 | * - the total volume size is limited to 2^63 frags and/or 2^63
|
||
773 | * disk blocks, and probably in practice 2^63 bytes.
|
||
774 | */
|
||
775 | |||
776 | #define LFS_MAGIC 0x070162 |
||
777 | #define LFS_MAGIC_SWAPPED 0x62010700 |
||
778 | |||
779 | #define LFS64_MAGIC 0x19620701 |
||
780 | #define LFS64_MAGIC_SWAPPED 0x01076219 |
||
781 | |||
782 | #define LFS_VERSION 2 |
||
783 | |||
784 | #define LFS_MIN_SBINTERVAL 5 /* min superblock segment spacing */ |
||
785 | #define LFS_MAXNUMSB 10 /* max number of superblocks */ |
||
786 | |||
787 | /* flags for dlfs_pflags */
|
||
788 | #define LFS_PF_CLEAN 0x1 |
||
789 | |||
790 | /* Inode format versions */
|
||
791 | #define LFS_44INODEFMT 0 |
||
792 | #define LFS_MAXINODEFMT 0 |
||
793 | |||
794 | struct dlfs {
|
||
795 | u_int32_t dlfs_magic; /* 0: magic number */
|
||
796 | u_int32_t dlfs_version; /* 4: version number */
|
||
797 | |||
798 | u_int32_t dlfs_size; /* 8: number of blocks in fs (v1) */
|
||
799 | /* number of frags in fs (v2) */
|
||
800 | u_int32_t dlfs_ssize; /* 12: number of blocks per segment (v1) */
|
||
801 | /* number of bytes per segment (v2) */
|
||
802 | u_int32_t dlfs_dsize; /* 16: number of disk blocks in fs */
|
||
803 | u_int32_t dlfs_bsize; /* 20: file system block size */
|
||
804 | u_int32_t dlfs_fsize; /* 24: size of frag blocks in fs */
|
||
805 | u_int32_t dlfs_frag; /* 28: number of frags in a block in fs */
|
||
806 | |||
807 | /* Checkpoint region. */
|
||
808 | u_int32_t dlfs_freehd; /* 32: start of the free inode list */
|
||
809 | int32_t dlfs_bfree; /* 36: number of free frags */
|
||
810 | u_int32_t dlfs_nfiles; /* 40: number of allocated inodes */
|
||
811 | int32_t dlfs_avail; /* 44: blocks available for writing */
|
||
812 | int32_t dlfs_uinodes; /* 48: inodes in cache not yet on disk */
|
||
813 | int32_t dlfs_idaddr; /* 52: inode file disk address */
|
||
814 | u_int32_t dlfs_ifile; /* 56: inode file inode number */
|
||
815 | int32_t dlfs_lastseg; /* 60: address of last segment written */
|
||
816 | int32_t dlfs_nextseg; /* 64: address of next segment to write */
|
||
817 | int32_t dlfs_curseg; /* 68: current segment being written */
|
||
818 | int32_t dlfs_offset; /* 72: offset in curseg for next partial */
|
||
819 | int32_t dlfs_lastpseg; /* 76: address of last partial written */
|
||
820 | u_int32_t dlfs_inopf; /* 80: v1: time stamp; v2: inodes per frag */
|
||
821 | |||
822 | /* These are configuration parameters. */
|
||
823 | u_int32_t dlfs_minfree; /* 84: minimum percentage of free blocks */
|
||
824 | |||
825 | /* These fields can be computed from the others. */
|
||
826 | u_int64_t dlfs_maxfilesize; /* 88: maximum representable file size */
|
||
827 | u_int32_t dlfs_fsbpseg; /* 96: frags (fsb) per segment */
|
||
828 | u_int32_t dlfs_inopb; /* 100: inodes per block */
|
||
829 | u_int32_t dlfs_ifpb; /* 104: IFILE entries per block */
|
||
830 | u_int32_t dlfs_sepb; /* 108: SEGUSE entries per block */
|
||
831 | u_int32_t dlfs_nindir; /* 112: indirect pointers per block */
|
||
832 | u_int32_t dlfs_nseg; /* 116: number of segments */
|
||
833 | u_int32_t dlfs_nspf; /* 120: number of sectors per fragment */
|
||
834 | u_int32_t dlfs_cleansz; /* 124: cleaner info size in blocks */
|
||
835 | u_int32_t dlfs_segtabsz; /* 128: segment table size in blocks */
|
||
836 | u_int32_t dlfs_segmask; /* 132: calculate offset within a segment */
|
||
837 | u_int32_t dlfs_segshift; /* 136: fast mult/div for segments */
|
||
838 | u_int32_t dlfs_bshift; /* 140: calc block number from file offset */
|
||
839 | u_int32_t dlfs_ffshift; /* 144: fast mult/div for frag from file */
|
||
840 | u_int32_t dlfs_fbshift; /* 148: fast mult/div for frag from block */
|
||
841 | u_int64_t dlfs_bmask; /* 152: calc block offset from file offset */
|
||
842 | u_int64_t dlfs_ffmask; /* 160: calc frag offset from file offset */
|
||
843 | u_int64_t dlfs_fbmask; /* 168: calc frag offset from block offset */
|
||
844 | u_int32_t dlfs_blktodb; /* 176: blktodb and dbtoblk shift constant */
|
||
845 | u_int32_t dlfs_sushift; /* 180: fast mult/div for segusage table */
|
||
846 | |||
847 | int32_t dlfs_maxsymlinklen; /* 184: max length of an internal symlink */
|
||
848 | /* 188: superblock disk offsets */
|
||
849 | int32_t dlfs_sboffs[LFS_MAXNUMSB]; |
||
850 | |||
851 | u_int32_t dlfs_nclean; /* 228: Number of clean segments */
|
||
852 | u_char dlfs_fsmnt[MNAMELEN]; /* 232: name mounted on */
|
||
853 | u_int16_t dlfs_pflags; /* 322: file system persistent flags */
|
||
854 | int32_t dlfs_dmeta; /* 324: total number of dirty summaries */
|
||
855 | u_int32_t dlfs_minfreeseg; /* 328: segments not counted in bfree */
|
||
856 | u_int32_t dlfs_sumsize; /* 332: size of summary blocks */
|
||
857 | u_int64_t dlfs_serial; /* 336: serial number */
|
||
858 | u_int32_t dlfs_ibsize; /* 344: size of inode blocks */
|
||
859 | int32_t dlfs_s0addr; /* 348: start of segment 0 */
|
||
860 | u_int64_t dlfs_tstamp; /* 352: time stamp */
|
||
861 | u_int32_t dlfs_inodefmt; /* 360: inode format version */
|
||
862 | u_int32_t dlfs_interleave; /* 364: segment interleave */
|
||
863 | u_int32_t dlfs_ident; /* 368: per-fs identifier */
|
||
864 | u_int32_t dlfs_fsbtodb; /* 372: fsbtodb and dbtodsb shift constant */
|
||
865 | u_int32_t dlfs_resvseg; /* 376: segments reserved for the cleaner */
|
||
866 | int8_t dlfs_pad[128]; /* 380: round to 512 bytes */ |
||
867 | /* Checksum -- last valid disk field. */
|
||
868 | u_int32_t dlfs_cksum; /* 508: checksum for superblock checking */
|
||
869 | }; |
||
870 | |||
871 | struct dlfs64 {
|
||
872 | u_int32_t dlfs_magic; /* 0: magic number */
|
||
873 | u_int32_t dlfs_version; /* 4: version number (2) */
|
||
874 | |||
875 | u_int64_t dlfs_size; /* 8: number of frags in fs (v2) */
|
||
876 | u_int64_t dlfs_dsize; /* 16: number of disk blocks in fs */
|
||
877 | u_int32_t dlfs_ssize; /* 24: number of bytes per segment (v2) */
|
||
878 | u_int32_t dlfs_bsize; /* 28: file system block size */
|
||
879 | u_int32_t dlfs_fsize; /* 32: size of frag blocks in fs */
|
||
880 | u_int32_t dlfs_frag; /* 36: number of frags in a block in fs */
|
||
881 | |||
882 | /* Checkpoint region. */
|
||
883 | u_int64_t dlfs_freehd; /* 40: start of the free inode list */
|
||
884 | u_int64_t dlfs_nfiles; /* 48: number of allocated inodes */
|
||
885 | int64_t dlfs_bfree; /* 56: number of free frags */
|
||
886 | int64_t dlfs_avail; /* 64: blocks available for writing */
|
||
887 | int64_t dlfs_idaddr; /* 72: inode file disk address */
|
||
888 | int32_t dlfs_uinodes; /* 80: inodes in cache not yet on disk */
|
||
889 | u_int32_t dlfs_unused_0; /* 84: not used */
|
||
890 | int64_t dlfs_lastseg; /* 88: address of last segment written */
|
||
891 | int64_t dlfs_nextseg; /* 96: address of next segment to write */
|
||
892 | int64_t dlfs_curseg; /* 104: current segment being written */
|
||
893 | int64_t dlfs_offset; /* 112: offset in curseg for next partial */
|
||
894 | int64_t dlfs_lastpseg; /* 120: address of last partial written */
|
||
895 | u_int32_t dlfs_inopf; /* 128: inodes per frag */
|
||
896 | |||
897 | /* These are configuration parameters. */
|
||
898 | u_int32_t dlfs_minfree; /* 132: minimum percentage of free blocks */
|
||
899 | |||
900 | /* These fields can be computed from the others. */
|
||
901 | u_int64_t dlfs_maxfilesize; /* 136: maximum representable file size */
|
||
902 | u_int32_t dlfs_fsbpseg; /* 144: frags (fsb) per segment */
|
||
903 | u_int32_t dlfs_inopb; /* 148: inodes per block */
|
||
904 | u_int32_t dlfs_ifpb; /* 152: IFILE entries per block */
|
||
905 | u_int32_t dlfs_sepb; /* 156: SEGUSE entries per block */
|
||
906 | u_int32_t dlfs_nindir; /* 160: indirect pointers per block */
|
||
907 | u_int32_t dlfs_nseg; /* 164: number of segments */
|
||
908 | u_int32_t dlfs_nspf; /* 168: number of sectors per fragment */
|
||
909 | u_int32_t dlfs_cleansz; /* 172: cleaner info size in blocks */
|
||
910 | u_int32_t dlfs_segtabsz; /* 176: segment table size in blocks */
|
||
911 | u_int32_t dlfs_bshift; /* 180: calc block number from file offset */
|
||
912 | u_int32_t dlfs_ffshift; /* 184: fast mult/div for frag from file */
|
||
913 | u_int32_t dlfs_fbshift; /* 188: fast mult/div for frag from block */
|
||
914 | u_int64_t dlfs_bmask; /* 192: calc block offset from file offset */
|
||
915 | u_int64_t dlfs_ffmask; /* 200: calc frag offset from file offset */
|
||
916 | u_int64_t dlfs_fbmask; /* 208: calc frag offset from block offset */
|
||
917 | u_int32_t dlfs_blktodb; /* 216: blktodb and dbtoblk shift constant */
|
||
918 | u_int32_t dlfs_sushift; /* 220: fast mult/div for segusage table */
|
||
919 | |||
920 | /* 224: superblock disk offsets */
|
||
921 | int64_t dlfs_sboffs[LFS_MAXNUMSB]; |
||
922 | |||
923 | int32_t dlfs_maxsymlinklen; /* 304: max len of an internal symlink */
|
||
924 | u_int32_t dlfs_nclean; /* 308: Number of clean segments */
|
||
925 | u_char dlfs_fsmnt[MNAMELEN]; /* 312: name mounted on */
|
||
926 | u_int16_t dlfs_pflags; /* 402: file system persistent flags */
|
||
927 | int32_t dlfs_dmeta; /* 404: total number of dirty summaries */
|
||
928 | u_int32_t dlfs_minfreeseg; /* 408: segments not counted in bfree */
|
||
929 | u_int32_t dlfs_sumsize; /* 412: size of summary blocks */
|
||
930 | u_int32_t dlfs_ibsize; /* 416: size of inode blocks */
|
||
931 | u_int32_t dlfs_inodefmt; /* 420: inode format version */
|
||
932 | u_int64_t dlfs_serial; /* 424: serial number */
|
||
933 | int64_t dlfs_s0addr; /* 432: start of segment 0 */
|
||
934 | u_int64_t dlfs_tstamp; /* 440: time stamp */
|
||
935 | u_int32_t dlfs_interleave; /* 448: segment interleave */
|
||
936 | u_int32_t dlfs_ident; /* 452: per-fs identifier */
|
||
937 | u_int32_t dlfs_fsbtodb; /* 456: fsbtodb and dbtodsb shift constant */
|
||
938 | u_int32_t dlfs_resvseg; /* 460: segments reserved for the cleaner */
|
||
939 | int8_t dlfs_pad[44]; /* 464: round to 512 bytes */ |
||
940 | /* Checksum -- last valid disk field. */
|
||
941 | u_int32_t dlfs_cksum; /* 508: checksum for superblock checking */
|
||
942 | }; |
||
943 | |||
944 | /* Type used for the inode bitmap */
|
||
945 | typedef u_int32_t lfs_bm_t;
|
||
946 | |||
947 | /*
|
||
948 | * Linked list of segments whose byte count needs updating following a
|
||
949 | * file truncation.
|
||
950 | */
|
||
951 | struct segdelta {
|
||
952 | long segnum;
|
||
953 | size_t num; |
||
954 | LIST_ENTRY(segdelta) list; |
||
955 | }; |
||
956 | |||
957 | /*
|
||
958 | * In-memory super block.
|
||
959 | */
|
||
960 | struct lfs {
|
||
961 | union { /* on-disk parameters */ |
||
962 | struct dlfs u_32;
|
||
963 | struct dlfs64 u_64;
|
||
964 | } lfs_dlfs_u; |
||
965 | |||
966 | /* These fields are set at mount time and are meaningless on disk. */
|
||
967 | unsigned lfs_is64 : 1, /* are we lfs64 or lfs32? */ |
||
968 | lfs_dobyteswap : 1, /* are we opposite-endian? */ |
||
969 | lfs_hasolddirfmt : 1; /* dir entries have no d_type */ |
||
970 | |||
971 | struct segment *lfs_sp; /* current segment being written */ |
||
972 | struct vnode *lfs_ivnode; /* vnode for the ifile */ |
||
973 | u_int32_t lfs_seglock; /* single-thread the segment writer */
|
||
974 | pid_t lfs_lockpid; /* pid of lock holder */
|
||
975 | lwpid_t lfs_locklwp; /* lwp of lock holder */
|
||
976 | u_int32_t lfs_iocount; /* number of ios pending */
|
||
977 | u_int32_t lfs_writer; /* don't allow any dirops to start */
|
||
978 | u_int32_t lfs_dirops; /* count of active directory ops */
|
||
979 | u_int32_t lfs_dirvcount; /* count of VDIROP nodes in this fs */
|
||
980 | u_int32_t lfs_doifile; /* Write ifile blocks on next write */
|
||
981 | u_int32_t lfs_nactive; /* Number of segments since last ckp */
|
||
982 | int8_t lfs_fmod; /* super block modified flag */
|
||
983 | int8_t lfs_ronly; /* mounted read-only flag */
|
||
984 | #define LFS_NOTYET 0x01 |
||
985 | #define LFS_IFDIRTY 0x02 |
||
986 | #define LFS_WARNED 0x04 |
||
987 | #define LFS_UNDIROP 0x08 |
||
988 | int8_t lfs_flags; /* currently unused flag */
|
||
989 | u_int16_t lfs_activesb; /* toggle between superblocks */
|
||
990 | daddr_t lfs_sbactive; /* disk address of current sb write */
|
||
991 | struct vnode *lfs_flushvp; /* vnode being flushed */ |
||
992 | int lfs_flushvp_fakevref; /* fake vref count for flushvp */ |
||
993 | struct vnode *lfs_unlockvp; /* being inactivated in lfs_segunlock */ |
||
994 | u_int32_t lfs_diropwait; /* # procs waiting on dirop flush */
|
||
995 | size_t lfs_devbsize; /* Device block size */
|
||
996 | size_t lfs_devbshift; /* Device block shift */
|
||
997 | krwlock_t lfs_fraglock; |
||
998 | krwlock_t lfs_iflock; /* Ifile lock */
|
||
999 | kcondvar_t lfs_stopcv; /* Wrap lock */
|
||
1000 | struct lwp *lfs_stoplwp;
|
||
1001 | pid_t lfs_rfpid; /* Process ID of roll-forward agent */
|
||
1002 | int lfs_nadirop; /* number of active dirop nodes */ |
||
1003 | long lfs_ravail; /* blocks pre-reserved for writing */ |
||
1004 | long lfs_favail; /* blocks pre-reserved for writing */ |
||
1005 | struct lfs_res_blk *lfs_resblk; /* Reserved memory for pageout */ |
||
1006 | TAILQ_HEAD(, inode) lfs_dchainhd; /* dirop vnodes */
|
||
1007 | TAILQ_HEAD(, inode) lfs_pchainhd; /* paging vnodes */
|
||
1008 | #define LFS_RESHASH_WIDTH 17 |
||
1009 | LIST_HEAD(, lfs_res_blk) lfs_reshash[LFS_RESHASH_WIDTH]; |
||
1010 | int lfs_pdflush; /* pagedaemon wants us to flush */ |
||
1011 | u_int32_t **lfs_suflags; /* Segment use flags */
|
||
1012 | #ifdef _KERNEL
|
||
1013 | struct pool lfs_clpool; /* Pool for struct lfs_cluster */ |
||
1014 | struct pool lfs_bpppool; /* Pool for bpp */ |
||
1015 | struct pool lfs_segpool; /* Pool for struct segment */ |
||
1016 | #endif /* _KERNEL */ |
||
1017 | #define LFS_MAX_CLEANIND 64 |
||
1018 | daddr_t lfs_cleanint[LFS_MAX_CLEANIND]; /* Active cleaning intervals */
|
||
1019 | int lfs_cleanind; /* Index into intervals */ |
||
1020 | int lfs_sleepers; /* # procs sleeping this fs */ |
||
1021 | int lfs_pages; /* dirty pages blaming this fs */ |
||
1022 | lfs_bm_t *lfs_ino_bitmap; /* Inuse inodes bitmap */
|
||
1023 | int lfs_nowrap; /* Suspend log wrap */ |
||
1024 | int lfs_wrappass; /* Allow first log wrap requester to pass */ |
||
1025 | int lfs_wrapstatus; /* Wrap status */ |
||
1026 | int lfs_reclino; /* Inode being reclaimed */ |
||
1027 | daddr_t lfs_startseg; /* Segment we started writing at */
|
||
1028 | LIST_HEAD(, segdelta) lfs_segdhd; /* List of pending trunc accounting events */
|
||
1029 | |||
1030 | #ifdef _KERNEL
|
||
1031 | /* ULFS-level information */
|
||
1032 | u_int32_t um_flags; /* ULFS flags (below) */
|
||
1033 | u_long um_nindir; /* indirect ptrs per block */
|
||
1034 | u_long um_lognindir; /* log2 of um_nindir */
|
||
1035 | u_long um_bptrtodb; /* indir ptr to disk block */
|
||
1036 | u_long um_seqinc; /* inc between seq blocks */
|
||
1037 | int um_maxsymlinklen;
|
||
1038 | int um_dirblksiz;
|
||
1039 | u_int64_t um_maxfilesize; |
||
1040 | |||
1041 | /* Stuff used by quota2 code, not currently operable */
|
||
1042 | unsigned lfs_use_quota2 : 1; |
||
1043 | uint32_t lfs_quota_magic; |
||
1044 | uint8_t lfs_quota_flags; |
||
1045 | uint64_t lfs_quotaino[2];
|
||
1046 | |||
1047 | /* Sleep address replacing &lfs_avail inside the on-disk superblock */
|
||
1048 | /* XXX: should be replaced with a condvar */
|
||
1049 | int lfs_availsleep;
|
||
1050 | /* This one replaces &lfs_nextseg... all ditto */
|
||
1051 | int lfs_nextsegsleep;
|
||
1052 | #endif
|
||
1053 | }; |
||
1054 | |||
1055 | /*
|
||
1056 | * Structures used by lfs_bmapv and lfs_markv to communicate information
|
||
1057 | * about inodes and data blocks.
|
||
1058 | */
|
||
1059 | typedef struct block_info { |
||
1060 | u_int64_t bi_inode; /* inode # */
|
||
1061 | int64_t bi_lbn; /* logical block w/in file */
|
||
1062 | int64_t bi_daddr; /* disk address of block */
|
||
1063 | u_int64_t bi_segcreate; /* origin segment create time */
|
||
1064 | int bi_version; /* file version number */ |
||
1065 | int bi_size; /* size of the block (if fragment) */ |
||
1066 | void *bi_bp; /* data buffer */ |
||
1067 | } BLOCK_INFO; |
||
1068 | |||
1069 | /* Compatibility for 7.0 binaries */
|
||
1070 | typedef struct block_info_70 { |
||
1071 | u_int32_t bi_inode; /* inode # */
|
||
1072 | int32_t bi_lbn; /* logical block w/in file */
|
||
1073 | int32_t bi_daddr; /* disk address of block */
|
||
1074 | u_int64_t bi_segcreate; /* origin segment create time */
|
||
1075 | int bi_version; /* file version number */ |
||
1076 | void *bi_bp; /* data buffer */ |
||
1077 | int bi_size; /* size of the block (if fragment) */ |
||
1078 | } BLOCK_INFO_70; |
||
1079 | |||
1080 | /* Compatibility for 1.5 binaries */
|
||
1081 | typedef struct block_info_15 { |
||
1082 | u_int32_t bi_inode; /* inode # */
|
||
1083 | int32_t bi_lbn; /* logical block w/in file */
|
||
1084 | int32_t bi_daddr; /* disk address of block */
|
||
1085 | u_int32_t bi_segcreate; /* origin segment create time */
|
||
1086 | int bi_version; /* file version number */ |
||
1087 | void *bi_bp; /* data buffer */ |
||
1088 | int bi_size; /* size of the block (if fragment) */ |
||
1089 | } BLOCK_INFO_15; |
||
1090 | |||
1091 | /*
|
||
1092 | * 32/64-bit-clean pointer to block pointers. This points into
|
||
1093 | * already-existing storage; it is mostly used to access the block
|
||
1094 | * pointers following a FINFO.
|
||
1095 | */
|
||
1096 | union lfs_blocks {
|
||
1097 | int64_t *b64; |
||
1098 | int32_t *b32; |
||
1099 | }; |
||
1100 | |||
1101 | /* In-memory description of a segment about to be written. */
|
||
1102 | struct segment {
|
||
1103 | struct lfs *fs; /* file system pointer */ |
||
1104 | struct buf **bpp; /* pointer to buffer array */ |
||
1105 | struct buf **cbpp; /* pointer to next available bp */ |
||
1106 | struct buf **start_bpp; /* pointer to first bp in this set */ |
||
1107 | struct buf *ibp; /* buffer pointer to inode page */ |
||
1108 | union lfs_dinode *idp; /* pointer to ifile dinode */ |
||
1109 | FINFO *fip; /* current fileinfo pointer */
|
||
1110 | struct vnode *vp; /* vnode being gathered */ |
||
1111 | void *segsum; /* segment summary info */ |
||
1112 | u_int32_t ninodes; /* number of inodes in this segment */
|
||
1113 | int32_t seg_bytes_left; /* bytes left in segment */
|
||
1114 | int32_t sum_bytes_left; /* bytes left in summary block */
|
||
1115 | u_int32_t seg_number; /* number of this segment */
|
||
1116 | union lfs_blocks start_lbp; /* beginning lbn for this set */ |
||
1117 | |||
1118 | #define SEGM_CKP 0x0001 /* doing a checkpoint */ |
||
1119 | #define SEGM_CLEAN 0x0002 /* cleaner call; don't sort */ |
||
1120 | #define SEGM_SYNC 0x0004 /* wait for segment */ |
||
1121 | #define SEGM_PROT 0x0008 /* don't inactivate at segunlock */ |
||
1122 | #define SEGM_PAGEDAEMON 0x0010 /* pagedaemon called us */ |
||
1123 | #define SEGM_WRITERD 0x0020 /* LFS writed called us */ |
||
1124 | #define SEGM_FORCE_CKP 0x0040 /* Force checkpoint right away */ |
||
1125 | #define SEGM_RECLAIM 0x0080 /* Writing to reclaim vnode */ |
||
1126 | #define SEGM_SINGLE 0x0100 /* Opportunistic writevnodes */ |
||
1127 | u_int16_t seg_flags; /* run-time flags for this segment */
|
||
1128 | u_int32_t seg_iocount; /* number of ios pending */
|
||
1129 | int ndupino; /* number of duplicate inodes */ |
||
1130 | }; |
||
1131 | |||
1132 | /* Statistics Counters */
|
||
1133 | struct lfs_stats { /* Must match sysctl list in lfs_vfsops.h ! */ |
||
1134 | u_int segsused; |
||
1135 | u_int psegwrites; |
||
1136 | u_int psyncwrites; |
||
1137 | u_int pcleanwrites; |
||
1138 | u_int blocktot; |
||
1139 | u_int cleanblocks; |
||
1140 | u_int ncheckpoints; |
||
1141 | u_int nwrites; |
||
1142 | u_int nsync_writes; |
||
1143 | u_int wait_exceeded; |
||
1144 | u_int write_exceeded; |
||
1145 | u_int flush_invoked; |
||
1146 | u_int vflush_invoked; |
||
1147 | u_int clean_inlocked; |
||
1148 | u_int clean_vnlocked; |
||
1149 | u_int segs_reclaimed; |
||
1150 | }; |
||
1151 | |||
1152 | /* Fcntls to take the place of the lfs syscalls */
|
||
1153 | struct lfs_fcntl_markv {
|
||
1154 | BLOCK_INFO *blkiov; /* blocks to relocate */
|
||
1155 | int blkcnt; /* number of blocks (limited to 65536) */ |
||
1156 | }; |
||
1157 | |||
1158 | #define LFCNSEGWAITALL _FCNR_FSPRIV('L', 14, struct timeval) |
||
1159 | #define LFCNSEGWAIT _FCNR_FSPRIV('L', 15, struct timeval) |
||
1160 | #define LFCNBMAPV _FCNRW_FSPRIV('L', 16, struct lfs_fcntl_markv) |
||
1161 | #define LFCNMARKV _FCNRW_FSPRIV('L', 17, struct lfs_fcntl_markv) |
||
1162 | #define LFCNRECLAIM _FCNO_FSPRIV('L', 4) |
||
1163 | |||
1164 | struct lfs_fhandle {
|
||
1165 | char space[28]; /* FHANDLE_SIZE_COMPAT (but used from userland too) */ |
||
1166 | }; |
||
1167 | #define LFCNREWIND _FCNR_FSPRIV('L', 6, int) |
||
1168 | #define LFCNINVAL _FCNR_FSPRIV('L', 7, int) |
||
1169 | #define LFCNRESIZE _FCNR_FSPRIV('L', 8, int) |
||
1170 | #define LFCNWRAPSTOP _FCNR_FSPRIV('L', 9, int) |
||
1171 | #define LFCNWRAPGO _FCNR_FSPRIV('L', 10, int) |
||
1172 | #define LFCNIFILEFH _FCNW_FSPRIV('L', 11, struct lfs_fhandle) |
||
1173 | #define LFCNWRAPPASS _FCNR_FSPRIV('L', 12, int) |
||
1174 | # define LFS_WRAP_GOING 0x0 |
||
1175 | # define LFS_WRAP_WAITING 0x1 |
||
1176 | #define LFCNWRAPSTATUS _FCNW_FSPRIV('L', 13, int) |
||
1177 | |||
1178 | /* Debug segment lock */
|
||
1179 | #ifdef notyet
|
||
1180 | # define ASSERT_SEGLOCK(fs) KASSERT(LFS_SEGLOCK_HELD(fs))
|
||
1181 | # define ASSERT_NO_SEGLOCK(fs) KASSERT(!LFS_SEGLOCK_HELD(fs))
|
||
1182 | # define ASSERT_DUNNO_SEGLOCK(fs)
|
||
1183 | # define ASSERT_MAYBE_SEGLOCK(fs)
|
||
1184 | #else /* !notyet */ |
||
1185 | # define ASSERT_DUNNO_SEGLOCK(fs) \
|
||
1186 | DLOG((DLOG_SEG, "lfs func %s seglock wrong (%d)\n", __func__, \
|
||
1187 | LFS_SEGLOCK_HELD(fs))) |
||
1188 | # define ASSERT_SEGLOCK(fs) do { \ |
||
1189 | if (!LFS_SEGLOCK_HELD(fs)) { \
|
||
1190 | DLOG((DLOG_SEG, "lfs func %s seglock wrong (0)\n", __func__)); \
|
||
1191 | } \ |
||
1192 | } while(0) |
||
1193 | # define ASSERT_NO_SEGLOCK(fs) do { \ |
||
1194 | if (LFS_SEGLOCK_HELD(fs)) { \
|
||
1195 | DLOG((DLOG_SEG, "lfs func %s seglock wrong (1)\n", __func__)); \
|
||
1196 | } \ |
||
1197 | } while(0) |
||
1198 | # define ASSERT_MAYBE_SEGLOCK(x)
|
||
1199 | #endif /* !notyet */ |
||
1200 | |||
1201 | /*
|
||
1202 | * Arguments to mount LFS filesystems
|
||
1203 | */
|
||
1204 | struct ulfs_args {
|
||
1205 | char *fspec; /* block special device to mount */ |
||
1206 | }; |
||
1207 | |||
1208 | __BEGIN_DECLS |
||
1209 | void lfs_itimes(struct inode *, const struct timespec *, |
||
1210 | const struct timespec *, const struct timespec *); |
||
1211 | __END_DECLS |
||
1212 | |||
1213 | #endif /* !_UFS_LFS_LFS_H_ */ |