1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #ifndef _SYS_FS_UFS_TRANS_H
28 #define _SYS_FS_UFS_TRANS_H
29
30 #pragma ident "%Z%%M% %I% %E% SMI"
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 #include <sys/types.h>
37 #include <sys/cred.h>
38 #include <sys/fs/ufs_fs.h>
39
40 /*
41 * Types of deltas
42 */
43 typedef enum delta_type {
44 DT_NONE, /* 0 no assigned type */
45 DT_SB, /* 1 superblock */
46 DT_CG, /* 2 cylinder group */
47 DT_SI, /* 3 summary info */
48 DT_AB, /* 4 allocation block */
49 DT_ABZERO, /* 5 a zero'ed allocation block */
50 DT_DIR, /* 6 directory */
51 DT_INODE, /* 7 inode */
52 DT_FBI, /* 8 fbiwrite */
53 DT_QR, /* 9 quota record */
54 DT_COMMIT, /* 10 commit record */
55 DT_CANCEL, /* 11 cancel record */
56 DT_BOT, /* 12 begin transaction */
57 DT_EOT, /* 13 end transaction */
58 DT_UD, /* 14 userdata */
59 DT_SUD, /* 15 userdata found during log scan */
60 DT_SHAD, /* 16 data for a shadow inode */
61 DT_MAX /* 17 maximum delta type */
62 } delta_t;
63
64 /*
65 * transaction operation types
66 */
67 typedef enum top_type {
68 TOP_READ_SYNC, /* 0 */
69 TOP_WRITE, /* 1 */
70 TOP_WRITE_SYNC, /* 2 */
71 TOP_SETATTR, /* 3 */
72 TOP_CREATE, /* 4 */
73 TOP_REMOVE, /* 5 */
74 TOP_LINK, /* 6 */
75 TOP_RENAME, /* 7 */
76 TOP_MKDIR, /* 8 */
77 TOP_RMDIR, /* 9 */
78 TOP_SYMLINK, /* 10 */
79 TOP_FSYNC, /* 11 */
80 TOP_GETPAGE, /* 12 */
81 TOP_PUTPAGE, /* 13 */
82 TOP_SBUPDATE_FLUSH, /* 14 */
83 TOP_SBUPDATE_UPDATE, /* 15 */
84 TOP_SBUPDATE_UNMOUNT, /* 16 */
85 TOP_SYNCIP_CLOSEDQ, /* 17 */
86 TOP_SYNCIP_FLUSHI, /* 18 */
87 TOP_SYNCIP_HLOCK, /* 19 */
88 TOP_SYNCIP_SYNC, /* 20 */
89 TOP_SYNCIP_FREE, /* 21 */
90 TOP_SBWRITE_RECLAIM, /* 22 */
91 TOP_SBWRITE_STABLE, /* 23 */
92 TOP_IFREE, /* 24 */
93 TOP_IUPDAT, /* 25 */
94 TOP_MOUNT, /* 26 */
95 TOP_COMMIT_ASYNC, /* 27 */
96 TOP_COMMIT_FLUSH, /* 28 */
97 TOP_COMMIT_UPDATE, /* 29 */
98 TOP_COMMIT_UNMOUNT, /* 30 */
99 TOP_SETSECATTR, /* 31 */
100 TOP_QUOTA, /* 32 */
101 TOP_ITRUNC, /* 33 */
102 TOP_ALLOCSP, /* 34 */
103 TOP_MAX /* 35 TOP_MAX MUST be the last entry */
104 } top_t;
105
106 struct inode;
107 struct ufsvfs;
108
109 /*
110 * vfs_log == NULL means not logging
111 */
112 #define TRANS_ISTRANS(ufsvfsp) (ufsvfsp->vfs_log)
113
114 /*
115 * begin a synchronous transaction
116 */
117 #define TRANS_BEGIN_SYNC(ufsvfsp, vid, vsize, error)\
118 {\
119 if (TRANS_ISTRANS(ufsvfsp)) { \
120 error = 0; \
121 top_begin_sync(ufsvfsp, vid, vsize, &error); \
122 } \
123 }
124
125 /*
126 * begin a asynchronous transaction
127 */
128 #define TRANS_BEGIN_ASYNC(ufsvfsp, vid, vsize)\
129 {\
130 if (TRANS_ISTRANS(ufsvfsp))\
131 (void) top_begin_async(ufsvfsp, vid, vsize, 0); \
132 }
133
134 /*
135 * try to begin a asynchronous transaction
136 */
137 #define TRANS_TRY_BEGIN_ASYNC(ufsvfsp, vid, vsize, err)\
138 {\
139 if (TRANS_ISTRANS(ufsvfsp))\
140 err = top_begin_async(ufsvfsp, vid, vsize, 1); \
141 else\
142 err = 0; \
143 }
144
145 /*
146 * Begin a synchronous or asynchronous transaction.
147 * The lint case is needed because vsize can be a constant.
148 */
149 #ifndef __lint
150
151 #define TRANS_BEGIN_CSYNC(ufsvfsp, issync, vid, vsize)\
152 {\
153 if (TRANS_ISTRANS(ufsvfsp)) {\
154 if (ufsvfsp->vfs_syncdir) {\
155 int error = 0; \
156 ASSERT(vsize); \
157 top_begin_sync(ufsvfsp, vid, vsize, &error); \
158 ASSERT(error == 0); \
159 issync = 1; \
160 } else {\
161 (void) top_begin_async(ufsvfsp, vid, vsize, 0); \
162 issync = 0; \
163 }\
164 }\
165 }
166
167 #else /* __lint */
168
169 #define TRANS_BEGIN_CSYNC(ufsvfsp, issync, vid, vsize)\
170 {\
171 if (TRANS_ISTRANS(ufsvfsp)) {\
172 if (ufsvfsp->vfs_syncdir) {\
173 int error = 0; \
174 top_begin_sync(ufsvfsp, vid, vsize, &error); \
175 issync = 1; \
176 } else {\
177 (void) top_begin_async(ufsvfsp, vid, vsize, 0); \
178 issync = 0; \
179 }\
180 }\
181 }
182 #endif /* __lint */
183
184 /*
185 * try to begin a synchronous or asynchronous transaction
186 */
187
188 #define TRANS_TRY_BEGIN_CSYNC(ufsvfsp, issync, vid, vsize, error)\
189 {\
190 if (TRANS_ISTRANS(ufsvfsp)) {\
191 if (ufsvfsp->vfs_syncdir) {\
192 ASSERT(vsize); \
193 top_begin_sync(ufsvfsp, vid, vsize, &error); \
194 ASSERT(error == 0); \
195 issync = 1; \
196 } else {\
197 error = top_begin_async(ufsvfsp, vid, vsize, 1); \
198 issync = 0; \
199 }\
200 }\
201 }\
202
203
204 /*
205 * end a asynchronous transaction
206 */
207 #define TRANS_END_ASYNC(ufsvfsp, vid, vsize)\
208 {\
209 if (TRANS_ISTRANS(ufsvfsp))\
210 top_end_async(ufsvfsp, vid, vsize); \
211 }
212
213 /*
214 * end a synchronous transaction
215 */
216 #define TRANS_END_SYNC(ufsvfsp, error, vid, vsize)\
217 {\
218 if (TRANS_ISTRANS(ufsvfsp))\
219 top_end_sync(ufsvfsp, &error, vid, vsize); \
220 }
221
222 /*
223 * end a synchronous or asynchronous transaction
224 */
225 #define TRANS_END_CSYNC(ufsvfsp, error, issync, vid, vsize)\
226 {\
227 if (TRANS_ISTRANS(ufsvfsp))\
228 if (issync)\
229 top_end_sync(ufsvfsp, &error, vid, vsize); \
230 else\
231 top_end_async(ufsvfsp, vid, vsize); \
232 }
233 /*
234 * record a delta
235 */
236 #define TRANS_DELTA(ufsvfsp, mof, nb, dtyp, func, arg) \
237 if (TRANS_ISTRANS(ufsvfsp)) \
238 top_delta(ufsvfsp, (offset_t)(mof), nb, dtyp, func, arg)
239
240 /*
241 * cancel a delta
242 */
243 #define TRANS_CANCEL(ufsvfsp, mof, nb, flags) \
244 if (TRANS_ISTRANS(ufsvfsp)) \
245 top_cancel(ufsvfsp, (offset_t)(mof), nb, flags)
246 /*
247 * log a delta
248 */
249 #define TRANS_LOG(ufsvfsp, va, mof, nb, buf, bufsz) \
250 if (TRANS_ISTRANS(ufsvfsp)) \
251 top_log(ufsvfsp, va, (offset_t)(mof), nb, buf, bufsz)
252 /*
253 * check if a range is being canceled (converting from metadata into userdata)
254 */
255 #define TRANS_ISCANCEL(ufsvfsp, mof, nb) \
256 ((TRANS_ISTRANS(ufsvfsp)) ? \
257 top_iscancel(ufsvfsp, (offset_t)(mof), nb) : 0)
258 /*
259 * put the log into error state
260 */
261 #define TRANS_SETERROR(ufsvfsp) \
262 if (TRANS_ISTRANS(ufsvfsp)) \
263 top_seterror(ufsvfsp)
264 /*
265 * check if device has had an error
266 */
267 #define TRANS_ISERROR(ufsvfsp) \
268 ((TRANS_ISTRANS(ufsvfsp)) ? \
269 ufsvfsp->vfs_log->un_flags & LDL_ERROR : 0)
270
271 /*
272 * The following macros provide a more readable interface to TRANS_DELTA
273 */
274 #define TRANS_BUF(ufsvfsp, vof, nb, bp, type) \
275 TRANS_DELTA(ufsvfsp, \
276 ldbtob(bp->b_blkno) + (offset_t)(vof), nb, type, \
277 ufs_trans_push_buf, bp->b_blkno)
278
279 #define TRANS_BUF_ITEM_128(ufsvfsp, item, base, bp, type) \
280 TRANS_BUF(ufsvfsp, \
281 (((uintptr_t)&(item)) & ~(128 - 1)) - (uintptr_t)(base), 128, bp, type)
282
283 #define TRANS_INODE(ufsvfsp, ip) \
284 TRANS_DELTA(ufsvfsp, ip->i_doff, sizeof (struct dinode), \
285 DT_INODE, ufs_trans_push_inode, ip->i_number)
286
287 /*
288 * If ever parts of an inode except the timestamps are logged using
289 * this macro (or any other technique), bootloader logging support must
290 * be made aware of these changes.
291 */
292 #define TRANS_INODE_DELTA(ufsvfsp, vof, nb, ip) \
293 TRANS_DELTA(ufsvfsp, (ip->i_doff + (offset_t)(vof)), \
294 nb, DT_INODE, ufs_trans_push_inode, ip->i_number)
295
296 #define TRANS_INODE_TIMES(ufsvfsp, ip) \
297 TRANS_INODE_DELTA(ufsvfsp, (caddr_t)&ip->i_atime - (caddr_t)&ip->i_ic, \
298 sizeof (struct timeval32) * 3, ip)
299
300 /*
301 * Check if we need to log cylinder group summary info.
302 */
303 #define TRANS_SI(ufsvfsp, fs, cg) \
304 if (TRANS_ISTRANS(ufsvfsp)) \
305 if (ufsvfsp->vfs_nolog_si) \
306 fs->fs_si = FS_SI_BAD; \
307 else \
308 TRANS_DELTA(ufsvfsp, \
309 ldbtob(fsbtodb(fs, fs->fs_csaddr)) + \
310 ((caddr_t)&fs->fs_cs(fs, cg) - \
311 (caddr_t)fs->fs_u.fs_csp), \
312 sizeof (struct csum), DT_SI, \
313 ufs_trans_push_si, cg)
314
315 #define TRANS_DIR(ip, offset) \
316 (TRANS_ISTRANS(ip->i_ufsvfs) ? ufs_trans_dir(ip, offset) : 0)
317
318 #define TRANS_QUOTA(dqp) \
319 if (TRANS_ISTRANS(dqp->dq_ufsvfsp)) \
320 ufs_trans_quota(dqp);
321
322 #define TRANS_DQRELE(ufsvfsp, dqp) \
323 if (TRANS_ISTRANS(ufsvfsp) && \
324 ((curthread->t_flag & T_DONTBLOCK) == 0)) { \
325 ufs_trans_dqrele(dqp); \
326 } else { \
327 rw_enter(&ufsvfsp->vfs_dqrwlock, RW_READER); \
328 dqrele(dqp); \
329 rw_exit(&ufsvfsp->vfs_dqrwlock); \
330 }
331
332 #define TRANS_ITRUNC(ip, length, flags, cr) \
333 ufs_trans_itrunc(ip, length, flags, cr);
334
335 #define TRANS_WRITE_RESV(ip, uiop, ulp, resvp, residp) \
336 if ((TRANS_ISTRANS(ip->i_ufsvfs) != NULL) && (ulp != NULL)) \
337 ufs_trans_write_resv(ip, uiop, resvp, residp);
338
339 #define TRANS_WRITE(ip, uiop, ioflag, err, ulp, cr, resv, resid) \
340 if ((TRANS_ISTRANS(ip->i_ufsvfs) != NULL) && (ulp != NULL)) \
341 err = ufs_trans_write(ip, uiop, ioflag, cr, resv, resid); \
342 else \
343 err = wrip(ip, uiop, ioflag, cr);
344
345 /*
346 * These functions "wrap" functions that are not VOP or VFS
347 * entry points but must still use the TRANS_BEGIN/TRANS_END
348 * protocol
349 */
350 #define TRANS_SBUPDATE(ufsvfsp, vfsp, topid) \
351 ufs_trans_sbupdate(ufsvfsp, vfsp, topid)
352 #define TRANS_SYNCIP(ip, bflags, iflag, topid) \
353 ufs_syncip(ip, bflags, iflag, topid)
354 #define TRANS_SBWRITE(ufsvfsp, topid) ufs_trans_sbwrite(ufsvfsp, topid)
355 #define TRANS_IUPDAT(ip, waitfor) ufs_trans_iupdat(ip, waitfor)
356
357 #ifdef DEBUG
358 /*
359 * Test/Debug ops
360 * The following ops maintain the metadata map.
361 * The metadata map is a debug/test feature.
362 * These ops are *not* used in the production product.
363 */
364
365 /*
366 * Set a flag if meta data checking.
367 */
368 #define TRANS_DOMATAMAP(ufsvfsp) \
369 ufsvfsp->vfs_domatamap = \
370 (TRANS_ISTRANS(ufsvfsp) && \
371 (ufsvfsp->vfs_log->un_debug & MT_MATAMAP))
372
373 #define TRANS_MATA_IGET(ufsvfsp, ip) \
374 if (ufsvfsp->vfs_domatamap) \
375 ufs_trans_mata_iget(ip)
376
377 #define TRANS_MATA_FREE(ufsvfsp, mof, nb) \
378 if (ufsvfsp->vfs_domatamap) \
379 ufs_trans_mata_free(ufsvfsp, (offset_t)(mof), nb)
380
381 #define TRANS_MATA_ALLOC(ufsvfsp, ip, bno, size, zero) \
382 if (ufsvfsp->vfs_domatamap) \
383 ufs_trans_mata_alloc(ufsvfsp, ip, bno, size, zero)
384
385 #define TRANS_MATA_MOUNT(ufsvfsp) \
386 if (ufsvfsp->vfs_domatamap) \
387 ufs_trans_mata_mount(ufsvfsp)
388
389 #define TRANS_MATA_UMOUNT(ufsvfsp) \
390 if (ufsvfsp->vfs_domatamap) \
391 ufs_trans_mata_umount(ufsvfsp)
392
393 #define TRANS_MATA_SI(ufsvfsp, fs) \
394 if (ufsvfsp->vfs_domatamap) \
395 ufs_trans_mata_si(ufsvfsp, fs)
396
397 #define TRANS_MATAADD(ufsvfsp, mof, nb) \
398 top_mataadd(ufsvfsp, (offset_t)(mof), nb)
399
400 #else /* !DEBUG */
401
402 #define TRANS_DOMATAMAP(ufsvfsp)
403 #define TRANS_MATA_IGET(ufsvfsp, ip)
404 #define TRANS_MATA_FREE(ufsvfsp, mof, nb)
405 #define TRANS_MATA_ALLOC(ufsvfsp, ip, bno, size, zero)
406 #define TRANS_MATA_MOUNT(ufsvfsp)
407 #define TRANS_MATA_UMOUNT(ufsvfsp)
408 #define TRANS_MATA_SI(ufsvfsp, fs)
409 #define TRANS_MATAADD(ufsvfsp, mof, nb)
410
411 #endif /* !DEBUG */
412
413 #include <sys/fs/ufs_quota.h>
414 #include <sys/fs/ufs_lockfs.h>
415 /*
416 * identifies the type of operation passed into TRANS_BEGIN/END
417 */
418 #define TOP_SYNC (0x00000001)
419 #define TOP_ASYNC (0x00000002)
420 #define TOP_SYNC_FORCED (0x00000004) /* forced sync transaction */
421 /*
422 * estimated values
423 */
424 #define HEADERSIZE (128)
425 #define ALLOCSIZE (160)
426 #define INODESIZE (sizeof (struct dinode) + HEADERSIZE)
427 #define SIZESB ((sizeof (struct fs)) + HEADERSIZE)
428 #define SIZEDIR (DIRBLKSIZ + HEADERSIZE)
429 /*
430 * calculated values
431 */
432 #define SIZECG(IP) ((IP)->i_fs->fs_cgsize + HEADERSIZE)
433 #define FRAGSIZE(IP) ((IP)->i_fs->fs_fsize + HEADERSIZE)
434 #define ACLSIZE(IP) (((IP)->i_ufsvfs->vfs_maxacl + HEADERSIZE) + \
435 INODESIZE)
436 #define MAXACLSIZE ((MAX_ACL_ENTRIES << 1) * sizeof (aclent_t))
437 #define DIRSIZE(IP) (INODESIZE + (4 * ALLOCSIZE) + \
438 (IP)->i_fs->fs_fsize + HEADERSIZE)
439 #define QUOTASIZE sizeof (struct dquot) + HEADERSIZE
440 /*
441 * size calculations
442 */
443 #define TOP_CREATE_SIZE(IP) \
444 (ACLSIZE(IP) + SIZECG(IP) + DIRSIZE(IP) + INODESIZE)
445 #define TOP_REMOVE_SIZE(IP) \
446 DIRSIZE(IP) + SIZECG(IP) + INODESIZE + SIZESB
447 #define TOP_LINK_SIZE(IP) \
448 DIRSIZE(IP) + INODESIZE
449 #define TOP_RENAME_SIZE(IP) \
450 DIRSIZE(IP) + DIRSIZE(IP) + SIZECG(IP)
451 #define TOP_MKDIR_SIZE(IP) \
452 DIRSIZE(IP) + INODESIZE + DIRSIZE(IP) + INODESIZE + FRAGSIZE(IP) + \
453 SIZECG(IP) + ACLSIZE(IP)
454 #define TOP_SYMLINK_SIZE(IP) \
455 DIRSIZE((IP)) + INODESIZE + INODESIZE + SIZECG(IP)
456 #define TOP_GETPAGE_SIZE(IP) \
457 ALLOCSIZE + ALLOCSIZE + ALLOCSIZE + INODESIZE + SIZECG(IP)
458 #define TOP_SYNCIP_SIZE INODESIZE
459 #define TOP_READ_SIZE INODESIZE
460 #define TOP_RMDIR_SIZE (SIZESB + (INODESIZE * 2) + SIZEDIR)
461 #define TOP_SETQUOTA_SIZE(FS) ((FS)->fs_bsize << 2)
462 #define TOP_QUOTA_SIZE (QUOTASIZE)
463 #define TOP_SETSECATTR_SIZE(IP) (MAXACLSIZE)
464 #define TOP_IUPDAT_SIZE(IP) INODESIZE + SIZECG(IP)
465 #define TOP_SBUPDATE_SIZE (SIZESB)
466 #define TOP_SBWRITE_SIZE (SIZESB)
467 #define TOP_PUTPAGE_SIZE(IP) (INODESIZE + SIZECG(IP))
468 #define TOP_SETATTR_SIZE(IP) (SIZECG(IP) + INODESIZE + QUOTASIZE + \
469 ACLSIZE(IP))
470 #define TOP_IFREE_SIZE(IP) (SIZECG(IP) + INODESIZE + QUOTASIZE)
471 #define TOP_MOUNT_SIZE (SIZESB)
472 #define TOP_COMMIT_SIZE (0)
473
474 /*
475 * The minimum log size is 1M. So we will allow 1 fs operation to
476 * reserve at most 512K of log space.
477 */
478 #define TOP_MAX_RESV (512 * 1024)
479
480
481 /*
482 * ufs trans function prototypes
483 */
484 #if defined(_KERNEL) && defined(__STDC__)
485
486 extern int ufs_trans_hlock();
487 extern void ufs_trans_onerror();
488 extern int ufs_trans_push_inode(struct ufsvfs *, delta_t, ino_t);
489 extern int ufs_trans_push_buf(struct ufsvfs *, delta_t, daddr_t);
490 extern int ufs_trans_push_si(struct ufsvfs *, delta_t, int);
491 extern void ufs_trans_sbupdate(struct ufsvfs *, struct vfs *,
492 top_t);
493 extern void ufs_trans_sbwrite(struct ufsvfs *, top_t);
494 extern void ufs_trans_iupdat(struct inode *, int);
495 extern void ufs_trans_mata_mount(struct ufsvfs *);
496 extern void ufs_trans_mata_umount(struct ufsvfs *);
497 extern void ufs_trans_mata_si(struct ufsvfs *, struct fs *);
498 extern void ufs_trans_mata_iget(struct inode *);
499 extern void ufs_trans_mata_free(struct ufsvfs *, offset_t, off_t);
500 extern void ufs_trans_mata_alloc(struct ufsvfs *, struct inode *,
501 daddr_t, ulong_t, int);
502 extern int ufs_trans_dir(struct inode *, off_t);
503 extern void ufs_trans_quota(struct dquot *);
504 extern void ufs_trans_dqrele(struct dquot *);
505 extern int ufs_trans_itrunc(struct inode *, u_offset_t, int,
506 cred_t *);
507 extern int ufs_trans_write(struct inode *, struct uio *, int,
508 cred_t *, int, long);
509 extern void ufs_trans_write_resv(struct inode *, struct uio *,
510 int *, int *);
511 extern int ufs_trans_check(dev_t);
512 extern void ufs_trans_redev(dev_t odev, dev_t ndev);
513 extern void ufs_trans_trunc_resv(struct inode *, u_offset_t, int *,
514 u_offset_t *);
515
516 /*
517 * transaction prototypes
518 */
519 void lufs_unsnarf(struct ufsvfs *ufsvfsp);
520 int lufs_snarf(struct ufsvfs *ufsvfsp, struct fs *fs, int ronly);
521 void top_delta(struct ufsvfs *ufsvfsp, offset_t mof, off_t nb, delta_t dtyp,
522 int (*func)(), ulong_t arg);
523 void top_cancel(struct ufsvfs *ufsvfsp, offset_t mof, off_t nb, int flags);
524 int top_iscancel(struct ufsvfs *ufsvfsp, offset_t mof, off_t nb);
525 void top_seterror(struct ufsvfs *ufsvfsp);
526 int top_iserror(struct ufsvfs *ufsvfsp);
527 void top_begin_sync(struct ufsvfs *ufsvfsp, top_t topid, ulong_t size,
528 int *error);
529 int top_begin_async(struct ufsvfs *ufsvfsp, top_t topid, ulong_t size,
530 int tryasync);
531 void top_end_sync(struct ufsvfs *ufsvfsp, int *ep, top_t topid,
532 ulong_t size);
533 void top_end_async(struct ufsvfs *ufsvfsp, top_t topid, ulong_t size);
534 void top_log(struct ufsvfs *ufsvfsp, char *va, offset_t vamof, off_t nb,
535 caddr_t buf, uint32_t bufsz);
536 void top_mataadd(struct ufsvfs *ufsvfsp, offset_t mof, off_t nb);
537 void top_matadel(struct ufsvfs *ufsvfsp, offset_t mof, off_t nb);
538 void top_mataclr(struct ufsvfs *ufsvfsp);
539
540
541 #endif /* defined(_KERNEL) && defined(__STDC__) */
542
543 #ifdef __cplusplus
544 }
545 #endif
546
547 #endif /* _SYS_FS_UFS_TRANS_H */