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 2014 Garrett D'Amore <garrett@damore.org> 24 * 25 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 26 * Use is subject to license terms. 27 */ 28 29 #ifndef _SYS_FS_UFS_TRANS_H 30 #define _SYS_FS_UFS_TRANS_H 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) 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) */ 542 543 #ifdef __cplusplus 544 } 545 #endif 546 547 #endif /* _SYS_FS_UFS_TRANS_H */