xref: /illumos-gate/usr/src/uts/common/sys/fs/ufs_lockfs.h (revision 814a60b13c0ad90e5d2edfd29a7a84bbf416cc1a)
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 
83 #define	ULOCKFS_IS_BUSY(LF)	((LF)->ul_flag & ULOCKFS_BUSY)
84 #define	ULOCKFS_IS_NOIACC(LF)	((LF)->ul_flag & ULOCKFS_NOIACC)
85 #define	ULOCKFS_IS_NOIDEL(LF)	((LF)->ul_flag & ULOCKFS_NOIDEL)
86 
87 #define	ULOCKFS_CLR_BUSY(LF)	((LF)->ul_flag &= ~ULOCKFS_BUSY)
88 
89 #define	ULOCKFS_SET_BUSY(LF)	((LF)->ul_flag |= ULOCKFS_BUSY)
90 
91 /*
92  * ul_fs_mod
93  */
94 #define	ULOCKFS_SET_MOD(LF)	((LF)->ul_fs_mod = 1)
95 #define	ULOCKFS_CLR_MOD(LF)	((LF)->ul_fs_mod = 0)
96 #define	ULOCKFS_IS_MOD(LF)	((LF)->ul_fs_mod)
97 
98 /*
99  * ul_fs_lock
100  *
101  * softlock will temporarily block most ufs_vnodeops.
102  * it is used so that a waiting lockfs command will not be starved
103  */
104 #define	ULOCKFS_ULOCK    ((1 << LOCKFS_ULOCK))	/* unlock */
105 #define	ULOCKFS_WLOCK    ((1 << LOCKFS_WLOCK))	/* write  lock */
106 #define	ULOCKFS_NLOCK    ((1 << LOCKFS_NLOCK))	/* name   lock */
107 #define	ULOCKFS_DLOCK    ((1 << LOCKFS_DLOCK))	/* delete lock */
108 #define	ULOCKFS_HLOCK    ((1 << LOCKFS_HLOCK))	/* hard   lock */
109 #define	ULOCKFS_ELOCK    ((1 << LOCKFS_ELOCK))	/* error  lock */
110 #define	ULOCKFS_ROELOCK  ((1 << LOCKFS_ROELOCK)) /* error lock (read-only) */
111 #define	ULOCKFS_SLOCK    0x80000000		/* soft   lock */
112 
113 #define	ULOCKFS_IS_WLOCK(LF)	((LF)->ul_fs_lock & ULOCKFS_WLOCK)
114 #define	ULOCKFS_IS_HLOCK(LF)	((LF)->ul_fs_lock & ULOCKFS_HLOCK)
115 #define	ULOCKFS_IS_ELOCK(LF)	((LF)->ul_fs_lock & ULOCKFS_ELOCK)
116 #define	ULOCKFS_IS_ROELOCK(LF)	((LF)->ul_fs_lock & ULOCKFS_ROELOCK)
117 #define	ULOCKFS_IS_ULOCK(LF)	((LF)->ul_fs_lock & ULOCKFS_ULOCK)
118 #define	ULOCKFS_IS_NLOCK(LF)	((LF)->ul_fs_lock & ULOCKFS_NLOCK)
119 #define	ULOCKFS_IS_DLOCK(LF)	((LF)->ul_fs_lock & ULOCKFS_DLOCK)
120 #define	ULOCKFS_IS_SLOCK(LF)	((LF)->ul_fs_lock & ULOCKFS_SLOCK)
121 #define	ULOCKFS_IS_JUSTULOCK(LF) \
122 	(((LF)->ul_fs_lock & (ULOCKFS_SLOCK | ULOCKFS_ULOCK)) == ULOCKFS_ULOCK)
123 
124 #define	ULOCKFS_SET_SLOCK(LF)	((LF)->ul_fs_lock |= ULOCKFS_SLOCK)
125 #define	ULOCKFS_CLR_SLOCK(LF)	((LF)->ul_fs_lock &= ~ULOCKFS_SLOCK)
126 
127 #define	ULOCKFS_READ_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
128 #define	ULOCKFS_WRITE_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | \
129 			ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK)
130 /* used by both ufs_getattr and ufs_getsecattr */
131 #define	ULOCKFS_GETATTR_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
132 /* used by both ufs_setattr and ufs_setsecattr */
133 #define	ULOCKFS_SETATTR_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | \
134 				ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK)
135 #define	ULOCKFS_ACCESS_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
136 #define	ULOCKFS_LOOKUP_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
137 #define	ULOCKFS_CREATE_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | \
138 				ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK)
139 #define	ULOCKFS_REMOVE_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | \
140 			ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK | \
141 					ULOCKFS_NLOCK | ULOCKFS_DLOCK)
142 #define	ULOCKFS_LINK_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | \
143 				ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK)
144 #define	ULOCKFS_RENAME_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | \
145 					ULOCKFS_SLOCK | ULOCKFS_WLOCK | \
146 					ULOCKFS_ROELOCK | ULOCKFS_NLOCK)
147 #define	ULOCKFS_MKDIR_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | \
148 				ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK)
149 #define	ULOCKFS_RMDIR_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | \
150 			ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK | \
151 					ULOCKFS_NLOCK | ULOCKFS_DLOCK)
152 #define	ULOCKFS_READDIR_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
153 #define	ULOCKFS_SYMLINK_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | \
154 				ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK)
155 #define	ULOCKFS_READLINK_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
156 #define	ULOCKFS_FSYNC_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
157 #define	ULOCKFS_FID_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
158 #define	ULOCKFS_RWLOCK_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
159 #define	ULOCKFS_RWUNLOCK_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
160 #define	ULOCKFS_SEEK_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
161 #define	ULOCKFS_FRLOCK_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
162 #define	ULOCKFS_SPACE_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | \
163 				ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK)
164 #define	ULOCKFS_QUOTA_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | \
165 				ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK)
166 /* GETPAGE breaks up into two masks */
167 #define	ULOCKFS_GETREAD_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
168 #define	ULOCKFS_GETWRITE_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | \
169 				ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK)
170 #define	ULOCKFS_MAP_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
171 #define	ULOCKFS_FIODUTIMES_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | \
172 				ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK)
173 #define	ULOCKFS_FIODIO_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | \
174 				ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK)
175 #define	ULOCKFS_FIODIOS_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
176 #define	ULOCKFS_PATHCONF_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
177 
178 #define	ULOCKFS_VGET_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | ULOCKFS_SLOCK)
179 #define	ULOCKFS_DELETE_MASK	(ULOCKFS_HLOCK | ULOCKFS_ELOCK | \
180 				ULOCKFS_ROELOCK | ULOCKFS_SLOCK | ULOCKFS_WLOCK)
181 
182 struct ulockfs {
183 	ulong_t		ul_flag;	/* flags */
184 	ulong_t		ul_fs_lock;	/* current file system lock state */
185 	ulong_t		ul_fs_mod;	/* for test; fs was modified */
186 	ulong_t		ul_vnops_cnt;	/* # of active ufs vnops outstanding */
187 	kmutex_t	ul_lock;	/* mutex to protect ulockfs structure */
188 	kcondvar_t 	ul_cv;
189 	kthread_id_t	ul_sbowner;	/* thread than can write superblock */
190 	struct lockfs	ul_lockfs;	/* ioctl lock struct */
191 };
192 
193 extern ulong_t ufs_quiesce_pend;
194 
195 #define	VTOUL(VP) \
196 	((struct ulockfs *) \
197 	&((struct ufsvfs *)((VP)->v_vfsp->vfs_data))->vfs_ulockfs)
198 #define	ITOUL(IP)	((struct ulockfs *)&((IP)->i_ufsvfs->vfs_ulockfs))
199 
200 #ifdef	__cplusplus
201 }
202 #endif
203 
204 #endif	/* _SYS_FS_UFS_LOCKFS_H */
205