xref: /titanic_51/usr/src/uts/common/sys/fs/ufs_inode.h (revision 9b5097ee22b7d249db813b466eda136ffc2c21fa)
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
55b024a5bSbatschul  * Common Development and Distribution License (the "License").
65b024a5bSbatschul  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*9b5097eeSOwen Roberts  * Copyright (c) 1983, 2010, Oracle and/or its affiliates. All rights reserved.
237c478bd9Sstevel@tonic-gate  */
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
267c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
307c478bd9Sstevel@tonic-gate  * The Regents of the University of California
317c478bd9Sstevel@tonic-gate  * All Rights Reserved
327c478bd9Sstevel@tonic-gate  *
337c478bd9Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
347c478bd9Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
357c478bd9Sstevel@tonic-gate  * contributors.
367c478bd9Sstevel@tonic-gate  */
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate #ifndef	_SYS_FS_UFS_INODE_H
397c478bd9Sstevel@tonic-gate #define	_SYS_FS_UFS_INODE_H
407c478bd9Sstevel@tonic-gate 
417c478bd9Sstevel@tonic-gate #include <sys/isa_defs.h>
427c478bd9Sstevel@tonic-gate #include <sys/fbuf.h>
437c478bd9Sstevel@tonic-gate #include <sys/fdbuffer.h>
447c478bd9Sstevel@tonic-gate #include <sys/fcntl.h>
457c478bd9Sstevel@tonic-gate #include <sys/uio.h>
467c478bd9Sstevel@tonic-gate #include <sys/t_lock.h>
477c478bd9Sstevel@tonic-gate #include <sys/thread.h>
487c478bd9Sstevel@tonic-gate #include <sys/cred.h>
497c478bd9Sstevel@tonic-gate #include <sys/time.h>
507c478bd9Sstevel@tonic-gate #include <sys/types32.h>
517c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_fs.h>
527c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_lockfs.h>
537c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_trans.h>
547c478bd9Sstevel@tonic-gate #include <sys/kstat.h>
557c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_acl.h>
567c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_panic.h>
577c478bd9Sstevel@tonic-gate #include <sys/dnlc.h>
587c478bd9Sstevel@tonic-gate 
59d67944fbSScott Rotondo #ifdef _KERNEL
60d67944fbSScott Rotondo #include <sys/vfs_opreg.h>
61d67944fbSScott Rotondo #endif
62d67944fbSScott Rotondo 
637c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
647c478bd9Sstevel@tonic-gate extern "C" {
657c478bd9Sstevel@tonic-gate #endif
667c478bd9Sstevel@tonic-gate 
677c478bd9Sstevel@tonic-gate /*
687c478bd9Sstevel@tonic-gate  * The I node is the focus of all local file activity in UNIX.
697c478bd9Sstevel@tonic-gate  * There is a unique inode allocated for each active file,
707c478bd9Sstevel@tonic-gate  * each current directory, each mounted-on file, each mapping,
717c478bd9Sstevel@tonic-gate  * and the root.  An inode is `named' by its dev/inumber pair.
727c478bd9Sstevel@tonic-gate  * Data in icommon is read in from permanent inode on volume.
737c478bd9Sstevel@tonic-gate  *
747c478bd9Sstevel@tonic-gate  * Each inode has 5 locks associated with it:
757c478bd9Sstevel@tonic-gate  *	i_rwlock:	Serializes ufs_write and ufs_setattr request
767c478bd9Sstevel@tonic-gate  *			and allows ufs_read requests to proceed in parallel.
777c478bd9Sstevel@tonic-gate  *			Serializes reads/updates to directories.
787c478bd9Sstevel@tonic-gate  *	vfs_dqrwlock:	Manages quota sub-system quiescence.  See below.
797c478bd9Sstevel@tonic-gate  *	i_contents:	Protects almost all of the fields in the inode
807c478bd9Sstevel@tonic-gate  *			except for those listed below. When held
817c478bd9Sstevel@tonic-gate  *			in writer mode also protects those fields
827c478bd9Sstevel@tonic-gate  *			listed under i_tlock.
837c478bd9Sstevel@tonic-gate  *	i_tlock:	When i_tlock is held with the i_contents reader
847c478bd9Sstevel@tonic-gate  *			lock the i_atime, i_mtime, i_ctime,
857c478bd9Sstevel@tonic-gate  *			i_delayoff, i_delaylen, i_nextrio, i_writes, i_flag
867c478bd9Sstevel@tonic-gate  *			i_seq, i_writer & i_mapcnt fields are protected.
877c478bd9Sstevel@tonic-gate  *			For more i_flag locking info see below.
887c478bd9Sstevel@tonic-gate  *	ih_lock:	Protects inode hash chain buckets
897c478bd9Sstevel@tonic-gate  *	ifree_lock:	Protects inode freelist
907c478bd9Sstevel@tonic-gate  *
917c478bd9Sstevel@tonic-gate  * Lock ordering:
927c478bd9Sstevel@tonic-gate  *	i_rwlock > i_contents > i_tlock
937c478bd9Sstevel@tonic-gate  *	i_rwlock > vfs_dqrwlock > i_contents(writer) > i_tlock
947c478bd9Sstevel@tonic-gate  *	i_contents > i_tlock
957c478bd9Sstevel@tonic-gate  *	vfs_dqrwlock > i_contents(writer) > i_tlock
967c478bd9Sstevel@tonic-gate  *	ih_lock > i_contents > i_tlock
977c478bd9Sstevel@tonic-gate  *
987c478bd9Sstevel@tonic-gate  * Making major changes to quota sub-system state, while the file
997c478bd9Sstevel@tonic-gate  * system is mounted required the addition of another lock.  The
1007c478bd9Sstevel@tonic-gate  * primary lock in the quota sub-system is vfs_dqrwlock in the ufsvfs
1017c478bd9Sstevel@tonic-gate  * structure.  This lock is used to manage quota sub-system quiescence
1027c478bd9Sstevel@tonic-gate  * for a particular file system. Major changes to quota sub-system
1037c478bd9Sstevel@tonic-gate  * state (disabling quotas, enabling quotas, and setting new quota
1047c478bd9Sstevel@tonic-gate  * limits) all require the file system to be quiescent and grabbing
1057c478bd9Sstevel@tonic-gate  * vfs_dqrwlock as writer accomplishes this.  On the other hand,
1067c478bd9Sstevel@tonic-gate  * grabbing vfs_dqrwlock as reader makes the quota sub-system
1077c478bd9Sstevel@tonic-gate  * non-quiescent and lets the quota sub-system know that now is not a
1087c478bd9Sstevel@tonic-gate  * good time to change major quota sub-system state.  Typically
1097c478bd9Sstevel@tonic-gate  * vfs_dqrwlock is grabbed for reading before i_contents is grabbed for
1107c478bd9Sstevel@tonic-gate  * writing.  However, there are cases where vfs_dqrwlock is grabbed for
1117c478bd9Sstevel@tonic-gate  * reading without a corresponding i_contents write grab because there
1127c478bd9Sstevel@tonic-gate  * is no relevant inode.  There are also cases where i_contents is
1137c478bd9Sstevel@tonic-gate  * grabbed for writing when a vfs_dqrwlock read grab is not needed
1147c478bd9Sstevel@tonic-gate  * because the inode changes do not affect quotas.
1157c478bd9Sstevel@tonic-gate  *
1167c478bd9Sstevel@tonic-gate  * Unfortunately, performance considerations have required that we be more
1177c478bd9Sstevel@tonic-gate  * intelligent about using i_tlock when updating i_flag.  Ideally, we would
1187c478bd9Sstevel@tonic-gate  * have simply separated out several of the bits in i_flag into their own
1197c478bd9Sstevel@tonic-gate  * ints to avoid problems.  But, instead, we have implemented the following
1207c478bd9Sstevel@tonic-gate  * rules:
1217c478bd9Sstevel@tonic-gate  *
1227c478bd9Sstevel@tonic-gate  *	o You can update any i_flag field while holding the writer-contents,
1237c478bd9Sstevel@tonic-gate  *	  or by holding the reader-contents AND holding i_tlock.
1247c478bd9Sstevel@tonic-gate  *	  You can only call ITIMES_NOLOCK while holding the writer-contents,
1257c478bd9Sstevel@tonic-gate  *	  or by holding the reader-contents AND holding i_tlock.
1267c478bd9Sstevel@tonic-gate  *
1277c478bd9Sstevel@tonic-gate  *	o For a directory, holding the reader-rw_lock is sufficient for setting
1287c478bd9Sstevel@tonic-gate  *	  IACC.
1297c478bd9Sstevel@tonic-gate  *
1307c478bd9Sstevel@tonic-gate  *	o Races with IREF are avoided by holding the reader contents lock
1317c478bd9Sstevel@tonic-gate  *	  and by holding i_tlock in ufs_rmidle, ufs_putapage, and ufs_getpage.
1327c478bd9Sstevel@tonic-gate  *	  And by holding the writer-contents in ufs_iinactive.
1337c478bd9Sstevel@tonic-gate  *
1347c478bd9Sstevel@tonic-gate  *	o The callers are no longer required to handle the calls to ITIMES
1357c478bd9Sstevel@tonic-gate  *	  and ITIMES_NOLOCK.  The functions that set the i_flag bits are
1367c478bd9Sstevel@tonic-gate  *	  responsible for managing those calls.  The exceptions are the
1377c478bd9Sstevel@tonic-gate  *	  bmap routines.
1387c478bd9Sstevel@tonic-gate  *
1397c478bd9Sstevel@tonic-gate  * SVR4 Extended Fundamental Type (EFT) support:
1407c478bd9Sstevel@tonic-gate  * 	The inode structure has been enhanced to support
1417c478bd9Sstevel@tonic-gate  *	32-bit user-id, 32-bit group-id, and 32-bit device number.
1427c478bd9Sstevel@tonic-gate  *	Standard SVR4 ufs also supports 32-bit mode field.  For the reason
1437c478bd9Sstevel@tonic-gate  *	of backward compatibility with the previous ufs disk format,
1447c478bd9Sstevel@tonic-gate  *	32-bit mode field is not supported.
1457c478bd9Sstevel@tonic-gate  *
1467c478bd9Sstevel@tonic-gate  *	The current inode structure is 100% backward compatible with
1477c478bd9Sstevel@tonic-gate  *	the previous inode structure if no user-id or group-id exceeds
1487c478bd9Sstevel@tonic-gate  *	USHRT_MAX, and no major or minor number of a device number
1497c478bd9Sstevel@tonic-gate  *	stored in an inode exceeds 255.
1507c478bd9Sstevel@tonic-gate  *
1517c478bd9Sstevel@tonic-gate  * Rules for managing i_seq:
1527c478bd9Sstevel@tonic-gate  *	o i_seq is locked under the same rules as i_flag
1537c478bd9Sstevel@tonic-gate  *	o The i_ctime or i_mtime MUST never change without increasing
1547c478bd9Sstevel@tonic-gate  *	  the value of i_seq.
1557c478bd9Sstevel@tonic-gate  *	o You may increase the value of i_seq without the timestamps
1567c478bd9Sstevel@tonic-gate  *	  changing, this may decrease the callers performance but will
1577c478bd9Sstevel@tonic-gate  *	  be functionally correct.
1587c478bd9Sstevel@tonic-gate  *	o The common case is when IUPD or ICHG is set, increase i_seq
1597c478bd9Sstevel@tonic-gate  *	  and immediately call ITIMES* or ufs_iupdat to create a new timestamp.
1607c478bd9Sstevel@tonic-gate  *	o A less common case is the setting of IUPD or ICHG and while still
1617c478bd9Sstevel@tonic-gate  *	  holding the correct lock defer the timestamp and i_seq update
1627c478bd9Sstevel@tonic-gate  *	  until later, but it must still be done before the lock is released.
1637c478bd9Sstevel@tonic-gate  *	  bmap_write is an example of this, where the caller does the update.
1647c478bd9Sstevel@tonic-gate  *	o If multiple changes are being made with the timestamps being
1657c478bd9Sstevel@tonic-gate  *	  updated only at the end, a single increase of i_seq is allowed.
1667c478bd9Sstevel@tonic-gate  *	o If changes are made with IUPD or ICHG being set, but
1677c478bd9Sstevel@tonic-gate  *	  the controlling lock is being dropped before the timestamp is
1687c478bd9Sstevel@tonic-gate  *	  updated, there is a risk that another thread will also change
1697c478bd9Sstevel@tonic-gate  *	  the file, update i_flag, and push just one timestamp update.
1707c478bd9Sstevel@tonic-gate  *	  There is also the risk that another thread calls ITIMES or
1717c478bd9Sstevel@tonic-gate  *	  ufs_iupdat without setting IUPD|ICHG and thus not changing i_seq,
1727c478bd9Sstevel@tonic-gate  *	  this will cause ufs_imark to change the timestamps without changing
1737c478bd9Sstevel@tonic-gate  *	  i_seq. If the controlling lock is dropped, ISEQ must be set to
1747c478bd9Sstevel@tonic-gate  *	  force i_seq to be increased on next ufs_imark, but i_seq MUST still
1757c478bd9Sstevel@tonic-gate  *	  be increased by the original setting thread before its deferred
1767c478bd9Sstevel@tonic-gate  *	  call to ITIMES to insure it is increased the correct number of times.
1777c478bd9Sstevel@tonic-gate  */
1787c478bd9Sstevel@tonic-gate 
1797c478bd9Sstevel@tonic-gate #define	UID_LONG  (o_uid_t)65535
1807c478bd9Sstevel@tonic-gate 				/* flag value to indicate uid is 32-bit long */
1817c478bd9Sstevel@tonic-gate #define	GID_LONG  (o_uid_t)65535
1827c478bd9Sstevel@tonic-gate 				/* flag value to indicate gid is 32-bit long */
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate #define	NDADDR	12		/* direct addresses in inode */
1857c478bd9Sstevel@tonic-gate #define	NIADDR	3		/* indirect addresses in inode */
1867c478bd9Sstevel@tonic-gate #define	FSL_SIZE (NDADDR + NIADDR - 1) * sizeof (daddr32_t)
1877c478bd9Sstevel@tonic-gate 				/* max fast symbolic name length is 56 */
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate #define	i_fs	i_ufsvfs->vfs_bufp->b_un.b_fs
1907c478bd9Sstevel@tonic-gate #define	i_vfs	i_vnode->v_vfsp
1917c478bd9Sstevel@tonic-gate 
1927c478bd9Sstevel@tonic-gate struct 	icommon {
1937c478bd9Sstevel@tonic-gate 	o_mode_t ic_smode;	/*  0: mode and type of file */
1947c478bd9Sstevel@tonic-gate 	short	ic_nlink;	/*  2: number of links to file */
1957c478bd9Sstevel@tonic-gate 	o_uid_t	ic_suid;	/*  4: owner's user id */
1967c478bd9Sstevel@tonic-gate 	o_gid_t	ic_sgid;	/*  6: owner's group id */
1977c478bd9Sstevel@tonic-gate 	u_offset_t ic_lsize;	/*  8: number of bytes in file */
1987c478bd9Sstevel@tonic-gate #ifdef _KERNEL
1997c478bd9Sstevel@tonic-gate 	struct timeval32 ic_atime;	/* 16: time last accessed */
2007c478bd9Sstevel@tonic-gate 	struct timeval32 ic_mtime;	/* 24: time last modified */
2017c478bd9Sstevel@tonic-gate 	struct timeval32 ic_ctime;	/* 32: last time inode changed */
2027c478bd9Sstevel@tonic-gate #else
2037c478bd9Sstevel@tonic-gate 	time32_t ic_atime;	/* 16: time last accessed */
2047c478bd9Sstevel@tonic-gate 	int32_t	ic_atspare;
2057c478bd9Sstevel@tonic-gate 	time32_t ic_mtime;	/* 24: time last modified */
2067c478bd9Sstevel@tonic-gate 	int32_t	ic_mtspare;
2077c478bd9Sstevel@tonic-gate 	time32_t ic_ctime;	/* 32: last time inode changed */
2087c478bd9Sstevel@tonic-gate 	int32_t	ic_ctspare;
2097c478bd9Sstevel@tonic-gate #endif
2107c478bd9Sstevel@tonic-gate 	daddr32_t	ic_db[NDADDR];	/* 40: disk block addresses */
2117c478bd9Sstevel@tonic-gate 	daddr32_t	ic_ib[NIADDR];	/* 88: indirect blocks */
2127c478bd9Sstevel@tonic-gate 	int32_t	ic_flags;	/* 100: cflags */
2137c478bd9Sstevel@tonic-gate 	int32_t	ic_blocks;	/* 104: 512 byte blocks actually held */
2147c478bd9Sstevel@tonic-gate 	int32_t	ic_gen;		/* 108: generation number */
2157c478bd9Sstevel@tonic-gate 	int32_t	ic_shadow;	/* 112: shadow inode */
2167c478bd9Sstevel@tonic-gate 	uid_t	ic_uid;		/* 116: long EFT version of uid */
2177c478bd9Sstevel@tonic-gate 	gid_t	ic_gid;		/* 120: long EFT version of gid */
2187c478bd9Sstevel@tonic-gate 	uint32_t ic_oeftflag;	/* 124: extended attr directory ino, 0 = none */
2197c478bd9Sstevel@tonic-gate };
2207c478bd9Sstevel@tonic-gate 
2217c478bd9Sstevel@tonic-gate /*
2227f63b8c3Svsakar  * Large directories can be cached. Directory caching can take the following
2237f63b8c3Svsakar  * states:
2247f63b8c3Svsakar  */
2257f63b8c3Svsakar typedef enum {
2267f63b8c3Svsakar 	CD_DISABLED_NOMEM = -2,
2277f63b8c3Svsakar 	CD_DISABLED_TOOBIG,
2287f63b8c3Svsakar 	CD_DISABLED,
2297f63b8c3Svsakar 	CD_ENABLED
2307f63b8c3Svsakar } cachedir_t;
2317f63b8c3Svsakar 
2327f63b8c3Svsakar /*
2337c478bd9Sstevel@tonic-gate  * Large Files: Note we use the inline functions load_double, store_double
2347c478bd9Sstevel@tonic-gate  * to load and store the long long values of i_size. Therefore the
2357c478bd9Sstevel@tonic-gate  * address of i_size must be eight byte aligned. Kmem_alloc of incore
2367c478bd9Sstevel@tonic-gate  * inode structure makes sure that the structure is 8-byte aligned.
2377c478bd9Sstevel@tonic-gate  * XX64 - reorder this structure?
2387c478bd9Sstevel@tonic-gate  */
2397c478bd9Sstevel@tonic-gate typedef struct inode {
2407c478bd9Sstevel@tonic-gate 	struct	inode *i_chain[2];	/* must be first */
2417c478bd9Sstevel@tonic-gate 	struct inode *i_freef;	/* free list forward - must be before i_ic */
2427c478bd9Sstevel@tonic-gate 	struct inode *i_freeb;	/* free list back - must be before i_ic */
2437c478bd9Sstevel@tonic-gate 	struct 	icommon	i_ic;	/* Must be here */
2447c478bd9Sstevel@tonic-gate 	struct	vnode *i_vnode;	/* vnode associated with this inode */
2457c478bd9Sstevel@tonic-gate 	struct	vnode *i_devvp;	/* vnode for block I/O */
2467c478bd9Sstevel@tonic-gate 	dev_t	i_dev;		/* device where inode resides */
2477c478bd9Sstevel@tonic-gate 	ino_t	i_number;	/* i number, 1-to-1 with device address */
2487c478bd9Sstevel@tonic-gate 	off_t	i_diroff;	/* offset in dir, where we found last entry */
2497c478bd9Sstevel@tonic-gate 				/* just a hint - no locking needed */
2507c478bd9Sstevel@tonic-gate 	struct ufsvfs *i_ufsvfs; /* incore fs associated with inode */
2517c478bd9Sstevel@tonic-gate 	struct	dquot *i_dquot;	/* quota structure controlling this file */
2527c478bd9Sstevel@tonic-gate 	krwlock_t i_rwlock;	/* serializes write/setattr requests */
2537c478bd9Sstevel@tonic-gate 	krwlock_t i_contents;	/* protects (most of) inode contents */
2547c478bd9Sstevel@tonic-gate 	kmutex_t i_tlock;	/* protects time fields, i_flag */
2557c478bd9Sstevel@tonic-gate 	offset_t i_nextr;	/*					*/
2567c478bd9Sstevel@tonic-gate 				/* next byte read offset (read-ahead)	*/
2577c478bd9Sstevel@tonic-gate 				/*   No lock required			*/
2587c478bd9Sstevel@tonic-gate 				/*					*/
2597c478bd9Sstevel@tonic-gate 	uint_t	i_flag;		/* inode flags */
2607c478bd9Sstevel@tonic-gate 	uint_t	i_seq;		/* modification sequence number */
2617f63b8c3Svsakar 	cachedir_t i_cachedir;	/* Cache this directory on next lookup */
2627c478bd9Sstevel@tonic-gate 				/* - no locking needed  */
2637c478bd9Sstevel@tonic-gate 	long	i_mapcnt;	/* mappings to file pages */
2647c478bd9Sstevel@tonic-gate 	int	*i_map;		/* block list for the corresponding file */
2657c478bd9Sstevel@tonic-gate 	dev_t	i_rdev;		/* INCORE rdev from i_oldrdev by ufs_iget */
2667c478bd9Sstevel@tonic-gate 	size_t	i_delaylen;	/* delayed writes, units=bytes */
2677c478bd9Sstevel@tonic-gate 	offset_t i_delayoff;	/* where we started delaying */
2687c478bd9Sstevel@tonic-gate 	offset_t i_nextrio;	/* where to start the next clust */
2697c478bd9Sstevel@tonic-gate 	long	i_writes;	/* number of outstanding bytes in write q */
2707c478bd9Sstevel@tonic-gate 	kcondvar_t i_wrcv;	/* sleep/wakeup for write throttle */
2717c478bd9Sstevel@tonic-gate 	offset_t i_doff;	/* dinode byte offset in file system */
2727c478bd9Sstevel@tonic-gate 	si_t *i_ufs_acl;	/* pointer to acl entry */
2737c478bd9Sstevel@tonic-gate 	dcanchor_t i_danchor;	/* directory cache anchor */
2747c478bd9Sstevel@tonic-gate 	kthread_t *i_writer;	/* thread which is in window in wrip() */
2757c478bd9Sstevel@tonic-gate } inode_t;
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate struct dinode {
2787c478bd9Sstevel@tonic-gate 	union {
2797c478bd9Sstevel@tonic-gate 		struct	icommon di_icom;
2807c478bd9Sstevel@tonic-gate 		char	di_size[128];
2817c478bd9Sstevel@tonic-gate 	} di_un;
2827c478bd9Sstevel@tonic-gate };
2837c478bd9Sstevel@tonic-gate 
2847c478bd9Sstevel@tonic-gate #define	i_mode		i_ic.ic_smode
2857c478bd9Sstevel@tonic-gate #define	i_nlink		i_ic.ic_nlink
2867c478bd9Sstevel@tonic-gate #define	i_uid		i_ic.ic_uid
2877c478bd9Sstevel@tonic-gate #define	i_gid		i_ic.ic_gid
2887c478bd9Sstevel@tonic-gate #define	i_smode		i_ic.ic_smode
2897c478bd9Sstevel@tonic-gate #define	i_suid		i_ic.ic_suid
2907c478bd9Sstevel@tonic-gate #define	i_sgid		i_ic.ic_sgid
2917c478bd9Sstevel@tonic-gate 
2927c478bd9Sstevel@tonic-gate #define	i_size		i_ic.ic_lsize
2937c478bd9Sstevel@tonic-gate #define	i_db		i_ic.ic_db
2947c478bd9Sstevel@tonic-gate #define	i_ib		i_ic.ic_ib
2957c478bd9Sstevel@tonic-gate 
2967c478bd9Sstevel@tonic-gate #define	i_atime		i_ic.ic_atime
2977c478bd9Sstevel@tonic-gate #define	i_mtime		i_ic.ic_mtime
2987c478bd9Sstevel@tonic-gate #define	i_ctime		i_ic.ic_ctime
2997c478bd9Sstevel@tonic-gate 
3007c478bd9Sstevel@tonic-gate #define	i_shadow	i_ic.ic_shadow
3017c478bd9Sstevel@tonic-gate #define	i_oeftflag	i_ic.ic_oeftflag
3027c478bd9Sstevel@tonic-gate #define	i_blocks	i_ic.ic_blocks
3037c478bd9Sstevel@tonic-gate #define	i_cflags	i_ic.ic_flags
3047c478bd9Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
3057c478bd9Sstevel@tonic-gate /*
3067c478bd9Sstevel@tonic-gate  * Originally done on x86, but carried on to all other little
3077c478bd9Sstevel@tonic-gate  * architectures, which provides for file system compatibility.
3087c478bd9Sstevel@tonic-gate  */
3097c478bd9Sstevel@tonic-gate #define	i_ordev		i_ic.ic_db[1]	/* USL SVR4 compatibility */
3107c478bd9Sstevel@tonic-gate #else
3117c478bd9Sstevel@tonic-gate #define	i_ordev		i_ic.ic_db[0]	/* was i_oldrdev */
3127c478bd9Sstevel@tonic-gate #endif
3137c478bd9Sstevel@tonic-gate #define	i_gen		i_ic.ic_gen
3147c478bd9Sstevel@tonic-gate #define	i_forw		i_chain[0]
3157c478bd9Sstevel@tonic-gate #define	i_back		i_chain[1]
3167c478bd9Sstevel@tonic-gate 
3177c478bd9Sstevel@tonic-gate /* EFT transition aids - obsolete */
3187c478bd9Sstevel@tonic-gate #define	oEFT_MAGIC	0x90909090
3197c478bd9Sstevel@tonic-gate #define	di_oeftflag	di_ic.ic_oeftflag
3207c478bd9Sstevel@tonic-gate 
3217c478bd9Sstevel@tonic-gate #define	di_ic		di_un.di_icom
3227c478bd9Sstevel@tonic-gate #define	di_mode		di_ic.ic_smode
3237c478bd9Sstevel@tonic-gate #define	di_nlink	di_ic.ic_nlink
3247c478bd9Sstevel@tonic-gate #define	di_uid		di_ic.ic_uid
3257c478bd9Sstevel@tonic-gate #define	di_gid		di_ic.ic_gid
3267c478bd9Sstevel@tonic-gate #define	di_smode	di_ic.ic_smode
3277c478bd9Sstevel@tonic-gate #define	di_suid		di_ic.ic_suid
3287c478bd9Sstevel@tonic-gate #define	di_sgid		di_ic.ic_sgid
3297c478bd9Sstevel@tonic-gate 
3307c478bd9Sstevel@tonic-gate #define	di_size		di_ic.ic_lsize
3317c478bd9Sstevel@tonic-gate #define	di_db		di_ic.ic_db
3327c478bd9Sstevel@tonic-gate #define	di_ib		di_ic.ic_ib
3337c478bd9Sstevel@tonic-gate 
3347c478bd9Sstevel@tonic-gate #define	di_atime	di_ic.ic_atime
3357c478bd9Sstevel@tonic-gate #define	di_mtime	di_ic.ic_mtime
3367c478bd9Sstevel@tonic-gate #define	di_ctime	di_ic.ic_ctime
3377c478bd9Sstevel@tonic-gate #define	di_cflags	di_ic.ic_flags
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate #ifdef _LITTLE_ENDIAN
3407c478bd9Sstevel@tonic-gate #define	di_ordev	di_ic.ic_db[1]
3417c478bd9Sstevel@tonic-gate #else
3427c478bd9Sstevel@tonic-gate #define	di_ordev	di_ic.ic_db[0]
3437c478bd9Sstevel@tonic-gate #endif
3447c478bd9Sstevel@tonic-gate #define	di_shadow	di_ic.ic_shadow
3457c478bd9Sstevel@tonic-gate #define	di_blocks	di_ic.ic_blocks
3467c478bd9Sstevel@tonic-gate #define	di_gen		di_ic.ic_gen
3477c478bd9Sstevel@tonic-gate 
3487c478bd9Sstevel@tonic-gate /* flags */
3497c478bd9Sstevel@tonic-gate #define	IUPD		0x0001		/* file has been modified */
3507c478bd9Sstevel@tonic-gate #define	IACC		0x0002		/* inode access time to be updated */
3517c478bd9Sstevel@tonic-gate #define	IMOD		0x0004		/* inode has been modified */
3527c478bd9Sstevel@tonic-gate #define	ICHG		0x0008		/* inode has been changed */
3537c478bd9Sstevel@tonic-gate #define	INOACC		0x0010		/* no access time update in getpage */
3547c478bd9Sstevel@tonic-gate #define	IMODTIME	0x0020		/* mod time already set */
3557c478bd9Sstevel@tonic-gate #define	IREF		0x0040		/* inode is being referenced */
3567c478bd9Sstevel@tonic-gate #define	ISYNC		0x0080		/* do all allocation synchronously */
3577c478bd9Sstevel@tonic-gate #define	IFASTSYMLNK	0x0100		/* fast symbolic link */
3587c478bd9Sstevel@tonic-gate #define	IMODACC		0x0200		/* only access time changed; */
3597c478bd9Sstevel@tonic-gate 					/*   filesystem won't become active */
3607c478bd9Sstevel@tonic-gate #define	IATTCHG		0x0400		/* only size/blocks have changed */
3617c478bd9Sstevel@tonic-gate #define	IBDWRITE	0x0800		/* the inode has been scheduled for */
3627c478bd9Sstevel@tonic-gate 					/* write operation asynchronously */
3637c478bd9Sstevel@tonic-gate #define	ISTALE		0x1000		/* inode couldn't be read from disk */
3647c478bd9Sstevel@tonic-gate #define	IDEL		0x2000		/* inode is being deleted */
3657c478bd9Sstevel@tonic-gate #define	IDIRECTIO	0x4000		/* attempt directio */
3667c478bd9Sstevel@tonic-gate #define	ISEQ		0x8000		/* deferred i_seq increase */
3677c478bd9Sstevel@tonic-gate #define	IJUNKIQ		0x10000		/* on junk idle queue */
3687c478bd9Sstevel@tonic-gate #define	IQUIET		0x20000		/* No file system full messages */
3697c478bd9Sstevel@tonic-gate 
3707c478bd9Sstevel@tonic-gate /* cflags */
371303bf60bSsdebnath #define	IXATTR		0x0001		/* extended attribute */
372303bf60bSsdebnath #define	IFALLOCATE	0x0002		/* fallocate'd file */
373986fd29aSsetje #define	ICOMPRESS	0x0004		/* compressed for dcfs - see */
374986fd29aSsetje 					/*   `ufs_ioctl()`_FIO_COMPRESSED */
3757c478bd9Sstevel@tonic-gate 
3767c478bd9Sstevel@tonic-gate /* modes */
3777c478bd9Sstevel@tonic-gate #define	IFMT		0170000		/* type of file */
3787c478bd9Sstevel@tonic-gate #define	IFIFO		0010000		/* named pipe (fifo) */
3797c478bd9Sstevel@tonic-gate #define	IFCHR		0020000		/* character special */
3807c478bd9Sstevel@tonic-gate #define	IFDIR		0040000		/* directory */
3817c478bd9Sstevel@tonic-gate #define	IFBLK		0060000		/* block special */
3827c478bd9Sstevel@tonic-gate #define	IFREG		0100000		/* regular */
3837c478bd9Sstevel@tonic-gate #define	IFLNK		0120000		/* symbolic link */
3847c478bd9Sstevel@tonic-gate #define	IFSHAD		0130000		/* shadow indode */
3857c478bd9Sstevel@tonic-gate #define	IFSOCK		0140000		/* socket */
3867c478bd9Sstevel@tonic-gate #define	IFATTRDIR	0160000		/* Attribute directory */
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate #define	ISUID		04000		/* set user id on execution */
3897c478bd9Sstevel@tonic-gate #define	ISGID		02000		/* set group id on execution */
3907c478bd9Sstevel@tonic-gate #define	ISVTX		01000		/* save swapped text even after use */
3917c478bd9Sstevel@tonic-gate #define	IREAD		0400		/* read, write, execute permissions */
3927c478bd9Sstevel@tonic-gate #define	IWRITE		0200
3937c478bd9Sstevel@tonic-gate #define	IEXEC		0100
3947c478bd9Sstevel@tonic-gate 
3957c478bd9Sstevel@tonic-gate /* specify how the inode info is written in ufs_syncip() */
3967c478bd9Sstevel@tonic-gate #define	I_SYNC		1		/* wait for the inode written to disk */
3977c478bd9Sstevel@tonic-gate #define	I_DSYNC		2		/* wait for the inode written to disk */
3987c478bd9Sstevel@tonic-gate 					/* only if IATTCHG is set */
3997c478bd9Sstevel@tonic-gate #define	I_ASYNC		0		/* don't wait for the inode written */
4007c478bd9Sstevel@tonic-gate 
4017c478bd9Sstevel@tonic-gate /* flags passed to ufs_itrunc(), indirtrunc(), and free() */
4027c478bd9Sstevel@tonic-gate #define	I_FREE	0x00000001		/* inode is being freed */
4037c478bd9Sstevel@tonic-gate #define	I_DIR	0x00000002		/* inode is a directory */
4047c478bd9Sstevel@tonic-gate #define	I_IBLK	0x00000004		/* indirect block */
4057c478bd9Sstevel@tonic-gate #define	I_CHEAP	0x00000008		/* cheap free */
4067c478bd9Sstevel@tonic-gate #define	I_SHAD	0x00000010		/* inode is a shadow inode */
4077c478bd9Sstevel@tonic-gate #define	I_QUOTA	0x00000020		/* quota file */
4087c478bd9Sstevel@tonic-gate #define	I_NOCANCEL	0x40		/* Don't cancel these fragments */
409121be23bSjkennedy #define	I_ACCT	0x00000080		/* Update ufsvfs' unreclaimed_blocks */
410baa4d099Sswilcox 
411baa4d099Sswilcox /*
412baa4d099Sswilcox  * If ufs_dircheckforname() fails to find an entry with the given name,
413baa4d099Sswilcox  * this "slot" structure holds state for ufs_direnter_*() as to where
414baa4d099Sswilcox  * there is space to put an entry with that name.
415baa4d099Sswilcox  * If ufs_dircheckforname() finds an entry with the given name, this structure
416baa4d099Sswilcox  * holds state for ufs_dirrename() and ufs_dirremove() as to where the
417baa4d099Sswilcox  * entry is. "status" indicates what ufs_dircheckforname() found:
418baa4d099Sswilcox  *      NONE            name not found, large enough free slot not found,
419baa4d099Sswilcox  *      FOUND           name not found, large enough free slot found
420baa4d099Sswilcox  *      EXIST           name found
421baa4d099Sswilcox  * If ufs_dircheckforname() fails due to an error, this structure is not
422baa4d099Sswilcox  * filled in.
423baa4d099Sswilcox  *
424baa4d099Sswilcox  * After ufs_dircheckforname() succeeds the values are:
425baa4d099Sswilcox  *      status  offset          size            fbp, ep
426baa4d099Sswilcox  *      ------  ------          ----            -------
427baa4d099Sswilcox  *      NONE    end of dir      needed          not valid
428baa4d099Sswilcox  *      FOUND   start of entry  of ent          both valid if fbp != NULL
429baa4d099Sswilcox  *      EXIST   start of entry  of prev ent     valid
430baa4d099Sswilcox  *
431baa4d099Sswilcox  * "endoff" is set to 0 if the an entry with the given name is found, or if no
432baa4d099Sswilcox  * free slot could be found or made; this means that the directory should not
433baa4d099Sswilcox  * be truncated.  If the entry was found, the search terminates so
434baa4d099Sswilcox  * ufs_dircheckforname() didn't find out where the last valid entry in the
435baa4d099Sswilcox  * directory was, so it doesn't know where to cut the directory off; if no free
436baa4d099Sswilcox  * slot could be found or made, the directory has to be extended to make room
437baa4d099Sswilcox  * for the new entry, so there's nothing to cut off.
438baa4d099Sswilcox  * Otherwise, "endoff" is set to the larger of the offset of the last
439baa4d099Sswilcox  * non-empty entry in the directory, or the offset at which the new entry will
440baa4d099Sswilcox  * be placed, whichever is larger.  This is used by ufs_diraddentry(); if a new
441baa4d099Sswilcox  * entry is to be added to the directory, any complete directory blocks at the
442baa4d099Sswilcox  * end of the directory that contain no non-empty entries are lopped off the
443baa4d099Sswilcox  * end, thus shrinking the directory dynamically.
444baa4d099Sswilcox  */
445baa4d099Sswilcox typedef enum {NONE, FOUND, EXIST} slotstat_t;
4465b024a5bSbatschul struct ufs_slot {
447baa4d099Sswilcox 	struct	direct *ep;	/* pointer to slot */
448baa4d099Sswilcox 	struct	fbuf *fbp;	/* dir buf where slot is */
449baa4d099Sswilcox 	off_t	offset;		/* offset of area with free space */
450baa4d099Sswilcox 	off_t	endoff;		/* last useful location found in search */
451baa4d099Sswilcox 	slotstat_t status;	/* status of slot */
452baa4d099Sswilcox 	int	size;		/* size of area at slotoffset */
453baa4d099Sswilcox 	int	cached;		/* cached directory */
454baa4d099Sswilcox };
455baa4d099Sswilcox 
4567c478bd9Sstevel@tonic-gate /*
4577c478bd9Sstevel@tonic-gate  * Statistics on inodes
4587c478bd9Sstevel@tonic-gate  * Not protected by locks
4597c478bd9Sstevel@tonic-gate  */
4607c478bd9Sstevel@tonic-gate struct instats {
4617c478bd9Sstevel@tonic-gate 	kstat_named_t in_size;		/* current cache size */
4627c478bd9Sstevel@tonic-gate 	kstat_named_t in_maxsize;	/* maximum cache size */
4637c478bd9Sstevel@tonic-gate 	kstat_named_t in_hits;		/* cache hits */
4647c478bd9Sstevel@tonic-gate 	kstat_named_t in_misses;	/* cache misses */
4657c478bd9Sstevel@tonic-gate 	kstat_named_t in_malloc;	/* kmem_alloce'd */
4667c478bd9Sstevel@tonic-gate 	kstat_named_t in_mfree;		/* kmem_free'd */
4677c478bd9Sstevel@tonic-gate 	kstat_named_t in_maxreached;	/* Largest size reached by cache */
4687c478bd9Sstevel@tonic-gate 	kstat_named_t in_frfront;	/* # put at front of freelist */
4697c478bd9Sstevel@tonic-gate 	kstat_named_t in_frback;	/* # put at back of freelist */
4707c478bd9Sstevel@tonic-gate 	kstat_named_t in_qfree;		/* q's to delete thread */
4717c478bd9Sstevel@tonic-gate 	kstat_named_t in_scan;		/* # inodes scanned */
4727c478bd9Sstevel@tonic-gate 	kstat_named_t in_tidles;	/* # inodes idled by idle thread */
4737c478bd9Sstevel@tonic-gate 	kstat_named_t in_lidles;	/* # inodes idled by ufs_lookup */
4747c478bd9Sstevel@tonic-gate 	kstat_named_t in_vidles;	/* # inodes idled by ufs_vget */
4757c478bd9Sstevel@tonic-gate 	kstat_named_t in_kcalloc;	/* # inodes kmem_cache_alloced */
4767c478bd9Sstevel@tonic-gate 	kstat_named_t in_kcfree;	/* # inodes kmem_cache_freed */
4777c478bd9Sstevel@tonic-gate 	kstat_named_t in_poc;		/* # push-on-close's */
4787c478bd9Sstevel@tonic-gate };
4797c478bd9Sstevel@tonic-gate 
4807c478bd9Sstevel@tonic-gate #ifdef _KERNEL
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate /*
4837c478bd9Sstevel@tonic-gate  * Extended attributes
4847c478bd9Sstevel@tonic-gate  */
4857c478bd9Sstevel@tonic-gate 
4867c478bd9Sstevel@tonic-gate #define	XATTR_DIR_NAME	"/@/"
4877c478bd9Sstevel@tonic-gate extern int	ufs_ninode;		/* high-water mark for inode cache */
4887c478bd9Sstevel@tonic-gate 
4897c478bd9Sstevel@tonic-gate extern struct vnodeops *ufs_vnodeops;	/* vnode operations for ufs */
4907c478bd9Sstevel@tonic-gate extern const struct fs_operation_def ufs_vnodeops_template[];
4917c478bd9Sstevel@tonic-gate 
4927c478bd9Sstevel@tonic-gate /*
4937c478bd9Sstevel@tonic-gate  * Convert between inode pointers and vnode pointers
4947c478bd9Sstevel@tonic-gate  */
4957c478bd9Sstevel@tonic-gate #define	VTOI(VP)	((struct inode *)(VP)->v_data)
4967c478bd9Sstevel@tonic-gate #define	ITOV(IP)	((struct vnode *)(IP)->i_vnode)
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate /*
4997c478bd9Sstevel@tonic-gate  * convert to fs
5007c478bd9Sstevel@tonic-gate  */
5017c478bd9Sstevel@tonic-gate #define	ITOF(IP)	((struct fs *)(IP)->i_fs)
5027c478bd9Sstevel@tonic-gate 
5037c478bd9Sstevel@tonic-gate /*
5047c478bd9Sstevel@tonic-gate  * Convert between vnode types and inode formats
5057c478bd9Sstevel@tonic-gate  */
5067c478bd9Sstevel@tonic-gate extern enum vtype	iftovt_tab[];
5077c478bd9Sstevel@tonic-gate 
5087c478bd9Sstevel@tonic-gate #ifdef notneeded
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate /* Look at sys/mode.h and os/vnode.c */
5117c478bd9Sstevel@tonic-gate 
5127c478bd9Sstevel@tonic-gate extern int		vttoif_tab[];
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate #endif
5157c478bd9Sstevel@tonic-gate 
5167c478bd9Sstevel@tonic-gate /*
5177c478bd9Sstevel@tonic-gate  * Mark an inode with the current (unique) timestamp.
5187c478bd9Sstevel@tonic-gate  * (Note that UFS's concept of time only keeps 32 bits of seconds
5197c478bd9Sstevel@tonic-gate  * in the on-disk format).
5207c478bd9Sstevel@tonic-gate  */
5217c478bd9Sstevel@tonic-gate struct timeval32 iuniqtime;
5227c478bd9Sstevel@tonic-gate extern kmutex_t ufs_iuniqtime_lock;
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate #define	ITIMES_NOLOCK(ip) ufs_itimes_nolock(ip)
5257c478bd9Sstevel@tonic-gate 
5267c478bd9Sstevel@tonic-gate #define	ITIMES(ip) { \
5277c478bd9Sstevel@tonic-gate 	mutex_enter(&(ip)->i_tlock); \
5287c478bd9Sstevel@tonic-gate 	ITIMES_NOLOCK(ip); \
5297c478bd9Sstevel@tonic-gate 	mutex_exit(&(ip)->i_tlock); \
5307c478bd9Sstevel@tonic-gate }
5317c478bd9Sstevel@tonic-gate 
5327c478bd9Sstevel@tonic-gate /*
5337c478bd9Sstevel@tonic-gate  * The following interfaces are used to do atomic loads and stores
5347c478bd9Sstevel@tonic-gate  * of an inode's i_size, which is a long long data type.
5357c478bd9Sstevel@tonic-gate  *
5367c478bd9Sstevel@tonic-gate  * For LP64, we just to a load or a store - atomicity and alignment
5377c478bd9Sstevel@tonic-gate  * are 8-byte guaranteed.  For x86 there are no such instructions,
5387c478bd9Sstevel@tonic-gate  * so we grab i_contents as reader to get the size; we already hold
5397c478bd9Sstevel@tonic-gate  * it as writer when we're setting the size.
5407c478bd9Sstevel@tonic-gate  */
5417c478bd9Sstevel@tonic-gate 
5427c478bd9Sstevel@tonic-gate #ifdef _LP64
5437c478bd9Sstevel@tonic-gate 
5447c478bd9Sstevel@tonic-gate #define	UFS_GET_ISIZE(resultp, ip)	*(resultp) = (ip)->i_size
5457c478bd9Sstevel@tonic-gate #define	UFS_SET_ISIZE(value, ip)	(ip)->i_size = (value)
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate #else	/* _LP64 */
5487c478bd9Sstevel@tonic-gate 
5497c478bd9Sstevel@tonic-gate #define	UFS_GET_ISIZE(resultp, ip)				\
5507c478bd9Sstevel@tonic-gate 	{							\
5517c478bd9Sstevel@tonic-gate 		rw_enter(&(ip)->i_contents, RW_READER);		\
5527c478bd9Sstevel@tonic-gate 		*(resultp) = (ip)->i_size;			\
5537c478bd9Sstevel@tonic-gate 		rw_exit(&(ip)->i_contents);			\
5547c478bd9Sstevel@tonic-gate 	}
5557c478bd9Sstevel@tonic-gate #define	UFS_SET_ISIZE(value, ip)				\
5567c478bd9Sstevel@tonic-gate 	{							\
5577c478bd9Sstevel@tonic-gate 		ASSERT(RW_WRITE_HELD(&(ip)->i_contents));	\
5587c478bd9Sstevel@tonic-gate 		(ip)->i_size = (value);				\
5597c478bd9Sstevel@tonic-gate 	}
5607c478bd9Sstevel@tonic-gate 
5617c478bd9Sstevel@tonic-gate #endif	/* _LP64 */
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate /*
5647c478bd9Sstevel@tonic-gate  * Allocate the specified block in the inode
5657c478bd9Sstevel@tonic-gate  * and make sure any in-core pages are initialized.
5667c478bd9Sstevel@tonic-gate  */
5677c478bd9Sstevel@tonic-gate #define	BMAPALLOC(ip, off, size, cr) \
568303bf60bSsdebnath 	bmap_write((ip), (u_offset_t)(off), (size), BI_NORMAL, NULL, cr)
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate #define	ESAME	(-1)		/* trying to rename linked files (special) */
5717c478bd9Sstevel@tonic-gate 
5727c478bd9Sstevel@tonic-gate #define	UFS_HOLE	(daddr32_t)-1	/* value used when no block allocated */
5737c478bd9Sstevel@tonic-gate 
5747c478bd9Sstevel@tonic-gate /*
5757c478bd9Sstevel@tonic-gate  * enums
5767c478bd9Sstevel@tonic-gate  */
5777c478bd9Sstevel@tonic-gate 
5787c478bd9Sstevel@tonic-gate /* direnter ops */
5797c478bd9Sstevel@tonic-gate enum de_op { DE_CREATE, DE_MKDIR, DE_LINK, DE_RENAME, DE_SYMLINK, DE_ATTRDIR};
5807c478bd9Sstevel@tonic-gate 
5817c478bd9Sstevel@tonic-gate /* dirremove ops */
5827c478bd9Sstevel@tonic-gate enum dr_op { DR_REMOVE, DR_RMDIR, DR_RENAME };
5837c478bd9Sstevel@tonic-gate 
5847c478bd9Sstevel@tonic-gate /*
585303bf60bSsdebnath  * block initialization type for bmap_write
586303bf60bSsdebnath  *
587303bf60bSsdebnath  * BI_NORMAL - allocate and zero fill pages in memory
588303bf60bSsdebnath  * BI_ALLOC_ONLY - only allocate the block, do not zero out pages in mem
589303bf60bSsdebnath  * BI_FALLOCATE - allocate only, do not zero out pages, and store as negative
590303bf60bSsdebnath  *                block number in inode block list
591303bf60bSsdebnath  */
592303bf60bSsdebnath enum bi_type { BI_NORMAL, BI_ALLOC_ONLY, BI_FALLOCATE };
593303bf60bSsdebnath 
594303bf60bSsdebnath /*
5957c478bd9Sstevel@tonic-gate  * This overlays the fid structure (see vfs.h)
5967c478bd9Sstevel@tonic-gate  *
5977c478bd9Sstevel@tonic-gate  * LP64 note: we use int32_t instead of ino_t since UFS does not use
5987c478bd9Sstevel@tonic-gate  * inode numbers larger than 32-bits and ufid's are passed to NFS
5997c478bd9Sstevel@tonic-gate  * which expects them to not grow in size beyond 10 bytes (12 including
6007c478bd9Sstevel@tonic-gate  * the length).
6017c478bd9Sstevel@tonic-gate  */
6027c478bd9Sstevel@tonic-gate struct ufid {
6037c478bd9Sstevel@tonic-gate 	ushort_t ufid_len;
6047c478bd9Sstevel@tonic-gate 	ushort_t ufid_flags;
6057c478bd9Sstevel@tonic-gate 	int32_t	ufid_ino;
6067c478bd9Sstevel@tonic-gate 	int32_t	ufid_gen;
6077c478bd9Sstevel@tonic-gate };
6087c478bd9Sstevel@tonic-gate 
6097c478bd9Sstevel@tonic-gate /*
6107c478bd9Sstevel@tonic-gate  * each ufs thread (see ufs_thread.c) is managed by this struct
6117c478bd9Sstevel@tonic-gate  */
6127c478bd9Sstevel@tonic-gate struct ufs_q {
6137c478bd9Sstevel@tonic-gate 	union uq_head {
6147c478bd9Sstevel@tonic-gate 		void		*_uq_generic;	/* first entry on q */
6157c478bd9Sstevel@tonic-gate 		struct inode	*_uq_i;
6167c478bd9Sstevel@tonic-gate 		ufs_failure_t	*_uq_uf;
6177c478bd9Sstevel@tonic-gate 	} _uq_head;
6187c478bd9Sstevel@tonic-gate 	int		uq_ne;		/* # of entries/failures found */
6197c478bd9Sstevel@tonic-gate 	int		uq_lowat;	/* thread runs when ne == lowat */
6207c478bd9Sstevel@tonic-gate 	int		uq_hiwat;	/* synchronous idle if ne >= hiwat */
6217c478bd9Sstevel@tonic-gate 	ushort_t	uq_flags;	/* flags (see below) */
6227c478bd9Sstevel@tonic-gate 	kcondvar_t	uq_cv;		/* for sleep/wakeup */
6237c478bd9Sstevel@tonic-gate 	kthread_id_t	uq_threadp;	/* thread managing this q */
6247c478bd9Sstevel@tonic-gate 	kmutex_t	uq_mutex;	/* protects this struct */
6257c478bd9Sstevel@tonic-gate };
6267c478bd9Sstevel@tonic-gate 
6277c478bd9Sstevel@tonic-gate #define	uq_head		_uq_head._uq_generic
6287c478bd9Sstevel@tonic-gate #define	uq_ihead	_uq_head._uq_i
6297c478bd9Sstevel@tonic-gate #define	uq_ufhead	_uq_head._uq_uf
6307c478bd9Sstevel@tonic-gate 
6317c478bd9Sstevel@tonic-gate /*
6327c478bd9Sstevel@tonic-gate  * uq_flags
6337c478bd9Sstevel@tonic-gate  */
6347c478bd9Sstevel@tonic-gate #define	UQ_EXIT		(0x0001)	/* q server exits at its convenience */
6357c478bd9Sstevel@tonic-gate #define	UQ_WAIT		(0x0002)	/* thread is waiting on q server */
6367c478bd9Sstevel@tonic-gate #define	UQ_SUSPEND	(0x0004)	/* request for suspension */
6377c478bd9Sstevel@tonic-gate #define	UQ_SUSPENDED	(0x0008)	/* thread has suspended itself */
638121be23bSjkennedy 
639121be23bSjkennedy /*
640121be23bSjkennedy  * When logging is enabled, statvfs must account for blocks and files that
641121be23bSjkennedy  * may be on the delete queue.  Protected by ufsvfsp->vfs_delete.uq_mutex
642121be23bSjkennedy  */
643121be23bSjkennedy struct ufs_delq_info {
644121be23bSjkennedy 	u_offset_t	delq_unreclaimed_blocks;
645121be23bSjkennedy 	ulong_t		delq_unreclaimed_files;
646121be23bSjkennedy };
647121be23bSjkennedy 
6487c478bd9Sstevel@tonic-gate 
6497c478bd9Sstevel@tonic-gate /*
6507c478bd9Sstevel@tonic-gate  * global idle queues
6517c478bd9Sstevel@tonic-gate  * The queues are sized dynamically in proportion to ufs_ninode
6527c478bd9Sstevel@tonic-gate  * which, unless overridden, scales with the amount of memory.
6537c478bd9Sstevel@tonic-gate  * The idle queue is halved whenever it hits the low water mark
6547c478bd9Sstevel@tonic-gate  * (1/4 of ufs_ninode), but can burst to sizes much larger. The number
6557c478bd9Sstevel@tonic-gate  * of hash queues is currently maintained to give on average IQHASHQLEN
6567c478bd9Sstevel@tonic-gate  * entries when the idle queue is at the low water mark.
6577c478bd9Sstevel@tonic-gate  * Note, we do not need to search along the hash queues, but use them
6587c478bd9Sstevel@tonic-gate  * in order to batch together geographically local inodes to allow
6597c478bd9Sstevel@tonic-gate  * their updates (via the log or buffer cache) to require less disk seeks.
6607c478bd9Sstevel@tonic-gate  * This gives an incredible performance boost for logging and a boost for
6617c478bd9Sstevel@tonic-gate  * non logging file systems.
6627c478bd9Sstevel@tonic-gate  */
6637c478bd9Sstevel@tonic-gate typedef struct {
6647c478bd9Sstevel@tonic-gate 	inode_t *i_chain[2];	/* must match inode_t, but unused */
6657c478bd9Sstevel@tonic-gate 	inode_t *i_freef;	/* must match inode_t, idle list forward */
6667c478bd9Sstevel@tonic-gate 	inode_t *i_freeb;	/* must match inode_t, idle list back  */
6677c478bd9Sstevel@tonic-gate } iqhead_t;
6687c478bd9Sstevel@tonic-gate 
6697c478bd9Sstevel@tonic-gate extern struct ufs_q ufs_idle_q;		/* used by global ufs idle thread */
6707c478bd9Sstevel@tonic-gate extern iqhead_t *ufs_junk_iq;		/* junk idle queues */
6717c478bd9Sstevel@tonic-gate extern iqhead_t *ufs_useful_iq;		/* useful idle queues */
6727c478bd9Sstevel@tonic-gate extern int ufs_njunk_iq;		/* number of entries in junk iq */
6737c478bd9Sstevel@tonic-gate extern int ufs_nuseful_iq;		/* number of entries in useful iq */
6747c478bd9Sstevel@tonic-gate extern int ufs_niqhash;			/* number of iq hash qs - power of 2 */
6757c478bd9Sstevel@tonic-gate extern int ufs_iqhashmask;		/* iq hash mask = ufs_niqhash - 1 */
6767c478bd9Sstevel@tonic-gate 
6777c478bd9Sstevel@tonic-gate #define	IQHASHQLEN 32			/* see comments above */
6787c478bd9Sstevel@tonic-gate #define	INOCGSHIFT 7			/* 128 inodes per cylinder group */
6797c478bd9Sstevel@tonic-gate #define	IQHASH(ip) (((ip)->i_number >> INOCGSHIFT) & ufs_iqhashmask)
6807c478bd9Sstevel@tonic-gate #define	IQNEXT(i) ((i) + 1) & ufs_iqhashmask /* next idle queue */
6817c478bd9Sstevel@tonic-gate 
6827c478bd9Sstevel@tonic-gate extern struct ufs_q	ufs_hlock;	/* used by global ufs hlock thread */
6837c478bd9Sstevel@tonic-gate 
6847c478bd9Sstevel@tonic-gate /*
6857c478bd9Sstevel@tonic-gate  * vfs_lfflags flags
6867c478bd9Sstevel@tonic-gate  */
6877c478bd9Sstevel@tonic-gate #define	UFS_LARGEFILES	((ushort_t)0x1)	/* set if mount allows largefiles */
6887c478bd9Sstevel@tonic-gate 
6897c478bd9Sstevel@tonic-gate /*
6907c478bd9Sstevel@tonic-gate  * vfs_dfritime flags
6917c478bd9Sstevel@tonic-gate  */
6927c478bd9Sstevel@tonic-gate #define	UFS_DFRATIME	0x1		/* deferred access time */
6937c478bd9Sstevel@tonic-gate 
6947c478bd9Sstevel@tonic-gate /*
6957c478bd9Sstevel@tonic-gate  * UFS VFS private data.
6967c478bd9Sstevel@tonic-gate  *
6977c478bd9Sstevel@tonic-gate  * UFS file system instances may be linked on several lists.
6987c478bd9Sstevel@tonic-gate  *
6997c478bd9Sstevel@tonic-gate  * -	The vfs_next field chains together every extant ufs instance; this
7007c478bd9Sstevel@tonic-gate  *	list is rooted at ufs_instances and should be used in preference to
7017c478bd9Sstevel@tonic-gate  *	the overall vfs list (which is properly the province of the generic
7027c478bd9Sstevel@tonic-gate  *	file system code, not of file system implementations).  This same list
7037c478bd9Sstevel@tonic-gate  *	link is used during forcible unmounts to chain together instances that
7047c478bd9Sstevel@tonic-gate  *	can't yet be completely dismantled,
7057c478bd9Sstevel@tonic-gate  *
7067c478bd9Sstevel@tonic-gate  * -	The vfs_wnext field is used within ufs_update to form a work list of
7077c478bd9Sstevel@tonic-gate  *	UFS instances to be synced out.
7087c478bd9Sstevel@tonic-gate  */
7097c478bd9Sstevel@tonic-gate typedef struct ufsvfs {
7107c478bd9Sstevel@tonic-gate 	struct vfs	*vfs_vfs;	/* back link			*/
7117c478bd9Sstevel@tonic-gate 	struct ufsvfs	*vfs_next;	/* instance list link		*/
7127c478bd9Sstevel@tonic-gate 	struct ufsvfs	*vfs_wnext;	/* work list link		*/
7137c478bd9Sstevel@tonic-gate 	struct vnode	*vfs_root;	/* root vnode			*/
7147c478bd9Sstevel@tonic-gate 	struct buf	*vfs_bufp;	/* buffer containing superblock */
7157c478bd9Sstevel@tonic-gate 	struct vnode	*vfs_devvp;	/* block device vnode		*/
7167c478bd9Sstevel@tonic-gate 	ushort_t	vfs_lfflags;	/* Large files (set by mount)   */
7177c478bd9Sstevel@tonic-gate 	ushort_t	vfs_qflags;	/* QUOTA: filesystem flags	*/
7187c478bd9Sstevel@tonic-gate 	struct inode	*vfs_qinod;	/* QUOTA: pointer to quota file */
7197c478bd9Sstevel@tonic-gate 	uint_t		vfs_btimelimit;	/* QUOTA: block time limit	*/
7207c478bd9Sstevel@tonic-gate 	uint_t		vfs_ftimelimit;	/* QUOTA: file time limit	*/
7217c478bd9Sstevel@tonic-gate 	krwlock_t	vfs_dqrwlock;	/* QUOTA: protects quota fields */
7227c478bd9Sstevel@tonic-gate 	/*
7237c478bd9Sstevel@tonic-gate 	 * some fs local threads
7247c478bd9Sstevel@tonic-gate 	 */
7257c478bd9Sstevel@tonic-gate 	struct ufs_q	vfs_delete;	/* delayed inode delete */
7267c478bd9Sstevel@tonic-gate 	struct ufs_q	vfs_reclaim;	/* reclaim open, deleted files */
727121be23bSjkennedy 
7287c478bd9Sstevel@tonic-gate 	/*
7297c478bd9Sstevel@tonic-gate 	 * This is copied from the super block at mount time.
7307c478bd9Sstevel@tonic-gate 	 */
7317c478bd9Sstevel@tonic-gate 	int		vfs_nrpos;	/* # rotational positions */
7327c478bd9Sstevel@tonic-gate 	/*
7337c478bd9Sstevel@tonic-gate 	 * This lock protects cg's and super block pointed at by
7347c478bd9Sstevel@tonic-gate 	 * vfs_bufp->b_fs.  Locks contents of fs and cg's and contents
7357c478bd9Sstevel@tonic-gate 	 * of vfs_dio.
7367c478bd9Sstevel@tonic-gate 	 */
7377c478bd9Sstevel@tonic-gate 	kmutex_t	vfs_lock;
7387c478bd9Sstevel@tonic-gate 	struct ulockfs	vfs_ulockfs;	/* ufs lockfs support */
7397c478bd9Sstevel@tonic-gate 	uint_t		vfs_dio;	/* delayed io (_FIODIO) */
7407c478bd9Sstevel@tonic-gate 	uint_t		vfs_nointr;	/* disallow lockfs interrupts */
7417c478bd9Sstevel@tonic-gate 	uint_t		vfs_nosetsec;	/* disallow ufs_setsecattr */
7427c478bd9Sstevel@tonic-gate 	uint_t		vfs_syncdir;	/* synchronous local directory ops */
7437c478bd9Sstevel@tonic-gate 	uint_t		vfs_dontblock;	/* don't block on forced umount */
7447c478bd9Sstevel@tonic-gate 
7457c478bd9Sstevel@tonic-gate 	/*
7467c478bd9Sstevel@tonic-gate 	 * trans (logging ufs) stuff
7477c478bd9Sstevel@tonic-gate 	 */
7487c478bd9Sstevel@tonic-gate 	uint_t		vfs_domatamap;	/* set if matamap enabled */
7497c478bd9Sstevel@tonic-gate 	ulong_t		vfs_maxacl;	/* transaction stuff - max acl size */
7507c478bd9Sstevel@tonic-gate 	ulong_t		vfs_dirsize;	/* logspace for directory creation */
7517c478bd9Sstevel@tonic-gate 	ulong_t		vfs_avgbfree;	/* average free blks in cg (blkpref) */
7527c478bd9Sstevel@tonic-gate 	/*
7537c478bd9Sstevel@tonic-gate 	 * Some useful constants
7547c478bd9Sstevel@tonic-gate 	 */
7557c478bd9Sstevel@tonic-gate 	int	vfs_nindirshift;	/* calc. from fs_nindir */
7567c478bd9Sstevel@tonic-gate 	int	vfs_nindiroffset;	/* calc. from fs_ninidr */
7577c478bd9Sstevel@tonic-gate 	int	vfs_ioclustsz;		/* bytes in read/write cluster */
7587c478bd9Sstevel@tonic-gate 	int	vfs_iotransz;		/* max device i/o transfer size  */
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate 	vfs_ufsfx_t	vfs_fsfx;	/* lock/fix-on-panic support */
7617c478bd9Sstevel@tonic-gate 	/*
7627c478bd9Sstevel@tonic-gate 	 * More useful constants
7637c478bd9Sstevel@tonic-gate 	 */
7647c478bd9Sstevel@tonic-gate 	int	vfs_minfrags;		/* calc. from fs_minfree */
7657c478bd9Sstevel@tonic-gate 	/*
7667c478bd9Sstevel@tonic-gate 	 * Force DirectIO on all files
7677c478bd9Sstevel@tonic-gate 	 */
7687c478bd9Sstevel@tonic-gate 	uint_t	vfs_forcedirectio;
7697c478bd9Sstevel@tonic-gate 	/*
7707c478bd9Sstevel@tonic-gate 	 * Deferred inode time related fields
7717c478bd9Sstevel@tonic-gate 	 */
7727c478bd9Sstevel@tonic-gate 	clock_t		vfs_iotstamp;	/* last I/O timestamp */
7737c478bd9Sstevel@tonic-gate 	uint_t		vfs_dfritime;	/* deferred inode time flags */
7747c478bd9Sstevel@tonic-gate 	/*
7757c478bd9Sstevel@tonic-gate 	 * Some more useful info
7767c478bd9Sstevel@tonic-gate 	 */
7777c478bd9Sstevel@tonic-gate 	dev_t		vfs_dev;	/* device mounted from */
7787c478bd9Sstevel@tonic-gate 	struct ml_unit	*vfs_log;	/* pointer to embedded log struct */
7797c478bd9Sstevel@tonic-gate 	uint_t		vfs_noatime;    /* disable inode atime updates */
7807c478bd9Sstevel@tonic-gate 	/*
7817c478bd9Sstevel@tonic-gate 	 * snapshot stuff
7827c478bd9Sstevel@tonic-gate 	 */
7837c478bd9Sstevel@tonic-gate 	void		*vfs_snapshot;	/* snapshot handle */
7847c478bd9Sstevel@tonic-gate 	/*
7857c478bd9Sstevel@tonic-gate 	 *  Controls logging "file system full" messages to messages file
7867c478bd9Sstevel@tonic-gate 	 */
7877c478bd9Sstevel@tonic-gate 	clock_t		vfs_lastwhinetime;
7887c478bd9Sstevel@tonic-gate 
7897c478bd9Sstevel@tonic-gate 	int 		vfs_nolog_si;	/* not logging summary info */
7907c478bd9Sstevel@tonic-gate 	int		vfs_validfs;	/* indicates mounted fs */
791121be23bSjkennedy 
792121be23bSjkennedy 	/*
793121be23bSjkennedy 	 * Additional information about vfs_delete above
794121be23bSjkennedy 	 */
795121be23bSjkennedy 	struct ufs_delq_info vfs_delete_info; /* what's on the delete queue */
7967c478bd9Sstevel@tonic-gate } ufsvfs_t;
7977c478bd9Sstevel@tonic-gate 
7987c478bd9Sstevel@tonic-gate #define	vfs_fs	vfs_bufp->b_un.b_fs
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate /*
8017c478bd9Sstevel@tonic-gate  * values for vfs_validfs
8027c478bd9Sstevel@tonic-gate  */
8037c478bd9Sstevel@tonic-gate #define	UT_UNMOUNTED	0
8047c478bd9Sstevel@tonic-gate #define	UT_MOUNTED	1
8057c478bd9Sstevel@tonic-gate #define	UT_HLOCKING	2
8067c478bd9Sstevel@tonic-gate 
8077c478bd9Sstevel@tonic-gate /* inohsz is guaranteed to be a power of 2 */
8087c478bd9Sstevel@tonic-gate #define	INOHASH(ino)	(((int)ino) & (inohsz - 1))
8097c478bd9Sstevel@tonic-gate 
810303bf60bSsdebnath #define	ISFALLOCBLK(ip, bn)	\
81133c22cb3Smishra 	(((bn) < 0) && ((bn) % ip->i_fs->fs_frag == 0) && \
812303bf60bSsdebnath 	((ip)->i_cflags & IFALLOCATE && (bn) != UFS_HOLE))
813303bf60bSsdebnath 
8147c478bd9Sstevel@tonic-gate union ihead {
8157c478bd9Sstevel@tonic-gate 	union	ihead	*ih_head[2];
8167c478bd9Sstevel@tonic-gate 	struct	inode	*ih_chain[2];
8177c478bd9Sstevel@tonic-gate };
8187c478bd9Sstevel@tonic-gate 
8197c478bd9Sstevel@tonic-gate extern	union	ihead	*ihead;
8207c478bd9Sstevel@tonic-gate extern  kmutex_t	*ih_lock;
8217c478bd9Sstevel@tonic-gate extern  int	*ih_ne;
8227c478bd9Sstevel@tonic-gate extern	int	inohsz;
8237c478bd9Sstevel@tonic-gate 
8247c478bd9Sstevel@tonic-gate extern	clock_t	ufs_iowait;
8257c478bd9Sstevel@tonic-gate 
8267c478bd9Sstevel@tonic-gate #endif /* _KERNEL */
8277c478bd9Sstevel@tonic-gate 
8287c478bd9Sstevel@tonic-gate /*
8297c478bd9Sstevel@tonic-gate  * ufs function prototypes
8307c478bd9Sstevel@tonic-gate  */
8317c478bd9Sstevel@tonic-gate #if defined(_KERNEL) && !defined(_BOOT)
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate extern	void	ufs_iinit(void);
8347c478bd9Sstevel@tonic-gate extern	int	ufs_iget(struct vfs *, ino_t, struct inode **, cred_t *);
8357c478bd9Sstevel@tonic-gate extern	int	ufs_iget_alloced(struct vfs *, ino_t, struct inode **,
8367c478bd9Sstevel@tonic-gate     cred_t *);
8377c478bd9Sstevel@tonic-gate extern	void	ufs_reset_vnode(vnode_t *);
8387c478bd9Sstevel@tonic-gate extern	void	ufs_iinactive(struct inode *);
8397c478bd9Sstevel@tonic-gate extern	void	ufs_iupdat(struct inode *, int);
8407c478bd9Sstevel@tonic-gate extern	int	ufs_rmidle(struct inode *);
8417c478bd9Sstevel@tonic-gate extern	int	ufs_itrunc(struct inode *, u_offset_t, int, cred_t *);
84260c8e821SFrank Batschulat extern	int	ufs_iaccess(struct inode *, int, cred_t *, int);
8437c478bd9Sstevel@tonic-gate extern  int	rdip(struct inode *, struct uio *, int, struct cred *);
8447c478bd9Sstevel@tonic-gate extern  int	wrip(struct inode *, struct uio *, int, struct cred *);
8457c478bd9Sstevel@tonic-gate 
8467c478bd9Sstevel@tonic-gate extern void	ufs_imark(struct inode *);
8477c478bd9Sstevel@tonic-gate extern void	ufs_itimes_nolock(struct inode *);
8487c478bd9Sstevel@tonic-gate 
84960c8e821SFrank Batschulat extern	int	ufs_diraccess(struct inode *, int, struct cred *);
8507c478bd9Sstevel@tonic-gate extern	int	ufs_dirlook(struct inode *, char *, struct inode **,
851*9b5097eeSOwen Roberts     cred_t *, int, int);
8527c478bd9Sstevel@tonic-gate extern	int	ufs_direnter_cm(struct inode *, char *, enum de_op,
8537c478bd9Sstevel@tonic-gate     struct vattr *, struct inode **, cred_t *, int);
8547c478bd9Sstevel@tonic-gate extern	int	ufs_direnter_lr(struct inode *, char *, enum de_op,
855*9b5097eeSOwen Roberts     struct inode *, struct inode *, cred_t *);
8567c478bd9Sstevel@tonic-gate extern	int	ufs_dircheckpath(ino_t, struct inode *, struct inode *,
8577c478bd9Sstevel@tonic-gate     struct cred *);
8587c478bd9Sstevel@tonic-gate extern	int	ufs_dirmakeinode(struct inode *, struct inode **,
8597c478bd9Sstevel@tonic-gate     struct vattr *, enum de_op, cred_t *);
8607c478bd9Sstevel@tonic-gate extern	int	ufs_dirremove(struct inode *, char *, struct inode *,
861*9b5097eeSOwen Roberts     vnode_t *, enum dr_op, cred_t *);
8625b024a5bSbatschul extern  int	ufs_dircheckforname(struct inode *, char *, int,
8635b024a5bSbatschul     struct ufs_slot *, struct inode **, struct cred *, int);
8647c478bd9Sstevel@tonic-gate extern	int	ufs_xattrdirempty(struct inode *, ino_t, cred_t *);
8657c478bd9Sstevel@tonic-gate extern	int	blkatoff(struct inode *, off_t, char **, struct fbuf **);
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate extern	void	sbupdate(struct vfs *);
8687c478bd9Sstevel@tonic-gate 
8697c478bd9Sstevel@tonic-gate extern	int	ufs_ialloc(struct inode *, ino_t, mode_t, struct inode **,
8707c478bd9Sstevel@tonic-gate     cred_t *);
8717c478bd9Sstevel@tonic-gate extern	void	ufs_ifree(struct inode *, ino_t, mode_t);
8727c478bd9Sstevel@tonic-gate extern	void	free(struct inode *, daddr_t, off_t, int);
8737c478bd9Sstevel@tonic-gate extern	int	alloc(struct inode *, daddr_t, int, daddr_t *, cred_t *);
8747c478bd9Sstevel@tonic-gate extern	int	realloccg(struct inode *, daddr_t, daddr_t, int, int,
8757c478bd9Sstevel@tonic-gate     daddr_t *, cred_t *);
876303bf60bSsdebnath extern	int	ufs_allocsp(struct vnode *, struct flock64 *, cred_t *);
8777c478bd9Sstevel@tonic-gate extern	int	ufs_freesp(struct vnode *, struct flock64 *, int, cred_t *);
8787c478bd9Sstevel@tonic-gate extern	ino_t	dirpref(inode_t *);
8797c478bd9Sstevel@tonic-gate extern	daddr_t	blkpref(struct inode *, daddr_t, int, daddr32_t *);
880e7da395aSOwen Roberts extern	daddr_t	contigpref(ufsvfs_t *, size_t, size_t);
8817c478bd9Sstevel@tonic-gate 
8827c478bd9Sstevel@tonic-gate extern	int	ufs_rdwri(enum uio_rw, int, struct inode *, caddr_t, ssize_t,
8837c478bd9Sstevel@tonic-gate 	offset_t, enum uio_seg, int *, cred_t *);
8847c478bd9Sstevel@tonic-gate 
8857c478bd9Sstevel@tonic-gate extern	int	bmap_read(struct inode *, u_offset_t, daddr_t *, int *);
886303bf60bSsdebnath extern	int	bmap_write(struct inode *, u_offset_t, int, enum bi_type,
887303bf60bSsdebnath     daddr_t *, struct cred *);
8887c478bd9Sstevel@tonic-gate extern	int	bmap_has_holes(struct inode *);
8897c478bd9Sstevel@tonic-gate extern	int	bmap_find(struct inode *, boolean_t, u_offset_t *);
890303bf60bSsdebnath extern	int	bmap_set_bn(struct vnode *, u_offset_t, daddr32_t);
8917c478bd9Sstevel@tonic-gate 
8927c478bd9Sstevel@tonic-gate extern	void	ufs_vfs_add(struct ufsvfs *);
8937c478bd9Sstevel@tonic-gate extern	void	ufs_vfs_remove(struct ufsvfs *);
8947c478bd9Sstevel@tonic-gate 
8957c478bd9Sstevel@tonic-gate extern	void	ufs_sbwrite(struct ufsvfs *);
8967c478bd9Sstevel@tonic-gate extern	void	ufs_update(int);
8977c478bd9Sstevel@tonic-gate extern	int	ufs_getsummaryinfo(dev_t, struct ufsvfs *, struct fs *);
8987c478bd9Sstevel@tonic-gate extern	int	ufs_putsummaryinfo(dev_t, struct ufsvfs *, struct fs *);
8997c478bd9Sstevel@tonic-gate extern	int	ufs_syncip(struct inode *, int, int, top_t);
9007c478bd9Sstevel@tonic-gate extern	int	ufs_sync_indir(struct inode *);
9017c478bd9Sstevel@tonic-gate extern	int	ufs_indirblk_sync(struct inode *, offset_t);
9027c478bd9Sstevel@tonic-gate extern	int	ufs_badblock(struct inode *, daddr_t);
9037c478bd9Sstevel@tonic-gate extern	int	ufs_indir_badblock(struct inode *, daddr32_t *);
9047c478bd9Sstevel@tonic-gate extern	void	ufs_notclean(struct ufsvfs *);
9057c478bd9Sstevel@tonic-gate extern	void	ufs_checkclean(struct vfs *);
9067c478bd9Sstevel@tonic-gate extern	int	isblock(struct fs *, uchar_t *, daddr_t);
9077c478bd9Sstevel@tonic-gate extern	void	setblock(struct fs *, uchar_t *, daddr_t);
9087c478bd9Sstevel@tonic-gate extern	void	clrblock(struct fs *, uchar_t *, daddr_t);
9097c478bd9Sstevel@tonic-gate extern	int	isclrblock(struct fs *, uchar_t *, daddr_t);
9107c478bd9Sstevel@tonic-gate extern	void	fragacct(struct fs *, int, int32_t *, int);
9117c478bd9Sstevel@tonic-gate extern	int	skpc(char, uint_t, char *);
9127c478bd9Sstevel@tonic-gate extern	int	ufs_fbwrite(struct fbuf *, struct inode *);
9137c478bd9Sstevel@tonic-gate extern	int	ufs_fbiwrite(struct fbuf *, struct inode *, daddr_t, long);
9147c478bd9Sstevel@tonic-gate extern	int	ufs_putapage(struct vnode *, struct page *, u_offset_t *,
9157c478bd9Sstevel@tonic-gate 				size_t *, int, struct cred *);
9167c478bd9Sstevel@tonic-gate extern inode_t	*ufs_alloc_inode(ufsvfs_t *, ino_t);
9177c478bd9Sstevel@tonic-gate extern void	ufs_free_inode(inode_t *);
9187c478bd9Sstevel@tonic-gate 
9197c478bd9Sstevel@tonic-gate /*
9207c478bd9Sstevel@tonic-gate  * special stuff
9217c478bd9Sstevel@tonic-gate  */
9227c478bd9Sstevel@tonic-gate extern	void	ufs_setreclaim(struct inode *);
9237c478bd9Sstevel@tonic-gate extern	int	ufs_scan_inodes(int, int (*)(struct inode *, void *), void *,
9247c478bd9Sstevel@tonic-gate 				struct ufsvfs *);
9257c478bd9Sstevel@tonic-gate extern	int	ufs_sync_inode(struct inode *, void *);
9267c478bd9Sstevel@tonic-gate extern	int	ufs_sticky_remove_access(struct inode *, struct inode *,
9277c478bd9Sstevel@tonic-gate     struct cred *);
9287c478bd9Sstevel@tonic-gate /*
9297c478bd9Sstevel@tonic-gate  * quota
9307c478bd9Sstevel@tonic-gate  */
9317c478bd9Sstevel@tonic-gate extern	int	chkiq(struct ufsvfs *, int, struct inode *, uid_t, int,
9327c478bd9Sstevel@tonic-gate 			struct cred *, char **errp, size_t *lenp);
9337c478bd9Sstevel@tonic-gate 
9347c478bd9Sstevel@tonic-gate /*
9357c478bd9Sstevel@tonic-gate  * ufs thread stuff
9367c478bd9Sstevel@tonic-gate  */
9377c478bd9Sstevel@tonic-gate extern	void	ufs_thread_delete(struct vfs *);
9387c478bd9Sstevel@tonic-gate extern	void	ufs_delete_drain(struct vfs *, int, int);
9397c478bd9Sstevel@tonic-gate extern	void	ufs_delete(struct ufsvfs *, struct inode *, int);
9407c478bd9Sstevel@tonic-gate extern	void	ufs_inode_cache_reclaim(void *);
9417c478bd9Sstevel@tonic-gate extern	void	ufs_idle_drain(struct vfs *);
9427c478bd9Sstevel@tonic-gate extern	void	ufs_idle_some(int);
9437c478bd9Sstevel@tonic-gate extern	void	ufs_thread_idle(void);
9447c478bd9Sstevel@tonic-gate extern	void	ufs_thread_reclaim(struct vfs *);
9457c478bd9Sstevel@tonic-gate extern	void	ufs_thread_init(struct ufs_q *, int);
9467c478bd9Sstevel@tonic-gate extern	void	ufs_thread_start(struct ufs_q *, void (*)(), struct vfs *);
9477c478bd9Sstevel@tonic-gate extern	void	ufs_thread_exit(struct ufs_q *);
9487c478bd9Sstevel@tonic-gate extern	void	ufs_thread_suspend(struct ufs_q *);
9497c478bd9Sstevel@tonic-gate extern	void	ufs_thread_continue(struct ufs_q *);
9507c478bd9Sstevel@tonic-gate extern	void	ufs_thread_hlock(void *);
951121be23bSjkennedy extern	void	ufs_delete_init(struct ufsvfs *, int);
9527c478bd9Sstevel@tonic-gate extern	void	ufs_delete_adjust_stats(struct ufsvfs *, struct statvfs64 *);
9537c478bd9Sstevel@tonic-gate extern	void	ufs_delete_drain_wait(struct ufsvfs *, int);
9547c478bd9Sstevel@tonic-gate 
9557c478bd9Sstevel@tonic-gate /*
9567c478bd9Sstevel@tonic-gate  * ufs lockfs stuff
9577c478bd9Sstevel@tonic-gate  */
9587c478bd9Sstevel@tonic-gate struct seg;
9597c478bd9Sstevel@tonic-gate extern int ufs_reconcile_fs(struct vfs *, struct ufsvfs *, int);
9607c478bd9Sstevel@tonic-gate extern int ufs_quiesce(struct ulockfs *);
9617c478bd9Sstevel@tonic-gate extern int ufs_flush(struct vfs *);
9627c478bd9Sstevel@tonic-gate extern int ufs_fiolfs(struct vnode *, struct lockfs *, int);
9637c478bd9Sstevel@tonic-gate extern int ufs__fiolfs(struct vnode *, struct lockfs *, int, int);
9647c478bd9Sstevel@tonic-gate extern int ufs_fiolfss(struct vnode *, struct lockfs *);
9657c478bd9Sstevel@tonic-gate extern int ufs_fioffs(struct vnode *, char *, struct cred *);
9667c478bd9Sstevel@tonic-gate extern int ufs_check_lockfs(struct ufsvfs *, struct ulockfs *, ulong_t);
9677c478bd9Sstevel@tonic-gate extern int ufs_lockfs_begin(struct ufsvfs *, struct ulockfs **, ulong_t);
9686ac3b8a8Svsakar extern int ufs_lockfs_trybegin(struct ufsvfs *, struct ulockfs **, ulong_t);
9697c478bd9Sstevel@tonic-gate extern int ufs_lockfs_begin_getpage(struct ufsvfs *, struct ulockfs **,
9707c478bd9Sstevel@tonic-gate 		struct seg *, int, uint_t *);
9717c478bd9Sstevel@tonic-gate extern void ufs_lockfs_end(struct ulockfs *);
9727c478bd9Sstevel@tonic-gate /*
9737c478bd9Sstevel@tonic-gate  * ufs acl stuff
9747c478bd9Sstevel@tonic-gate  */
9757c478bd9Sstevel@tonic-gate extern int ufs_si_inherit(struct inode *, struct inode *, o_mode_t, cred_t *);
9767c478bd9Sstevel@tonic-gate extern void si_cache_init(void);
9777c478bd9Sstevel@tonic-gate extern int ufs_si_load(struct inode *, cred_t *);
9787c478bd9Sstevel@tonic-gate extern void ufs_si_del(struct inode *);
9797c478bd9Sstevel@tonic-gate extern int ufs_acl_access(struct inode *, int, cred_t *);
9807c478bd9Sstevel@tonic-gate extern void ufs_si_cache_flush(dev_t);
9817c478bd9Sstevel@tonic-gate extern int ufs_si_free(si_t *, struct vfs *, cred_t *);
9827c478bd9Sstevel@tonic-gate extern int ufs_acl_setattr(struct inode *, struct vattr *, cred_t *);
9837c478bd9Sstevel@tonic-gate extern int ufs_acl_get(struct inode *, vsecattr_t *, int, cred_t *);
9847c478bd9Sstevel@tonic-gate extern int ufs_acl_set(struct inode *, vsecattr_t *, int, cred_t *);
9857c478bd9Sstevel@tonic-gate /*
9867c478bd9Sstevel@tonic-gate  * ufs directio stuff
9877c478bd9Sstevel@tonic-gate  */
9887c478bd9Sstevel@tonic-gate extern void ufs_directio_init();
9897c478bd9Sstevel@tonic-gate extern int ufs_directio_write(struct inode *, uio_t *, int, int, cred_t *,
9907c478bd9Sstevel@tonic-gate     int *);
9917c478bd9Sstevel@tonic-gate extern int ufs_directio_read(struct inode *, uio_t *, cred_t *, int *);
9927c478bd9Sstevel@tonic-gate #define	DIRECTIO_FAILURE	(0)
9937c478bd9Sstevel@tonic-gate #define	DIRECTIO_SUCCESS	(1)
9947c478bd9Sstevel@tonic-gate 
9957c478bd9Sstevel@tonic-gate /*
9967c478bd9Sstevel@tonic-gate  * ufs extensions for PXFS
9977c478bd9Sstevel@tonic-gate  */
9987c478bd9Sstevel@tonic-gate 
9997c478bd9Sstevel@tonic-gate int ufs_rdwr_data(vnode_t *vp, u_offset_t offset, size_t len, fdbuffer_t *fdb,
10007c478bd9Sstevel@tonic-gate     int flags, cred_t *cr);
10017c478bd9Sstevel@tonic-gate int ufs_alloc_data(vnode_t *vp, u_offset_t offset, size_t *len, fdbuffer_t *fdb,
10027c478bd9Sstevel@tonic-gate     int flags, cred_t *cr);
10037c478bd9Sstevel@tonic-gate 
10047c478bd9Sstevel@tonic-gate /*
10057c478bd9Sstevel@tonic-gate  * prototypes to support the forced unmount
10067c478bd9Sstevel@tonic-gate  */
10077c478bd9Sstevel@tonic-gate 
10087c478bd9Sstevel@tonic-gate void ufs_freeze(struct ulockfs *, struct lockfs *);
10097c478bd9Sstevel@tonic-gate int ufs_thaw(struct vfs *, struct ufsvfs *, struct ulockfs *);
10107c478bd9Sstevel@tonic-gate 
10117c478bd9Sstevel@tonic-gate /*
10127c478bd9Sstevel@tonic-gate  * extended attributes
10137c478bd9Sstevel@tonic-gate  */
10147c478bd9Sstevel@tonic-gate 
10157c478bd9Sstevel@tonic-gate int ufs_xattrmkdir(inode_t *, inode_t **, int, struct cred *);
10167c478bd9Sstevel@tonic-gate int ufs_xattr_getattrdir(vnode_t *, inode_t **, int, struct cred *);
10177c478bd9Sstevel@tonic-gate void ufs_unhook_shadow(inode_t *, inode_t *);
10187c478bd9Sstevel@tonic-gate 
10197c478bd9Sstevel@tonic-gate #endif	/* defined(_KERNEL) && !defined(_BOOT) */
10207c478bd9Sstevel@tonic-gate 
10217c478bd9Sstevel@tonic-gate #ifdef	__cplusplus
10227c478bd9Sstevel@tonic-gate }
10237c478bd9Sstevel@tonic-gate #endif
10247c478bd9Sstevel@tonic-gate 
10257c478bd9Sstevel@tonic-gate #endif	/* _SYS_FS_UFS_INODE_H */
1026