17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 23*ba3594baSGarrett D'Amore * Copyright 2014 Garrett D'Amore <garrett@damore.org> 24*ba3594baSGarrett D'Amore * 25303bf60bSsdebnath * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 267c478bd9Sstevel@tonic-gate * Use is subject to license terms. 277c478bd9Sstevel@tonic-gate */ 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #ifndef _SYS_FS_UFS_TRANS_H 307c478bd9Sstevel@tonic-gate #define _SYS_FS_UFS_TRANS_H 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #ifdef __cplusplus 337c478bd9Sstevel@tonic-gate extern "C" { 347c478bd9Sstevel@tonic-gate #endif 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include <sys/types.h> 377c478bd9Sstevel@tonic-gate #include <sys/cred.h> 387c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_fs.h> 397c478bd9Sstevel@tonic-gate 407c478bd9Sstevel@tonic-gate /* 417c478bd9Sstevel@tonic-gate * Types of deltas 427c478bd9Sstevel@tonic-gate */ 437c478bd9Sstevel@tonic-gate typedef enum delta_type { 447c478bd9Sstevel@tonic-gate DT_NONE, /* 0 no assigned type */ 457c478bd9Sstevel@tonic-gate DT_SB, /* 1 superblock */ 467c478bd9Sstevel@tonic-gate DT_CG, /* 2 cylinder group */ 477c478bd9Sstevel@tonic-gate DT_SI, /* 3 summary info */ 487c478bd9Sstevel@tonic-gate DT_AB, /* 4 allocation block */ 497c478bd9Sstevel@tonic-gate DT_ABZERO, /* 5 a zero'ed allocation block */ 507c478bd9Sstevel@tonic-gate DT_DIR, /* 6 directory */ 517c478bd9Sstevel@tonic-gate DT_INODE, /* 7 inode */ 527c478bd9Sstevel@tonic-gate DT_FBI, /* 8 fbiwrite */ 537c478bd9Sstevel@tonic-gate DT_QR, /* 9 quota record */ 547c478bd9Sstevel@tonic-gate DT_COMMIT, /* 10 commit record */ 557c478bd9Sstevel@tonic-gate DT_CANCEL, /* 11 cancel record */ 567c478bd9Sstevel@tonic-gate DT_BOT, /* 12 begin transaction */ 577c478bd9Sstevel@tonic-gate DT_EOT, /* 13 end transaction */ 587c478bd9Sstevel@tonic-gate DT_UD, /* 14 userdata */ 597c478bd9Sstevel@tonic-gate DT_SUD, /* 15 userdata found during log scan */ 607c478bd9Sstevel@tonic-gate DT_SHAD, /* 16 data for a shadow inode */ 617c478bd9Sstevel@tonic-gate DT_MAX /* 17 maximum delta type */ 627c478bd9Sstevel@tonic-gate } delta_t; 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate /* 657c478bd9Sstevel@tonic-gate * transaction operation types 667c478bd9Sstevel@tonic-gate */ 677c478bd9Sstevel@tonic-gate typedef enum top_type { 687c478bd9Sstevel@tonic-gate TOP_READ_SYNC, /* 0 */ 697c478bd9Sstevel@tonic-gate TOP_WRITE, /* 1 */ 707c478bd9Sstevel@tonic-gate TOP_WRITE_SYNC, /* 2 */ 717c478bd9Sstevel@tonic-gate TOP_SETATTR, /* 3 */ 727c478bd9Sstevel@tonic-gate TOP_CREATE, /* 4 */ 737c478bd9Sstevel@tonic-gate TOP_REMOVE, /* 5 */ 747c478bd9Sstevel@tonic-gate TOP_LINK, /* 6 */ 757c478bd9Sstevel@tonic-gate TOP_RENAME, /* 7 */ 767c478bd9Sstevel@tonic-gate TOP_MKDIR, /* 8 */ 777c478bd9Sstevel@tonic-gate TOP_RMDIR, /* 9 */ 787c478bd9Sstevel@tonic-gate TOP_SYMLINK, /* 10 */ 797c478bd9Sstevel@tonic-gate TOP_FSYNC, /* 11 */ 807c478bd9Sstevel@tonic-gate TOP_GETPAGE, /* 12 */ 817c478bd9Sstevel@tonic-gate TOP_PUTPAGE, /* 13 */ 827c478bd9Sstevel@tonic-gate TOP_SBUPDATE_FLUSH, /* 14 */ 837c478bd9Sstevel@tonic-gate TOP_SBUPDATE_UPDATE, /* 15 */ 847c478bd9Sstevel@tonic-gate TOP_SBUPDATE_UNMOUNT, /* 16 */ 857c478bd9Sstevel@tonic-gate TOP_SYNCIP_CLOSEDQ, /* 17 */ 867c478bd9Sstevel@tonic-gate TOP_SYNCIP_FLUSHI, /* 18 */ 877c478bd9Sstevel@tonic-gate TOP_SYNCIP_HLOCK, /* 19 */ 887c478bd9Sstevel@tonic-gate TOP_SYNCIP_SYNC, /* 20 */ 897c478bd9Sstevel@tonic-gate TOP_SYNCIP_FREE, /* 21 */ 907c478bd9Sstevel@tonic-gate TOP_SBWRITE_RECLAIM, /* 22 */ 917c478bd9Sstevel@tonic-gate TOP_SBWRITE_STABLE, /* 23 */ 927c478bd9Sstevel@tonic-gate TOP_IFREE, /* 24 */ 937c478bd9Sstevel@tonic-gate TOP_IUPDAT, /* 25 */ 947c478bd9Sstevel@tonic-gate TOP_MOUNT, /* 26 */ 957c478bd9Sstevel@tonic-gate TOP_COMMIT_ASYNC, /* 27 */ 967c478bd9Sstevel@tonic-gate TOP_COMMIT_FLUSH, /* 28 */ 977c478bd9Sstevel@tonic-gate TOP_COMMIT_UPDATE, /* 29 */ 987c478bd9Sstevel@tonic-gate TOP_COMMIT_UNMOUNT, /* 30 */ 997c478bd9Sstevel@tonic-gate TOP_SETSECATTR, /* 31 */ 1007c478bd9Sstevel@tonic-gate TOP_QUOTA, /* 32 */ 1017c478bd9Sstevel@tonic-gate TOP_ITRUNC, /* 33 */ 102303bf60bSsdebnath TOP_ALLOCSP, /* 34 */ 103303bf60bSsdebnath TOP_MAX /* 35 TOP_MAX MUST be the last entry */ 1047c478bd9Sstevel@tonic-gate } top_t; 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate struct inode; 1077c478bd9Sstevel@tonic-gate struct ufsvfs; 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate /* 1107c478bd9Sstevel@tonic-gate * vfs_log == NULL means not logging 1117c478bd9Sstevel@tonic-gate */ 1127c478bd9Sstevel@tonic-gate #define TRANS_ISTRANS(ufsvfsp) (ufsvfsp->vfs_log) 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate /* 1157c478bd9Sstevel@tonic-gate * begin a synchronous transaction 1167c478bd9Sstevel@tonic-gate */ 1177c478bd9Sstevel@tonic-gate #define TRANS_BEGIN_SYNC(ufsvfsp, vid, vsize, error)\ 1187c478bd9Sstevel@tonic-gate {\ 1197c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(ufsvfsp)) { \ 1207c478bd9Sstevel@tonic-gate error = 0; \ 1217c478bd9Sstevel@tonic-gate top_begin_sync(ufsvfsp, vid, vsize, &error); \ 1227c478bd9Sstevel@tonic-gate } \ 1237c478bd9Sstevel@tonic-gate } 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate /* 1267c478bd9Sstevel@tonic-gate * begin a asynchronous transaction 1277c478bd9Sstevel@tonic-gate */ 1287c478bd9Sstevel@tonic-gate #define TRANS_BEGIN_ASYNC(ufsvfsp, vid, vsize)\ 1297c478bd9Sstevel@tonic-gate {\ 1307c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(ufsvfsp))\ 1317c478bd9Sstevel@tonic-gate (void) top_begin_async(ufsvfsp, vid, vsize, 0); \ 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate /* 1357c478bd9Sstevel@tonic-gate * try to begin a asynchronous transaction 1367c478bd9Sstevel@tonic-gate */ 1377c478bd9Sstevel@tonic-gate #define TRANS_TRY_BEGIN_ASYNC(ufsvfsp, vid, vsize, err)\ 1387c478bd9Sstevel@tonic-gate {\ 1397c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(ufsvfsp))\ 1407c478bd9Sstevel@tonic-gate err = top_begin_async(ufsvfsp, vid, vsize, 1); \ 1417c478bd9Sstevel@tonic-gate else\ 1427c478bd9Sstevel@tonic-gate err = 0; \ 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate /* 1467c478bd9Sstevel@tonic-gate * Begin a synchronous or asynchronous transaction. 1477c478bd9Sstevel@tonic-gate * The lint case is needed because vsize can be a constant. 1487c478bd9Sstevel@tonic-gate */ 1497c478bd9Sstevel@tonic-gate #ifndef __lint 1507c478bd9Sstevel@tonic-gate 1517c478bd9Sstevel@tonic-gate #define TRANS_BEGIN_CSYNC(ufsvfsp, issync, vid, vsize)\ 1527c478bd9Sstevel@tonic-gate {\ 1537c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(ufsvfsp)) {\ 1547c478bd9Sstevel@tonic-gate if (ufsvfsp->vfs_syncdir) {\ 1557c478bd9Sstevel@tonic-gate int error = 0; \ 1567c478bd9Sstevel@tonic-gate ASSERT(vsize); \ 1577c478bd9Sstevel@tonic-gate top_begin_sync(ufsvfsp, vid, vsize, &error); \ 1587c478bd9Sstevel@tonic-gate ASSERT(error == 0); \ 1597c478bd9Sstevel@tonic-gate issync = 1; \ 1607c478bd9Sstevel@tonic-gate } else {\ 1617c478bd9Sstevel@tonic-gate (void) top_begin_async(ufsvfsp, vid, vsize, 0); \ 1627c478bd9Sstevel@tonic-gate issync = 0; \ 1637c478bd9Sstevel@tonic-gate }\ 1647c478bd9Sstevel@tonic-gate }\ 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate #else /* __lint */ 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate #define TRANS_BEGIN_CSYNC(ufsvfsp, issync, vid, vsize)\ 1707c478bd9Sstevel@tonic-gate {\ 1717c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(ufsvfsp)) {\ 1727c478bd9Sstevel@tonic-gate if (ufsvfsp->vfs_syncdir) {\ 1737c478bd9Sstevel@tonic-gate int error = 0; \ 1747c478bd9Sstevel@tonic-gate top_begin_sync(ufsvfsp, vid, vsize, &error); \ 1757c478bd9Sstevel@tonic-gate issync = 1; \ 1767c478bd9Sstevel@tonic-gate } else {\ 1777c478bd9Sstevel@tonic-gate (void) top_begin_async(ufsvfsp, vid, vsize, 0); \ 1787c478bd9Sstevel@tonic-gate issync = 0; \ 1797c478bd9Sstevel@tonic-gate }\ 1807c478bd9Sstevel@tonic-gate }\ 1817c478bd9Sstevel@tonic-gate } 1827c478bd9Sstevel@tonic-gate #endif /* __lint */ 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate /* 1857c478bd9Sstevel@tonic-gate * try to begin a synchronous or asynchronous transaction 1867c478bd9Sstevel@tonic-gate */ 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate #define TRANS_TRY_BEGIN_CSYNC(ufsvfsp, issync, vid, vsize, error)\ 1897c478bd9Sstevel@tonic-gate {\ 1907c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(ufsvfsp)) {\ 1917c478bd9Sstevel@tonic-gate if (ufsvfsp->vfs_syncdir) {\ 1927c478bd9Sstevel@tonic-gate ASSERT(vsize); \ 1937c478bd9Sstevel@tonic-gate top_begin_sync(ufsvfsp, vid, vsize, &error); \ 1947c478bd9Sstevel@tonic-gate ASSERT(error == 0); \ 1957c478bd9Sstevel@tonic-gate issync = 1; \ 1967c478bd9Sstevel@tonic-gate } else {\ 1977c478bd9Sstevel@tonic-gate error = top_begin_async(ufsvfsp, vid, vsize, 1); \ 1987c478bd9Sstevel@tonic-gate issync = 0; \ 1997c478bd9Sstevel@tonic-gate }\ 2007c478bd9Sstevel@tonic-gate }\ 2017c478bd9Sstevel@tonic-gate }\ 2027c478bd9Sstevel@tonic-gate 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate /* 2057c478bd9Sstevel@tonic-gate * end a asynchronous transaction 2067c478bd9Sstevel@tonic-gate */ 2077c478bd9Sstevel@tonic-gate #define TRANS_END_ASYNC(ufsvfsp, vid, vsize)\ 2087c478bd9Sstevel@tonic-gate {\ 2097c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(ufsvfsp))\ 2107c478bd9Sstevel@tonic-gate top_end_async(ufsvfsp, vid, vsize); \ 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate /* 2147c478bd9Sstevel@tonic-gate * end a synchronous transaction 2157c478bd9Sstevel@tonic-gate */ 2167c478bd9Sstevel@tonic-gate #define TRANS_END_SYNC(ufsvfsp, error, vid, vsize)\ 2177c478bd9Sstevel@tonic-gate {\ 2187c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(ufsvfsp))\ 2197c478bd9Sstevel@tonic-gate top_end_sync(ufsvfsp, &error, vid, vsize); \ 2207c478bd9Sstevel@tonic-gate } 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate /* 2237c478bd9Sstevel@tonic-gate * end a synchronous or asynchronous transaction 2247c478bd9Sstevel@tonic-gate */ 2257c478bd9Sstevel@tonic-gate #define TRANS_END_CSYNC(ufsvfsp, error, issync, vid, vsize)\ 2267c478bd9Sstevel@tonic-gate {\ 2277c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(ufsvfsp))\ 2287c478bd9Sstevel@tonic-gate if (issync)\ 2297c478bd9Sstevel@tonic-gate top_end_sync(ufsvfsp, &error, vid, vsize); \ 2307c478bd9Sstevel@tonic-gate else\ 2317c478bd9Sstevel@tonic-gate top_end_async(ufsvfsp, vid, vsize); \ 2327c478bd9Sstevel@tonic-gate } 2337c478bd9Sstevel@tonic-gate /* 2347c478bd9Sstevel@tonic-gate * record a delta 2357c478bd9Sstevel@tonic-gate */ 2367c478bd9Sstevel@tonic-gate #define TRANS_DELTA(ufsvfsp, mof, nb, dtyp, func, arg) \ 2377c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(ufsvfsp)) \ 2387c478bd9Sstevel@tonic-gate top_delta(ufsvfsp, (offset_t)(mof), nb, dtyp, func, arg) 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate /* 2417c478bd9Sstevel@tonic-gate * cancel a delta 2427c478bd9Sstevel@tonic-gate */ 2437c478bd9Sstevel@tonic-gate #define TRANS_CANCEL(ufsvfsp, mof, nb, flags) \ 2447c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(ufsvfsp)) \ 2457c478bd9Sstevel@tonic-gate top_cancel(ufsvfsp, (offset_t)(mof), nb, flags) 2467c478bd9Sstevel@tonic-gate /* 2477c478bd9Sstevel@tonic-gate * log a delta 2487c478bd9Sstevel@tonic-gate */ 2497c478bd9Sstevel@tonic-gate #define TRANS_LOG(ufsvfsp, va, mof, nb, buf, bufsz) \ 2507c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(ufsvfsp)) \ 2517c478bd9Sstevel@tonic-gate top_log(ufsvfsp, va, (offset_t)(mof), nb, buf, bufsz) 2527c478bd9Sstevel@tonic-gate /* 2537c478bd9Sstevel@tonic-gate * check if a range is being canceled (converting from metadata into userdata) 2547c478bd9Sstevel@tonic-gate */ 2557c478bd9Sstevel@tonic-gate #define TRANS_ISCANCEL(ufsvfsp, mof, nb) \ 2567c478bd9Sstevel@tonic-gate ((TRANS_ISTRANS(ufsvfsp)) ? \ 2577c478bd9Sstevel@tonic-gate top_iscancel(ufsvfsp, (offset_t)(mof), nb) : 0) 2587c478bd9Sstevel@tonic-gate /* 2597c478bd9Sstevel@tonic-gate * put the log into error state 2607c478bd9Sstevel@tonic-gate */ 2617c478bd9Sstevel@tonic-gate #define TRANS_SETERROR(ufsvfsp) \ 2627c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(ufsvfsp)) \ 2637c478bd9Sstevel@tonic-gate top_seterror(ufsvfsp) 2647c478bd9Sstevel@tonic-gate /* 2657c478bd9Sstevel@tonic-gate * check if device has had an error 2667c478bd9Sstevel@tonic-gate */ 2677c478bd9Sstevel@tonic-gate #define TRANS_ISERROR(ufsvfsp) \ 2687c478bd9Sstevel@tonic-gate ((TRANS_ISTRANS(ufsvfsp)) ? \ 2697c478bd9Sstevel@tonic-gate ufsvfsp->vfs_log->un_flags & LDL_ERROR : 0) 2707c478bd9Sstevel@tonic-gate 2717c478bd9Sstevel@tonic-gate /* 2727c478bd9Sstevel@tonic-gate * The following macros provide a more readable interface to TRANS_DELTA 2737c478bd9Sstevel@tonic-gate */ 2747c478bd9Sstevel@tonic-gate #define TRANS_BUF(ufsvfsp, vof, nb, bp, type) \ 2757c478bd9Sstevel@tonic-gate TRANS_DELTA(ufsvfsp, \ 2767c478bd9Sstevel@tonic-gate ldbtob(bp->b_blkno) + (offset_t)(vof), nb, type, \ 2777c478bd9Sstevel@tonic-gate ufs_trans_push_buf, bp->b_blkno) 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate #define TRANS_BUF_ITEM_128(ufsvfsp, item, base, bp, type) \ 2807c478bd9Sstevel@tonic-gate TRANS_BUF(ufsvfsp, \ 2817c478bd9Sstevel@tonic-gate (((uintptr_t)&(item)) & ~(128 - 1)) - (uintptr_t)(base), 128, bp, type) 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate #define TRANS_INODE(ufsvfsp, ip) \ 2847c478bd9Sstevel@tonic-gate TRANS_DELTA(ufsvfsp, ip->i_doff, sizeof (struct dinode), \ 2857c478bd9Sstevel@tonic-gate DT_INODE, ufs_trans_push_inode, ip->i_number) 2867c478bd9Sstevel@tonic-gate 2877c478bd9Sstevel@tonic-gate /* 2887c478bd9Sstevel@tonic-gate * If ever parts of an inode except the timestamps are logged using 2897c478bd9Sstevel@tonic-gate * this macro (or any other technique), bootloader logging support must 2907c478bd9Sstevel@tonic-gate * be made aware of these changes. 2917c478bd9Sstevel@tonic-gate */ 2927c478bd9Sstevel@tonic-gate #define TRANS_INODE_DELTA(ufsvfsp, vof, nb, ip) \ 2937c478bd9Sstevel@tonic-gate TRANS_DELTA(ufsvfsp, (ip->i_doff + (offset_t)(vof)), \ 2947c478bd9Sstevel@tonic-gate nb, DT_INODE, ufs_trans_push_inode, ip->i_number) 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate #define TRANS_INODE_TIMES(ufsvfsp, ip) \ 2977c478bd9Sstevel@tonic-gate TRANS_INODE_DELTA(ufsvfsp, (caddr_t)&ip->i_atime - (caddr_t)&ip->i_ic, \ 2987c478bd9Sstevel@tonic-gate sizeof (struct timeval32) * 3, ip) 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate /* 3017c478bd9Sstevel@tonic-gate * Check if we need to log cylinder group summary info. 3027c478bd9Sstevel@tonic-gate */ 3037c478bd9Sstevel@tonic-gate #define TRANS_SI(ufsvfsp, fs, cg) \ 3047c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(ufsvfsp)) \ 3057c478bd9Sstevel@tonic-gate if (ufsvfsp->vfs_nolog_si) \ 3067c478bd9Sstevel@tonic-gate fs->fs_si = FS_SI_BAD; \ 3077c478bd9Sstevel@tonic-gate else \ 3087c478bd9Sstevel@tonic-gate TRANS_DELTA(ufsvfsp, \ 3097c478bd9Sstevel@tonic-gate ldbtob(fsbtodb(fs, fs->fs_csaddr)) + \ 3107c478bd9Sstevel@tonic-gate ((caddr_t)&fs->fs_cs(fs, cg) - \ 3117c478bd9Sstevel@tonic-gate (caddr_t)fs->fs_u.fs_csp), \ 3127c478bd9Sstevel@tonic-gate sizeof (struct csum), DT_SI, \ 3137c478bd9Sstevel@tonic-gate ufs_trans_push_si, cg) 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate #define TRANS_DIR(ip, offset) \ 3167c478bd9Sstevel@tonic-gate (TRANS_ISTRANS(ip->i_ufsvfs) ? ufs_trans_dir(ip, offset) : 0) 3177c478bd9Sstevel@tonic-gate 3187c478bd9Sstevel@tonic-gate #define TRANS_QUOTA(dqp) \ 3197c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(dqp->dq_ufsvfsp)) \ 3207c478bd9Sstevel@tonic-gate ufs_trans_quota(dqp); 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate #define TRANS_DQRELE(ufsvfsp, dqp) \ 3237c478bd9Sstevel@tonic-gate if (TRANS_ISTRANS(ufsvfsp) && \ 3247c478bd9Sstevel@tonic-gate ((curthread->t_flag & T_DONTBLOCK) == 0)) { \ 3257c478bd9Sstevel@tonic-gate ufs_trans_dqrele(dqp); \ 3267c478bd9Sstevel@tonic-gate } else { \ 3277c478bd9Sstevel@tonic-gate rw_enter(&ufsvfsp->vfs_dqrwlock, RW_READER); \ 3287c478bd9Sstevel@tonic-gate dqrele(dqp); \ 3297c478bd9Sstevel@tonic-gate rw_exit(&ufsvfsp->vfs_dqrwlock); \ 3307c478bd9Sstevel@tonic-gate } 3317c478bd9Sstevel@tonic-gate 3327c478bd9Sstevel@tonic-gate #define TRANS_ITRUNC(ip, length, flags, cr) \ 3337c478bd9Sstevel@tonic-gate ufs_trans_itrunc(ip, length, flags, cr); 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate #define TRANS_WRITE_RESV(ip, uiop, ulp, resvp, residp) \ 3367c478bd9Sstevel@tonic-gate if ((TRANS_ISTRANS(ip->i_ufsvfs) != NULL) && (ulp != NULL)) \ 3377c478bd9Sstevel@tonic-gate ufs_trans_write_resv(ip, uiop, resvp, residp); 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate #define TRANS_WRITE(ip, uiop, ioflag, err, ulp, cr, resv, resid) \ 3407c478bd9Sstevel@tonic-gate if ((TRANS_ISTRANS(ip->i_ufsvfs) != NULL) && (ulp != NULL)) \ 3417c478bd9Sstevel@tonic-gate err = ufs_trans_write(ip, uiop, ioflag, cr, resv, resid); \ 3427c478bd9Sstevel@tonic-gate else \ 3437c478bd9Sstevel@tonic-gate err = wrip(ip, uiop, ioflag, cr); 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate /* 3467c478bd9Sstevel@tonic-gate * These functions "wrap" functions that are not VOP or VFS 3477c478bd9Sstevel@tonic-gate * entry points but must still use the TRANS_BEGIN/TRANS_END 3487c478bd9Sstevel@tonic-gate * protocol 3497c478bd9Sstevel@tonic-gate */ 3507c478bd9Sstevel@tonic-gate #define TRANS_SBUPDATE(ufsvfsp, vfsp, topid) \ 3517c478bd9Sstevel@tonic-gate ufs_trans_sbupdate(ufsvfsp, vfsp, topid) 3527c478bd9Sstevel@tonic-gate #define TRANS_SYNCIP(ip, bflags, iflag, topid) \ 3537c478bd9Sstevel@tonic-gate ufs_syncip(ip, bflags, iflag, topid) 3547c478bd9Sstevel@tonic-gate #define TRANS_SBWRITE(ufsvfsp, topid) ufs_trans_sbwrite(ufsvfsp, topid) 3557c478bd9Sstevel@tonic-gate #define TRANS_IUPDAT(ip, waitfor) ufs_trans_iupdat(ip, waitfor) 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate #ifdef DEBUG 3587c478bd9Sstevel@tonic-gate /* 3597c478bd9Sstevel@tonic-gate * Test/Debug ops 3607c478bd9Sstevel@tonic-gate * The following ops maintain the metadata map. 3617c478bd9Sstevel@tonic-gate * The metadata map is a debug/test feature. 3627c478bd9Sstevel@tonic-gate * These ops are *not* used in the production product. 3637c478bd9Sstevel@tonic-gate */ 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate /* 3667c478bd9Sstevel@tonic-gate * Set a flag if meta data checking. 3677c478bd9Sstevel@tonic-gate */ 3687c478bd9Sstevel@tonic-gate #define TRANS_DOMATAMAP(ufsvfsp) \ 3697c478bd9Sstevel@tonic-gate ufsvfsp->vfs_domatamap = \ 3707c478bd9Sstevel@tonic-gate (TRANS_ISTRANS(ufsvfsp) && \ 3717c478bd9Sstevel@tonic-gate (ufsvfsp->vfs_log->un_debug & MT_MATAMAP)) 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate #define TRANS_MATA_IGET(ufsvfsp, ip) \ 3747c478bd9Sstevel@tonic-gate if (ufsvfsp->vfs_domatamap) \ 3757c478bd9Sstevel@tonic-gate ufs_trans_mata_iget(ip) 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate #define TRANS_MATA_FREE(ufsvfsp, mof, nb) \ 3787c478bd9Sstevel@tonic-gate if (ufsvfsp->vfs_domatamap) \ 3797c478bd9Sstevel@tonic-gate ufs_trans_mata_free(ufsvfsp, (offset_t)(mof), nb) 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate #define TRANS_MATA_ALLOC(ufsvfsp, ip, bno, size, zero) \ 3827c478bd9Sstevel@tonic-gate if (ufsvfsp->vfs_domatamap) \ 3837c478bd9Sstevel@tonic-gate ufs_trans_mata_alloc(ufsvfsp, ip, bno, size, zero) 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate #define TRANS_MATA_MOUNT(ufsvfsp) \ 3867c478bd9Sstevel@tonic-gate if (ufsvfsp->vfs_domatamap) \ 3877c478bd9Sstevel@tonic-gate ufs_trans_mata_mount(ufsvfsp) 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate #define TRANS_MATA_UMOUNT(ufsvfsp) \ 3907c478bd9Sstevel@tonic-gate if (ufsvfsp->vfs_domatamap) \ 3917c478bd9Sstevel@tonic-gate ufs_trans_mata_umount(ufsvfsp) 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate #define TRANS_MATA_SI(ufsvfsp, fs) \ 3947c478bd9Sstevel@tonic-gate if (ufsvfsp->vfs_domatamap) \ 3957c478bd9Sstevel@tonic-gate ufs_trans_mata_si(ufsvfsp, fs) 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate #define TRANS_MATAADD(ufsvfsp, mof, nb) \ 3987c478bd9Sstevel@tonic-gate top_mataadd(ufsvfsp, (offset_t)(mof), nb) 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate #else /* !DEBUG */ 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate #define TRANS_DOMATAMAP(ufsvfsp) 4037c478bd9Sstevel@tonic-gate #define TRANS_MATA_IGET(ufsvfsp, ip) 4047c478bd9Sstevel@tonic-gate #define TRANS_MATA_FREE(ufsvfsp, mof, nb) 4057c478bd9Sstevel@tonic-gate #define TRANS_MATA_ALLOC(ufsvfsp, ip, bno, size, zero) 4067c478bd9Sstevel@tonic-gate #define TRANS_MATA_MOUNT(ufsvfsp) 4077c478bd9Sstevel@tonic-gate #define TRANS_MATA_UMOUNT(ufsvfsp) 4087c478bd9Sstevel@tonic-gate #define TRANS_MATA_SI(ufsvfsp, fs) 4097c478bd9Sstevel@tonic-gate #define TRANS_MATAADD(ufsvfsp, mof, nb) 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate #endif /* !DEBUG */ 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_quota.h> 4147c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_lockfs.h> 4157c478bd9Sstevel@tonic-gate /* 4167c478bd9Sstevel@tonic-gate * identifies the type of operation passed into TRANS_BEGIN/END 4177c478bd9Sstevel@tonic-gate */ 4187c478bd9Sstevel@tonic-gate #define TOP_SYNC (0x00000001) 4197c478bd9Sstevel@tonic-gate #define TOP_ASYNC (0x00000002) 4207c478bd9Sstevel@tonic-gate #define TOP_SYNC_FORCED (0x00000004) /* forced sync transaction */ 4217c478bd9Sstevel@tonic-gate /* 4227c478bd9Sstevel@tonic-gate * estimated values 4237c478bd9Sstevel@tonic-gate */ 4247c478bd9Sstevel@tonic-gate #define HEADERSIZE (128) 4257c478bd9Sstevel@tonic-gate #define ALLOCSIZE (160) 4267c478bd9Sstevel@tonic-gate #define INODESIZE (sizeof (struct dinode) + HEADERSIZE) 4277c478bd9Sstevel@tonic-gate #define SIZESB ((sizeof (struct fs)) + HEADERSIZE) 4287c478bd9Sstevel@tonic-gate #define SIZEDIR (DIRBLKSIZ + HEADERSIZE) 4297c478bd9Sstevel@tonic-gate /* 4307c478bd9Sstevel@tonic-gate * calculated values 4317c478bd9Sstevel@tonic-gate */ 4327c478bd9Sstevel@tonic-gate #define SIZECG(IP) ((IP)->i_fs->fs_cgsize + HEADERSIZE) 4337c478bd9Sstevel@tonic-gate #define FRAGSIZE(IP) ((IP)->i_fs->fs_fsize + HEADERSIZE) 4347c478bd9Sstevel@tonic-gate #define ACLSIZE(IP) (((IP)->i_ufsvfs->vfs_maxacl + HEADERSIZE) + \ 4357c478bd9Sstevel@tonic-gate INODESIZE) 4367c478bd9Sstevel@tonic-gate #define MAXACLSIZE ((MAX_ACL_ENTRIES << 1) * sizeof (aclent_t)) 4377c478bd9Sstevel@tonic-gate #define DIRSIZE(IP) (INODESIZE + (4 * ALLOCSIZE) + \ 4387c478bd9Sstevel@tonic-gate (IP)->i_fs->fs_fsize + HEADERSIZE) 4397c478bd9Sstevel@tonic-gate #define QUOTASIZE sizeof (struct dquot) + HEADERSIZE 4407c478bd9Sstevel@tonic-gate /* 4417c478bd9Sstevel@tonic-gate * size calculations 4427c478bd9Sstevel@tonic-gate */ 4437c478bd9Sstevel@tonic-gate #define TOP_CREATE_SIZE(IP) \ 4447c478bd9Sstevel@tonic-gate (ACLSIZE(IP) + SIZECG(IP) + DIRSIZE(IP) + INODESIZE) 4457c478bd9Sstevel@tonic-gate #define TOP_REMOVE_SIZE(IP) \ 4467c478bd9Sstevel@tonic-gate DIRSIZE(IP) + SIZECG(IP) + INODESIZE + SIZESB 4477c478bd9Sstevel@tonic-gate #define TOP_LINK_SIZE(IP) \ 4487c478bd9Sstevel@tonic-gate DIRSIZE(IP) + INODESIZE 4497c478bd9Sstevel@tonic-gate #define TOP_RENAME_SIZE(IP) \ 4507c478bd9Sstevel@tonic-gate DIRSIZE(IP) + DIRSIZE(IP) + SIZECG(IP) 4517c478bd9Sstevel@tonic-gate #define TOP_MKDIR_SIZE(IP) \ 4527c478bd9Sstevel@tonic-gate DIRSIZE(IP) + INODESIZE + DIRSIZE(IP) + INODESIZE + FRAGSIZE(IP) + \ 4537c478bd9Sstevel@tonic-gate SIZECG(IP) + ACLSIZE(IP) 4547c478bd9Sstevel@tonic-gate #define TOP_SYMLINK_SIZE(IP) \ 4557c478bd9Sstevel@tonic-gate DIRSIZE((IP)) + INODESIZE + INODESIZE + SIZECG(IP) 4567c478bd9Sstevel@tonic-gate #define TOP_GETPAGE_SIZE(IP) \ 4577c478bd9Sstevel@tonic-gate ALLOCSIZE + ALLOCSIZE + ALLOCSIZE + INODESIZE + SIZECG(IP) 4587c478bd9Sstevel@tonic-gate #define TOP_SYNCIP_SIZE INODESIZE 4597c478bd9Sstevel@tonic-gate #define TOP_READ_SIZE INODESIZE 4607c478bd9Sstevel@tonic-gate #define TOP_RMDIR_SIZE (SIZESB + (INODESIZE * 2) + SIZEDIR) 4617c478bd9Sstevel@tonic-gate #define TOP_SETQUOTA_SIZE(FS) ((FS)->fs_bsize << 2) 4627c478bd9Sstevel@tonic-gate #define TOP_QUOTA_SIZE (QUOTASIZE) 4637c478bd9Sstevel@tonic-gate #define TOP_SETSECATTR_SIZE(IP) (MAXACLSIZE) 4647c478bd9Sstevel@tonic-gate #define TOP_IUPDAT_SIZE(IP) INODESIZE + SIZECG(IP) 4657c478bd9Sstevel@tonic-gate #define TOP_SBUPDATE_SIZE (SIZESB) 4667c478bd9Sstevel@tonic-gate #define TOP_SBWRITE_SIZE (SIZESB) 4677c478bd9Sstevel@tonic-gate #define TOP_PUTPAGE_SIZE(IP) (INODESIZE + SIZECG(IP)) 4687c478bd9Sstevel@tonic-gate #define TOP_SETATTR_SIZE(IP) (SIZECG(IP) + INODESIZE + QUOTASIZE + \ 4697c478bd9Sstevel@tonic-gate ACLSIZE(IP)) 4707c478bd9Sstevel@tonic-gate #define TOP_IFREE_SIZE(IP) (SIZECG(IP) + INODESIZE + QUOTASIZE) 4717c478bd9Sstevel@tonic-gate #define TOP_MOUNT_SIZE (SIZESB) 4727c478bd9Sstevel@tonic-gate #define TOP_COMMIT_SIZE (0) 4737c478bd9Sstevel@tonic-gate 4747c478bd9Sstevel@tonic-gate /* 4757c478bd9Sstevel@tonic-gate * The minimum log size is 1M. So we will allow 1 fs operation to 4767c478bd9Sstevel@tonic-gate * reserve at most 512K of log space. 4777c478bd9Sstevel@tonic-gate */ 4787c478bd9Sstevel@tonic-gate #define TOP_MAX_RESV (512 * 1024) 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate /* 4827c478bd9Sstevel@tonic-gate * ufs trans function prototypes 4837c478bd9Sstevel@tonic-gate */ 484*ba3594baSGarrett D'Amore #if defined(_KERNEL) 4857c478bd9Sstevel@tonic-gate 4867c478bd9Sstevel@tonic-gate extern int ufs_trans_hlock(); 4877c478bd9Sstevel@tonic-gate extern void ufs_trans_onerror(); 4887c478bd9Sstevel@tonic-gate extern int ufs_trans_push_inode(struct ufsvfs *, delta_t, ino_t); 4897c478bd9Sstevel@tonic-gate extern int ufs_trans_push_buf(struct ufsvfs *, delta_t, daddr_t); 4907c478bd9Sstevel@tonic-gate extern int ufs_trans_push_si(struct ufsvfs *, delta_t, int); 4917c478bd9Sstevel@tonic-gate extern void ufs_trans_sbupdate(struct ufsvfs *, struct vfs *, 4927c478bd9Sstevel@tonic-gate top_t); 4937c478bd9Sstevel@tonic-gate extern void ufs_trans_sbwrite(struct ufsvfs *, top_t); 4947c478bd9Sstevel@tonic-gate extern void ufs_trans_iupdat(struct inode *, int); 4957c478bd9Sstevel@tonic-gate extern void ufs_trans_mata_mount(struct ufsvfs *); 4967c478bd9Sstevel@tonic-gate extern void ufs_trans_mata_umount(struct ufsvfs *); 4977c478bd9Sstevel@tonic-gate extern void ufs_trans_mata_si(struct ufsvfs *, struct fs *); 4987c478bd9Sstevel@tonic-gate extern void ufs_trans_mata_iget(struct inode *); 4997c478bd9Sstevel@tonic-gate extern void ufs_trans_mata_free(struct ufsvfs *, offset_t, off_t); 5007c478bd9Sstevel@tonic-gate extern void ufs_trans_mata_alloc(struct ufsvfs *, struct inode *, 5017c478bd9Sstevel@tonic-gate daddr_t, ulong_t, int); 5027c478bd9Sstevel@tonic-gate extern int ufs_trans_dir(struct inode *, off_t); 5037c478bd9Sstevel@tonic-gate extern void ufs_trans_quota(struct dquot *); 5047c478bd9Sstevel@tonic-gate extern void ufs_trans_dqrele(struct dquot *); 5057c478bd9Sstevel@tonic-gate extern int ufs_trans_itrunc(struct inode *, u_offset_t, int, 5067c478bd9Sstevel@tonic-gate cred_t *); 5077c478bd9Sstevel@tonic-gate extern int ufs_trans_write(struct inode *, struct uio *, int, 5087c478bd9Sstevel@tonic-gate cred_t *, int, long); 5097c478bd9Sstevel@tonic-gate extern void ufs_trans_write_resv(struct inode *, struct uio *, 5107c478bd9Sstevel@tonic-gate int *, int *); 5117c478bd9Sstevel@tonic-gate extern int ufs_trans_check(dev_t); 5127c478bd9Sstevel@tonic-gate extern void ufs_trans_redev(dev_t odev, dev_t ndev); 513303bf60bSsdebnath extern void ufs_trans_trunc_resv(struct inode *, u_offset_t, int *, 514303bf60bSsdebnath u_offset_t *); 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate /* 5177c478bd9Sstevel@tonic-gate * transaction prototypes 5187c478bd9Sstevel@tonic-gate */ 5197c478bd9Sstevel@tonic-gate void lufs_unsnarf(struct ufsvfs *ufsvfsp); 5207c478bd9Sstevel@tonic-gate int lufs_snarf(struct ufsvfs *ufsvfsp, struct fs *fs, int ronly); 5217c478bd9Sstevel@tonic-gate void top_delta(struct ufsvfs *ufsvfsp, offset_t mof, off_t nb, delta_t dtyp, 5227c478bd9Sstevel@tonic-gate int (*func)(), ulong_t arg); 5237c478bd9Sstevel@tonic-gate void top_cancel(struct ufsvfs *ufsvfsp, offset_t mof, off_t nb, int flags); 5247c478bd9Sstevel@tonic-gate int top_iscancel(struct ufsvfs *ufsvfsp, offset_t mof, off_t nb); 5257c478bd9Sstevel@tonic-gate void top_seterror(struct ufsvfs *ufsvfsp); 5267c478bd9Sstevel@tonic-gate int top_iserror(struct ufsvfs *ufsvfsp); 5277c478bd9Sstevel@tonic-gate void top_begin_sync(struct ufsvfs *ufsvfsp, top_t topid, ulong_t size, 5287c478bd9Sstevel@tonic-gate int *error); 5297c478bd9Sstevel@tonic-gate int top_begin_async(struct ufsvfs *ufsvfsp, top_t topid, ulong_t size, 5307c478bd9Sstevel@tonic-gate int tryasync); 5317c478bd9Sstevel@tonic-gate void top_end_sync(struct ufsvfs *ufsvfsp, int *ep, top_t topid, 5327c478bd9Sstevel@tonic-gate ulong_t size); 5337c478bd9Sstevel@tonic-gate void top_end_async(struct ufsvfs *ufsvfsp, top_t topid, ulong_t size); 5347c478bd9Sstevel@tonic-gate void top_log(struct ufsvfs *ufsvfsp, char *va, offset_t vamof, off_t nb, 5357c478bd9Sstevel@tonic-gate caddr_t buf, uint32_t bufsz); 5367c478bd9Sstevel@tonic-gate void top_mataadd(struct ufsvfs *ufsvfsp, offset_t mof, off_t nb); 5377c478bd9Sstevel@tonic-gate void top_matadel(struct ufsvfs *ufsvfsp, offset_t mof, off_t nb); 5387c478bd9Sstevel@tonic-gate void top_mataclr(struct ufsvfs *ufsvfsp); 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate 541*ba3594baSGarrett D'Amore #endif /* defined(_KERNEL) */ 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate #ifdef __cplusplus 5447c478bd9Sstevel@tonic-gate } 5457c478bd9Sstevel@tonic-gate #endif 5467c478bd9Sstevel@tonic-gate 5477c478bd9Sstevel@tonic-gate #endif /* _SYS_FS_UFS_TRANS_H */ 548