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_LOCKFS_H 28 #define _SYS_FS_UFS_LOCKFS_H 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <sys/lockfs.h> 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 /* 39 * Sun ufs file system locking (lockfs) 40 * 41 * ufs file system supports the following lock types: 42 * unlock - releasing existing locks, or do a file system flush 43 * name lock - no delete, no rename 44 * write lock - no update to file system, including delete 45 * delete lock - no delete, rename is allowed 46 * hard lock - no update, no access, cannot be unlocked 47 * - for supporting forcible umount 48 * error lock - no update, no access, may only be unlocked 49 * - once fs becomes clean, may be upgraded to 50 * - a hard lock 51 * error lock (read-only) -- not yet implemented -- 52 * - no write changes allowed to fs, may be upgraded 53 * - to error or hard lock 54 * - degrades to panic on subsequent failures 55 * 56 * ufs_vnodeops(es) that conflict with the above file system lock types 57 * will get either suspended, or get a EAGAIN error, 58 * or get an EIO error if the file sytem is hard locked, 59 * or will block if the file system is error locked. 60 * 61 * There are exceptions. 62 * The following ufs_vnops do not obey the locking protocol: 63 * ufs_close, ufs_putpage, ufs_inactive, ufs_addmap, ufs_delmap, 64 * ufs_rwlock, ufs_rwunlock, ufs_poll. 65 * 66 * ul_vnops_cnt will get increment by 1 when a ufs vnodeops is entered; 67 * it will be decremented by 1 when a ufs_vnodeops is exited. 68 * A file system is in a quiescent state if ufs_vnops_cnt is zero. 69 * Since ufs_pageio() has to change ul_vnops_cnt without using ul_lock 70 * all users of ul_vnops_cnt increment and decrement it via atomic_add_long(). 71 */ 72 73 #include <sys/fs/ufs_trans.h> 74 #include <sys/thread.h> 75 76 /* 77 * ul_flag 78 */ 79 #define ULOCKFS_BUSY 0x00000001 /* ul_fs_lock is being set */ 80 #define ULOCKFS_NOIACC 0x00000004 /* don't keep access times */ 81 #define ULOCKFS_NOIDEL 0x00000008 /* don't free deleted files */ 82 #define ULOCKFS_FALLOC 0x00000010 /* fallocate threads exist */ 83 84 #define ULOCKFS_IS_BUSY(LF) ((LF)->ul_flag & ULOCKFS_BUSY) 85 #define ULOCKFS_IS_NOIACC(LF) ((LF)->ul_flag & ULOCKFS_NOIACC) 86 #define ULOCKFS_IS_NOIDEL(LF) ((LF)->ul_flag & ULOCKFS_NOIDEL) 87 #define ULOCKFS_IS_FALLOC(LF) ((LF)->ul_flag & ULOCKFS_FALLOC) 88 89 #define ULOCKFS_CLR_BUSY(LF) ((LF)->ul_flag &= ~ULOCKFS_BUSY) 90 #define ULOCKFS_SET_BUSY(LF) ((LF)->ul_flag |= ULOCKFS_BUSY) 91 92 #define ULOCKFS_CLR_FALLOC(LF) ((LF)->ul_flag &= ~ULOCKFS_FALLOC) 93 #define ULOCKFS_SET_FALLOC(LF) ((LF)->ul_flag |= ULOCKFS_FALLOC) 94 95 /* 96 * ul_fs_mod 97 */ 98 #define ULOCKFS_SET_MOD(LF) ((LF)->ul_fs_mod = 1) 99 #define ULOCKFS_CLR_MOD(LF) ((LF)->ul_fs_mod = 0) 100 #define ULOCKFS_IS_MOD(LF) ((LF)->ul_fs_mod) 101 102 /* 103 * ul_fs_lock 104 * 105 * softlock will temporarily block most ufs_vnodeops. 106 * it is used so that a waiting lockfs command will not be starved 107 * 108 * fwlock will block other fallocate threads wanting to obtain a write lock 109 * on the file system. 110 */ 111 #define ULOCKFS_ULOCK ((1 << LOCKFS_ULOCK)) /* unlock */ 112 #define ULOCKFS_WLOCK ((1 << LOCKFS_WLOCK)) /* write lock */ 113 #define ULOCKFS_NLOCK ((1 << LOCKFS_NLOCK)) /* name lock */ 114 #define ULOCKFS_DLOCK ((1 << LOCKFS_DLOCK)) /* delete lock */ 115 #define ULOCKFS_HLOCK ((1 << LOCKFS_HLOCK)) /* hard lock */ 116 #define ULOCKFS_ELOCK ((1 << LOCKFS_ELOCK)) /* error lock */ 117 #define ULOCKFS_ROELOCK ((1 << LOCKFS_ROELOCK)) /* error lock (read-only) */ 118 /* Maximum number of LOCKFS lockfs defined in sys/lockfs.h are 6 */ 119 #define ULOCKFS_FWLOCK (1 << (LOCKFS_MAXLOCK + 1)) /* fallocate write lock */ 120 #define ULOCKFS_SLOCK 0x80000000 /* soft lock */ 121 122 #define ULOCKFS_IS_WLOCK(LF) ((LF)->ul_fs_lock & ULOCKFS_WLOCK) 123 #define ULOCKFS_IS_HLOCK(LF) ((LF)->ul_fs_lock & ULOCKFS_HLOCK) 124 #define ULOCKFS_IS_ELOCK(LF) ((LF)->ul_fs_lock & ULOCKFS_ELOCK) 125 #define ULOCKFS_IS_ROELOCK(LF) ((LF)->ul_fs_lock & ULOCKFS_ROELOCK) 126 #define ULOCKFS_IS_ULOCK(LF) ((LF)->ul_fs_lock & ULOCKFS_ULOCK) 127 #define ULOCKFS_IS_NLOCK(LF) ((LF)->ul_fs_lock & ULOCKFS_NLOCK) 128 #define ULOCKFS_IS_DLOCK(LF) ((LF)->ul_fs_lock & ULOCKFS_DLOCK) 129 #define ULOCKFS_IS_SLOCK(LF) ((LF)->ul_fs_lock & ULOCKFS_SLOCK) 130 #define ULOCKFS_IS_FWLOCK(LF) ((LF)->ul_fs_lock & ULOCKFS_FWLOCK) 131 #define ULOCKFS_IS_JUSTULOCK(LF) \ 132 (((LF)->ul_fs_lock & (ULOCKFS_SLOCK | ULOCKFS_ULOCK)) == ULOCKFS_ULOCK) 133 134 #define ULOCKFS_SET_SLOCK(LF) ((LF)->ul_fs_lock |= ULOCKFS_SLOCK) 135 #define ULOCKFS_CLR_SLOCK(LF) ((LF)->ul_fs_lock &= ~ULOCKFS_SLOCK) 136 137 #define ULOCKFS_SET_FWLOCK(LF) ((LF)->ul_fs_lock |= ULOCKFS_FWLOCK) 138 #define ULOCKFS_CLR_FWLOCK(LF) ((LF)->ul_fs_lock &= ~ULOCKFS_FWLOCK) 139 140 #define ULOCKFS_READ_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 141 #define ULOCKFS_WRITE_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 142 ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK) 143 /* used by both ufs_getattr and ufs_getsecattr */ 144 #define ULOCKFS_GETATTR_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 145 /* used by both ufs_setattr and ufs_setsecattr */ 146 #define ULOCKFS_SETATTR_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 147 ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK) 148 #define ULOCKFS_ACCESS_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 149 #define ULOCKFS_LOOKUP_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 150 #define ULOCKFS_CREATE_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 151 ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK) 152 #define ULOCKFS_REMOVE_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 153 ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK | \ 154 ULOCKFS_NLOCK | ULOCKFS_DLOCK) 155 #define ULOCKFS_LINK_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 156 ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK) 157 #define ULOCKFS_RENAME_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 158 ULOCKFS_SLOCK | ULOCKFS_WLOCK | \ 159 ULOCKFS_ROELOCK | ULOCKFS_NLOCK) 160 #define ULOCKFS_MKDIR_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 161 ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK) 162 #define ULOCKFS_RMDIR_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 163 ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK | \ 164 ULOCKFS_NLOCK | ULOCKFS_DLOCK) 165 #define ULOCKFS_READDIR_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 166 #define ULOCKFS_SYMLINK_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 167 ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK) 168 #define ULOCKFS_READLINK_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 169 #define ULOCKFS_FSYNC_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 170 #define ULOCKFS_FID_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 171 #define ULOCKFS_RWLOCK_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 172 #define ULOCKFS_RWUNLOCK_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 173 #define ULOCKFS_SEEK_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 174 #define ULOCKFS_FRLOCK_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 175 #define ULOCKFS_SPACE_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 176 ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK) 177 #define ULOCKFS_FALLOCATE_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 178 ULOCKFS_ROELOCK | ULOCKFS_SLOCK | \ 179 ULOCKFS_WLOCK | ULOCKFS_FWLOCK) 180 #define ULOCKFS_QUOTA_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 181 ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK) 182 /* GETPAGE breaks up into two masks */ 183 #define ULOCKFS_GETREAD_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 184 #define ULOCKFS_GETWRITE_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 185 ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK) 186 #define ULOCKFS_MAP_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 187 #define ULOCKFS_FIODUTIMES_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 188 ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK) 189 #define ULOCKFS_FIODIO_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 190 ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK) 191 #define ULOCKFS_FIODIOS_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 192 #define ULOCKFS_PATHCONF_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 193 194 #define ULOCKFS_VGET_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK) 195 #define ULOCKFS_DELETE_MASK (ULOCKFS_HLOCK | ULOCKFS_ELOCK | \ 196 ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK) 197 198 struct ulockfs { 199 ulong_t ul_flag; /* flags */ 200 ulong_t ul_fs_lock; /* current file system lock state */ 201 ulong_t ul_fs_mod; /* for test; fs was modified */ 202 ulong_t ul_vnops_cnt; /* # of active ufs vnops outstanding */ 203 kmutex_t ul_lock; /* mutex to protect ulockfs structure */ 204 kcondvar_t ul_cv; 205 kthread_id_t ul_sbowner; /* thread than can write superblock */ 206 struct lockfs ul_lockfs; /* ioctl lock struct */ 207 ulong_t ul_falloc_cnt; /* # of on-going fallocate ops */ 208 }; 209 210 extern ulong_t ufs_quiesce_pend; 211 212 #define VTOUL(VP) \ 213 ((struct ulockfs *) \ 214 &((struct ufsvfs *)((VP)->v_vfsp->vfs_data))->vfs_ulockfs) 215 #define ITOUL(IP) ((struct ulockfs *)&((IP)->i_ufsvfs->vfs_ulockfs)) 216 217 #ifdef __cplusplus 218 } 219 #endif 220 221 #endif /* _SYS_FS_UFS_LOCKFS_H */ 222