Home | History | Annotate | Download | only in fs
      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