xref: /illumos-gate/usr/src/uts/common/fs/zfs/zfs_vnops.c (revision fa9e4066)
1*fa9e4066Sahrens /*
2*fa9e4066Sahrens  * CDDL HEADER START
3*fa9e4066Sahrens  *
4*fa9e4066Sahrens  * The contents of this file are subject to the terms of the
5*fa9e4066Sahrens  * Common Development and Distribution License, Version 1.0 only
6*fa9e4066Sahrens  * (the "License").  You may not use this file except in compliance
7*fa9e4066Sahrens  * with the License.
8*fa9e4066Sahrens  *
9*fa9e4066Sahrens  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*fa9e4066Sahrens  * or http://www.opensolaris.org/os/licensing.
11*fa9e4066Sahrens  * See the License for the specific language governing permissions
12*fa9e4066Sahrens  * and limitations under the License.
13*fa9e4066Sahrens  *
14*fa9e4066Sahrens  * When distributing Covered Code, include this CDDL HEADER in each
15*fa9e4066Sahrens  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*fa9e4066Sahrens  * If applicable, add the following below this CDDL HEADER, with the
17*fa9e4066Sahrens  * fields enclosed by brackets "[]" replaced with your own identifying
18*fa9e4066Sahrens  * information: Portions Copyright [yyyy] [name of copyright owner]
19*fa9e4066Sahrens  *
20*fa9e4066Sahrens  * CDDL HEADER END
21*fa9e4066Sahrens  */
22*fa9e4066Sahrens /*
23*fa9e4066Sahrens  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24*fa9e4066Sahrens  * Use is subject to license terms.
25*fa9e4066Sahrens  */
26*fa9e4066Sahrens 
27*fa9e4066Sahrens #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*fa9e4066Sahrens 
29*fa9e4066Sahrens #include <sys/types.h>
30*fa9e4066Sahrens #include <sys/param.h>
31*fa9e4066Sahrens #include <sys/time.h>
32*fa9e4066Sahrens #include <sys/systm.h>
33*fa9e4066Sahrens #include <sys/sysmacros.h>
34*fa9e4066Sahrens #include <sys/resource.h>
35*fa9e4066Sahrens #include <sys/vfs.h>
36*fa9e4066Sahrens #include <sys/vnode.h>
37*fa9e4066Sahrens #include <sys/file.h>
38*fa9e4066Sahrens #include <sys/stat.h>
39*fa9e4066Sahrens #include <sys/kmem.h>
40*fa9e4066Sahrens #include <sys/taskq.h>
41*fa9e4066Sahrens #include <sys/uio.h>
42*fa9e4066Sahrens #include <sys/vmsystm.h>
43*fa9e4066Sahrens #include <sys/atomic.h>
44*fa9e4066Sahrens #include <vm/seg_vn.h>
45*fa9e4066Sahrens #include <vm/pvn.h>
46*fa9e4066Sahrens #include <vm/as.h>
47*fa9e4066Sahrens #include <sys/mman.h>
48*fa9e4066Sahrens #include <sys/pathname.h>
49*fa9e4066Sahrens #include <sys/cmn_err.h>
50*fa9e4066Sahrens #include <sys/errno.h>
51*fa9e4066Sahrens #include <sys/unistd.h>
52*fa9e4066Sahrens #include <sys/zfs_vfsops.h>
53*fa9e4066Sahrens #include <sys/zfs_dir.h>
54*fa9e4066Sahrens #include <sys/zfs_acl.h>
55*fa9e4066Sahrens #include <sys/zfs_ioctl.h>
56*fa9e4066Sahrens #include <sys/fs/zfs.h>
57*fa9e4066Sahrens #include <sys/dmu.h>
58*fa9e4066Sahrens #include <sys/spa.h>
59*fa9e4066Sahrens #include <sys/txg.h>
60*fa9e4066Sahrens #include <sys/refcount.h>  /* temporary for debugging purposes */
61*fa9e4066Sahrens #include <sys/dbuf.h>
62*fa9e4066Sahrens #include <sys/zap.h>
63*fa9e4066Sahrens #include <sys/dirent.h>
64*fa9e4066Sahrens #include <sys/policy.h>
65*fa9e4066Sahrens #include <sys/sunddi.h>
66*fa9e4066Sahrens #include <sys/filio.h>
67*fa9e4066Sahrens #include "fs/fs_subr.h"
68*fa9e4066Sahrens #include <sys/zfs_ctldir.h>
69*fa9e4066Sahrens 
70*fa9e4066Sahrens /*
71*fa9e4066Sahrens  * Programming rules.
72*fa9e4066Sahrens  *
73*fa9e4066Sahrens  * Each vnode op performs some logical unit of work.  To do this, the ZPL must
74*fa9e4066Sahrens  * properly lock its in-core state, create a DMU transaction, do the work,
75*fa9e4066Sahrens  * record this work in the intent log (ZIL), commit the DMU transaction,
76*fa9e4066Sahrens  * and wait the the intent log to commit if it's is a synchronous operation.
77*fa9e4066Sahrens  * Morover, the vnode ops must work in both normal and log replay context.
78*fa9e4066Sahrens  * The ordering of events is important to avoid deadlocks and references
79*fa9e4066Sahrens  * to freed memory.  The example below illustrates the following Big Rules:
80*fa9e4066Sahrens  *
81*fa9e4066Sahrens  *  (1) A check must be made in each zfs thread for a mounted file system.
82*fa9e4066Sahrens  *	This is done avoiding races using ZFS_ENTER(zfsvfs).
83*fa9e4066Sahrens  *	A ZFS_EXIT(zfsvfs) is needed before all returns.
84*fa9e4066Sahrens  *
85*fa9e4066Sahrens  *  (2)	VN_RELE() should always be the last thing except for zil_commit()
86*fa9e4066Sahrens  *	and ZFS_EXIT(). This is for 3 reasons:
87*fa9e4066Sahrens  *	First, if it's the last reference, the vnode/znode
88*fa9e4066Sahrens  *	can be freed, so the zp may point to freed memory.  Second, the last
89*fa9e4066Sahrens  *	reference will call zfs_zinactive(), which may induce a lot of work --
90*fa9e4066Sahrens  *	pushing cached pages (which requires z_grow_lock) and syncing out
91*fa9e4066Sahrens  *	cached atime changes.  Third, zfs_zinactive() may require a new tx,
92*fa9e4066Sahrens  *	which could deadlock the system if you were already holding one.
93*fa9e4066Sahrens  *
94*fa9e4066Sahrens  *  (3)	Always pass zfsvfs->z_assign as the second argument to dmu_tx_assign().
95*fa9e4066Sahrens  *	In normal operation, this will be TXG_NOWAIT.  During ZIL replay,
96*fa9e4066Sahrens  *	it will be a specific txg.  Either way, dmu_tx_assign() never blocks.
97*fa9e4066Sahrens  *	This is critical because we don't want to block while holding locks.
98*fa9e4066Sahrens  *	Note, in particular, that if a lock is sometimes acquired before
99*fa9e4066Sahrens  *	the tx assigns, and sometimes after (e.g. z_lock), then failing to
100*fa9e4066Sahrens  *	use a non-blocking assign can deadlock the system.  The scenario:
101*fa9e4066Sahrens  *
102*fa9e4066Sahrens  *	Thread A has grabbed a lock before calling dmu_tx_assign().
103*fa9e4066Sahrens  *	Thread B is in an already-assigned tx, and blocks for this lock.
104*fa9e4066Sahrens  *	Thread A calls dmu_tx_assign(TXG_WAIT) and blocks in txg_wait_open()
105*fa9e4066Sahrens  *	forever, because the previous txg can't quiesce until B's tx commits.
106*fa9e4066Sahrens  *
107*fa9e4066Sahrens  *	If dmu_tx_assign() returns ERESTART and zfsvfs->z_assign is TXG_NOWAIT,
108*fa9e4066Sahrens  *	then drop all locks, call txg_wait_open(), and try again.
109*fa9e4066Sahrens  *
110*fa9e4066Sahrens  *  (4)	If the operation succeeded, generate the intent log entry for it
111*fa9e4066Sahrens  *	before dropping locks.  This ensures that the ordering of events
112*fa9e4066Sahrens  *	in the intent log matches the order in which they actually occurred.
113*fa9e4066Sahrens  *
114*fa9e4066Sahrens  *  (5)	At the end of each vnode op, the DMU tx must always commit,
115*fa9e4066Sahrens  *	regardless of whether there were any errors.
116*fa9e4066Sahrens  *
117*fa9e4066Sahrens  *  (6)	After dropping all locks, invoke zil_commit(zilog, seq, ioflag)
118*fa9e4066Sahrens  *	to ensure that synchronous semantics are provided when necessary.
119*fa9e4066Sahrens  *
120*fa9e4066Sahrens  * In general, this is how things should be ordered in each vnode op:
121*fa9e4066Sahrens  *
122*fa9e4066Sahrens  *	ZFS_ENTER(zfsvfs);		// exit if unmounted
123*fa9e4066Sahrens  * top:
124*fa9e4066Sahrens  *	zfs_dirent_lock(&dl, ...)	// lock directory entry (may VN_HOLD())
125*fa9e4066Sahrens  *	rw_enter(...);			// grab any other locks you need
126*fa9e4066Sahrens  *	tx = dmu_tx_create(...);	// get DMU tx
127*fa9e4066Sahrens  *	dmu_tx_hold_*();		// hold each object you might modify
128*fa9e4066Sahrens  *	error = dmu_tx_assign(tx, zfsvfs->z_assign);	// try to assign
129*fa9e4066Sahrens  *	if (error) {
130*fa9e4066Sahrens  *		dmu_tx_abort(tx);	// abort DMU tx
131*fa9e4066Sahrens  *		rw_exit(...);		// drop locks
132*fa9e4066Sahrens  *		zfs_dirent_unlock(dl);	// unlock directory entry
133*fa9e4066Sahrens  *		VN_RELE(...);		// release held vnodes
134*fa9e4066Sahrens  *		if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) {
135*fa9e4066Sahrens  *			txg_wait_open(dmu_objset_pool(os), 0);
136*fa9e4066Sahrens  *			goto top;
137*fa9e4066Sahrens  *		}
138*fa9e4066Sahrens  *		ZFS_EXIT(zfsvfs);	// finished in zfs
139*fa9e4066Sahrens  *		return (error);		// really out of space
140*fa9e4066Sahrens  *	}
141*fa9e4066Sahrens  *	error = do_real_work();		// do whatever this VOP does
142*fa9e4066Sahrens  *	if (error == 0)
143*fa9e4066Sahrens  *		seq = zfs_log_*(...);	// on success, make ZIL entry
144*fa9e4066Sahrens  *	dmu_tx_commit(tx);		// commit DMU tx -- error or not
145*fa9e4066Sahrens  *	rw_exit(...);			// drop locks
146*fa9e4066Sahrens  *	zfs_dirent_unlock(dl);		// unlock directory entry
147*fa9e4066Sahrens  *	VN_RELE(...);			// release held vnodes
148*fa9e4066Sahrens  *	zil_commit(zilog, seq, ioflag);	// synchronous when necessary
149*fa9e4066Sahrens  *	ZFS_EXIT(zfsvfs);		// finished in zfs
150*fa9e4066Sahrens  *	return (error);			// done, report error
151*fa9e4066Sahrens  */
152*fa9e4066Sahrens 
153*fa9e4066Sahrens /* ARGSUSED */
154*fa9e4066Sahrens static int
155*fa9e4066Sahrens zfs_open(vnode_t **vpp, int flag, cred_t *cr)
156*fa9e4066Sahrens {
157*fa9e4066Sahrens 	return (0);
158*fa9e4066Sahrens }
159*fa9e4066Sahrens 
160*fa9e4066Sahrens /* ARGSUSED */
161*fa9e4066Sahrens static int
162*fa9e4066Sahrens zfs_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr)
163*fa9e4066Sahrens {
164*fa9e4066Sahrens 	/*
165*fa9e4066Sahrens 	 * Clean up any locks held by this process on the vp.
166*fa9e4066Sahrens 	 */
167*fa9e4066Sahrens 	cleanlocks(vp, ddi_get_pid(), 0);
168*fa9e4066Sahrens 	cleanshares(vp, ddi_get_pid());
169*fa9e4066Sahrens 
170*fa9e4066Sahrens 	return (0);
171*fa9e4066Sahrens }
172*fa9e4066Sahrens 
173*fa9e4066Sahrens /*
174*fa9e4066Sahrens  * Lseek support for finding holes (cmd == _FIO_SEEK_HOLE) and
175*fa9e4066Sahrens  * data (cmd == _FIO_SEEK_DATA). "off" is an in/out parameter.
176*fa9e4066Sahrens  */
177*fa9e4066Sahrens static int
178*fa9e4066Sahrens zfs_holey(vnode_t *vp, int cmd, offset_t *off)
179*fa9e4066Sahrens {
180*fa9e4066Sahrens 	znode_t	*zp = VTOZ(vp);
181*fa9e4066Sahrens 	uint64_t noff = (uint64_t)*off; /* new offset */
182*fa9e4066Sahrens 	uint64_t file_sz;
183*fa9e4066Sahrens 	int error;
184*fa9e4066Sahrens 	boolean_t hole;
185*fa9e4066Sahrens 
186*fa9e4066Sahrens 	rw_enter(&zp->z_grow_lock, RW_READER);
187*fa9e4066Sahrens 	file_sz = zp->z_phys->zp_size;
188*fa9e4066Sahrens 	if (noff >= file_sz)  {
189*fa9e4066Sahrens 		rw_exit(&zp->z_grow_lock);
190*fa9e4066Sahrens 		return (ENXIO);
191*fa9e4066Sahrens 	}
192*fa9e4066Sahrens 
193*fa9e4066Sahrens 	if (cmd == _FIO_SEEK_HOLE)
194*fa9e4066Sahrens 		hole = B_TRUE;
195*fa9e4066Sahrens 	else
196*fa9e4066Sahrens 		hole = B_FALSE;
197*fa9e4066Sahrens 
198*fa9e4066Sahrens 	error = dmu_offset_next(zp->z_zfsvfs->z_os, zp->z_id, hole, &noff);
199*fa9e4066Sahrens 	rw_exit(&zp->z_grow_lock);
200*fa9e4066Sahrens 
201*fa9e4066Sahrens 	/* end of file? */
202*fa9e4066Sahrens 	if ((error == ESRCH) || (noff > file_sz)) {
203*fa9e4066Sahrens 		/*
204*fa9e4066Sahrens 		 * Handle the virtual hole at the end of file.
205*fa9e4066Sahrens 		 */
206*fa9e4066Sahrens 		if (hole) {
207*fa9e4066Sahrens 			*off = file_sz;
208*fa9e4066Sahrens 			return (0);
209*fa9e4066Sahrens 		}
210*fa9e4066Sahrens 		return (ENXIO);
211*fa9e4066Sahrens 	}
212*fa9e4066Sahrens 
213*fa9e4066Sahrens 	if (noff < *off)
214*fa9e4066Sahrens 		return (error);
215*fa9e4066Sahrens 	*off = noff;
216*fa9e4066Sahrens 	return (error);
217*fa9e4066Sahrens }
218*fa9e4066Sahrens 
219*fa9e4066Sahrens /* ARGSUSED */
220*fa9e4066Sahrens static int
221*fa9e4066Sahrens zfs_ioctl(vnode_t *vp, int com, intptr_t data, int flag, cred_t *cred,
222*fa9e4066Sahrens     int *rvalp)
223*fa9e4066Sahrens {
224*fa9e4066Sahrens 	offset_t off;
225*fa9e4066Sahrens 	int error;
226*fa9e4066Sahrens 	zfsvfs_t *zfsvfs;
227*fa9e4066Sahrens 
228*fa9e4066Sahrens 	switch (com) {
229*fa9e4066Sahrens 	    case _FIOFFS:
230*fa9e4066Sahrens 		return (zfs_sync(vp->v_vfsp, 0, cred));
231*fa9e4066Sahrens 
232*fa9e4066Sahrens 	    case _FIO_SEEK_DATA:
233*fa9e4066Sahrens 	    case _FIO_SEEK_HOLE:
234*fa9e4066Sahrens 		if (ddi_copyin((void *)data, &off, sizeof (off), flag))
235*fa9e4066Sahrens 			return (EFAULT);
236*fa9e4066Sahrens 
237*fa9e4066Sahrens 		zfsvfs = VTOZ(vp)->z_zfsvfs;
238*fa9e4066Sahrens 		ZFS_ENTER(zfsvfs);
239*fa9e4066Sahrens 
240*fa9e4066Sahrens 		/* offset parameter is in/out */
241*fa9e4066Sahrens 		error = zfs_holey(vp, com, &off);
242*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
243*fa9e4066Sahrens 		if (error)
244*fa9e4066Sahrens 			return (error);
245*fa9e4066Sahrens 		if (ddi_copyout(&off, (void *)data, sizeof (off), flag))
246*fa9e4066Sahrens 			return (EFAULT);
247*fa9e4066Sahrens 		return (0);
248*fa9e4066Sahrens 	}
249*fa9e4066Sahrens 	return (ENOTTY);
250*fa9e4066Sahrens }
251*fa9e4066Sahrens 
252*fa9e4066Sahrens /*
253*fa9e4066Sahrens  * When a file is memory mapped, we must keep the IO data synchronized
254*fa9e4066Sahrens  * between the DMU cache and the memory mapped pages.  What this means:
255*fa9e4066Sahrens  *
256*fa9e4066Sahrens  * On Write:	If we find a memory mapped page, we write to *both*
257*fa9e4066Sahrens  *		the page and the dmu buffer.
258*fa9e4066Sahrens  *
259*fa9e4066Sahrens  * NOTE: We will always "break up" the IO into PAGESIZE uiomoves when
260*fa9e4066Sahrens  *	the file is memory mapped.
261*fa9e4066Sahrens  */
262*fa9e4066Sahrens static int
263*fa9e4066Sahrens mappedwrite(vnode_t *vp, uint64_t woff, int nbytes, uio_t *uio, dmu_tx_t *tx)
264*fa9e4066Sahrens {
265*fa9e4066Sahrens 	znode_t	*zp = VTOZ(vp);
266*fa9e4066Sahrens 	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
267*fa9e4066Sahrens 	int64_t	start, off;
268*fa9e4066Sahrens 	int len = nbytes;
269*fa9e4066Sahrens 	int error = 0;
270*fa9e4066Sahrens 
271*fa9e4066Sahrens 	start = uio->uio_loffset;
272*fa9e4066Sahrens 	off = start & PAGEOFFSET;
273*fa9e4066Sahrens 	for (start &= PAGEMASK; len > 0; start += PAGESIZE) {
274*fa9e4066Sahrens 		page_t *pp;
275*fa9e4066Sahrens 		uint64_t bytes = MIN(PAGESIZE - off, len);
276*fa9e4066Sahrens 
277*fa9e4066Sahrens 		/*
278*fa9e4066Sahrens 		 * We don't want a new page to "appear" in the middle of
279*fa9e4066Sahrens 		 * the file update (because it may not get the write
280*fa9e4066Sahrens 		 * update data), so we grab a lock to block
281*fa9e4066Sahrens 		 * zfs_getpage().
282*fa9e4066Sahrens 		 */
283*fa9e4066Sahrens 		rw_enter(&zp->z_map_lock, RW_WRITER);
284*fa9e4066Sahrens 		if (pp = page_lookup(vp, start, SE_SHARED)) {
285*fa9e4066Sahrens 			caddr_t va;
286*fa9e4066Sahrens 
287*fa9e4066Sahrens 			rw_exit(&zp->z_map_lock);
288*fa9e4066Sahrens 			va = ppmapin(pp, PROT_READ | PROT_WRITE, (caddr_t)-1L);
289*fa9e4066Sahrens 			error = uiomove(va+off, bytes, UIO_WRITE, uio);
290*fa9e4066Sahrens 			if (error == 0) {
291*fa9e4066Sahrens 				dmu_write(zfsvfs->z_os, zp->z_id,
292*fa9e4066Sahrens 				    woff, bytes, va+off, tx);
293*fa9e4066Sahrens 			}
294*fa9e4066Sahrens 			ppmapout(va);
295*fa9e4066Sahrens 			page_unlock(pp);
296*fa9e4066Sahrens 		} else {
297*fa9e4066Sahrens 			error = dmu_write_uio(zfsvfs->z_os, zp->z_id,
298*fa9e4066Sahrens 			    woff, bytes, uio, tx);
299*fa9e4066Sahrens 			rw_exit(&zp->z_map_lock);
300*fa9e4066Sahrens 		}
301*fa9e4066Sahrens 		len -= bytes;
302*fa9e4066Sahrens 		woff += bytes;
303*fa9e4066Sahrens 		off = 0;
304*fa9e4066Sahrens 		if (error)
305*fa9e4066Sahrens 			break;
306*fa9e4066Sahrens 	}
307*fa9e4066Sahrens 	return (error);
308*fa9e4066Sahrens }
309*fa9e4066Sahrens 
310*fa9e4066Sahrens /*
311*fa9e4066Sahrens  * When a file is memory mapped, we must keep the IO data synchronized
312*fa9e4066Sahrens  * between the DMU cache and the memory mapped pages.  What this means:
313*fa9e4066Sahrens  *
314*fa9e4066Sahrens  * On Read:	We "read" preferentially from memory mapped pages,
315*fa9e4066Sahrens  *		else we default from the dmu buffer.
316*fa9e4066Sahrens  *
317*fa9e4066Sahrens  * NOTE: We will always "break up" the IO into PAGESIZE uiomoves when
318*fa9e4066Sahrens  *	the file is memory mapped.
319*fa9e4066Sahrens  */
320*fa9e4066Sahrens static int
321*fa9e4066Sahrens mappedread(vnode_t *vp, char *addr, int nbytes, uio_t *uio)
322*fa9e4066Sahrens {
323*fa9e4066Sahrens 	int64_t	start, off, bytes;
324*fa9e4066Sahrens 	int len = nbytes;
325*fa9e4066Sahrens 	int error = 0;
326*fa9e4066Sahrens 
327*fa9e4066Sahrens 	start = uio->uio_loffset;
328*fa9e4066Sahrens 	off = start & PAGEOFFSET;
329*fa9e4066Sahrens 	for (start &= PAGEMASK; len > 0; start += PAGESIZE) {
330*fa9e4066Sahrens 		page_t *pp;
331*fa9e4066Sahrens 
332*fa9e4066Sahrens 		bytes = MIN(PAGESIZE - off, len);
333*fa9e4066Sahrens 		if (pp = page_lookup(vp, start, SE_SHARED)) {
334*fa9e4066Sahrens 			caddr_t va;
335*fa9e4066Sahrens 
336*fa9e4066Sahrens 			va = ppmapin(pp, PROT_READ | PROT_WRITE, (caddr_t)-1L);
337*fa9e4066Sahrens 			error = uiomove(va + off, bytes, UIO_READ, uio);
338*fa9e4066Sahrens 			ppmapout(va);
339*fa9e4066Sahrens 			page_unlock(pp);
340*fa9e4066Sahrens 		} else {
341*fa9e4066Sahrens 			/* XXX use dmu_read here? */
342*fa9e4066Sahrens 			error = uiomove(addr, bytes, UIO_READ, uio);
343*fa9e4066Sahrens 		}
344*fa9e4066Sahrens 		len -= bytes;
345*fa9e4066Sahrens 		addr += bytes;
346*fa9e4066Sahrens 		off = 0;
347*fa9e4066Sahrens 		if (error)
348*fa9e4066Sahrens 			break;
349*fa9e4066Sahrens 	}
350*fa9e4066Sahrens 	return (error);
351*fa9e4066Sahrens }
352*fa9e4066Sahrens 
353*fa9e4066Sahrens uint_t zfs_read_chunk_size = 1024 * 1024; /* Tunable */
354*fa9e4066Sahrens 
355*fa9e4066Sahrens /*
356*fa9e4066Sahrens  * Read bytes from specified file into supplied buffer.
357*fa9e4066Sahrens  *
358*fa9e4066Sahrens  *	IN:	vp	- vnode of file to be read from.
359*fa9e4066Sahrens  *		uio	- structure supplying read location, range info,
360*fa9e4066Sahrens  *			  and return buffer.
361*fa9e4066Sahrens  *		ioflag	- SYNC flags; used to provide FRSYNC semantics.
362*fa9e4066Sahrens  *		cr	- credentials of caller.
363*fa9e4066Sahrens  *
364*fa9e4066Sahrens  *	OUT:	uio	- updated offset and range, buffer filled.
365*fa9e4066Sahrens  *
366*fa9e4066Sahrens  *	RETURN:	0 if success
367*fa9e4066Sahrens  *		error code if failure
368*fa9e4066Sahrens  *
369*fa9e4066Sahrens  * Side Effects:
370*fa9e4066Sahrens  *	vp - atime updated if byte count > 0
371*fa9e4066Sahrens  */
372*fa9e4066Sahrens /* ARGSUSED */
373*fa9e4066Sahrens static int
374*fa9e4066Sahrens zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct)
375*fa9e4066Sahrens {
376*fa9e4066Sahrens 	znode_t		*zp = VTOZ(vp);
377*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
378*fa9e4066Sahrens 	uint64_t	delta;
379*fa9e4066Sahrens 	ssize_t		n, size, cnt, ndone;
380*fa9e4066Sahrens 	int		error, i, numbufs;
381*fa9e4066Sahrens 	dmu_buf_t	*dbp, **dbpp;
382*fa9e4066Sahrens 
383*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
384*fa9e4066Sahrens 
385*fa9e4066Sahrens 	/*
386*fa9e4066Sahrens 	 * Validate file offset
387*fa9e4066Sahrens 	 */
388*fa9e4066Sahrens 	if (uio->uio_loffset < (offset_t)0) {
389*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
390*fa9e4066Sahrens 		return (EINVAL);
391*fa9e4066Sahrens 	}
392*fa9e4066Sahrens 
393*fa9e4066Sahrens 	/*
394*fa9e4066Sahrens 	 * Fasttrack empty reads
395*fa9e4066Sahrens 	 */
396*fa9e4066Sahrens 	if (uio->uio_resid == 0) {
397*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
398*fa9e4066Sahrens 		return (0);
399*fa9e4066Sahrens 	}
400*fa9e4066Sahrens 
401*fa9e4066Sahrens 	/*
402*fa9e4066Sahrens 	 * Check for region locks
403*fa9e4066Sahrens 	 */
404*fa9e4066Sahrens 	if (MANDMODE((mode_t)zp->z_phys->zp_mode)) {
405*fa9e4066Sahrens 		if (error = chklock(vp, FREAD,
406*fa9e4066Sahrens 		    uio->uio_loffset, uio->uio_resid, uio->uio_fmode, ct)) {
407*fa9e4066Sahrens 			ZFS_EXIT(zfsvfs);
408*fa9e4066Sahrens 			return (error);
409*fa9e4066Sahrens 		}
410*fa9e4066Sahrens 	}
411*fa9e4066Sahrens 
412*fa9e4066Sahrens 	/*
413*fa9e4066Sahrens 	 * If we're in FRSYNC mode, sync out this znode before reading it.
414*fa9e4066Sahrens 	 */
415*fa9e4066Sahrens 	zil_commit(zfsvfs->z_log, zp->z_last_itx, ioflag & FRSYNC);
416*fa9e4066Sahrens 
417*fa9e4066Sahrens 	/*
418*fa9e4066Sahrens 	 * Make sure nobody restructures the file (changes block size)
419*fa9e4066Sahrens 	 * in the middle of the read.
420*fa9e4066Sahrens 	 */
421*fa9e4066Sahrens 	rw_enter(&zp->z_grow_lock, RW_READER);
422*fa9e4066Sahrens 	/*
423*fa9e4066Sahrens 	 * If we are reading past end-of-file we can skip
424*fa9e4066Sahrens 	 * to the end; but we might still need to set atime.
425*fa9e4066Sahrens 	 */
426*fa9e4066Sahrens 	if (uio->uio_loffset >= zp->z_phys->zp_size) {
427*fa9e4066Sahrens 		cnt = 0;
428*fa9e4066Sahrens 		error = 0;
429*fa9e4066Sahrens 		goto out;
430*fa9e4066Sahrens 	}
431*fa9e4066Sahrens 
432*fa9e4066Sahrens 	cnt = MIN(uio->uio_resid, zp->z_phys->zp_size - uio->uio_loffset);
433*fa9e4066Sahrens 
434*fa9e4066Sahrens 	for (ndone = 0; ndone < cnt; ndone += zfs_read_chunk_size) {
435*fa9e4066Sahrens 		ASSERT(uio->uio_loffset < zp->z_phys->zp_size);
436*fa9e4066Sahrens 		n = MIN(zfs_read_chunk_size,
437*fa9e4066Sahrens 		    zp->z_phys->zp_size - uio->uio_loffset);
438*fa9e4066Sahrens 		n = MIN(n, cnt);
439*fa9e4066Sahrens 		dbpp = dmu_buf_hold_array(zfsvfs->z_os, zp->z_id,
440*fa9e4066Sahrens 		    uio->uio_loffset, n, &numbufs);
441*fa9e4066Sahrens 		if (error = dmu_buf_read_array_canfail(dbpp, numbufs)) {
442*fa9e4066Sahrens 			dmu_buf_rele_array(dbpp, numbufs);
443*fa9e4066Sahrens 			goto out;
444*fa9e4066Sahrens 		}
445*fa9e4066Sahrens 		/*
446*fa9e4066Sahrens 		 * Compute the adjustment to align the dmu buffers
447*fa9e4066Sahrens 		 * with the uio buffer.
448*fa9e4066Sahrens 		 */
449*fa9e4066Sahrens 		delta = uio->uio_loffset - dbpp[0]->db_offset;
450*fa9e4066Sahrens 
451*fa9e4066Sahrens 		for (i = 0; i < numbufs; i++) {
452*fa9e4066Sahrens 			if (n < 0)
453*fa9e4066Sahrens 				break;
454*fa9e4066Sahrens 			dbp = dbpp[i];
455*fa9e4066Sahrens 			size = dbp->db_size - delta;
456*fa9e4066Sahrens 			/*
457*fa9e4066Sahrens 			 * XXX -- this is correct, but may be suboptimal.
458*fa9e4066Sahrens 			 * If the pages are all clean, we don't need to
459*fa9e4066Sahrens 			 * go through mappedread().  Maybe the VMODSORT
460*fa9e4066Sahrens 			 * stuff can help us here.
461*fa9e4066Sahrens 			 */
462*fa9e4066Sahrens 			if (vn_has_cached_data(vp)) {
463*fa9e4066Sahrens 				error = mappedread(vp, (caddr_t)dbp->db_data +
464*fa9e4066Sahrens 				    delta, (n < size ? n : size), uio);
465*fa9e4066Sahrens 			} else {
466*fa9e4066Sahrens 				error = uiomove((caddr_t)dbp->db_data + delta,
467*fa9e4066Sahrens 					(n < size ? n : size), UIO_READ, uio);
468*fa9e4066Sahrens 			}
469*fa9e4066Sahrens 			if (error) {
470*fa9e4066Sahrens 				dmu_buf_rele_array(dbpp, numbufs);
471*fa9e4066Sahrens 				goto out;
472*fa9e4066Sahrens 			}
473*fa9e4066Sahrens 			n -= dbp->db_size;
474*fa9e4066Sahrens 			if (delta) {
475*fa9e4066Sahrens 				n += delta;
476*fa9e4066Sahrens 				delta = 0;
477*fa9e4066Sahrens 			}
478*fa9e4066Sahrens 		}
479*fa9e4066Sahrens 		dmu_buf_rele_array(dbpp, numbufs);
480*fa9e4066Sahrens 	}
481*fa9e4066Sahrens out:
482*fa9e4066Sahrens 	rw_exit(&zp->z_grow_lock);
483*fa9e4066Sahrens 
484*fa9e4066Sahrens 	ZFS_ACCESSTIME_STAMP(zfsvfs, zp);
485*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
486*fa9e4066Sahrens 	return (error);
487*fa9e4066Sahrens }
488*fa9e4066Sahrens 
489*fa9e4066Sahrens /*
490*fa9e4066Sahrens  * Fault in the pages of the first n bytes specified by the uio structure.
491*fa9e4066Sahrens  * 1 byte in each page is touched and the uio struct is unmodified.
492*fa9e4066Sahrens  * Any error will exit this routine as this is only a best
493*fa9e4066Sahrens  * attempt to get the pages resident. This is a copy of ufs_trans_touch().
494*fa9e4066Sahrens  */
495*fa9e4066Sahrens static void
496*fa9e4066Sahrens zfs_prefault_write(ssize_t n, struct uio *uio)
497*fa9e4066Sahrens {
498*fa9e4066Sahrens 	struct iovec *iov;
499*fa9e4066Sahrens 	ulong_t cnt, incr;
500*fa9e4066Sahrens 	caddr_t p;
501*fa9e4066Sahrens 	uint8_t tmp;
502*fa9e4066Sahrens 
503*fa9e4066Sahrens 	iov = uio->uio_iov;
504*fa9e4066Sahrens 
505*fa9e4066Sahrens 	while (n) {
506*fa9e4066Sahrens 		cnt = MIN(iov->iov_len, n);
507*fa9e4066Sahrens 		if (cnt == 0) {
508*fa9e4066Sahrens 			/* empty iov entry */
509*fa9e4066Sahrens 			iov++;
510*fa9e4066Sahrens 			continue;
511*fa9e4066Sahrens 		}
512*fa9e4066Sahrens 		n -= cnt;
513*fa9e4066Sahrens 		/*
514*fa9e4066Sahrens 		 * touch each page in this segment.
515*fa9e4066Sahrens 		 */
516*fa9e4066Sahrens 		p = iov->iov_base;
517*fa9e4066Sahrens 		while (cnt) {
518*fa9e4066Sahrens 			switch (uio->uio_segflg) {
519*fa9e4066Sahrens 			case UIO_USERSPACE:
520*fa9e4066Sahrens 			case UIO_USERISPACE:
521*fa9e4066Sahrens 				if (fuword8(p, &tmp))
522*fa9e4066Sahrens 					return;
523*fa9e4066Sahrens 				break;
524*fa9e4066Sahrens 			case UIO_SYSSPACE:
525*fa9e4066Sahrens 				if (kcopy(p, &tmp, 1))
526*fa9e4066Sahrens 					return;
527*fa9e4066Sahrens 				break;
528*fa9e4066Sahrens 			}
529*fa9e4066Sahrens 			incr = MIN(cnt, PAGESIZE);
530*fa9e4066Sahrens 			p += incr;
531*fa9e4066Sahrens 			cnt -= incr;
532*fa9e4066Sahrens 		}
533*fa9e4066Sahrens 		/*
534*fa9e4066Sahrens 		 * touch the last byte in case it straddles a page.
535*fa9e4066Sahrens 		 */
536*fa9e4066Sahrens 		p--;
537*fa9e4066Sahrens 		switch (uio->uio_segflg) {
538*fa9e4066Sahrens 		case UIO_USERSPACE:
539*fa9e4066Sahrens 		case UIO_USERISPACE:
540*fa9e4066Sahrens 			if (fuword8(p, &tmp))
541*fa9e4066Sahrens 				return;
542*fa9e4066Sahrens 			break;
543*fa9e4066Sahrens 		case UIO_SYSSPACE:
544*fa9e4066Sahrens 			if (kcopy(p, &tmp, 1))
545*fa9e4066Sahrens 				return;
546*fa9e4066Sahrens 			break;
547*fa9e4066Sahrens 		}
548*fa9e4066Sahrens 		iov++;
549*fa9e4066Sahrens 	}
550*fa9e4066Sahrens }
551*fa9e4066Sahrens 
552*fa9e4066Sahrens /*
553*fa9e4066Sahrens  * Write the bytes to a file.
554*fa9e4066Sahrens  *
555*fa9e4066Sahrens  *	IN:	vp	- vnode of file to be written to.
556*fa9e4066Sahrens  *		uio	- structure supplying write location, range info,
557*fa9e4066Sahrens  *			  and data buffer.
558*fa9e4066Sahrens  *		ioflag	- FAPPEND flag set if in append mode.
559*fa9e4066Sahrens  *		cr	- credentials of caller.
560*fa9e4066Sahrens  *
561*fa9e4066Sahrens  *	OUT:	uio	- updated offset and range.
562*fa9e4066Sahrens  *
563*fa9e4066Sahrens  *	RETURN:	0 if success
564*fa9e4066Sahrens  *		error code if failure
565*fa9e4066Sahrens  *
566*fa9e4066Sahrens  * Timestamps:
567*fa9e4066Sahrens  *	vp - ctime|mtime updated if byte count > 0
568*fa9e4066Sahrens  *
569*fa9e4066Sahrens  * Note: zfs_write() holds z_append_lock across calls to txg_wait_open().
570*fa9e4066Sahrens  * It has to because of the semantics of FAPPEND.  The implication is that
571*fa9e4066Sahrens  * we must never grab z_append_lock while in an assigned tx.
572*fa9e4066Sahrens  */
573*fa9e4066Sahrens /* ARGSUSED */
574*fa9e4066Sahrens static int
575*fa9e4066Sahrens zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct)
576*fa9e4066Sahrens {
577*fa9e4066Sahrens 	znode_t		*zp = VTOZ(vp);
578*fa9e4066Sahrens 	rlim64_t	limit = uio->uio_llimit;
579*fa9e4066Sahrens 	ssize_t		start_resid = uio->uio_resid;
580*fa9e4066Sahrens 	ssize_t		tx_bytes;
581*fa9e4066Sahrens 	uint64_t	end_size;
582*fa9e4066Sahrens 	dmu_tx_t	*tx;
583*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
584*fa9e4066Sahrens 	zilog_t		*zilog = zfsvfs->z_log;
585*fa9e4066Sahrens 	uint64_t	seq = 0;
586*fa9e4066Sahrens 	offset_t	woff;
587*fa9e4066Sahrens 	ssize_t		n, nbytes;
588*fa9e4066Sahrens 	int		max_blksz = zfsvfs->z_max_blksz;
589*fa9e4066Sahrens 	int		need_append_lock, error;
590*fa9e4066Sahrens 	krw_t		grow_rw = RW_READER;
591*fa9e4066Sahrens 
592*fa9e4066Sahrens 	if (limit == RLIM64_INFINITY || limit > MAXOFFSET_T)
593*fa9e4066Sahrens 		limit = MAXOFFSET_T;
594*fa9e4066Sahrens 
595*fa9e4066Sahrens 	n = start_resid;
596*fa9e4066Sahrens 
597*fa9e4066Sahrens 	/*
598*fa9e4066Sahrens 	 * Fasttrack empty write
599*fa9e4066Sahrens 	 */
600*fa9e4066Sahrens 	if (n == 0)
601*fa9e4066Sahrens 		return (0);
602*fa9e4066Sahrens 
603*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
604*fa9e4066Sahrens 
605*fa9e4066Sahrens 	/*
606*fa9e4066Sahrens 	 * Pre-fault the pages to ensure slow (eg NFS) pages don't hold up txg
607*fa9e4066Sahrens 	 */
608*fa9e4066Sahrens 	zfs_prefault_write(MIN(start_resid, SPA_MAXBLOCKSIZE), uio);
609*fa9e4066Sahrens 
610*fa9e4066Sahrens 	/*
611*fa9e4066Sahrens 	 * If in append mode, set the io offset pointer to eof.
612*fa9e4066Sahrens 	 */
613*fa9e4066Sahrens 	need_append_lock = ioflag & FAPPEND;
614*fa9e4066Sahrens 	if (need_append_lock) {
615*fa9e4066Sahrens 		rw_enter(&zp->z_append_lock, RW_WRITER);
616*fa9e4066Sahrens 		woff = uio->uio_loffset = zp->z_phys->zp_size;
617*fa9e4066Sahrens 	} else {
618*fa9e4066Sahrens 		woff = uio->uio_loffset;
619*fa9e4066Sahrens 		/*
620*fa9e4066Sahrens 		 * Validate file offset
621*fa9e4066Sahrens 		 */
622*fa9e4066Sahrens 		if (woff < 0) {
623*fa9e4066Sahrens 			ZFS_EXIT(zfsvfs);
624*fa9e4066Sahrens 			return (EINVAL);
625*fa9e4066Sahrens 		}
626*fa9e4066Sahrens 
627*fa9e4066Sahrens 		/*
628*fa9e4066Sahrens 		 * If this write could change the file length,
629*fa9e4066Sahrens 		 * we need to synchronize with "appenders".
630*fa9e4066Sahrens 		 */
631*fa9e4066Sahrens 		if (woff < limit - n && woff + n > zp->z_phys->zp_size) {
632*fa9e4066Sahrens 			need_append_lock = TRUE;
633*fa9e4066Sahrens 			rw_enter(&zp->z_append_lock, RW_READER);
634*fa9e4066Sahrens 		}
635*fa9e4066Sahrens 	}
636*fa9e4066Sahrens 
637*fa9e4066Sahrens 	if (woff >= limit) {
638*fa9e4066Sahrens 		error = EFBIG;
639*fa9e4066Sahrens 		goto no_tx_done;
640*fa9e4066Sahrens 	}
641*fa9e4066Sahrens 
642*fa9e4066Sahrens 	if ((woff + n) > limit || woff > (limit - n))
643*fa9e4066Sahrens 		n = limit - woff;
644*fa9e4066Sahrens 
645*fa9e4066Sahrens 	/*
646*fa9e4066Sahrens 	 * Check for region locks
647*fa9e4066Sahrens 	 */
648*fa9e4066Sahrens 	if (MANDMODE((mode_t)zp->z_phys->zp_mode) &&
649*fa9e4066Sahrens 	    (error = chklock(vp, FWRITE, woff, n, uio->uio_fmode, ct)) != 0)
650*fa9e4066Sahrens 		goto no_tx_done;
651*fa9e4066Sahrens top:
652*fa9e4066Sahrens 	/*
653*fa9e4066Sahrens 	 * Make sure nobody restructures the file (changes block size)
654*fa9e4066Sahrens 	 * in the middle of the write.
655*fa9e4066Sahrens 	 */
656*fa9e4066Sahrens 	rw_enter(&zp->z_grow_lock, grow_rw);
657*fa9e4066Sahrens 
658*fa9e4066Sahrens 	end_size = MAX(zp->z_phys->zp_size, woff + n);
659*fa9e4066Sahrens 	tx = dmu_tx_create(zfsvfs->z_os);
660*fa9e4066Sahrens 	dmu_tx_hold_bonus(tx, zp->z_id);
661*fa9e4066Sahrens 	dmu_tx_hold_write(tx, zp->z_id, woff, MIN(n, max_blksz));
662*fa9e4066Sahrens 	error = dmu_tx_assign(tx, zfsvfs->z_assign);
663*fa9e4066Sahrens 	if (error) {
664*fa9e4066Sahrens 		dmu_tx_abort(tx);
665*fa9e4066Sahrens 		rw_exit(&zp->z_grow_lock);
666*fa9e4066Sahrens 		if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) {
667*fa9e4066Sahrens 			txg_wait_open(dmu_objset_pool(zfsvfs->z_os), 0);
668*fa9e4066Sahrens 			goto top;
669*fa9e4066Sahrens 		}
670*fa9e4066Sahrens 		goto no_tx_done;
671*fa9e4066Sahrens 	}
672*fa9e4066Sahrens 
673*fa9e4066Sahrens 	if (end_size > zp->z_blksz &&
674*fa9e4066Sahrens 	    (!ISP2(zp->z_blksz) || zp->z_blksz < max_blksz)) {
675*fa9e4066Sahrens 		uint64_t new_blksz;
676*fa9e4066Sahrens 		/*
677*fa9e4066Sahrens 		 * This write will increase the file size beyond
678*fa9e4066Sahrens 		 * the current block size so increase the block size.
679*fa9e4066Sahrens 		 */
680*fa9e4066Sahrens 		if (grow_rw == RW_READER && !rw_tryupgrade(&zp->z_grow_lock)) {
681*fa9e4066Sahrens 			dmu_tx_commit(tx);
682*fa9e4066Sahrens 			rw_exit(&zp->z_grow_lock);
683*fa9e4066Sahrens 			grow_rw = RW_WRITER;
684*fa9e4066Sahrens 			goto top;
685*fa9e4066Sahrens 		}
686*fa9e4066Sahrens 		if (zp->z_blksz > max_blksz) {
687*fa9e4066Sahrens 			ASSERT(!ISP2(zp->z_blksz));
688*fa9e4066Sahrens 			new_blksz = MIN(end_size, SPA_MAXBLOCKSIZE);
689*fa9e4066Sahrens 		} else {
690*fa9e4066Sahrens 			new_blksz = MIN(end_size, max_blksz);
691*fa9e4066Sahrens 		}
692*fa9e4066Sahrens 		error = zfs_grow_blocksize(zp, new_blksz, tx);
693*fa9e4066Sahrens 		if (error) {
694*fa9e4066Sahrens 			tx_bytes = 0;
695*fa9e4066Sahrens 			goto tx_done;
696*fa9e4066Sahrens 		}
697*fa9e4066Sahrens 	}
698*fa9e4066Sahrens 
699*fa9e4066Sahrens 	if (grow_rw == RW_WRITER) {
700*fa9e4066Sahrens 		rw_downgrade(&zp->z_grow_lock);
701*fa9e4066Sahrens 		grow_rw = RW_READER;
702*fa9e4066Sahrens 	}
703*fa9e4066Sahrens 
704*fa9e4066Sahrens 	/*
705*fa9e4066Sahrens 	 * The file data does not fit in the znode "cache", so we
706*fa9e4066Sahrens 	 * will be writing to the file block data buffers.
707*fa9e4066Sahrens 	 * Each buffer will be written in a separate transaction;
708*fa9e4066Sahrens 	 * this keeps the intent log records small and allows us
709*fa9e4066Sahrens 	 * to do more fine-grained space accounting.
710*fa9e4066Sahrens 	 */
711*fa9e4066Sahrens 	while (n > 0) {
712*fa9e4066Sahrens 		/*
713*fa9e4066Sahrens 		 * XXX - should we really limit each write to z_max_blksz?
714*fa9e4066Sahrens 		 * Perhaps we should use SPA_MAXBLOCKSIZE chunks?
715*fa9e4066Sahrens 		 */
716*fa9e4066Sahrens 		nbytes = MIN(n, max_blksz - P2PHASE(woff, max_blksz));
717*fa9e4066Sahrens 		rw_enter(&zp->z_map_lock, RW_READER);
718*fa9e4066Sahrens 
719*fa9e4066Sahrens 		tx_bytes = uio->uio_resid;
720*fa9e4066Sahrens 		if (vn_has_cached_data(vp)) {
721*fa9e4066Sahrens 			rw_exit(&zp->z_map_lock);
722*fa9e4066Sahrens 			error = mappedwrite(vp, woff, nbytes, uio, tx);
723*fa9e4066Sahrens 		} else {
724*fa9e4066Sahrens 			error = dmu_write_uio(zfsvfs->z_os, zp->z_id,
725*fa9e4066Sahrens 			    woff, nbytes, uio, tx);
726*fa9e4066Sahrens 			rw_exit(&zp->z_map_lock);
727*fa9e4066Sahrens 		}
728*fa9e4066Sahrens 		tx_bytes -= uio->uio_resid;
729*fa9e4066Sahrens 
730*fa9e4066Sahrens 		if (error) {
731*fa9e4066Sahrens 			/* XXX - do we need to "clean up" the dmu buffer? */
732*fa9e4066Sahrens 			break;
733*fa9e4066Sahrens 		}
734*fa9e4066Sahrens 
735*fa9e4066Sahrens 		ASSERT(tx_bytes == nbytes);
736*fa9e4066Sahrens 
737*fa9e4066Sahrens 		n -= nbytes;
738*fa9e4066Sahrens 		if (n <= 0)
739*fa9e4066Sahrens 			break;
740*fa9e4066Sahrens 
741*fa9e4066Sahrens 		/*
742*fa9e4066Sahrens 		 * We have more work ahead of us, so wrap up this transaction
743*fa9e4066Sahrens 		 * and start another.  Exact same logic as tx_done below.
744*fa9e4066Sahrens 		 */
745*fa9e4066Sahrens 		while ((end_size = zp->z_phys->zp_size) < uio->uio_loffset) {
746*fa9e4066Sahrens 			dmu_buf_will_dirty(zp->z_dbuf, tx);
747*fa9e4066Sahrens 			(void) atomic_cas_64(&zp->z_phys->zp_size, end_size,
748*fa9e4066Sahrens 			    uio->uio_loffset);
749*fa9e4066Sahrens 		}
750*fa9e4066Sahrens 		zfs_time_stamper(zp, CONTENT_MODIFIED, tx);
751*fa9e4066Sahrens 		seq = zfs_log_write(zilog, tx, TX_WRITE, zp, woff, tx_bytes,
752*fa9e4066Sahrens 		    ioflag, uio);
753*fa9e4066Sahrens 		dmu_tx_commit(tx);
754*fa9e4066Sahrens 
755*fa9e4066Sahrens 		/* Pre-fault the next set of pages */
756*fa9e4066Sahrens 		zfs_prefault_write(MIN(n, SPA_MAXBLOCKSIZE), uio);
757*fa9e4066Sahrens 
758*fa9e4066Sahrens 		/*
759*fa9e4066Sahrens 		 * Start another transaction.
760*fa9e4066Sahrens 		 */
761*fa9e4066Sahrens 		woff = uio->uio_loffset;
762*fa9e4066Sahrens 		tx = dmu_tx_create(zfsvfs->z_os);
763*fa9e4066Sahrens 		dmu_tx_hold_bonus(tx, zp->z_id);
764*fa9e4066Sahrens 		dmu_tx_hold_write(tx, zp->z_id, woff, MIN(n, max_blksz));
765*fa9e4066Sahrens 		error = dmu_tx_assign(tx, zfsvfs->z_assign);
766*fa9e4066Sahrens 		if (error) {
767*fa9e4066Sahrens 			dmu_tx_abort(tx);
768*fa9e4066Sahrens 			rw_exit(&zp->z_grow_lock);
769*fa9e4066Sahrens 			if (error == ERESTART &&
770*fa9e4066Sahrens 			    zfsvfs->z_assign == TXG_NOWAIT) {
771*fa9e4066Sahrens 				txg_wait_open(dmu_objset_pool(zfsvfs->z_os), 0);
772*fa9e4066Sahrens 				goto top;
773*fa9e4066Sahrens 			}
774*fa9e4066Sahrens 			goto no_tx_done;
775*fa9e4066Sahrens 		}
776*fa9e4066Sahrens 	}
777*fa9e4066Sahrens 
778*fa9e4066Sahrens tx_done:
779*fa9e4066Sahrens 
780*fa9e4066Sahrens 	if (tx_bytes != 0) {
781*fa9e4066Sahrens 		/*
782*fa9e4066Sahrens 		 * Update the file size if it has changed; account
783*fa9e4066Sahrens 		 * for possible concurrent updates.
784*fa9e4066Sahrens 		 */
785*fa9e4066Sahrens 		while ((end_size = zp->z_phys->zp_size) < uio->uio_loffset) {
786*fa9e4066Sahrens 			dmu_buf_will_dirty(zp->z_dbuf, tx);
787*fa9e4066Sahrens 			(void) atomic_cas_64(&zp->z_phys->zp_size, end_size,
788*fa9e4066Sahrens 			    uio->uio_loffset);
789*fa9e4066Sahrens 		}
790*fa9e4066Sahrens 		zfs_time_stamper(zp, CONTENT_MODIFIED, tx);
791*fa9e4066Sahrens 		seq = zfs_log_write(zilog, tx, TX_WRITE, zp, woff, tx_bytes,
792*fa9e4066Sahrens 		    ioflag, uio);
793*fa9e4066Sahrens 	}
794*fa9e4066Sahrens 	dmu_tx_commit(tx);
795*fa9e4066Sahrens 
796*fa9e4066Sahrens 	rw_exit(&zp->z_grow_lock);
797*fa9e4066Sahrens 
798*fa9e4066Sahrens no_tx_done:
799*fa9e4066Sahrens 
800*fa9e4066Sahrens 	if (need_append_lock)
801*fa9e4066Sahrens 		rw_exit(&zp->z_append_lock);
802*fa9e4066Sahrens 
803*fa9e4066Sahrens 	/*
804*fa9e4066Sahrens 	 * If we're in replay mode, or we made no progress, return error.
805*fa9e4066Sahrens 	 * Otherwise, it's at least a partial write, so it's successful.
806*fa9e4066Sahrens 	 */
807*fa9e4066Sahrens 	if (zfsvfs->z_assign >= TXG_INITIAL || uio->uio_resid == start_resid) {
808*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
809*fa9e4066Sahrens 		return (error);
810*fa9e4066Sahrens 	}
811*fa9e4066Sahrens 
812*fa9e4066Sahrens 	zil_commit(zilog, seq, ioflag & (FSYNC | FDSYNC));
813*fa9e4066Sahrens 
814*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
815*fa9e4066Sahrens 	return (0);
816*fa9e4066Sahrens }
817*fa9e4066Sahrens 
818*fa9e4066Sahrens /*
819*fa9e4066Sahrens  * Get data to generate a TX_WRITE intent log record.
820*fa9e4066Sahrens  */
821*fa9e4066Sahrens int
822*fa9e4066Sahrens zfs_get_data(void *arg, lr_write_t *lr)
823*fa9e4066Sahrens {
824*fa9e4066Sahrens 	zfsvfs_t *zfsvfs = arg;
825*fa9e4066Sahrens 	objset_t *os = zfsvfs->z_os;
826*fa9e4066Sahrens 	znode_t *zp;
827*fa9e4066Sahrens 	uint64_t off = lr->lr_offset;
828*fa9e4066Sahrens 	int dlen = lr->lr_length;  		/* length of user data */
829*fa9e4066Sahrens 	int reclen = lr->lr_common.lrc_reclen;
830*fa9e4066Sahrens 	int error = 0;
831*fa9e4066Sahrens 
832*fa9e4066Sahrens 	ASSERT(dlen != 0);
833*fa9e4066Sahrens 
834*fa9e4066Sahrens 	/*
835*fa9e4066Sahrens 	 * Nothing to do if the file has been removed or truncated.
836*fa9e4066Sahrens 	 */
837*fa9e4066Sahrens 	if (zfs_zget(zfsvfs, lr->lr_foid, &zp) != 0)
838*fa9e4066Sahrens 		return (ENOENT);
839*fa9e4066Sahrens 	if (off >= zp->z_phys->zp_size || zp->z_reap) {
840*fa9e4066Sahrens 		VN_RELE(ZTOV(zp));
841*fa9e4066Sahrens 		return (ENOENT);
842*fa9e4066Sahrens 	}
843*fa9e4066Sahrens 
844*fa9e4066Sahrens 	/*
845*fa9e4066Sahrens 	 * Write records come in two flavors: immediate and indirect.
846*fa9e4066Sahrens 	 * For small writes it's cheaper to store the data with the
847*fa9e4066Sahrens 	 * log record (immediate); for large writes it's cheaper to
848*fa9e4066Sahrens 	 * sync the data and get a pointer to it (indirect) so that
849*fa9e4066Sahrens 	 * we don't have to write the data twice.
850*fa9e4066Sahrens 	 */
851*fa9e4066Sahrens 	if (sizeof (lr_write_t) + dlen <= reclen) { /* immediate write */
852*fa9e4066Sahrens 		rw_enter(&zp->z_grow_lock, RW_READER);
853*fa9e4066Sahrens 		dmu_buf_t *db = dmu_buf_hold(os, lr->lr_foid, off);
854*fa9e4066Sahrens 		dmu_buf_read(db);
855*fa9e4066Sahrens 		bcopy((char *)db->db_data + off - db->db_offset, lr + 1, dlen);
856*fa9e4066Sahrens 		dmu_buf_rele(db);
857*fa9e4066Sahrens 		rw_exit(&zp->z_grow_lock);
858*fa9e4066Sahrens 	} else {
859*fa9e4066Sahrens 		/*
860*fa9e4066Sahrens 		 * We have to grab z_grow_lock as RW_WRITER because
861*fa9e4066Sahrens 		 * dmu_sync() can't handle concurrent dbuf_dirty() (6313856).
862*fa9e4066Sahrens 		 * z_grow_lock will be replaced with a range lock soon,
863*fa9e4066Sahrens 		 * which will eliminate the concurrency hit, but dmu_sync()
864*fa9e4066Sahrens 		 * really needs more thought.  It shouldn't have to rely on
865*fa9e4066Sahrens 		 * the caller to provide MT safety.
866*fa9e4066Sahrens 		 */
867*fa9e4066Sahrens 		rw_enter(&zp->z_grow_lock, RW_WRITER);
868*fa9e4066Sahrens 		txg_suspend(dmu_objset_pool(os));
869*fa9e4066Sahrens 		error = dmu_sync(os, lr->lr_foid, off, &lr->lr_blkoff,
870*fa9e4066Sahrens 		    &lr->lr_blkptr, lr->lr_common.lrc_txg);
871*fa9e4066Sahrens 		txg_resume(dmu_objset_pool(os));
872*fa9e4066Sahrens 		rw_exit(&zp->z_grow_lock);
873*fa9e4066Sahrens 	}
874*fa9e4066Sahrens 	VN_RELE(ZTOV(zp));
875*fa9e4066Sahrens 	return (error);
876*fa9e4066Sahrens }
877*fa9e4066Sahrens 
878*fa9e4066Sahrens /*ARGSUSED*/
879*fa9e4066Sahrens static int
880*fa9e4066Sahrens zfs_access(vnode_t *vp, int mode, int flags, cred_t *cr)
881*fa9e4066Sahrens {
882*fa9e4066Sahrens 	znode_t *zp = VTOZ(vp);
883*fa9e4066Sahrens 	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
884*fa9e4066Sahrens 	int error;
885*fa9e4066Sahrens 
886*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
887*fa9e4066Sahrens 	error = zfs_zaccess_rwx(zp, mode, cr);
888*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
889*fa9e4066Sahrens 	return (error);
890*fa9e4066Sahrens }
891*fa9e4066Sahrens 
892*fa9e4066Sahrens /*
893*fa9e4066Sahrens  * Lookup an entry in a directory, or an extended attribute directory.
894*fa9e4066Sahrens  * If it exists, return a held vnode reference for it.
895*fa9e4066Sahrens  *
896*fa9e4066Sahrens  *	IN:	dvp	- vnode of directory to search.
897*fa9e4066Sahrens  *		nm	- name of entry to lookup.
898*fa9e4066Sahrens  *		pnp	- full pathname to lookup [UNUSED].
899*fa9e4066Sahrens  *		flags	- LOOKUP_XATTR set if looking for an attribute.
900*fa9e4066Sahrens  *		rdir	- root directory vnode [UNUSED].
901*fa9e4066Sahrens  *		cr	- credentials of caller.
902*fa9e4066Sahrens  *
903*fa9e4066Sahrens  *	OUT:	vpp	- vnode of located entry, NULL if not found.
904*fa9e4066Sahrens  *
905*fa9e4066Sahrens  *	RETURN:	0 if success
906*fa9e4066Sahrens  *		error code if failure
907*fa9e4066Sahrens  *
908*fa9e4066Sahrens  * Timestamps:
909*fa9e4066Sahrens  *	NA
910*fa9e4066Sahrens  */
911*fa9e4066Sahrens /* ARGSUSED */
912*fa9e4066Sahrens static int
913*fa9e4066Sahrens zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp,
914*fa9e4066Sahrens     int flags, vnode_t *rdir, cred_t *cr)
915*fa9e4066Sahrens {
916*fa9e4066Sahrens 
917*fa9e4066Sahrens 	znode_t *zdp = VTOZ(dvp);
918*fa9e4066Sahrens 	zfsvfs_t *zfsvfs = zdp->z_zfsvfs;
919*fa9e4066Sahrens 	int	error;
920*fa9e4066Sahrens 
921*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
922*fa9e4066Sahrens 
923*fa9e4066Sahrens 	*vpp = NULL;
924*fa9e4066Sahrens 
925*fa9e4066Sahrens 	if (flags & LOOKUP_XATTR) {
926*fa9e4066Sahrens 		/*
927*fa9e4066Sahrens 		 * We don't allow recursive attributes..
928*fa9e4066Sahrens 		 * Maybe someday we will.
929*fa9e4066Sahrens 		 */
930*fa9e4066Sahrens 		if (zdp->z_phys->zp_flags & ZFS_XATTR) {
931*fa9e4066Sahrens 			ZFS_EXIT(zfsvfs);
932*fa9e4066Sahrens 			return (EINVAL);
933*fa9e4066Sahrens 		}
934*fa9e4066Sahrens 
935*fa9e4066Sahrens 		if (error = zfs_get_xattrdir(VTOZ(dvp), vpp, cr)) {
936*fa9e4066Sahrens 			ZFS_EXIT(zfsvfs);
937*fa9e4066Sahrens 			return (error);
938*fa9e4066Sahrens 		}
939*fa9e4066Sahrens 
940*fa9e4066Sahrens 		/*
941*fa9e4066Sahrens 		 * Do we have permission to get into attribute directory?
942*fa9e4066Sahrens 		 */
943*fa9e4066Sahrens 
944*fa9e4066Sahrens 		if (error = zfs_zaccess(VTOZ(*vpp), ACE_EXECUTE, cr)) {
945*fa9e4066Sahrens 			VN_RELE(*vpp);
946*fa9e4066Sahrens 		}
947*fa9e4066Sahrens 
948*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
949*fa9e4066Sahrens 		return (error);
950*fa9e4066Sahrens 	}
951*fa9e4066Sahrens 
952*fa9e4066Sahrens 	/*
953*fa9e4066Sahrens 	 * Check accessibility of directory.
954*fa9e4066Sahrens 	 */
955*fa9e4066Sahrens 
956*fa9e4066Sahrens 	if (error = zfs_zaccess(zdp, ACE_EXECUTE, cr)) {
957*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
958*fa9e4066Sahrens 		return (error);
959*fa9e4066Sahrens 	}
960*fa9e4066Sahrens 
961*fa9e4066Sahrens 	if ((error = zfs_dirlook(zdp, nm, vpp)) == 0) {
962*fa9e4066Sahrens 
963*fa9e4066Sahrens 		/*
964*fa9e4066Sahrens 		 * Convert device special files
965*fa9e4066Sahrens 		 */
966*fa9e4066Sahrens 		if (IS_DEVVP(*vpp)) {
967*fa9e4066Sahrens 			vnode_t	*svp;
968*fa9e4066Sahrens 
969*fa9e4066Sahrens 			svp = specvp(*vpp, (*vpp)->v_rdev, (*vpp)->v_type, cr);
970*fa9e4066Sahrens 			VN_RELE(*vpp);
971*fa9e4066Sahrens 			if (svp == NULL)
972*fa9e4066Sahrens 				error = ENOSYS;
973*fa9e4066Sahrens 			else
974*fa9e4066Sahrens 				*vpp = svp;
975*fa9e4066Sahrens 		}
976*fa9e4066Sahrens 	}
977*fa9e4066Sahrens 
978*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
979*fa9e4066Sahrens 	return (error);
980*fa9e4066Sahrens }
981*fa9e4066Sahrens 
982*fa9e4066Sahrens /*
983*fa9e4066Sahrens  * Attempt to create a new entry in a directory.  If the entry
984*fa9e4066Sahrens  * already exists, truncate the file if permissible, else return
985*fa9e4066Sahrens  * an error.  Return the vp of the created or trunc'd file.
986*fa9e4066Sahrens  *
987*fa9e4066Sahrens  *	IN:	dvp	- vnode of directory to put new file entry in.
988*fa9e4066Sahrens  *		name	- name of new file entry.
989*fa9e4066Sahrens  *		vap	- attributes of new file.
990*fa9e4066Sahrens  *		excl	- flag indicating exclusive or non-exclusive mode.
991*fa9e4066Sahrens  *		mode	- mode to open file with.
992*fa9e4066Sahrens  *		cr	- credentials of caller.
993*fa9e4066Sahrens  *		flag	- large file flag [UNUSED].
994*fa9e4066Sahrens  *
995*fa9e4066Sahrens  *	OUT:	vpp	- vnode of created or trunc'd entry.
996*fa9e4066Sahrens  *
997*fa9e4066Sahrens  *	RETURN:	0 if success
998*fa9e4066Sahrens  *		error code if failure
999*fa9e4066Sahrens  *
1000*fa9e4066Sahrens  * Timestamps:
1001*fa9e4066Sahrens  *	dvp - ctime|mtime updated if new entry created
1002*fa9e4066Sahrens  *	 vp - ctime|mtime always, atime if new
1003*fa9e4066Sahrens  */
1004*fa9e4066Sahrens /* ARGSUSED */
1005*fa9e4066Sahrens static int
1006*fa9e4066Sahrens zfs_create(vnode_t *dvp, char *name, vattr_t *vap, vcexcl_t excl,
1007*fa9e4066Sahrens     int mode, vnode_t **vpp, cred_t *cr, int flag)
1008*fa9e4066Sahrens {
1009*fa9e4066Sahrens 	znode_t		*zp, *dzp = VTOZ(dvp);
1010*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = dzp->z_zfsvfs;
1011*fa9e4066Sahrens 	zilog_t		*zilog = zfsvfs->z_log;
1012*fa9e4066Sahrens 	uint64_t	seq = 0;
1013*fa9e4066Sahrens 	objset_t	*os = zfsvfs->z_os;
1014*fa9e4066Sahrens 	zfs_dirlock_t	*dl;
1015*fa9e4066Sahrens 	dmu_tx_t	*tx;
1016*fa9e4066Sahrens 	int		error;
1017*fa9e4066Sahrens 	uint64_t	zoid;
1018*fa9e4066Sahrens 
1019*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
1020*fa9e4066Sahrens 
1021*fa9e4066Sahrens top:
1022*fa9e4066Sahrens 	*vpp = NULL;
1023*fa9e4066Sahrens 
1024*fa9e4066Sahrens 	if ((vap->va_mode & VSVTX) && secpolicy_vnode_stky_modify(cr))
1025*fa9e4066Sahrens 		vap->va_mode &= ~VSVTX;
1026*fa9e4066Sahrens 
1027*fa9e4066Sahrens 	if (*name == '\0') {
1028*fa9e4066Sahrens 		/*
1029*fa9e4066Sahrens 		 * Null component name refers to the directory itself.
1030*fa9e4066Sahrens 		 */
1031*fa9e4066Sahrens 		VN_HOLD(dvp);
1032*fa9e4066Sahrens 		zp = dzp;
1033*fa9e4066Sahrens 		dl = NULL;
1034*fa9e4066Sahrens 		error = 0;
1035*fa9e4066Sahrens 	} else {
1036*fa9e4066Sahrens 		/* possible VN_HOLD(zp) */
1037*fa9e4066Sahrens 		if (error = zfs_dirent_lock(&dl, dzp, name, &zp, 0)) {
1038*fa9e4066Sahrens 			if (strcmp(name, "..") == 0)
1039*fa9e4066Sahrens 				error = EISDIR;
1040*fa9e4066Sahrens 			ZFS_EXIT(zfsvfs);
1041*fa9e4066Sahrens 			return (error);
1042*fa9e4066Sahrens 		}
1043*fa9e4066Sahrens 	}
1044*fa9e4066Sahrens 
1045*fa9e4066Sahrens 	zoid = zp ? zp->z_id : -1ULL;
1046*fa9e4066Sahrens 
1047*fa9e4066Sahrens 	if (zp == NULL) {
1048*fa9e4066Sahrens 		/*
1049*fa9e4066Sahrens 		 * Create a new file object and update the directory
1050*fa9e4066Sahrens 		 * to reference it.
1051*fa9e4066Sahrens 		 */
1052*fa9e4066Sahrens 		if (error = zfs_zaccess(dzp, ACE_ADD_FILE, cr)) {
1053*fa9e4066Sahrens 			goto out;
1054*fa9e4066Sahrens 		}
1055*fa9e4066Sahrens 
1056*fa9e4066Sahrens 		/*
1057*fa9e4066Sahrens 		 * We only support the creation of regular files in
1058*fa9e4066Sahrens 		 * extended attribute directories.
1059*fa9e4066Sahrens 		 */
1060*fa9e4066Sahrens 		if ((dzp->z_phys->zp_flags & ZFS_XATTR) &&
1061*fa9e4066Sahrens 		    (vap->va_type != VREG)) {
1062*fa9e4066Sahrens 			error = EINVAL;
1063*fa9e4066Sahrens 			goto out;
1064*fa9e4066Sahrens 		}
1065*fa9e4066Sahrens 
1066*fa9e4066Sahrens 		tx = dmu_tx_create(os);
1067*fa9e4066Sahrens 		dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
1068*fa9e4066Sahrens 		dmu_tx_hold_bonus(tx, dzp->z_id);
1069*fa9e4066Sahrens 		dmu_tx_hold_zap(tx, dzp->z_id, 1);
1070*fa9e4066Sahrens 		if (dzp->z_phys->zp_flags & ZFS_INHERIT_ACE)
1071*fa9e4066Sahrens 			dmu_tx_hold_write(tx, DMU_NEW_OBJECT,
1072*fa9e4066Sahrens 			    0, SPA_MAXBLOCKSIZE);
1073*fa9e4066Sahrens 		error = dmu_tx_assign(tx, zfsvfs->z_assign);
1074*fa9e4066Sahrens 		if (error) {
1075*fa9e4066Sahrens 			dmu_tx_abort(tx);
1076*fa9e4066Sahrens 			zfs_dirent_unlock(dl);
1077*fa9e4066Sahrens 			if (error == ERESTART &&
1078*fa9e4066Sahrens 			    zfsvfs->z_assign == TXG_NOWAIT) {
1079*fa9e4066Sahrens 				txg_wait_open(dmu_objset_pool(os), 0);
1080*fa9e4066Sahrens 				goto top;
1081*fa9e4066Sahrens 			}
1082*fa9e4066Sahrens 			ZFS_EXIT(zfsvfs);
1083*fa9e4066Sahrens 			return (error);
1084*fa9e4066Sahrens 		}
1085*fa9e4066Sahrens 		zfs_mknode(dzp, vap, &zoid, tx, cr, 0, &zp, 0);
1086*fa9e4066Sahrens 		ASSERT(zp->z_id == zoid);
1087*fa9e4066Sahrens 		(void) zfs_link_create(dl, zp, tx, ZNEW);
1088*fa9e4066Sahrens 		seq = zfs_log_create(zilog, tx, TX_CREATE, dzp, zp, name);
1089*fa9e4066Sahrens 		dmu_tx_commit(tx);
1090*fa9e4066Sahrens 	} else {
1091*fa9e4066Sahrens 		/*
1092*fa9e4066Sahrens 		 * A directory entry already exists for this name.
1093*fa9e4066Sahrens 		 */
1094*fa9e4066Sahrens 		/*
1095*fa9e4066Sahrens 		 * Can't truncate an existing file if in exclusive mode.
1096*fa9e4066Sahrens 		 */
1097*fa9e4066Sahrens 		if (excl == EXCL) {
1098*fa9e4066Sahrens 			error = EEXIST;
1099*fa9e4066Sahrens 			goto out;
1100*fa9e4066Sahrens 		}
1101*fa9e4066Sahrens 		/*
1102*fa9e4066Sahrens 		 * Can't open a directory for writing.
1103*fa9e4066Sahrens 		 */
1104*fa9e4066Sahrens 		if ((ZTOV(zp)->v_type == VDIR) && (mode & S_IWRITE)) {
1105*fa9e4066Sahrens 			error = EISDIR;
1106*fa9e4066Sahrens 			goto out;
1107*fa9e4066Sahrens 		}
1108*fa9e4066Sahrens 		/*
1109*fa9e4066Sahrens 		 * Verify requested access to file.
1110*fa9e4066Sahrens 		 */
1111*fa9e4066Sahrens 		if (mode && (error = zfs_zaccess_rwx(zp, mode, cr))) {
1112*fa9e4066Sahrens 			goto out;
1113*fa9e4066Sahrens 		}
1114*fa9e4066Sahrens 		/*
1115*fa9e4066Sahrens 		 * Truncate regular files if requested.
1116*fa9e4066Sahrens 		 */
1117*fa9e4066Sahrens 
1118*fa9e4066Sahrens 		/*
1119*fa9e4066Sahrens 		 * Need to update dzp->z_seq?
1120*fa9e4066Sahrens 		 */
1121*fa9e4066Sahrens 
1122*fa9e4066Sahrens 		mutex_enter(&dzp->z_lock);
1123*fa9e4066Sahrens 		dzp->z_seq++;
1124*fa9e4066Sahrens 		mutex_exit(&dzp->z_lock);
1125*fa9e4066Sahrens 
1126*fa9e4066Sahrens 		if ((ZTOV(zp)->v_type == VREG) && (zp->z_phys->zp_size != 0) &&
1127*fa9e4066Sahrens 		    (vap->va_mask & AT_SIZE) && (vap->va_size == 0)) {
1128*fa9e4066Sahrens 			/*
1129*fa9e4066Sahrens 			 * Truncate the file.
1130*fa9e4066Sahrens 			 */
1131*fa9e4066Sahrens 			tx = dmu_tx_create(os);
1132*fa9e4066Sahrens 			dmu_tx_hold_bonus(tx, zoid);
1133*fa9e4066Sahrens 			dmu_tx_hold_free(tx, zoid, 0, DMU_OBJECT_END);
1134*fa9e4066Sahrens 			error = dmu_tx_assign(tx, zfsvfs->z_assign);
1135*fa9e4066Sahrens 			if (error) {
1136*fa9e4066Sahrens 				dmu_tx_abort(tx);
1137*fa9e4066Sahrens 				if (dl)
1138*fa9e4066Sahrens 					zfs_dirent_unlock(dl);
1139*fa9e4066Sahrens 				VN_RELE(ZTOV(zp));
1140*fa9e4066Sahrens 				if (error == ERESTART &&
1141*fa9e4066Sahrens 				    zfsvfs->z_assign == TXG_NOWAIT) {
1142*fa9e4066Sahrens 					txg_wait_open(dmu_objset_pool(os), 0);
1143*fa9e4066Sahrens 					goto top;
1144*fa9e4066Sahrens 				}
1145*fa9e4066Sahrens 				ZFS_EXIT(zfsvfs);
1146*fa9e4066Sahrens 				return (error);
1147*fa9e4066Sahrens 			}
1148*fa9e4066Sahrens 			/*
1149*fa9e4066Sahrens 			 * Grab the grow_lock to serialize this change with
1150*fa9e4066Sahrens 			 * respect to other file manipulations.
1151*fa9e4066Sahrens 			 */
1152*fa9e4066Sahrens 			rw_enter(&zp->z_grow_lock, RW_WRITER);
1153*fa9e4066Sahrens 			error = zfs_freesp(zp, 0, 0, mode, tx, cr);
1154*fa9e4066Sahrens 			if (error == 0) {
1155*fa9e4066Sahrens 				zfs_time_stamper(zp, CONTENT_MODIFIED, tx);
1156*fa9e4066Sahrens 				seq = zfs_log_truncate(zilog, tx,
1157*fa9e4066Sahrens 				    TX_TRUNCATE, zp, 0, 0);
1158*fa9e4066Sahrens 			}
1159*fa9e4066Sahrens 			rw_exit(&zp->z_grow_lock);
1160*fa9e4066Sahrens 			dmu_tx_commit(tx);
1161*fa9e4066Sahrens 		}
1162*fa9e4066Sahrens 	}
1163*fa9e4066Sahrens out:
1164*fa9e4066Sahrens 
1165*fa9e4066Sahrens 	if (dl)
1166*fa9e4066Sahrens 		zfs_dirent_unlock(dl);
1167*fa9e4066Sahrens 
1168*fa9e4066Sahrens 	if (error) {
1169*fa9e4066Sahrens 		if (zp)
1170*fa9e4066Sahrens 			VN_RELE(ZTOV(zp));
1171*fa9e4066Sahrens 	} else {
1172*fa9e4066Sahrens 		*vpp = ZTOV(zp);
1173*fa9e4066Sahrens 		/*
1174*fa9e4066Sahrens 		 * If vnode is for a device return a specfs vnode instead.
1175*fa9e4066Sahrens 		 */
1176*fa9e4066Sahrens 		if (IS_DEVVP(*vpp)) {
1177*fa9e4066Sahrens 			struct vnode *svp;
1178*fa9e4066Sahrens 
1179*fa9e4066Sahrens 			svp = specvp(*vpp, (*vpp)->v_rdev, (*vpp)->v_type, cr);
1180*fa9e4066Sahrens 			VN_RELE(*vpp);
1181*fa9e4066Sahrens 			if (svp == NULL) {
1182*fa9e4066Sahrens 				error = ENOSYS;
1183*fa9e4066Sahrens 			}
1184*fa9e4066Sahrens 			*vpp = svp;
1185*fa9e4066Sahrens 		}
1186*fa9e4066Sahrens 	}
1187*fa9e4066Sahrens 
1188*fa9e4066Sahrens 	zil_commit(zilog, seq, 0);
1189*fa9e4066Sahrens 
1190*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
1191*fa9e4066Sahrens 	return (error);
1192*fa9e4066Sahrens }
1193*fa9e4066Sahrens 
1194*fa9e4066Sahrens /*
1195*fa9e4066Sahrens  * Remove an entry from a directory.
1196*fa9e4066Sahrens  *
1197*fa9e4066Sahrens  *	IN:	dvp	- vnode of directory to remove entry from.
1198*fa9e4066Sahrens  *		name	- name of entry to remove.
1199*fa9e4066Sahrens  *		cr	- credentials of caller.
1200*fa9e4066Sahrens  *
1201*fa9e4066Sahrens  *	RETURN:	0 if success
1202*fa9e4066Sahrens  *		error code if failure
1203*fa9e4066Sahrens  *
1204*fa9e4066Sahrens  * Timestamps:
1205*fa9e4066Sahrens  *	dvp - ctime|mtime
1206*fa9e4066Sahrens  *	 vp - ctime (if nlink > 0)
1207*fa9e4066Sahrens  */
1208*fa9e4066Sahrens static int
1209*fa9e4066Sahrens zfs_remove(vnode_t *dvp, char *name, cred_t *cr)
1210*fa9e4066Sahrens {
1211*fa9e4066Sahrens 	znode_t		*zp, *dzp = VTOZ(dvp);
1212*fa9e4066Sahrens 	znode_t		*xzp = NULL;
1213*fa9e4066Sahrens 	vnode_t		*vp;
1214*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = dzp->z_zfsvfs;
1215*fa9e4066Sahrens 	zilog_t		*zilog = zfsvfs->z_log;
1216*fa9e4066Sahrens 	uint64_t	seq = 0;
1217*fa9e4066Sahrens 	uint64_t	acl_obj, xattr_obj;
1218*fa9e4066Sahrens 	zfs_dirlock_t	*dl;
1219*fa9e4066Sahrens 	dmu_tx_t	*tx;
1220*fa9e4066Sahrens 	int		may_delete_now, delete_now = FALSE;
1221*fa9e4066Sahrens 	int		reaped;
1222*fa9e4066Sahrens 	int		error;
1223*fa9e4066Sahrens 
1224*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
1225*fa9e4066Sahrens 
1226*fa9e4066Sahrens top:
1227*fa9e4066Sahrens 	/*
1228*fa9e4066Sahrens 	 * Attempt to lock directory; fail if entry doesn't exist.
1229*fa9e4066Sahrens 	 */
1230*fa9e4066Sahrens 	if (error = zfs_dirent_lock(&dl, dzp, name, &zp, ZEXISTS)) {
1231*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
1232*fa9e4066Sahrens 		return (error);
1233*fa9e4066Sahrens 	}
1234*fa9e4066Sahrens 
1235*fa9e4066Sahrens 	vp = ZTOV(zp);
1236*fa9e4066Sahrens 
1237*fa9e4066Sahrens 	if (error = zfs_zaccess_delete(dzp, zp, cr)) {
1238*fa9e4066Sahrens 		goto out;
1239*fa9e4066Sahrens 	}
1240*fa9e4066Sahrens 
1241*fa9e4066Sahrens 	/*
1242*fa9e4066Sahrens 	 * Check the restrictions that apply on sticky directories.
1243*fa9e4066Sahrens 	 */
1244*fa9e4066Sahrens 	if (error = zfs_sticky_remove_access(dzp, zp, cr))
1245*fa9e4066Sahrens 		goto out;
1246*fa9e4066Sahrens 
1247*fa9e4066Sahrens 	/*
1248*fa9e4066Sahrens 	 * Need to use rmdir for removing directories.
1249*fa9e4066Sahrens 	 */
1250*fa9e4066Sahrens 	if (vp->v_type == VDIR) {
1251*fa9e4066Sahrens 		error = EPERM;
1252*fa9e4066Sahrens 		goto out;
1253*fa9e4066Sahrens 	}
1254*fa9e4066Sahrens 
1255*fa9e4066Sahrens 	vnevent_remove(vp);
1256*fa9e4066Sahrens 
1257*fa9e4066Sahrens 	mutex_enter(&vp->v_lock);
1258*fa9e4066Sahrens 	may_delete_now = vp->v_count == 1 && !vn_has_cached_data(vp);
1259*fa9e4066Sahrens 	mutex_exit(&vp->v_lock);
1260*fa9e4066Sahrens 
1261*fa9e4066Sahrens 	/*
1262*fa9e4066Sahrens 	 * We may delete the znode now, or we may put it on the delete queue;
1263*fa9e4066Sahrens 	 * it depends on whether we're the last link, and on whether there are
1264*fa9e4066Sahrens 	 * other holds on the vnode.  So we dmu_tx_hold() the right things to
1265*fa9e4066Sahrens 	 * allow for either case.
1266*fa9e4066Sahrens 	 */
1267*fa9e4066Sahrens 	tx = dmu_tx_create(zfsvfs->z_os);
1268*fa9e4066Sahrens 	dmu_tx_hold_zap(tx, dzp->z_id, -1);
1269*fa9e4066Sahrens 	dmu_tx_hold_bonus(tx, zp->z_id);
1270*fa9e4066Sahrens 	if (may_delete_now)
1271*fa9e4066Sahrens 		dmu_tx_hold_free(tx, zp->z_id, 0, DMU_OBJECT_END);
1272*fa9e4066Sahrens 
1273*fa9e4066Sahrens 	/* are there any extended attributes? */
1274*fa9e4066Sahrens 	if ((xattr_obj = zp->z_phys->zp_xattr) != 0) {
1275*fa9e4066Sahrens 		/*
1276*fa9e4066Sahrens 		 * XXX - There is a possibility that the delete
1277*fa9e4066Sahrens 		 * of the parent file could succeed, but then we get
1278*fa9e4066Sahrens 		 * an ENOSPC when we try to delete the xattrs...
1279*fa9e4066Sahrens 		 * so we would need to re-try the deletes periodically
1280*fa9e4066Sahrens 		 */
1281*fa9e4066Sahrens 		/* XXX - do we need this if we are deleting? */
1282*fa9e4066Sahrens 		dmu_tx_hold_bonus(tx, xattr_obj);
1283*fa9e4066Sahrens 	}
1284*fa9e4066Sahrens 
1285*fa9e4066Sahrens 	/* are there any additional acls */
1286*fa9e4066Sahrens 	if ((acl_obj = zp->z_phys->zp_acl.z_acl_extern_obj) != 0 &&
1287*fa9e4066Sahrens 	    may_delete_now)
1288*fa9e4066Sahrens 		dmu_tx_hold_free(tx, acl_obj, 0, DMU_OBJECT_END);
1289*fa9e4066Sahrens 
1290*fa9e4066Sahrens 	/* charge as an update -- would be nice not to charge at all */
1291*fa9e4066Sahrens 	dmu_tx_hold_zap(tx, zfsvfs->z_dqueue, -1);
1292*fa9e4066Sahrens 
1293*fa9e4066Sahrens 	error = dmu_tx_assign(tx, zfsvfs->z_assign);
1294*fa9e4066Sahrens 	if (error) {
1295*fa9e4066Sahrens 		dmu_tx_abort(tx);
1296*fa9e4066Sahrens 		zfs_dirent_unlock(dl);
1297*fa9e4066Sahrens 		VN_RELE(vp);
1298*fa9e4066Sahrens 		if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) {
1299*fa9e4066Sahrens 			txg_wait_open(dmu_objset_pool(zfsvfs->z_os), 0);
1300*fa9e4066Sahrens 			goto top;
1301*fa9e4066Sahrens 		}
1302*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
1303*fa9e4066Sahrens 		return (error);
1304*fa9e4066Sahrens 	}
1305*fa9e4066Sahrens 
1306*fa9e4066Sahrens 	/*
1307*fa9e4066Sahrens 	 * Remove the directory entry.
1308*fa9e4066Sahrens 	 */
1309*fa9e4066Sahrens 	error = zfs_link_destroy(dl, zp, tx, 0, &reaped);
1310*fa9e4066Sahrens 
1311*fa9e4066Sahrens 	if (error) {
1312*fa9e4066Sahrens 		dmu_tx_commit(tx);
1313*fa9e4066Sahrens 		goto out;
1314*fa9e4066Sahrens 	}
1315*fa9e4066Sahrens 
1316*fa9e4066Sahrens 	if (reaped) {
1317*fa9e4066Sahrens 		mutex_enter(&vp->v_lock);
1318*fa9e4066Sahrens 		delete_now = may_delete_now &&
1319*fa9e4066Sahrens 		    vp->v_count == 1 && !vn_has_cached_data(vp) &&
1320*fa9e4066Sahrens 		    zp->z_phys->zp_xattr == xattr_obj &&
1321*fa9e4066Sahrens 		    zp->z_phys->zp_acl.z_acl_extern_obj == acl_obj;
1322*fa9e4066Sahrens 		mutex_exit(&vp->v_lock);
1323*fa9e4066Sahrens 	}
1324*fa9e4066Sahrens 
1325*fa9e4066Sahrens 	if (delete_now) {
1326*fa9e4066Sahrens 		if (zp->z_phys->zp_xattr) {
1327*fa9e4066Sahrens 			error = zfs_zget(zfsvfs, zp->z_phys->zp_xattr, &xzp);
1328*fa9e4066Sahrens 			ASSERT3U(error, ==, 0);
1329*fa9e4066Sahrens 			ASSERT3U(xzp->z_phys->zp_links, ==, 2);
1330*fa9e4066Sahrens 			dmu_buf_will_dirty(xzp->z_dbuf, tx);
1331*fa9e4066Sahrens 			mutex_enter(&xzp->z_lock);
1332*fa9e4066Sahrens 			xzp->z_reap = 1;
1333*fa9e4066Sahrens 			xzp->z_phys->zp_links = 0;
1334*fa9e4066Sahrens 			mutex_exit(&xzp->z_lock);
1335*fa9e4066Sahrens 			zfs_dq_add(xzp, tx);
1336*fa9e4066Sahrens 			zp->z_phys->zp_xattr = 0; /* probably unnecessary */
1337*fa9e4066Sahrens 		}
1338*fa9e4066Sahrens 		mutex_enter(&zp->z_lock);
1339*fa9e4066Sahrens 		mutex_enter(&vp->v_lock);
1340*fa9e4066Sahrens 		vp->v_count--;
1341*fa9e4066Sahrens 		ASSERT3U(vp->v_count, ==, 0);
1342*fa9e4066Sahrens 		mutex_exit(&vp->v_lock);
1343*fa9e4066Sahrens 		zp->z_active = 0;
1344*fa9e4066Sahrens 		mutex_exit(&zp->z_lock);
1345*fa9e4066Sahrens 		zfs_znode_delete(zp, tx);
1346*fa9e4066Sahrens 		VFS_RELE(zfsvfs->z_vfs);
1347*fa9e4066Sahrens 	} else if (reaped) {
1348*fa9e4066Sahrens 		zfs_dq_add(zp, tx);
1349*fa9e4066Sahrens 	}
1350*fa9e4066Sahrens 
1351*fa9e4066Sahrens 	seq = zfs_log_remove(zilog, tx, TX_REMOVE, dzp, name);
1352*fa9e4066Sahrens 
1353*fa9e4066Sahrens 	dmu_tx_commit(tx);
1354*fa9e4066Sahrens out:
1355*fa9e4066Sahrens 	zfs_dirent_unlock(dl);
1356*fa9e4066Sahrens 
1357*fa9e4066Sahrens 	if (!delete_now) {
1358*fa9e4066Sahrens 		VN_RELE(vp);
1359*fa9e4066Sahrens 	} else if (xzp) {
1360*fa9e4066Sahrens 		/* this rele delayed to prevent nesting transactions */
1361*fa9e4066Sahrens 		VN_RELE(ZTOV(xzp));
1362*fa9e4066Sahrens 	}
1363*fa9e4066Sahrens 
1364*fa9e4066Sahrens 	zil_commit(zilog, seq, 0);
1365*fa9e4066Sahrens 
1366*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
1367*fa9e4066Sahrens 	return (error);
1368*fa9e4066Sahrens }
1369*fa9e4066Sahrens 
1370*fa9e4066Sahrens /*
1371*fa9e4066Sahrens  * Create a new directory and insert it into dvp using the name
1372*fa9e4066Sahrens  * provided.  Return a pointer to the inserted directory.
1373*fa9e4066Sahrens  *
1374*fa9e4066Sahrens  *	IN:	dvp	- vnode of directory to add subdir to.
1375*fa9e4066Sahrens  *		dirname	- name of new directory.
1376*fa9e4066Sahrens  *		vap	- attributes of new directory.
1377*fa9e4066Sahrens  *		cr	- credentials of caller.
1378*fa9e4066Sahrens  *
1379*fa9e4066Sahrens  *	OUT:	vpp	- vnode of created directory.
1380*fa9e4066Sahrens  *
1381*fa9e4066Sahrens  *	RETURN:	0 if success
1382*fa9e4066Sahrens  *		error code if failure
1383*fa9e4066Sahrens  *
1384*fa9e4066Sahrens  * Timestamps:
1385*fa9e4066Sahrens  *	dvp - ctime|mtime updated
1386*fa9e4066Sahrens  *	 vp - ctime|mtime|atime updated
1387*fa9e4066Sahrens  */
1388*fa9e4066Sahrens static int
1389*fa9e4066Sahrens zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, vnode_t **vpp, cred_t *cr)
1390*fa9e4066Sahrens {
1391*fa9e4066Sahrens 	znode_t		*zp, *dzp = VTOZ(dvp);
1392*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = dzp->z_zfsvfs;
1393*fa9e4066Sahrens 	zilog_t		*zilog = zfsvfs->z_log;
1394*fa9e4066Sahrens 	uint64_t	seq = 0;
1395*fa9e4066Sahrens 	zfs_dirlock_t	*dl;
1396*fa9e4066Sahrens 	uint64_t	zoid = 0;
1397*fa9e4066Sahrens 	dmu_tx_t	*tx;
1398*fa9e4066Sahrens 	int		error;
1399*fa9e4066Sahrens 
1400*fa9e4066Sahrens 	ASSERT(vap->va_type == VDIR);
1401*fa9e4066Sahrens 
1402*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
1403*fa9e4066Sahrens 
1404*fa9e4066Sahrens 	if (dzp->z_phys->zp_flags & ZFS_XATTR) {
1405*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
1406*fa9e4066Sahrens 		return (EINVAL);
1407*fa9e4066Sahrens 	}
1408*fa9e4066Sahrens top:
1409*fa9e4066Sahrens 	*vpp = NULL;
1410*fa9e4066Sahrens 	if (error = zfs_zaccess(dzp, ACE_ADD_SUBDIRECTORY, cr)) {
1411*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
1412*fa9e4066Sahrens 		return (error);
1413*fa9e4066Sahrens 	}
1414*fa9e4066Sahrens 
1415*fa9e4066Sahrens 	/*
1416*fa9e4066Sahrens 	 * First make sure the new directory doesn't exist.
1417*fa9e4066Sahrens 	 */
1418*fa9e4066Sahrens 	if (error = zfs_dirent_lock(&dl, dzp, dirname, &zp, ZNEW)) {
1419*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
1420*fa9e4066Sahrens 		return (error);
1421*fa9e4066Sahrens 	}
1422*fa9e4066Sahrens 
1423*fa9e4066Sahrens 	/*
1424*fa9e4066Sahrens 	 * Add a new entry to the directory.
1425*fa9e4066Sahrens 	 */
1426*fa9e4066Sahrens 	tx = dmu_tx_create(zfsvfs->z_os);
1427*fa9e4066Sahrens 	dmu_tx_hold_zap(tx, dzp->z_id, 1);
1428*fa9e4066Sahrens 	dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, 0);
1429*fa9e4066Sahrens 	if (dzp->z_phys->zp_flags & ZFS_INHERIT_ACE)
1430*fa9e4066Sahrens 		dmu_tx_hold_write(tx, DMU_NEW_OBJECT,
1431*fa9e4066Sahrens 		    0, SPA_MAXBLOCKSIZE);
1432*fa9e4066Sahrens 	error = dmu_tx_assign(tx, zfsvfs->z_assign);
1433*fa9e4066Sahrens 	if (error) {
1434*fa9e4066Sahrens 		dmu_tx_abort(tx);
1435*fa9e4066Sahrens 		zfs_dirent_unlock(dl);
1436*fa9e4066Sahrens 		if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) {
1437*fa9e4066Sahrens 			txg_wait_open(dmu_objset_pool(zfsvfs->z_os), 0);
1438*fa9e4066Sahrens 			goto top;
1439*fa9e4066Sahrens 		}
1440*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
1441*fa9e4066Sahrens 		return (error);
1442*fa9e4066Sahrens 	}
1443*fa9e4066Sahrens 
1444*fa9e4066Sahrens 	/*
1445*fa9e4066Sahrens 	 * Create new node.
1446*fa9e4066Sahrens 	 */
1447*fa9e4066Sahrens 	zfs_mknode(dzp, vap, &zoid, tx, cr, 0, &zp, 0);
1448*fa9e4066Sahrens 
1449*fa9e4066Sahrens 	/*
1450*fa9e4066Sahrens 	 * Now put new name in parent dir.
1451*fa9e4066Sahrens 	 */
1452*fa9e4066Sahrens 	(void) zfs_link_create(dl, zp, tx, ZNEW);
1453*fa9e4066Sahrens 
1454*fa9e4066Sahrens 	*vpp = ZTOV(zp);
1455*fa9e4066Sahrens 
1456*fa9e4066Sahrens 	seq = zfs_log_create(zilog, tx, TX_MKDIR, dzp, zp, dirname);
1457*fa9e4066Sahrens 	dmu_tx_commit(tx);
1458*fa9e4066Sahrens 
1459*fa9e4066Sahrens 	zfs_dirent_unlock(dl);
1460*fa9e4066Sahrens 
1461*fa9e4066Sahrens 	zil_commit(zilog, seq, 0);
1462*fa9e4066Sahrens 
1463*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
1464*fa9e4066Sahrens 	return (0);
1465*fa9e4066Sahrens }
1466*fa9e4066Sahrens 
1467*fa9e4066Sahrens /*
1468*fa9e4066Sahrens  * Remove a directory subdir entry.  If the current working
1469*fa9e4066Sahrens  * directory is the same as the subdir to be removed, the
1470*fa9e4066Sahrens  * remove will fail.
1471*fa9e4066Sahrens  *
1472*fa9e4066Sahrens  *	IN:	dvp	- vnode of directory to remove from.
1473*fa9e4066Sahrens  *		name	- name of directory to be removed.
1474*fa9e4066Sahrens  *		cwd	- vnode of current working directory.
1475*fa9e4066Sahrens  *		cr	- credentials of caller.
1476*fa9e4066Sahrens  *
1477*fa9e4066Sahrens  *	RETURN:	0 if success
1478*fa9e4066Sahrens  *		error code if failure
1479*fa9e4066Sahrens  *
1480*fa9e4066Sahrens  * Timestamps:
1481*fa9e4066Sahrens  *	dvp - ctime|mtime updated
1482*fa9e4066Sahrens  */
1483*fa9e4066Sahrens static int
1484*fa9e4066Sahrens zfs_rmdir(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr)
1485*fa9e4066Sahrens {
1486*fa9e4066Sahrens 	znode_t		*dzp = VTOZ(dvp);
1487*fa9e4066Sahrens 	znode_t		*zp;
1488*fa9e4066Sahrens 	vnode_t		*vp;
1489*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = dzp->z_zfsvfs;
1490*fa9e4066Sahrens 	zilog_t		*zilog = zfsvfs->z_log;
1491*fa9e4066Sahrens 	uint64_t	seq = 0;
1492*fa9e4066Sahrens 	zfs_dirlock_t	*dl;
1493*fa9e4066Sahrens 	dmu_tx_t	*tx;
1494*fa9e4066Sahrens 	int		error;
1495*fa9e4066Sahrens 
1496*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
1497*fa9e4066Sahrens 
1498*fa9e4066Sahrens top:
1499*fa9e4066Sahrens 	zp = NULL;
1500*fa9e4066Sahrens 
1501*fa9e4066Sahrens 	/*
1502*fa9e4066Sahrens 	 * Attempt to lock directory; fail if entry doesn't exist.
1503*fa9e4066Sahrens 	 */
1504*fa9e4066Sahrens 	if (error = zfs_dirent_lock(&dl, dzp, name, &zp, ZEXISTS)) {
1505*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
1506*fa9e4066Sahrens 		return (error);
1507*fa9e4066Sahrens 	}
1508*fa9e4066Sahrens 
1509*fa9e4066Sahrens 	vp = ZTOV(zp);
1510*fa9e4066Sahrens 
1511*fa9e4066Sahrens 	if (error = zfs_zaccess_delete(dzp, zp, cr)) {
1512*fa9e4066Sahrens 		goto out;
1513*fa9e4066Sahrens 	}
1514*fa9e4066Sahrens 
1515*fa9e4066Sahrens 	/*
1516*fa9e4066Sahrens 	 * Check the restrictions that apply on sticky directories.
1517*fa9e4066Sahrens 	 */
1518*fa9e4066Sahrens 	if (error = zfs_sticky_remove_access(dzp, zp, cr))
1519*fa9e4066Sahrens 		goto out;
1520*fa9e4066Sahrens 
1521*fa9e4066Sahrens 	if (vp->v_type != VDIR) {
1522*fa9e4066Sahrens 		error = ENOTDIR;
1523*fa9e4066Sahrens 		goto out;
1524*fa9e4066Sahrens 	}
1525*fa9e4066Sahrens 
1526*fa9e4066Sahrens 	if (vp == cwd) {
1527*fa9e4066Sahrens 		error = EINVAL;
1528*fa9e4066Sahrens 		goto out;
1529*fa9e4066Sahrens 	}
1530*fa9e4066Sahrens 
1531*fa9e4066Sahrens 	vnevent_rmdir(vp);
1532*fa9e4066Sahrens 
1533*fa9e4066Sahrens 	/*
1534*fa9e4066Sahrens 	 * Grab a lock on the parent pointer make sure we play well
1535*fa9e4066Sahrens 	 * with the treewalk and directory rename code.
1536*fa9e4066Sahrens 	 */
1537*fa9e4066Sahrens 	rw_enter(&zp->z_parent_lock, RW_WRITER);
1538*fa9e4066Sahrens 
1539*fa9e4066Sahrens 	tx = dmu_tx_create(zfsvfs->z_os);
1540*fa9e4066Sahrens 	dmu_tx_hold_zap(tx, dzp->z_id, 1);
1541*fa9e4066Sahrens 	dmu_tx_hold_bonus(tx, zp->z_id);
1542*fa9e4066Sahrens 	dmu_tx_hold_zap(tx, zfsvfs->z_dqueue, 1);
1543*fa9e4066Sahrens 	error = dmu_tx_assign(tx, zfsvfs->z_assign);
1544*fa9e4066Sahrens 	if (error) {
1545*fa9e4066Sahrens 		dmu_tx_abort(tx);
1546*fa9e4066Sahrens 		rw_exit(&zp->z_parent_lock);
1547*fa9e4066Sahrens 		zfs_dirent_unlock(dl);
1548*fa9e4066Sahrens 		VN_RELE(vp);
1549*fa9e4066Sahrens 		if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) {
1550*fa9e4066Sahrens 			txg_wait_open(dmu_objset_pool(zfsvfs->z_os), 0);
1551*fa9e4066Sahrens 			goto top;
1552*fa9e4066Sahrens 		}
1553*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
1554*fa9e4066Sahrens 		return (error);
1555*fa9e4066Sahrens 	}
1556*fa9e4066Sahrens 
1557*fa9e4066Sahrens 	error = zfs_link_destroy(dl, zp, tx, 0, NULL);
1558*fa9e4066Sahrens 
1559*fa9e4066Sahrens 	if (error == 0)
1560*fa9e4066Sahrens 		seq = zfs_log_remove(zilog, tx, TX_RMDIR, dzp, name);
1561*fa9e4066Sahrens 
1562*fa9e4066Sahrens 	dmu_tx_commit(tx);
1563*fa9e4066Sahrens 
1564*fa9e4066Sahrens 	rw_exit(&zp->z_parent_lock);
1565*fa9e4066Sahrens out:
1566*fa9e4066Sahrens 	zfs_dirent_unlock(dl);
1567*fa9e4066Sahrens 
1568*fa9e4066Sahrens 	VN_RELE(vp);
1569*fa9e4066Sahrens 
1570*fa9e4066Sahrens 	zil_commit(zilog, seq, 0);
1571*fa9e4066Sahrens 
1572*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
1573*fa9e4066Sahrens 	return (error);
1574*fa9e4066Sahrens }
1575*fa9e4066Sahrens 
1576*fa9e4066Sahrens /*
1577*fa9e4066Sahrens  * Read as many directory entries as will fit into the provided
1578*fa9e4066Sahrens  * buffer from the given directory cursor position (specified in
1579*fa9e4066Sahrens  * the uio structure.
1580*fa9e4066Sahrens  *
1581*fa9e4066Sahrens  *	IN:	vp	- vnode of directory to read.
1582*fa9e4066Sahrens  *		uio	- structure supplying read location, range info,
1583*fa9e4066Sahrens  *			  and return buffer.
1584*fa9e4066Sahrens  *		cr	- credentials of caller.
1585*fa9e4066Sahrens  *
1586*fa9e4066Sahrens  *	OUT:	uio	- updated offset and range, buffer filled.
1587*fa9e4066Sahrens  *		eofp	- set to true if end-of-file detected.
1588*fa9e4066Sahrens  *
1589*fa9e4066Sahrens  *	RETURN:	0 if success
1590*fa9e4066Sahrens  *		error code if failure
1591*fa9e4066Sahrens  *
1592*fa9e4066Sahrens  * Timestamps:
1593*fa9e4066Sahrens  *	vp - atime updated
1594*fa9e4066Sahrens  *
1595*fa9e4066Sahrens  * Note that the low 4 bits of the cookie returned by zap is always zero.
1596*fa9e4066Sahrens  * This allows us to use the low range for "special" directory entries:
1597*fa9e4066Sahrens  * We use 0 for '.', and 1 for '..'.  If this is the root of the filesystem,
1598*fa9e4066Sahrens  * we use the offset 2 for the '.zfs' directory.
1599*fa9e4066Sahrens  */
1600*fa9e4066Sahrens /* ARGSUSED */
1601*fa9e4066Sahrens static int
1602*fa9e4066Sahrens zfs_readdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp)
1603*fa9e4066Sahrens {
1604*fa9e4066Sahrens 	znode_t		*zp = VTOZ(vp);
1605*fa9e4066Sahrens 	iovec_t		*iovp;
1606*fa9e4066Sahrens 	dirent64_t	*odp;
1607*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
1608*fa9e4066Sahrens 	caddr_t		outbuf;
1609*fa9e4066Sahrens 	size_t		bufsize;
1610*fa9e4066Sahrens 	zap_cursor_t	zc;
1611*fa9e4066Sahrens 	zap_attribute_t	zap;
1612*fa9e4066Sahrens 	uint_t		bytes_wanted;
1613*fa9e4066Sahrens 	ushort_t	this_reclen;
1614*fa9e4066Sahrens 	uint64_t	offset; /* must be unsigned; checks for < 1 */
1615*fa9e4066Sahrens 	off64_t		*next;
1616*fa9e4066Sahrens 	int		local_eof;
1617*fa9e4066Sahrens 	int		outcount = 0;
1618*fa9e4066Sahrens 	int		error = 0;
1619*fa9e4066Sahrens 
1620*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
1621*fa9e4066Sahrens 
1622*fa9e4066Sahrens 	/*
1623*fa9e4066Sahrens 	 * If we are not given an eof variable,
1624*fa9e4066Sahrens 	 * use a local one.
1625*fa9e4066Sahrens 	 */
1626*fa9e4066Sahrens 	if (eofp == NULL)
1627*fa9e4066Sahrens 		eofp = &local_eof;
1628*fa9e4066Sahrens 
1629*fa9e4066Sahrens 	/*
1630*fa9e4066Sahrens 	 * Check for valid iov_len.
1631*fa9e4066Sahrens 	 */
1632*fa9e4066Sahrens 	if (uio->uio_iov->iov_len <= 0) {
1633*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
1634*fa9e4066Sahrens 		return (EINVAL);
1635*fa9e4066Sahrens 	}
1636*fa9e4066Sahrens 
1637*fa9e4066Sahrens 	/*
1638*fa9e4066Sahrens 	 * Quit if directory has been removed (posix)
1639*fa9e4066Sahrens 	 */
1640*fa9e4066Sahrens 	if ((*eofp = zp->z_reap) != 0) {
1641*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
1642*fa9e4066Sahrens 		return (0);
1643*fa9e4066Sahrens 	}
1644*fa9e4066Sahrens 
1645*fa9e4066Sahrens 	/*
1646*fa9e4066Sahrens 	 * Initialize the iterator cursor.
1647*fa9e4066Sahrens 	 */
1648*fa9e4066Sahrens 	offset = uio->uio_loffset;
1649*fa9e4066Sahrens 	if (offset <= 3) {
1650*fa9e4066Sahrens 		/*
1651*fa9e4066Sahrens 		 * Start iteration from the beginning of the directory.
1652*fa9e4066Sahrens 		 */
1653*fa9e4066Sahrens 		zap_cursor_init(&zc, zfsvfs->z_os, zp->z_id);
1654*fa9e4066Sahrens 	} else {
1655*fa9e4066Sahrens 		/*
1656*fa9e4066Sahrens 		 * The offset is a serialized cursor.
1657*fa9e4066Sahrens 		 */
1658*fa9e4066Sahrens 		zap_cursor_init_serialized(&zc, zfsvfs->z_os, zp->z_id,
1659*fa9e4066Sahrens 		    offset);
1660*fa9e4066Sahrens 	}
1661*fa9e4066Sahrens 
1662*fa9e4066Sahrens 	/*
1663*fa9e4066Sahrens 	 * Get space to change directory entries into fs independent format.
1664*fa9e4066Sahrens 	 */
1665*fa9e4066Sahrens 	iovp = uio->uio_iov;
1666*fa9e4066Sahrens 	bytes_wanted = iovp->iov_len;
1667*fa9e4066Sahrens 	if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1) {
1668*fa9e4066Sahrens 		bufsize = bytes_wanted;
1669*fa9e4066Sahrens 		outbuf = kmem_alloc(bufsize, KM_SLEEP);
1670*fa9e4066Sahrens 		odp = (struct dirent64 *)outbuf;
1671*fa9e4066Sahrens 	} else {
1672*fa9e4066Sahrens 		bufsize = bytes_wanted;
1673*fa9e4066Sahrens 		odp = (struct dirent64 *)iovp->iov_base;
1674*fa9e4066Sahrens 	}
1675*fa9e4066Sahrens 
1676*fa9e4066Sahrens 	/*
1677*fa9e4066Sahrens 	 * Transform to file-system independent format
1678*fa9e4066Sahrens 	 */
1679*fa9e4066Sahrens 	outcount = 0;
1680*fa9e4066Sahrens 	while (outcount < bytes_wanted) {
1681*fa9e4066Sahrens 		/*
1682*fa9e4066Sahrens 		 * Special case `.', `..', and `.zfs'.
1683*fa9e4066Sahrens 		 */
1684*fa9e4066Sahrens 		if (offset == 0) {
1685*fa9e4066Sahrens 			(void) strcpy(zap.za_name, ".");
1686*fa9e4066Sahrens 			zap.za_first_integer = zp->z_id;
1687*fa9e4066Sahrens 			this_reclen = DIRENT64_RECLEN(1);
1688*fa9e4066Sahrens 		} else if (offset == 1) {
1689*fa9e4066Sahrens 			(void) strcpy(zap.za_name, "..");
1690*fa9e4066Sahrens 			zap.za_first_integer = zp->z_phys->zp_parent;
1691*fa9e4066Sahrens 			this_reclen = DIRENT64_RECLEN(2);
1692*fa9e4066Sahrens 		} else if (offset == 2 && zfs_show_ctldir(zp)) {
1693*fa9e4066Sahrens 			(void) strcpy(zap.za_name, ZFS_CTLDIR_NAME);
1694*fa9e4066Sahrens 			zap.za_first_integer = ZFSCTL_INO_ROOT;
1695*fa9e4066Sahrens 			this_reclen =
1696*fa9e4066Sahrens 			    DIRENT64_RECLEN(sizeof (ZFS_CTLDIR_NAME) - 1);
1697*fa9e4066Sahrens 		} else {
1698*fa9e4066Sahrens 			/*
1699*fa9e4066Sahrens 			 * Grab next entry.
1700*fa9e4066Sahrens 			 */
1701*fa9e4066Sahrens 			if (error = zap_cursor_retrieve(&zc, &zap)) {
1702*fa9e4066Sahrens 				if ((*eofp = (error == ENOENT)) != 0)
1703*fa9e4066Sahrens 					break;
1704*fa9e4066Sahrens 				else
1705*fa9e4066Sahrens 					goto update;
1706*fa9e4066Sahrens 			}
1707*fa9e4066Sahrens 
1708*fa9e4066Sahrens 			if (zap.za_integer_length != 8 ||
1709*fa9e4066Sahrens 			    zap.za_num_integers != 1) {
1710*fa9e4066Sahrens 				cmn_err(CE_WARN, "zap_readdir: bad directory "
1711*fa9e4066Sahrens 				    "entry, obj = %lld, offset = %lld\n",
1712*fa9e4066Sahrens 				    (u_longlong_t)zp->z_id,
1713*fa9e4066Sahrens 				    (u_longlong_t)offset);
1714*fa9e4066Sahrens 				error = ENXIO;
1715*fa9e4066Sahrens 				goto update;
1716*fa9e4066Sahrens 			}
1717*fa9e4066Sahrens 			this_reclen = DIRENT64_RECLEN(strlen(zap.za_name));
1718*fa9e4066Sahrens 		}
1719*fa9e4066Sahrens 
1720*fa9e4066Sahrens 		/*
1721*fa9e4066Sahrens 		 * Will this entry fit in the buffer?
1722*fa9e4066Sahrens 		 */
1723*fa9e4066Sahrens 		if (outcount + this_reclen > bufsize) {
1724*fa9e4066Sahrens 			/*
1725*fa9e4066Sahrens 			 * Did we manage to fit anything in the buffer?
1726*fa9e4066Sahrens 			 */
1727*fa9e4066Sahrens 			if (!outcount) {
1728*fa9e4066Sahrens 				error = EINVAL;
1729*fa9e4066Sahrens 				goto update;
1730*fa9e4066Sahrens 			}
1731*fa9e4066Sahrens 			break;
1732*fa9e4066Sahrens 		}
1733*fa9e4066Sahrens 		/*
1734*fa9e4066Sahrens 		 * Add this entry:
1735*fa9e4066Sahrens 		 */
1736*fa9e4066Sahrens 		odp->d_ino = (ino64_t)zap.za_first_integer;
1737*fa9e4066Sahrens 		odp->d_reclen = (ushort_t)this_reclen;
1738*fa9e4066Sahrens 		/* NOTE: d_off is the offset for the *next* entry */
1739*fa9e4066Sahrens 		next = &(odp->d_off);
1740*fa9e4066Sahrens 		(void) strncpy(odp->d_name, zap.za_name,
1741*fa9e4066Sahrens 		    DIRENT64_NAMELEN(this_reclen));
1742*fa9e4066Sahrens 		outcount += this_reclen;
1743*fa9e4066Sahrens 		odp = (dirent64_t *)((intptr_t)odp + this_reclen);
1744*fa9e4066Sahrens 
1745*fa9e4066Sahrens 		ASSERT(outcount <= bufsize);
1746*fa9e4066Sahrens 
1747*fa9e4066Sahrens 		/* Prefetch znode */
1748*fa9e4066Sahrens 		dmu_prefetch(zfsvfs->z_os, zap.za_first_integer, 0, 0);
1749*fa9e4066Sahrens 
1750*fa9e4066Sahrens 		/*
1751*fa9e4066Sahrens 		 * Move to the next entry, fill in the previous offset.
1752*fa9e4066Sahrens 		 */
1753*fa9e4066Sahrens 		if (offset > 2 || (offset == 2 && !zfs_show_ctldir(zp))) {
1754*fa9e4066Sahrens 			zap_cursor_advance(&zc);
1755*fa9e4066Sahrens 			offset = zap_cursor_serialize(&zc);
1756*fa9e4066Sahrens 		} else {
1757*fa9e4066Sahrens 			offset += 1;
1758*fa9e4066Sahrens 		}
1759*fa9e4066Sahrens 		*next = offset;
1760*fa9e4066Sahrens 	}
1761*fa9e4066Sahrens 
1762*fa9e4066Sahrens 	if (uio->uio_segflg == UIO_SYSSPACE && uio->uio_iovcnt == 1) {
1763*fa9e4066Sahrens 		iovp->iov_base += outcount;
1764*fa9e4066Sahrens 		iovp->iov_len -= outcount;
1765*fa9e4066Sahrens 		uio->uio_resid -= outcount;
1766*fa9e4066Sahrens 	} else if (error = uiomove(outbuf, (long)outcount, UIO_READ, uio)) {
1767*fa9e4066Sahrens 		/*
1768*fa9e4066Sahrens 		 * Reset the pointer.
1769*fa9e4066Sahrens 		 */
1770*fa9e4066Sahrens 		offset = uio->uio_loffset;
1771*fa9e4066Sahrens 	}
1772*fa9e4066Sahrens 
1773*fa9e4066Sahrens update:
1774*fa9e4066Sahrens 	if (uio->uio_segflg != UIO_SYSSPACE || uio->uio_iovcnt != 1)
1775*fa9e4066Sahrens 		kmem_free(outbuf, bufsize);
1776*fa9e4066Sahrens 
1777*fa9e4066Sahrens 	if (error == ENOENT)
1778*fa9e4066Sahrens 		error = 0;
1779*fa9e4066Sahrens 
1780*fa9e4066Sahrens 	ZFS_ACCESSTIME_STAMP(zfsvfs, zp);
1781*fa9e4066Sahrens 
1782*fa9e4066Sahrens 	uio->uio_loffset = offset;
1783*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
1784*fa9e4066Sahrens 	return (error);
1785*fa9e4066Sahrens }
1786*fa9e4066Sahrens 
1787*fa9e4066Sahrens /* ARGSUSED */
1788*fa9e4066Sahrens static int
1789*fa9e4066Sahrens zfs_fsync(vnode_t *vp, int syncflag, cred_t *cr)
1790*fa9e4066Sahrens {
1791*fa9e4066Sahrens 	znode_t	*zp = VTOZ(vp);
1792*fa9e4066Sahrens 	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
1793*fa9e4066Sahrens 
1794*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
1795*fa9e4066Sahrens 	zil_commit(zfsvfs->z_log, zp->z_last_itx, FSYNC);
1796*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
1797*fa9e4066Sahrens 	return (0);
1798*fa9e4066Sahrens }
1799*fa9e4066Sahrens 
1800*fa9e4066Sahrens /*
1801*fa9e4066Sahrens  * Get the requested file attributes and place them in the provided
1802*fa9e4066Sahrens  * vattr structure.
1803*fa9e4066Sahrens  *
1804*fa9e4066Sahrens  *	IN:	vp	- vnode of file.
1805*fa9e4066Sahrens  *		vap	- va_mask identifies requested attributes.
1806*fa9e4066Sahrens  *		flags	- [UNUSED]
1807*fa9e4066Sahrens  *		cr	- credentials of caller.
1808*fa9e4066Sahrens  *
1809*fa9e4066Sahrens  *	OUT:	vap	- attribute values.
1810*fa9e4066Sahrens  *
1811*fa9e4066Sahrens  *	RETURN:	0 (always succeeds)
1812*fa9e4066Sahrens  */
1813*fa9e4066Sahrens /* ARGSUSED */
1814*fa9e4066Sahrens static int
1815*fa9e4066Sahrens zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr)
1816*fa9e4066Sahrens {
1817*fa9e4066Sahrens 	znode_t *zp = VTOZ(vp);
1818*fa9e4066Sahrens 	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
1819*fa9e4066Sahrens 	znode_phys_t *pzp = zp->z_phys;
1820*fa9e4066Sahrens 	int	error;
1821*fa9e4066Sahrens 
1822*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
1823*fa9e4066Sahrens 
1824*fa9e4066Sahrens 	/*
1825*fa9e4066Sahrens 	 * Return all attributes.  It's cheaper to provide the answer
1826*fa9e4066Sahrens 	 * than to determine whether we were asked the question.
1827*fa9e4066Sahrens 	 */
1828*fa9e4066Sahrens 	mutex_enter(&zp->z_lock);
1829*fa9e4066Sahrens 
1830*fa9e4066Sahrens 	vap->va_type = vp->v_type;
1831*fa9e4066Sahrens 	vap->va_mode = pzp->zp_mode & MODEMASK;
1832*fa9e4066Sahrens 	vap->va_uid = zp->z_phys->zp_uid;
1833*fa9e4066Sahrens 	vap->va_gid = zp->z_phys->zp_gid;
1834*fa9e4066Sahrens 	vap->va_fsid = zp->z_zfsvfs->z_vfs->vfs_dev;
1835*fa9e4066Sahrens 	vap->va_nodeid = zp->z_id;
1836*fa9e4066Sahrens 	vap->va_nlink = MIN(pzp->zp_links, UINT32_MAX);	/* nlink_t limit! */
1837*fa9e4066Sahrens 	vap->va_size = pzp->zp_size;
1838*fa9e4066Sahrens 	vap->va_rdev = pzp->zp_rdev;
1839*fa9e4066Sahrens 	vap->va_seq = zp->z_seq;
1840*fa9e4066Sahrens 
1841*fa9e4066Sahrens 	ZFS_TIME_DECODE(&vap->va_atime, pzp->zp_atime);
1842*fa9e4066Sahrens 	ZFS_TIME_DECODE(&vap->va_mtime, pzp->zp_mtime);
1843*fa9e4066Sahrens 	ZFS_TIME_DECODE(&vap->va_ctime, pzp->zp_ctime);
1844*fa9e4066Sahrens 
1845*fa9e4066Sahrens 	/*
1846*fa9e4066Sahrens 	 * Owner should be allowed to always read_attributes
1847*fa9e4066Sahrens 	 */
1848*fa9e4066Sahrens 	if (error = zfs_zaccess(zp, ACE_READ_ATTRIBUTES, cr)) {
1849*fa9e4066Sahrens 		if (zp->z_phys->zp_uid != crgetuid(cr)) {
1850*fa9e4066Sahrens 			mutex_exit(&zp->z_lock);
1851*fa9e4066Sahrens 			ZFS_EXIT(zfsvfs);
1852*fa9e4066Sahrens 			return (error);
1853*fa9e4066Sahrens 		}
1854*fa9e4066Sahrens 	}
1855*fa9e4066Sahrens 
1856*fa9e4066Sahrens 	mutex_exit(&zp->z_lock);
1857*fa9e4066Sahrens 
1858*fa9e4066Sahrens 	dmu_object_size_from_db(zp->z_dbuf, &vap->va_blksize, &vap->va_nblocks);
1859*fa9e4066Sahrens 
1860*fa9e4066Sahrens 	if (zp->z_blksz == 0) {
1861*fa9e4066Sahrens 		/*
1862*fa9e4066Sahrens 		 * Block size hasn't been set; suggest maximal I/O transfers.
1863*fa9e4066Sahrens 		 */
1864*fa9e4066Sahrens 		vap->va_blksize = zfsvfs->z_max_blksz;
1865*fa9e4066Sahrens 	}
1866*fa9e4066Sahrens 
1867*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
1868*fa9e4066Sahrens 	return (0);
1869*fa9e4066Sahrens }
1870*fa9e4066Sahrens 
1871*fa9e4066Sahrens /*
1872*fa9e4066Sahrens  * Set the file attributes to the values contained in the
1873*fa9e4066Sahrens  * vattr structure.
1874*fa9e4066Sahrens  *
1875*fa9e4066Sahrens  *	IN:	vp	- vnode of file to be modified.
1876*fa9e4066Sahrens  *		vap	- new attribute values.
1877*fa9e4066Sahrens  *		flags	- ATTR_UTIME set if non-default time values provided.
1878*fa9e4066Sahrens  *		cr	- credentials of caller.
1879*fa9e4066Sahrens  *
1880*fa9e4066Sahrens  *	RETURN:	0 if success
1881*fa9e4066Sahrens  *		error code if failure
1882*fa9e4066Sahrens  *
1883*fa9e4066Sahrens  * Timestamps:
1884*fa9e4066Sahrens  *	vp - ctime updated, mtime updated if size changed.
1885*fa9e4066Sahrens  */
1886*fa9e4066Sahrens /* ARGSUSED */
1887*fa9e4066Sahrens static int
1888*fa9e4066Sahrens zfs_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
1889*fa9e4066Sahrens 	caller_context_t *ct)
1890*fa9e4066Sahrens {
1891*fa9e4066Sahrens 	struct znode	*zp = VTOZ(vp);
1892*fa9e4066Sahrens 	znode_phys_t	*pzp = zp->z_phys;
1893*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
1894*fa9e4066Sahrens 	zilog_t		*zilog = zfsvfs->z_log;
1895*fa9e4066Sahrens 	uint64_t	seq = 0;
1896*fa9e4066Sahrens 	dmu_tx_t	*tx;
1897*fa9e4066Sahrens 	uint_t		mask = vap->va_mask;
1898*fa9e4066Sahrens 	uint_t		mask_applied = 0;
1899*fa9e4066Sahrens 	vattr_t		oldva;
1900*fa9e4066Sahrens 	uint64_t	new_mode;
1901*fa9e4066Sahrens 	int		have_grow_lock;
1902*fa9e4066Sahrens 	int		need_policy = FALSE;
1903*fa9e4066Sahrens 	int		err;
1904*fa9e4066Sahrens 
1905*fa9e4066Sahrens 	if (mask == 0)
1906*fa9e4066Sahrens 		return (0);
1907*fa9e4066Sahrens 
1908*fa9e4066Sahrens 	if (mask & AT_NOSET)
1909*fa9e4066Sahrens 		return (EINVAL);
1910*fa9e4066Sahrens 
1911*fa9e4066Sahrens 	if (mask & AT_SIZE && vp->v_type == VDIR)
1912*fa9e4066Sahrens 		return (EISDIR);
1913*fa9e4066Sahrens 
1914*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
1915*fa9e4066Sahrens 
1916*fa9e4066Sahrens top:
1917*fa9e4066Sahrens 	have_grow_lock = FALSE;
1918*fa9e4066Sahrens 
1919*fa9e4066Sahrens 	if (zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) {
1920*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
1921*fa9e4066Sahrens 		return (EROFS);
1922*fa9e4066Sahrens 	}
1923*fa9e4066Sahrens 
1924*fa9e4066Sahrens 	/*
1925*fa9e4066Sahrens 	 * First validate permissions
1926*fa9e4066Sahrens 	 */
1927*fa9e4066Sahrens 
1928*fa9e4066Sahrens 	if (mask & AT_SIZE) {
1929*fa9e4066Sahrens 		err = zfs_zaccess(zp, ACE_WRITE_DATA, cr);
1930*fa9e4066Sahrens 		if (err) {
1931*fa9e4066Sahrens 			ZFS_EXIT(zfsvfs);
1932*fa9e4066Sahrens 			return (err);
1933*fa9e4066Sahrens 		}
1934*fa9e4066Sahrens 	}
1935*fa9e4066Sahrens 
1936*fa9e4066Sahrens 	if (mask & (AT_ATIME|AT_MTIME))
1937*fa9e4066Sahrens 		need_policy = zfs_zaccess_v4_perm(zp, ACE_WRITE_ATTRIBUTES, cr);
1938*fa9e4066Sahrens 
1939*fa9e4066Sahrens 	if (mask & (AT_UID|AT_GID)) {
1940*fa9e4066Sahrens 		int	idmask = (mask & (AT_UID|AT_GID));
1941*fa9e4066Sahrens 		int	take_owner;
1942*fa9e4066Sahrens 		int	take_group;
1943*fa9e4066Sahrens 
1944*fa9e4066Sahrens 		/*
1945*fa9e4066Sahrens 		 * Take ownership or chgrp to group we are a member of
1946*fa9e4066Sahrens 		 */
1947*fa9e4066Sahrens 
1948*fa9e4066Sahrens 		take_owner = (mask & AT_UID) && (vap->va_uid == crgetuid(cr));
1949*fa9e4066Sahrens 		take_group = (mask & AT_GID) && groupmember(vap->va_gid, cr);
1950*fa9e4066Sahrens 
1951*fa9e4066Sahrens 		/*
1952*fa9e4066Sahrens 		 * If both AT_UID and AT_GID are set then take_owner and
1953*fa9e4066Sahrens 		 * take_group must both be set in order to allow taking
1954*fa9e4066Sahrens 		 * ownership.
1955*fa9e4066Sahrens 		 *
1956*fa9e4066Sahrens 		 * Otherwise, send the check through secpolicy_vnode_setattr()
1957*fa9e4066Sahrens 		 *
1958*fa9e4066Sahrens 		 */
1959*fa9e4066Sahrens 
1960*fa9e4066Sahrens 		if (((idmask == (AT_UID|AT_GID)) && take_owner && take_group) ||
1961*fa9e4066Sahrens 		    ((idmask == AT_UID) && take_owner) ||
1962*fa9e4066Sahrens 		    ((idmask == AT_GID) && take_group)) {
1963*fa9e4066Sahrens 			if (zfs_zaccess_v4_perm(zp, ACE_WRITE_OWNER, cr) == 0) {
1964*fa9e4066Sahrens 				/*
1965*fa9e4066Sahrens 				 * Remove setuid/setgid for non-privileged users
1966*fa9e4066Sahrens 				 */
1967*fa9e4066Sahrens 				if ((vap->va_mode & (S_ISUID | S_ISGID)) != 0 &&
1968*fa9e4066Sahrens 				    secpolicy_vnode_setid_retain(cr,
1969*fa9e4066Sahrens 				    (vap->va_mode & S_ISUID) != 0 &&
1970*fa9e4066Sahrens 				    (mask & AT_UID) != 0 &&
1971*fa9e4066Sahrens 				    vap->va_uid == 0) != 0) {
1972*fa9e4066Sahrens 					vap->va_mode = pzp->zp_mode;
1973*fa9e4066Sahrens 					vap->va_mask |= AT_MODE;
1974*fa9e4066Sahrens 					vap->va_mode &= ~(S_ISUID|S_ISGID);
1975*fa9e4066Sahrens 				}
1976*fa9e4066Sahrens 			} else {
1977*fa9e4066Sahrens 				need_policy =  TRUE;
1978*fa9e4066Sahrens 			}
1979*fa9e4066Sahrens 		} else {
1980*fa9e4066Sahrens 			need_policy =  TRUE;
1981*fa9e4066Sahrens 		}
1982*fa9e4066Sahrens 	}
1983*fa9e4066Sahrens 
1984*fa9e4066Sahrens 	if (mask & AT_MODE)
1985*fa9e4066Sahrens 		need_policy = TRUE;
1986*fa9e4066Sahrens 
1987*fa9e4066Sahrens 	if (need_policy) {
1988*fa9e4066Sahrens 		mutex_enter(&zp->z_lock);
1989*fa9e4066Sahrens 		oldva.va_mode = pzp->zp_mode;
1990*fa9e4066Sahrens 		oldva.va_uid = zp->z_phys->zp_uid;
1991*fa9e4066Sahrens 		oldva.va_gid = zp->z_phys->zp_gid;
1992*fa9e4066Sahrens 		mutex_exit(&zp->z_lock);
1993*fa9e4066Sahrens 		err = secpolicy_vnode_setattr(cr, vp, vap, &oldva, flags,
1994*fa9e4066Sahrens 		    (int (*)(void *, int, cred_t *))zfs_zaccess_rwx, zp);
1995*fa9e4066Sahrens 		if (err) {
1996*fa9e4066Sahrens 			ZFS_EXIT(zfsvfs);
1997*fa9e4066Sahrens 			return (err);
1998*fa9e4066Sahrens 		}
1999*fa9e4066Sahrens 	}
2000*fa9e4066Sahrens 
2001*fa9e4066Sahrens 	/*
2002*fa9e4066Sahrens 	 * secpolicy_vnode_setattr, or take ownership may have
2003*fa9e4066Sahrens 	 * changed va_mask
2004*fa9e4066Sahrens 	 */
2005*fa9e4066Sahrens 	mask = vap->va_mask;
2006*fa9e4066Sahrens 
2007*fa9e4066Sahrens 	tx = dmu_tx_create(zfsvfs->z_os);
2008*fa9e4066Sahrens 	dmu_tx_hold_bonus(tx, zp->z_id);
2009*fa9e4066Sahrens 
2010*fa9e4066Sahrens 	if (mask & AT_MODE) {
2011*fa9e4066Sahrens 
2012*fa9e4066Sahrens 		new_mode = (pzp->zp_mode & S_IFMT) | (vap->va_mode & ~S_IFMT);
2013*fa9e4066Sahrens 
2014*fa9e4066Sahrens 		if (zp->z_phys->zp_acl.z_acl_extern_obj)
2015*fa9e4066Sahrens 			dmu_tx_hold_write(tx,
2016*fa9e4066Sahrens 			    pzp->zp_acl.z_acl_extern_obj, 0, SPA_MAXBLOCKSIZE);
2017*fa9e4066Sahrens 		else
2018*fa9e4066Sahrens 			dmu_tx_hold_write(tx, DMU_NEW_OBJECT,
2019*fa9e4066Sahrens 			    0, ZFS_ACL_SIZE(MAX_ACL_SIZE));
2020*fa9e4066Sahrens 	}
2021*fa9e4066Sahrens 
2022*fa9e4066Sahrens 	if (mask & AT_SIZE) {
2023*fa9e4066Sahrens 		uint64_t off = vap->va_size;
2024*fa9e4066Sahrens 		/*
2025*fa9e4066Sahrens 		 * Grab the grow_lock to serialize this change with
2026*fa9e4066Sahrens 		 * respect to other file manipulations.
2027*fa9e4066Sahrens 		 */
2028*fa9e4066Sahrens 		rw_enter(&zp->z_grow_lock, RW_WRITER);
2029*fa9e4066Sahrens 		have_grow_lock = TRUE;
2030*fa9e4066Sahrens 		if (off < zp->z_phys->zp_size)
2031*fa9e4066Sahrens 			dmu_tx_hold_free(tx, zp->z_id, off, DMU_OBJECT_END);
2032*fa9e4066Sahrens 		else if (zp->z_phys->zp_size &&
2033*fa9e4066Sahrens 		    zp->z_blksz < zfsvfs->z_max_blksz && off > zp->z_blksz)
2034*fa9e4066Sahrens 			/* we will rewrite this block if we grow */
2035*fa9e4066Sahrens 			dmu_tx_hold_write(tx, zp->z_id, 0, zp->z_phys->zp_size);
2036*fa9e4066Sahrens 	}
2037*fa9e4066Sahrens 
2038*fa9e4066Sahrens 	err = dmu_tx_assign(tx, zfsvfs->z_assign);
2039*fa9e4066Sahrens 	if (err) {
2040*fa9e4066Sahrens 		dmu_tx_abort(tx);
2041*fa9e4066Sahrens 		if (have_grow_lock)
2042*fa9e4066Sahrens 			rw_exit(&zp->z_grow_lock);
2043*fa9e4066Sahrens 		if (err == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) {
2044*fa9e4066Sahrens 			txg_wait_open(dmu_objset_pool(zfsvfs->z_os), 0);
2045*fa9e4066Sahrens 			goto top;
2046*fa9e4066Sahrens 		}
2047*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2048*fa9e4066Sahrens 		return (err);
2049*fa9e4066Sahrens 	}
2050*fa9e4066Sahrens 
2051*fa9e4066Sahrens 	dmu_buf_will_dirty(zp->z_dbuf, tx);
2052*fa9e4066Sahrens 
2053*fa9e4066Sahrens 	/*
2054*fa9e4066Sahrens 	 * Set each attribute requested.
2055*fa9e4066Sahrens 	 * We group settings according to the locks they need to acquire.
2056*fa9e4066Sahrens 	 *
2057*fa9e4066Sahrens 	 * Note: you cannot set ctime directly, although it will be
2058*fa9e4066Sahrens 	 * updated as a side-effect of calling this function.
2059*fa9e4066Sahrens 	 */
2060*fa9e4066Sahrens 	if (mask & AT_SIZE) {
2061*fa9e4066Sahrens 		/*
2062*fa9e4066Sahrens 		 * XXX - Note, we are not providing any open
2063*fa9e4066Sahrens 		 * mode flags here (like FNDELAY), so we may
2064*fa9e4066Sahrens 		 * block if there are locks present... this
2065*fa9e4066Sahrens 		 * should be addressed in openat().
2066*fa9e4066Sahrens 		 */
2067*fa9e4066Sahrens 		err = zfs_freesp(zp, vap->va_size, 0, 0, tx, cr);
2068*fa9e4066Sahrens 		if (err) {
2069*fa9e4066Sahrens 			mutex_enter(&zp->z_lock);
2070*fa9e4066Sahrens 			goto out;
2071*fa9e4066Sahrens 		}
2072*fa9e4066Sahrens 		mask_applied |= AT_SIZE;
2073*fa9e4066Sahrens 	}
2074*fa9e4066Sahrens 
2075*fa9e4066Sahrens 	mask_applied = mask;	/* no errors after this point */
2076*fa9e4066Sahrens 
2077*fa9e4066Sahrens 	mutex_enter(&zp->z_lock);
2078*fa9e4066Sahrens 
2079*fa9e4066Sahrens 	if (mask & AT_MODE) {
2080*fa9e4066Sahrens 		err = zfs_acl_chmod_setattr(zp, new_mode, tx);
2081*fa9e4066Sahrens 		ASSERT3U(err, ==, 0);
2082*fa9e4066Sahrens 	}
2083*fa9e4066Sahrens 
2084*fa9e4066Sahrens 	if ((mask & AT_UID) && vap->va_uid != oldva.va_uid)
2085*fa9e4066Sahrens 		zp->z_phys->zp_uid = (uint64_t)vap->va_uid;
2086*fa9e4066Sahrens 
2087*fa9e4066Sahrens 	if ((mask & AT_GID) && vap->va_gid != oldva.va_gid)
2088*fa9e4066Sahrens 		zp->z_phys->zp_gid = (uint64_t)vap->va_gid;
2089*fa9e4066Sahrens 
2090*fa9e4066Sahrens 	if (mask & AT_ATIME)
2091*fa9e4066Sahrens 		ZFS_TIME_ENCODE(&vap->va_atime, pzp->zp_atime);
2092*fa9e4066Sahrens 
2093*fa9e4066Sahrens 	if (mask & AT_MTIME)
2094*fa9e4066Sahrens 		ZFS_TIME_ENCODE(&vap->va_mtime, pzp->zp_mtime);
2095*fa9e4066Sahrens 
2096*fa9e4066Sahrens 	if (mask_applied & AT_SIZE)
2097*fa9e4066Sahrens 		zfs_time_stamper_locked(zp, CONTENT_MODIFIED, tx);
2098*fa9e4066Sahrens 	else if (mask_applied != 0)
2099*fa9e4066Sahrens 		zfs_time_stamper_locked(zp, STATE_CHANGED, tx);
2100*fa9e4066Sahrens 
2101*fa9e4066Sahrens out:
2102*fa9e4066Sahrens 	if (mask_applied != 0)
2103*fa9e4066Sahrens 		seq = zfs_log_setattr(zilog, tx, TX_SETATTR, zp, vap,
2104*fa9e4066Sahrens 		    mask_applied);
2105*fa9e4066Sahrens 
2106*fa9e4066Sahrens 	mutex_exit(&zp->z_lock);
2107*fa9e4066Sahrens 
2108*fa9e4066Sahrens 	if (have_grow_lock)
2109*fa9e4066Sahrens 		rw_exit(&zp->z_grow_lock);
2110*fa9e4066Sahrens 
2111*fa9e4066Sahrens 	dmu_tx_commit(tx);
2112*fa9e4066Sahrens 
2113*fa9e4066Sahrens 	zil_commit(zilog, seq, 0);
2114*fa9e4066Sahrens 
2115*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
2116*fa9e4066Sahrens 	return (err);
2117*fa9e4066Sahrens }
2118*fa9e4066Sahrens 
2119*fa9e4066Sahrens /*
2120*fa9e4066Sahrens  * Search back through the directory tree, using the ".." entries.
2121*fa9e4066Sahrens  * Lock each directory in the chain to prevent concurrent renames.
2122*fa9e4066Sahrens  * Fail any attempt to move a directory into one of its own descendants.
2123*fa9e4066Sahrens  * XXX - z_parent_lock can overlap with map or grow locks
2124*fa9e4066Sahrens  */
2125*fa9e4066Sahrens typedef struct zfs_zlock {
2126*fa9e4066Sahrens 	krwlock_t	*zl_rwlock;	/* lock we acquired */
2127*fa9e4066Sahrens 	znode_t		*zl_znode;	/* znode we held */
2128*fa9e4066Sahrens 	struct zfs_zlock *zl_next;	/* next in list */
2129*fa9e4066Sahrens } zfs_zlock_t;
2130*fa9e4066Sahrens 
2131*fa9e4066Sahrens static int
2132*fa9e4066Sahrens zfs_rename_lock(znode_t *szp, znode_t *tdzp, znode_t *sdzp, zfs_zlock_t **zlpp)
2133*fa9e4066Sahrens {
2134*fa9e4066Sahrens 	zfs_zlock_t	*zl;
2135*fa9e4066Sahrens 	znode_t 	*zp = tdzp;
2136*fa9e4066Sahrens 	uint64_t	rootid = zp->z_zfsvfs->z_root;
2137*fa9e4066Sahrens 	uint64_t	*oidp = &zp->z_id;
2138*fa9e4066Sahrens 	krwlock_t	*rwlp = &szp->z_parent_lock;
2139*fa9e4066Sahrens 	krw_t		rw = RW_WRITER;
2140*fa9e4066Sahrens 
2141*fa9e4066Sahrens 	/*
2142*fa9e4066Sahrens 	 * First pass write-locks szp and compares to zp->z_id.
2143*fa9e4066Sahrens 	 * Later passes read-lock zp and compare to zp->z_parent.
2144*fa9e4066Sahrens 	 */
2145*fa9e4066Sahrens 	do {
2146*fa9e4066Sahrens 		zl = kmem_alloc(sizeof (*zl), KM_SLEEP);
2147*fa9e4066Sahrens 		zl->zl_rwlock = rwlp;
2148*fa9e4066Sahrens 		zl->zl_znode = NULL;
2149*fa9e4066Sahrens 		zl->zl_next = *zlpp;
2150*fa9e4066Sahrens 		*zlpp = zl;
2151*fa9e4066Sahrens 
2152*fa9e4066Sahrens 		rw_enter(rwlp, rw);
2153*fa9e4066Sahrens 
2154*fa9e4066Sahrens 		if (*oidp == szp->z_id)		/* We're a descendant of szp */
2155*fa9e4066Sahrens 			return (EINVAL);
2156*fa9e4066Sahrens 
2157*fa9e4066Sahrens 		if (*oidp == rootid)		/* We've hit the top */
2158*fa9e4066Sahrens 			return (0);
2159*fa9e4066Sahrens 
2160*fa9e4066Sahrens 		if (rw == RW_READER) {		/* i.e. not the first pass */
2161*fa9e4066Sahrens 			int error = zfs_zget(zp->z_zfsvfs, *oidp, &zp);
2162*fa9e4066Sahrens 			if (error)
2163*fa9e4066Sahrens 				return (error);
2164*fa9e4066Sahrens 			zl->zl_znode = zp;
2165*fa9e4066Sahrens 		}
2166*fa9e4066Sahrens 		oidp = &zp->z_phys->zp_parent;
2167*fa9e4066Sahrens 		rwlp = &zp->z_parent_lock;
2168*fa9e4066Sahrens 		rw = RW_READER;
2169*fa9e4066Sahrens 
2170*fa9e4066Sahrens 	} while (zp->z_id != sdzp->z_id);
2171*fa9e4066Sahrens 
2172*fa9e4066Sahrens 	return (0);
2173*fa9e4066Sahrens }
2174*fa9e4066Sahrens 
2175*fa9e4066Sahrens /*
2176*fa9e4066Sahrens  * Drop locks and release vnodes that were held by zfs_rename_lock().
2177*fa9e4066Sahrens  */
2178*fa9e4066Sahrens static void
2179*fa9e4066Sahrens zfs_rename_unlock(zfs_zlock_t **zlpp)
2180*fa9e4066Sahrens {
2181*fa9e4066Sahrens 	zfs_zlock_t *zl;
2182*fa9e4066Sahrens 
2183*fa9e4066Sahrens 	while ((zl = *zlpp) != NULL) {
2184*fa9e4066Sahrens 		if (zl->zl_znode != NULL)
2185*fa9e4066Sahrens 			VN_RELE(ZTOV(zl->zl_znode));
2186*fa9e4066Sahrens 		rw_exit(zl->zl_rwlock);
2187*fa9e4066Sahrens 		*zlpp = zl->zl_next;
2188*fa9e4066Sahrens 		kmem_free(zl, sizeof (*zl));
2189*fa9e4066Sahrens 	}
2190*fa9e4066Sahrens }
2191*fa9e4066Sahrens 
2192*fa9e4066Sahrens /*
2193*fa9e4066Sahrens  * Move an entry from the provided source directory to the target
2194*fa9e4066Sahrens  * directory.  Change the entry name as indicated.
2195*fa9e4066Sahrens  *
2196*fa9e4066Sahrens  *	IN:	sdvp	- Source directory containing the "old entry".
2197*fa9e4066Sahrens  *		snm	- Old entry name.
2198*fa9e4066Sahrens  *		tdvp	- Target directory to contain the "new entry".
2199*fa9e4066Sahrens  *		tnm	- New entry name.
2200*fa9e4066Sahrens  *		cr	- credentials of caller.
2201*fa9e4066Sahrens  *
2202*fa9e4066Sahrens  *	RETURN:	0 if success
2203*fa9e4066Sahrens  *		error code if failure
2204*fa9e4066Sahrens  *
2205*fa9e4066Sahrens  * Timestamps:
2206*fa9e4066Sahrens  *	sdvp,tdvp - ctime|mtime updated
2207*fa9e4066Sahrens  */
2208*fa9e4066Sahrens static int
2209*fa9e4066Sahrens zfs_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm, cred_t *cr)
2210*fa9e4066Sahrens {
2211*fa9e4066Sahrens 	znode_t		*tdzp, *szp, *tzp;
2212*fa9e4066Sahrens 	znode_t		*sdzp = VTOZ(sdvp);
2213*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = sdzp->z_zfsvfs;
2214*fa9e4066Sahrens 	zilog_t		*zilog = zfsvfs->z_log;
2215*fa9e4066Sahrens 	uint64_t	seq = 0;
2216*fa9e4066Sahrens 	vnode_t		*realvp;
2217*fa9e4066Sahrens 	zfs_dirlock_t	*sdl, *tdl;
2218*fa9e4066Sahrens 	dmu_tx_t	*tx;
2219*fa9e4066Sahrens 	zfs_zlock_t	*zl;
2220*fa9e4066Sahrens 	int		cmp, serr, terr, error;
2221*fa9e4066Sahrens 
2222*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
2223*fa9e4066Sahrens 
2224*fa9e4066Sahrens 	/*
2225*fa9e4066Sahrens 	 * Make sure we have the real vp for the target directory.
2226*fa9e4066Sahrens 	 */
2227*fa9e4066Sahrens 	if (VOP_REALVP(tdvp, &realvp) == 0)
2228*fa9e4066Sahrens 		tdvp = realvp;
2229*fa9e4066Sahrens 
2230*fa9e4066Sahrens 	if (tdvp->v_vfsp != sdvp->v_vfsp) {
2231*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2232*fa9e4066Sahrens 		return (EXDEV);
2233*fa9e4066Sahrens 	}
2234*fa9e4066Sahrens 
2235*fa9e4066Sahrens 	tdzp = VTOZ(tdvp);
2236*fa9e4066Sahrens top:
2237*fa9e4066Sahrens 	szp = NULL;
2238*fa9e4066Sahrens 	tzp = NULL;
2239*fa9e4066Sahrens 	zl = NULL;
2240*fa9e4066Sahrens 
2241*fa9e4066Sahrens 	/*
2242*fa9e4066Sahrens 	 * This is to prevent the creation of links into attribute space
2243*fa9e4066Sahrens 	 * by renaming a linked file into/outof an attribute directory.
2244*fa9e4066Sahrens 	 * See the comment in zfs_link() for why this is considered bad.
2245*fa9e4066Sahrens 	 */
2246*fa9e4066Sahrens 	if ((tdzp->z_phys->zp_flags & ZFS_XATTR) !=
2247*fa9e4066Sahrens 	    (sdzp->z_phys->zp_flags & ZFS_XATTR)) {
2248*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2249*fa9e4066Sahrens 		return (EINVAL);
2250*fa9e4066Sahrens 	}
2251*fa9e4066Sahrens 
2252*fa9e4066Sahrens 	/*
2253*fa9e4066Sahrens 	 * Lock source and target directory entries.  To prevent deadlock,
2254*fa9e4066Sahrens 	 * a lock ordering must be defined.  We lock the directory with
2255*fa9e4066Sahrens 	 * the smallest object id first, or if it's a tie, the one with
2256*fa9e4066Sahrens 	 * the lexically first name.
2257*fa9e4066Sahrens 	 */
2258*fa9e4066Sahrens 	if (sdzp->z_id < tdzp->z_id) {
2259*fa9e4066Sahrens 		cmp = -1;
2260*fa9e4066Sahrens 	} else if (sdzp->z_id > tdzp->z_id) {
2261*fa9e4066Sahrens 		cmp = 1;
2262*fa9e4066Sahrens 	} else {
2263*fa9e4066Sahrens 		cmp = strcmp(snm, tnm);
2264*fa9e4066Sahrens 		if (cmp == 0) {
2265*fa9e4066Sahrens 			/*
2266*fa9e4066Sahrens 			 * POSIX: "If the old argument and the new argument
2267*fa9e4066Sahrens 			 * both refer to links to the same existing file,
2268*fa9e4066Sahrens 			 * the rename() function shall return successfully
2269*fa9e4066Sahrens 			 * and perform no other action."
2270*fa9e4066Sahrens 			 */
2271*fa9e4066Sahrens 			ZFS_EXIT(zfsvfs);
2272*fa9e4066Sahrens 			return (0);
2273*fa9e4066Sahrens 		}
2274*fa9e4066Sahrens 	}
2275*fa9e4066Sahrens 	if (cmp < 0) {
2276*fa9e4066Sahrens 		serr = zfs_dirent_lock(&sdl, sdzp, snm, &szp, ZEXISTS);
2277*fa9e4066Sahrens 		terr = zfs_dirent_lock(&tdl, tdzp, tnm, &tzp, 0);
2278*fa9e4066Sahrens 	} else {
2279*fa9e4066Sahrens 		terr = zfs_dirent_lock(&tdl, tdzp, tnm, &tzp, 0);
2280*fa9e4066Sahrens 		serr = zfs_dirent_lock(&sdl, sdzp, snm, &szp, ZEXISTS);
2281*fa9e4066Sahrens 	}
2282*fa9e4066Sahrens 
2283*fa9e4066Sahrens 	if (serr) {
2284*fa9e4066Sahrens 		/*
2285*fa9e4066Sahrens 		 * Source entry invalid or not there.
2286*fa9e4066Sahrens 		 */
2287*fa9e4066Sahrens 		if (!terr) {
2288*fa9e4066Sahrens 			zfs_dirent_unlock(tdl);
2289*fa9e4066Sahrens 			if (tzp)
2290*fa9e4066Sahrens 				VN_RELE(ZTOV(tzp));
2291*fa9e4066Sahrens 		}
2292*fa9e4066Sahrens 		if (strcmp(snm, "..") == 0)
2293*fa9e4066Sahrens 			serr = EINVAL;
2294*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2295*fa9e4066Sahrens 		return (serr);
2296*fa9e4066Sahrens 	}
2297*fa9e4066Sahrens 	if (terr) {
2298*fa9e4066Sahrens 		zfs_dirent_unlock(sdl);
2299*fa9e4066Sahrens 		VN_RELE(ZTOV(szp));
2300*fa9e4066Sahrens 		if (strcmp(tnm, "..") == 0)
2301*fa9e4066Sahrens 			terr = EINVAL;
2302*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2303*fa9e4066Sahrens 		return (terr);
2304*fa9e4066Sahrens 	}
2305*fa9e4066Sahrens 
2306*fa9e4066Sahrens 	/*
2307*fa9e4066Sahrens 	 * Must have write access at the source to remove the old entry
2308*fa9e4066Sahrens 	 * and write access at the target to create the new entry.
2309*fa9e4066Sahrens 	 * Note that if target and source are the same, this can be
2310*fa9e4066Sahrens 	 * done in a single check.
2311*fa9e4066Sahrens 	 */
2312*fa9e4066Sahrens 
2313*fa9e4066Sahrens 	if (error = zfs_zaccess_rename(sdzp, szp, tdzp, tzp, cr))
2314*fa9e4066Sahrens 		goto out;
2315*fa9e4066Sahrens 
2316*fa9e4066Sahrens 	if (ZTOV(szp)->v_type == VDIR) {
2317*fa9e4066Sahrens 		/*
2318*fa9e4066Sahrens 		 * Check to make sure rename is valid.
2319*fa9e4066Sahrens 		 * Can't do a move like this: /usr/a/b to /usr/a/b/c/d
2320*fa9e4066Sahrens 		 */
2321*fa9e4066Sahrens 		if (error = zfs_rename_lock(szp, tdzp, sdzp, &zl))
2322*fa9e4066Sahrens 			goto out;
2323*fa9e4066Sahrens 	}
2324*fa9e4066Sahrens 
2325*fa9e4066Sahrens 	/*
2326*fa9e4066Sahrens 	 * Does target exist?
2327*fa9e4066Sahrens 	 */
2328*fa9e4066Sahrens 	if (tzp) {
2329*fa9e4066Sahrens 		/*
2330*fa9e4066Sahrens 		 * Source and target must be the same type.
2331*fa9e4066Sahrens 		 */
2332*fa9e4066Sahrens 		if (ZTOV(szp)->v_type == VDIR) {
2333*fa9e4066Sahrens 			if (ZTOV(tzp)->v_type != VDIR) {
2334*fa9e4066Sahrens 				error = ENOTDIR;
2335*fa9e4066Sahrens 				goto out;
2336*fa9e4066Sahrens 			}
2337*fa9e4066Sahrens 		} else {
2338*fa9e4066Sahrens 			if (ZTOV(tzp)->v_type == VDIR) {
2339*fa9e4066Sahrens 				error = EISDIR;
2340*fa9e4066Sahrens 				goto out;
2341*fa9e4066Sahrens 			}
2342*fa9e4066Sahrens 		}
2343*fa9e4066Sahrens 		/*
2344*fa9e4066Sahrens 		 * POSIX dictates that when the source and target
2345*fa9e4066Sahrens 		 * entries refer to the same file object, rename
2346*fa9e4066Sahrens 		 * must do nothing and exit without error.
2347*fa9e4066Sahrens 		 */
2348*fa9e4066Sahrens 		if (szp->z_id == tzp->z_id) {
2349*fa9e4066Sahrens 			error = 0;
2350*fa9e4066Sahrens 			goto out;
2351*fa9e4066Sahrens 		}
2352*fa9e4066Sahrens 	}
2353*fa9e4066Sahrens 
2354*fa9e4066Sahrens 	vnevent_rename_src(ZTOV(szp));
2355*fa9e4066Sahrens 	if (tzp)
2356*fa9e4066Sahrens 		vnevent_rename_dest(ZTOV(tzp));
2357*fa9e4066Sahrens 
2358*fa9e4066Sahrens 	tx = dmu_tx_create(zfsvfs->z_os);
2359*fa9e4066Sahrens 	dmu_tx_hold_bonus(tx, szp->z_id);	/* nlink changes */
2360*fa9e4066Sahrens 	dmu_tx_hold_bonus(tx, sdzp->z_id);	/* nlink changes */
2361*fa9e4066Sahrens 	if (sdzp != tdzp) {
2362*fa9e4066Sahrens 		dmu_tx_hold_zap(tx, sdzp->z_id, 1);
2363*fa9e4066Sahrens 		dmu_tx_hold_zap(tx, tdzp->z_id, 1);
2364*fa9e4066Sahrens 		dmu_tx_hold_bonus(tx, tdzp->z_id);	/* nlink changes */
2365*fa9e4066Sahrens 	} else {
2366*fa9e4066Sahrens 		dmu_tx_hold_zap(tx, sdzp->z_id, 2);
2367*fa9e4066Sahrens 	}
2368*fa9e4066Sahrens 	if (tzp) {
2369*fa9e4066Sahrens 		dmu_tx_hold_bonus(tx, tzp->z_id);	/* nlink changes */
2370*fa9e4066Sahrens 	}
2371*fa9e4066Sahrens 	dmu_tx_hold_zap(tx, zfsvfs->z_dqueue, 1);
2372*fa9e4066Sahrens 	error = dmu_tx_assign(tx, zfsvfs->z_assign);
2373*fa9e4066Sahrens 	if (error) {
2374*fa9e4066Sahrens 		dmu_tx_abort(tx);
2375*fa9e4066Sahrens 		if (zl != NULL)
2376*fa9e4066Sahrens 			zfs_rename_unlock(&zl);
2377*fa9e4066Sahrens 		zfs_dirent_unlock(sdl);
2378*fa9e4066Sahrens 		zfs_dirent_unlock(tdl);
2379*fa9e4066Sahrens 		VN_RELE(ZTOV(szp));
2380*fa9e4066Sahrens 		if (tzp)
2381*fa9e4066Sahrens 			VN_RELE(ZTOV(tzp));
2382*fa9e4066Sahrens 		if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) {
2383*fa9e4066Sahrens 			txg_wait_open(dmu_objset_pool(zfsvfs->z_os), 0);
2384*fa9e4066Sahrens 			goto top;
2385*fa9e4066Sahrens 		}
2386*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2387*fa9e4066Sahrens 		return (error);
2388*fa9e4066Sahrens 	}
2389*fa9e4066Sahrens 
2390*fa9e4066Sahrens 	if (tzp)	/* Attempt to remove the existing target */
2391*fa9e4066Sahrens 		error = zfs_link_destroy(tdl, tzp, tx, 0, NULL);
2392*fa9e4066Sahrens 
2393*fa9e4066Sahrens 	if (error == 0) {
2394*fa9e4066Sahrens 		error = zfs_link_create(tdl, szp, tx, ZRENAMING);
2395*fa9e4066Sahrens 		if (error == 0) {
2396*fa9e4066Sahrens 			error = zfs_link_destroy(sdl, szp, tx, ZRENAMING, NULL);
2397*fa9e4066Sahrens 			ASSERT(error == 0);
2398*fa9e4066Sahrens 			seq = zfs_log_rename(zilog, tx, TX_RENAME,
2399*fa9e4066Sahrens 			    sdzp, sdl->dl_name, tdzp, tdl->dl_name, szp);
2400*fa9e4066Sahrens 		}
2401*fa9e4066Sahrens 	}
2402*fa9e4066Sahrens 
2403*fa9e4066Sahrens 	dmu_tx_commit(tx);
2404*fa9e4066Sahrens out:
2405*fa9e4066Sahrens 	if (zl != NULL)
2406*fa9e4066Sahrens 		zfs_rename_unlock(&zl);
2407*fa9e4066Sahrens 
2408*fa9e4066Sahrens 	zfs_dirent_unlock(sdl);
2409*fa9e4066Sahrens 	zfs_dirent_unlock(tdl);
2410*fa9e4066Sahrens 
2411*fa9e4066Sahrens 	VN_RELE(ZTOV(szp));
2412*fa9e4066Sahrens 	if (tzp)
2413*fa9e4066Sahrens 		VN_RELE(ZTOV(tzp));
2414*fa9e4066Sahrens 
2415*fa9e4066Sahrens 	zil_commit(zilog, seq, 0);
2416*fa9e4066Sahrens 
2417*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
2418*fa9e4066Sahrens 	return (error);
2419*fa9e4066Sahrens }
2420*fa9e4066Sahrens 
2421*fa9e4066Sahrens /*
2422*fa9e4066Sahrens  * Insert the indicated symbolic reference entry into the directory.
2423*fa9e4066Sahrens  *
2424*fa9e4066Sahrens  *	IN:	dvp	- Directory to contain new symbolic link.
2425*fa9e4066Sahrens  *		link	- Name for new symlink entry.
2426*fa9e4066Sahrens  *		vap	- Attributes of new entry.
2427*fa9e4066Sahrens  *		target	- Target path of new symlink.
2428*fa9e4066Sahrens  *		cr	- credentials of caller.
2429*fa9e4066Sahrens  *
2430*fa9e4066Sahrens  *	RETURN:	0 if success
2431*fa9e4066Sahrens  *		error code if failure
2432*fa9e4066Sahrens  *
2433*fa9e4066Sahrens  * Timestamps:
2434*fa9e4066Sahrens  *	dvp - ctime|mtime updated
2435*fa9e4066Sahrens  */
2436*fa9e4066Sahrens static int
2437*fa9e4066Sahrens zfs_symlink(vnode_t *dvp, char *name, vattr_t *vap, char *link, cred_t *cr)
2438*fa9e4066Sahrens {
2439*fa9e4066Sahrens 	znode_t		*zp, *dzp = VTOZ(dvp);
2440*fa9e4066Sahrens 	zfs_dirlock_t	*dl;
2441*fa9e4066Sahrens 	dmu_tx_t	*tx;
2442*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = dzp->z_zfsvfs;
2443*fa9e4066Sahrens 	zilog_t		*zilog = zfsvfs->z_log;
2444*fa9e4066Sahrens 	uint64_t	seq = 0;
2445*fa9e4066Sahrens 	uint64_t	zoid;
2446*fa9e4066Sahrens 	int		len = strlen(link);
2447*fa9e4066Sahrens 	int		error;
2448*fa9e4066Sahrens 
2449*fa9e4066Sahrens 	ASSERT(vap->va_type == VLNK);
2450*fa9e4066Sahrens 
2451*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
2452*fa9e4066Sahrens top:
2453*fa9e4066Sahrens 	if (error = zfs_zaccess(dzp, ACE_ADD_FILE, cr)) {
2454*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2455*fa9e4066Sahrens 		return (error);
2456*fa9e4066Sahrens 	}
2457*fa9e4066Sahrens 
2458*fa9e4066Sahrens 	if (len > MAXPATHLEN) {
2459*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2460*fa9e4066Sahrens 		return (ENAMETOOLONG);
2461*fa9e4066Sahrens 	}
2462*fa9e4066Sahrens 
2463*fa9e4066Sahrens 	/*
2464*fa9e4066Sahrens 	 * Attempt to lock directory; fail if entry already exists.
2465*fa9e4066Sahrens 	 */
2466*fa9e4066Sahrens 	if (error = zfs_dirent_lock(&dl, dzp, name, &zp, ZNEW)) {
2467*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2468*fa9e4066Sahrens 		return (error);
2469*fa9e4066Sahrens 	}
2470*fa9e4066Sahrens 
2471*fa9e4066Sahrens 	tx = dmu_tx_create(zfsvfs->z_os);
2472*fa9e4066Sahrens 	dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, MAX(1, len));
2473*fa9e4066Sahrens 	dmu_tx_hold_bonus(tx, dzp->z_id);
2474*fa9e4066Sahrens 	dmu_tx_hold_zap(tx, dzp->z_id, 1);
2475*fa9e4066Sahrens 	if (dzp->z_phys->zp_flags & ZFS_INHERIT_ACE)
2476*fa9e4066Sahrens 		dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, SPA_MAXBLOCKSIZE);
2477*fa9e4066Sahrens 	error = dmu_tx_assign(tx, zfsvfs->z_assign);
2478*fa9e4066Sahrens 	if (error) {
2479*fa9e4066Sahrens 		dmu_tx_abort(tx);
2480*fa9e4066Sahrens 		zfs_dirent_unlock(dl);
2481*fa9e4066Sahrens 		if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) {
2482*fa9e4066Sahrens 			txg_wait_open(dmu_objset_pool(zfsvfs->z_os), 0);
2483*fa9e4066Sahrens 			goto top;
2484*fa9e4066Sahrens 		}
2485*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2486*fa9e4066Sahrens 		return (error);
2487*fa9e4066Sahrens 	}
2488*fa9e4066Sahrens 
2489*fa9e4066Sahrens 	dmu_buf_will_dirty(dzp->z_dbuf, tx);
2490*fa9e4066Sahrens 
2491*fa9e4066Sahrens 	/*
2492*fa9e4066Sahrens 	 * Create a new object for the symlink.
2493*fa9e4066Sahrens 	 * Put the link content into bonus buffer if it will fit;
2494*fa9e4066Sahrens 	 * otherwise, store it just like any other file data.
2495*fa9e4066Sahrens 	 */
2496*fa9e4066Sahrens 	zoid = 0;
2497*fa9e4066Sahrens 	if (sizeof (znode_phys_t) + len <= dmu_bonus_max()) {
2498*fa9e4066Sahrens 		zfs_mknode(dzp, vap, &zoid, tx, cr, 0, &zp, len);
2499*fa9e4066Sahrens 		if (len != 0)
2500*fa9e4066Sahrens 			bcopy(link, zp->z_phys + 1, len);
2501*fa9e4066Sahrens 	} else {
2502*fa9e4066Sahrens 		dmu_buf_t *dbp;
2503*fa9e4066Sahrens 		zfs_mknode(dzp, vap, &zoid, tx, cr, 0, &zp, 0);
2504*fa9e4066Sahrens 
2505*fa9e4066Sahrens 		rw_enter(&zp->z_grow_lock, RW_WRITER);
2506*fa9e4066Sahrens 		error = zfs_grow_blocksize(zp, len, tx);
2507*fa9e4066Sahrens 		rw_exit(&zp->z_grow_lock);
2508*fa9e4066Sahrens 		if (error)
2509*fa9e4066Sahrens 			goto out;
2510*fa9e4066Sahrens 
2511*fa9e4066Sahrens 		dbp = dmu_buf_hold(zfsvfs->z_os, zoid, 0);
2512*fa9e4066Sahrens 		dmu_buf_will_dirty(dbp, tx);
2513*fa9e4066Sahrens 
2514*fa9e4066Sahrens 		ASSERT3U(len, <=, dbp->db_size);
2515*fa9e4066Sahrens 		bcopy(link, dbp->db_data, len);
2516*fa9e4066Sahrens 		dmu_buf_rele(dbp);
2517*fa9e4066Sahrens 	}
2518*fa9e4066Sahrens 	zp->z_phys->zp_size = len;
2519*fa9e4066Sahrens 
2520*fa9e4066Sahrens 	/*
2521*fa9e4066Sahrens 	 * Insert the new object into the directory.
2522*fa9e4066Sahrens 	 */
2523*fa9e4066Sahrens 	(void) zfs_link_create(dl, zp, tx, ZNEW);
2524*fa9e4066Sahrens out:
2525*fa9e4066Sahrens 	if (error == 0)
2526*fa9e4066Sahrens 		seq = zfs_log_symlink(zilog, tx, TX_SYMLINK,
2527*fa9e4066Sahrens 		    dzp, zp, name, link);
2528*fa9e4066Sahrens 
2529*fa9e4066Sahrens 	dmu_tx_commit(tx);
2530*fa9e4066Sahrens 
2531*fa9e4066Sahrens 	zfs_dirent_unlock(dl);
2532*fa9e4066Sahrens 
2533*fa9e4066Sahrens 	VN_RELE(ZTOV(zp));
2534*fa9e4066Sahrens 
2535*fa9e4066Sahrens 	zil_commit(zilog, seq, 0);
2536*fa9e4066Sahrens 
2537*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
2538*fa9e4066Sahrens 	return (error);
2539*fa9e4066Sahrens }
2540*fa9e4066Sahrens 
2541*fa9e4066Sahrens /*
2542*fa9e4066Sahrens  * Return, in the buffer contained in the provided uio structure,
2543*fa9e4066Sahrens  * the symbolic path referred to by vp.
2544*fa9e4066Sahrens  *
2545*fa9e4066Sahrens  *	IN:	vp	- vnode of symbolic link.
2546*fa9e4066Sahrens  *		uoip	- structure to contain the link path.
2547*fa9e4066Sahrens  *		cr	- credentials of caller.
2548*fa9e4066Sahrens  *
2549*fa9e4066Sahrens  *	OUT:	uio	- structure to contain the link path.
2550*fa9e4066Sahrens  *
2551*fa9e4066Sahrens  *	RETURN:	0 if success
2552*fa9e4066Sahrens  *		error code if failure
2553*fa9e4066Sahrens  *
2554*fa9e4066Sahrens  * Timestamps:
2555*fa9e4066Sahrens  *	vp - atime updated
2556*fa9e4066Sahrens  */
2557*fa9e4066Sahrens /* ARGSUSED */
2558*fa9e4066Sahrens static int
2559*fa9e4066Sahrens zfs_readlink(vnode_t *vp, uio_t *uio, cred_t *cr)
2560*fa9e4066Sahrens {
2561*fa9e4066Sahrens 	znode_t		*zp = VTOZ(vp);
2562*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
2563*fa9e4066Sahrens 	size_t		bufsz;
2564*fa9e4066Sahrens 	int		error;
2565*fa9e4066Sahrens 
2566*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
2567*fa9e4066Sahrens 
2568*fa9e4066Sahrens 	bufsz = (size_t)zp->z_phys->zp_size;
2569*fa9e4066Sahrens 	if (bufsz + sizeof (znode_phys_t) <= zp->z_dbuf->db_size) {
2570*fa9e4066Sahrens 		error = uiomove(zp->z_phys + 1,
2571*fa9e4066Sahrens 		    MIN((size_t)bufsz, uio->uio_resid), UIO_READ, uio);
2572*fa9e4066Sahrens 	} else {
2573*fa9e4066Sahrens 		dmu_buf_t *dbp = dmu_buf_hold(zfsvfs->z_os, zp->z_id, 0);
2574*fa9e4066Sahrens 		if ((error = dmu_buf_read_canfail(dbp)) != 0) {
2575*fa9e4066Sahrens 			dmu_buf_rele(dbp);
2576*fa9e4066Sahrens 			ZFS_EXIT(zfsvfs);
2577*fa9e4066Sahrens 			return (error);
2578*fa9e4066Sahrens 		}
2579*fa9e4066Sahrens 		error = uiomove(dbp->db_data,
2580*fa9e4066Sahrens 		    MIN((size_t)bufsz, uio->uio_resid), UIO_READ, uio);
2581*fa9e4066Sahrens 		dmu_buf_rele(dbp);
2582*fa9e4066Sahrens 	}
2583*fa9e4066Sahrens 
2584*fa9e4066Sahrens 	ZFS_ACCESSTIME_STAMP(zfsvfs, zp);
2585*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
2586*fa9e4066Sahrens 	return (error);
2587*fa9e4066Sahrens }
2588*fa9e4066Sahrens 
2589*fa9e4066Sahrens /*
2590*fa9e4066Sahrens  * Insert a new entry into directory tdvp referencing svp.
2591*fa9e4066Sahrens  *
2592*fa9e4066Sahrens  *	IN:	tdvp	- Directory to contain new entry.
2593*fa9e4066Sahrens  *		svp	- vnode of new entry.
2594*fa9e4066Sahrens  *		name	- name of new entry.
2595*fa9e4066Sahrens  *		cr	- credentials of caller.
2596*fa9e4066Sahrens  *
2597*fa9e4066Sahrens  *	RETURN:	0 if success
2598*fa9e4066Sahrens  *		error code if failure
2599*fa9e4066Sahrens  *
2600*fa9e4066Sahrens  * Timestamps:
2601*fa9e4066Sahrens  *	tdvp - ctime|mtime updated
2602*fa9e4066Sahrens  *	 svp - ctime updated
2603*fa9e4066Sahrens  */
2604*fa9e4066Sahrens /* ARGSUSED */
2605*fa9e4066Sahrens static int
2606*fa9e4066Sahrens zfs_link(vnode_t *tdvp, vnode_t *svp, char *name, cred_t *cr)
2607*fa9e4066Sahrens {
2608*fa9e4066Sahrens 	znode_t		*dzp = VTOZ(tdvp);
2609*fa9e4066Sahrens 	znode_t		*tzp, *szp;
2610*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = dzp->z_zfsvfs;
2611*fa9e4066Sahrens 	zilog_t		*zilog = zfsvfs->z_log;
2612*fa9e4066Sahrens 	uint64_t	seq = 0;
2613*fa9e4066Sahrens 	zfs_dirlock_t	*dl;
2614*fa9e4066Sahrens 	dmu_tx_t	*tx;
2615*fa9e4066Sahrens 	vnode_t		*realvp;
2616*fa9e4066Sahrens 	int		error;
2617*fa9e4066Sahrens 
2618*fa9e4066Sahrens 	ASSERT(tdvp->v_type == VDIR);
2619*fa9e4066Sahrens 
2620*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
2621*fa9e4066Sahrens 
2622*fa9e4066Sahrens 	if (VOP_REALVP(svp, &realvp) == 0)
2623*fa9e4066Sahrens 		svp = realvp;
2624*fa9e4066Sahrens 
2625*fa9e4066Sahrens 	if (svp->v_vfsp != tdvp->v_vfsp) {
2626*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2627*fa9e4066Sahrens 		return (EXDEV);
2628*fa9e4066Sahrens 	}
2629*fa9e4066Sahrens 
2630*fa9e4066Sahrens 	szp = VTOZ(svp);
2631*fa9e4066Sahrens top:
2632*fa9e4066Sahrens 	/*
2633*fa9e4066Sahrens 	 * We do not support links between attributes and non-attributes
2634*fa9e4066Sahrens 	 * because of the potential security risk of creating links
2635*fa9e4066Sahrens 	 * into "normal" file space in order to circumvent restrictions
2636*fa9e4066Sahrens 	 * imposed in attribute space.
2637*fa9e4066Sahrens 	 */
2638*fa9e4066Sahrens 	if ((szp->z_phys->zp_flags & ZFS_XATTR) !=
2639*fa9e4066Sahrens 	    (dzp->z_phys->zp_flags & ZFS_XATTR)) {
2640*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2641*fa9e4066Sahrens 		return (EINVAL);
2642*fa9e4066Sahrens 	}
2643*fa9e4066Sahrens 
2644*fa9e4066Sahrens 	/*
2645*fa9e4066Sahrens 	 * POSIX dictates that we return EPERM here.
2646*fa9e4066Sahrens 	 * Better choices include ENOTSUP or EISDIR.
2647*fa9e4066Sahrens 	 */
2648*fa9e4066Sahrens 	if (svp->v_type == VDIR) {
2649*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2650*fa9e4066Sahrens 		return (EPERM);
2651*fa9e4066Sahrens 	}
2652*fa9e4066Sahrens 
2653*fa9e4066Sahrens 	if ((uid_t)szp->z_phys->zp_uid != crgetuid(cr) &&
2654*fa9e4066Sahrens 	    secpolicy_basic_link(cr) != 0) {
2655*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2656*fa9e4066Sahrens 		return (EPERM);
2657*fa9e4066Sahrens 	}
2658*fa9e4066Sahrens 
2659*fa9e4066Sahrens 	if (error = zfs_zaccess(dzp, ACE_ADD_FILE, cr)) {
2660*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2661*fa9e4066Sahrens 		return (error);
2662*fa9e4066Sahrens 	}
2663*fa9e4066Sahrens 
2664*fa9e4066Sahrens 	/*
2665*fa9e4066Sahrens 	 * Attempt to lock directory; fail if entry already exists.
2666*fa9e4066Sahrens 	 */
2667*fa9e4066Sahrens 	if (error = zfs_dirent_lock(&dl, dzp, name, &tzp, ZNEW)) {
2668*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2669*fa9e4066Sahrens 		return (error);
2670*fa9e4066Sahrens 	}
2671*fa9e4066Sahrens 
2672*fa9e4066Sahrens 	tx = dmu_tx_create(zfsvfs->z_os);
2673*fa9e4066Sahrens 	dmu_tx_hold_bonus(tx, szp->z_id);
2674*fa9e4066Sahrens 	dmu_tx_hold_zap(tx, dzp->z_id, 1);
2675*fa9e4066Sahrens 	error = dmu_tx_assign(tx, zfsvfs->z_assign);
2676*fa9e4066Sahrens 	if (error) {
2677*fa9e4066Sahrens 		dmu_tx_abort(tx);
2678*fa9e4066Sahrens 		zfs_dirent_unlock(dl);
2679*fa9e4066Sahrens 		if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) {
2680*fa9e4066Sahrens 			txg_wait_open(dmu_objset_pool(zfsvfs->z_os), 0);
2681*fa9e4066Sahrens 			goto top;
2682*fa9e4066Sahrens 		}
2683*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2684*fa9e4066Sahrens 		return (error);
2685*fa9e4066Sahrens 	}
2686*fa9e4066Sahrens 
2687*fa9e4066Sahrens 	error = zfs_link_create(dl, szp, tx, 0);
2688*fa9e4066Sahrens 
2689*fa9e4066Sahrens 	if (error == 0)
2690*fa9e4066Sahrens 		seq = zfs_log_link(zilog, tx, TX_LINK, dzp, szp, name);
2691*fa9e4066Sahrens 
2692*fa9e4066Sahrens 	dmu_tx_commit(tx);
2693*fa9e4066Sahrens 
2694*fa9e4066Sahrens 	zfs_dirent_unlock(dl);
2695*fa9e4066Sahrens 
2696*fa9e4066Sahrens 	zil_commit(zilog, seq, 0);
2697*fa9e4066Sahrens 
2698*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
2699*fa9e4066Sahrens 	return (error);
2700*fa9e4066Sahrens }
2701*fa9e4066Sahrens 
2702*fa9e4066Sahrens /*
2703*fa9e4066Sahrens  * zfs_null_putapage() is used when the file system has been force
2704*fa9e4066Sahrens  * unmounted. It just drops the pages.
2705*fa9e4066Sahrens  */
2706*fa9e4066Sahrens /* ARGSUSED */
2707*fa9e4066Sahrens static int
2708*fa9e4066Sahrens zfs_null_putapage(vnode_t *vp, page_t *pp, u_offset_t *offp,
2709*fa9e4066Sahrens 		size_t *lenp, int flags, cred_t *cr)
2710*fa9e4066Sahrens {
2711*fa9e4066Sahrens 	pvn_write_done(pp, B_INVAL|B_FORCE|B_ERROR);
2712*fa9e4066Sahrens 	return (0);
2713*fa9e4066Sahrens }
2714*fa9e4066Sahrens 
2715*fa9e4066Sahrens /* ARGSUSED */
2716*fa9e4066Sahrens static int
2717*fa9e4066Sahrens zfs_putapage(vnode_t *vp, page_t *pp, u_offset_t *offp,
2718*fa9e4066Sahrens 		size_t *lenp, int flags, cred_t *cr)
2719*fa9e4066Sahrens {
2720*fa9e4066Sahrens 	znode_t		*zp = VTOZ(vp);
2721*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
2722*fa9e4066Sahrens 	zilog_t		*zilog = zfsvfs->z_log;
2723*fa9e4066Sahrens 	uint64_t	seq = 0;
2724*fa9e4066Sahrens 	dmu_tx_t	*tx;
2725*fa9e4066Sahrens 	u_offset_t	off;
2726*fa9e4066Sahrens 	ssize_t		len;
2727*fa9e4066Sahrens 	caddr_t		va;
2728*fa9e4066Sahrens 	int		err;
2729*fa9e4066Sahrens 
2730*fa9e4066Sahrens top:
2731*fa9e4066Sahrens 	rw_enter(&zp->z_grow_lock, RW_READER);
2732*fa9e4066Sahrens 
2733*fa9e4066Sahrens 	off = pp->p_offset;
2734*fa9e4066Sahrens 	len = MIN(PAGESIZE, zp->z_phys->zp_size - off);
2735*fa9e4066Sahrens 
2736*fa9e4066Sahrens 	tx = dmu_tx_create(zfsvfs->z_os);
2737*fa9e4066Sahrens 	dmu_tx_hold_write(tx, zp->z_id, off, len);
2738*fa9e4066Sahrens 	dmu_tx_hold_bonus(tx, zp->z_id);
2739*fa9e4066Sahrens 	err = dmu_tx_assign(tx, zfsvfs->z_assign);
2740*fa9e4066Sahrens 	if (err != 0) {
2741*fa9e4066Sahrens 		dmu_tx_abort(tx);
2742*fa9e4066Sahrens 		rw_exit(&zp->z_grow_lock);
2743*fa9e4066Sahrens 		if (err == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) {
2744*fa9e4066Sahrens 			txg_wait_open(dmu_objset_pool(zfsvfs->z_os), 0);
2745*fa9e4066Sahrens 			goto top;
2746*fa9e4066Sahrens 		}
2747*fa9e4066Sahrens 		goto out;
2748*fa9e4066Sahrens 	}
2749*fa9e4066Sahrens 
2750*fa9e4066Sahrens 	va = ppmapin(pp, PROT_READ | PROT_WRITE, (caddr_t)-1);
2751*fa9e4066Sahrens 
2752*fa9e4066Sahrens 	dmu_write(zfsvfs->z_os, zp->z_id, off, len, va, tx);
2753*fa9e4066Sahrens 
2754*fa9e4066Sahrens 	ppmapout(va);
2755*fa9e4066Sahrens 
2756*fa9e4066Sahrens 	zfs_time_stamper(zp, CONTENT_MODIFIED, tx);
2757*fa9e4066Sahrens 	seq = zfs_log_write(zilog, tx, TX_WRITE, zp, off, len, 0, NULL);
2758*fa9e4066Sahrens 	dmu_tx_commit(tx);
2759*fa9e4066Sahrens 
2760*fa9e4066Sahrens 	rw_exit(&zp->z_grow_lock);
2761*fa9e4066Sahrens 
2762*fa9e4066Sahrens 	pvn_write_done(pp, B_WRITE | flags);
2763*fa9e4066Sahrens 	if (offp)
2764*fa9e4066Sahrens 		*offp = off;
2765*fa9e4066Sahrens 	if (lenp)
2766*fa9e4066Sahrens 		*lenp = len;
2767*fa9e4066Sahrens 
2768*fa9e4066Sahrens 	zil_commit(zilog, seq, 0);
2769*fa9e4066Sahrens out:
2770*fa9e4066Sahrens 	return (err);
2771*fa9e4066Sahrens }
2772*fa9e4066Sahrens 
2773*fa9e4066Sahrens /*
2774*fa9e4066Sahrens  * Copy the portion of the file indicated from pages into the file.
2775*fa9e4066Sahrens  * The pages are stored in a page list attached to the files vnode.
2776*fa9e4066Sahrens  *
2777*fa9e4066Sahrens  *	IN:	vp	- vnode of file to push page data to.
2778*fa9e4066Sahrens  *		off	- position in file to put data.
2779*fa9e4066Sahrens  *		len	- amount of data to write.
2780*fa9e4066Sahrens  *		flags	- flags to control the operation.
2781*fa9e4066Sahrens  *		cr	- credentials of caller.
2782*fa9e4066Sahrens  *
2783*fa9e4066Sahrens  *	RETURN:	0 if success
2784*fa9e4066Sahrens  *		error code if failure
2785*fa9e4066Sahrens  *
2786*fa9e4066Sahrens  * Timestamps:
2787*fa9e4066Sahrens  *	vp - ctime|mtime updated
2788*fa9e4066Sahrens  */
2789*fa9e4066Sahrens static int
2790*fa9e4066Sahrens zfs_putpage(vnode_t *vp, offset_t off, size_t len, int flags, cred_t *cr)
2791*fa9e4066Sahrens {
2792*fa9e4066Sahrens 	znode_t		*zp = VTOZ(vp);
2793*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
2794*fa9e4066Sahrens 	page_t		*pp;
2795*fa9e4066Sahrens 	size_t		io_len;
2796*fa9e4066Sahrens 	u_offset_t	io_off;
2797*fa9e4066Sahrens 	int		error = 0;
2798*fa9e4066Sahrens 
2799*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
2800*fa9e4066Sahrens 
2801*fa9e4066Sahrens 	ASSERT(zp->z_dbuf_held && zp->z_phys);
2802*fa9e4066Sahrens 
2803*fa9e4066Sahrens 	if (len == 0) {
2804*fa9e4066Sahrens 		/*
2805*fa9e4066Sahrens 		 * Search the entire vp list for pages >= off.
2806*fa9e4066Sahrens 		 */
2807*fa9e4066Sahrens 		error = pvn_vplist_dirty(vp, (u_offset_t)off, zfs_putapage,
2808*fa9e4066Sahrens 		    flags, cr);
2809*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2810*fa9e4066Sahrens 		return (error);
2811*fa9e4066Sahrens 	}
2812*fa9e4066Sahrens 
2813*fa9e4066Sahrens 	if (off > zp->z_phys->zp_size) {
2814*fa9e4066Sahrens 		/* past end of file */
2815*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2816*fa9e4066Sahrens 		return (0);
2817*fa9e4066Sahrens 	}
2818*fa9e4066Sahrens 
2819*fa9e4066Sahrens 	len = MIN(len, zp->z_phys->zp_size - off);
2820*fa9e4066Sahrens 
2821*fa9e4066Sahrens 	io_off = off;
2822*fa9e4066Sahrens 	while (io_off < off + len) {
2823*fa9e4066Sahrens 		if ((flags & B_INVAL) || ((flags & B_ASYNC) == 0)) {
2824*fa9e4066Sahrens 			pp  = page_lookup(vp, io_off,
2825*fa9e4066Sahrens 				(flags & (B_INVAL | B_FREE)) ?
2826*fa9e4066Sahrens 					SE_EXCL : SE_SHARED);
2827*fa9e4066Sahrens 		} else {
2828*fa9e4066Sahrens 			pp = page_lookup_nowait(vp, io_off,
2829*fa9e4066Sahrens 				(flags & B_FREE) ? SE_EXCL : SE_SHARED);
2830*fa9e4066Sahrens 		}
2831*fa9e4066Sahrens 
2832*fa9e4066Sahrens 		if (pp != NULL && pvn_getdirty(pp, flags)) {
2833*fa9e4066Sahrens 			int err;
2834*fa9e4066Sahrens 
2835*fa9e4066Sahrens 			/*
2836*fa9e4066Sahrens 			 * Found a dirty page to push
2837*fa9e4066Sahrens 			 */
2838*fa9e4066Sahrens 			if (err =
2839*fa9e4066Sahrens 			    zfs_putapage(vp, pp, &io_off, &io_len, flags, cr))
2840*fa9e4066Sahrens 				error = err;
2841*fa9e4066Sahrens 		} else {
2842*fa9e4066Sahrens 			io_len = PAGESIZE;
2843*fa9e4066Sahrens 		}
2844*fa9e4066Sahrens 		io_off += io_len;
2845*fa9e4066Sahrens 	}
2846*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
2847*fa9e4066Sahrens 	return (error);
2848*fa9e4066Sahrens }
2849*fa9e4066Sahrens 
2850*fa9e4066Sahrens void
2851*fa9e4066Sahrens zfs_inactive(vnode_t *vp, cred_t *cr)
2852*fa9e4066Sahrens {
2853*fa9e4066Sahrens 	znode_t	*zp = VTOZ(vp);
2854*fa9e4066Sahrens 	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
2855*fa9e4066Sahrens 	int error;
2856*fa9e4066Sahrens 
2857*fa9e4066Sahrens 	rw_enter(&zfsvfs->z_um_lock, RW_READER);
2858*fa9e4066Sahrens 	if (zfsvfs->z_unmounted2) {
2859*fa9e4066Sahrens 		ASSERT(zp->z_dbuf_held == 0);
2860*fa9e4066Sahrens 
2861*fa9e4066Sahrens 		if (vn_has_cached_data(vp)) {
2862*fa9e4066Sahrens 			(void) pvn_vplist_dirty(vp, 0, zfs_null_putapage,
2863*fa9e4066Sahrens 			    B_INVAL, cr);
2864*fa9e4066Sahrens 		}
2865*fa9e4066Sahrens 
2866*fa9e4066Sahrens 		vp->v_count = 0; /* count arrives as 1 */
2867*fa9e4066Sahrens 		zfs_znode_free(zp);
2868*fa9e4066Sahrens 		rw_exit(&zfsvfs->z_um_lock);
2869*fa9e4066Sahrens 		VFS_RELE(zfsvfs->z_vfs);
2870*fa9e4066Sahrens 		return;
2871*fa9e4066Sahrens 	}
2872*fa9e4066Sahrens 
2873*fa9e4066Sahrens 	/*
2874*fa9e4066Sahrens 	 * Attempt to push any data in the page cache.  If this fails
2875*fa9e4066Sahrens 	 * we will get kicked out later in zfs_zinactive().
2876*fa9e4066Sahrens 	 */
2877*fa9e4066Sahrens 	if (vn_has_cached_data(vp))
2878*fa9e4066Sahrens 		(void) pvn_vplist_dirty(vp, 0, zfs_putapage, B_INVAL, cr);
2879*fa9e4066Sahrens 
2880*fa9e4066Sahrens 	if (zp->z_atime_dirty && zp->z_reap == 0) {
2881*fa9e4066Sahrens 		dmu_tx_t *tx = dmu_tx_create(zfsvfs->z_os);
2882*fa9e4066Sahrens 
2883*fa9e4066Sahrens 		dmu_tx_hold_bonus(tx, zp->z_id);
2884*fa9e4066Sahrens 		error = dmu_tx_assign(tx, TXG_WAIT);
2885*fa9e4066Sahrens 		if (error) {
2886*fa9e4066Sahrens 			dmu_tx_abort(tx);
2887*fa9e4066Sahrens 		} else {
2888*fa9e4066Sahrens 			dmu_buf_will_dirty(zp->z_dbuf, tx);
2889*fa9e4066Sahrens 			mutex_enter(&zp->z_lock);
2890*fa9e4066Sahrens 			zp->z_atime_dirty = 0;
2891*fa9e4066Sahrens 			mutex_exit(&zp->z_lock);
2892*fa9e4066Sahrens 			dmu_tx_commit(tx);
2893*fa9e4066Sahrens 		}
2894*fa9e4066Sahrens 	}
2895*fa9e4066Sahrens 
2896*fa9e4066Sahrens 	zfs_zinactive(zp);
2897*fa9e4066Sahrens 	rw_exit(&zfsvfs->z_um_lock);
2898*fa9e4066Sahrens }
2899*fa9e4066Sahrens 
2900*fa9e4066Sahrens /*
2901*fa9e4066Sahrens  * Bounds-check the seek operation.
2902*fa9e4066Sahrens  *
2903*fa9e4066Sahrens  *	IN:	vp	- vnode seeking within
2904*fa9e4066Sahrens  *		ooff	- old file offset
2905*fa9e4066Sahrens  *		noffp	- pointer to new file offset
2906*fa9e4066Sahrens  *
2907*fa9e4066Sahrens  *	RETURN:	0 if success
2908*fa9e4066Sahrens  *		EINVAL if new offset invalid
2909*fa9e4066Sahrens  */
2910*fa9e4066Sahrens /* ARGSUSED */
2911*fa9e4066Sahrens static int
2912*fa9e4066Sahrens zfs_seek(vnode_t *vp, offset_t ooff, offset_t *noffp)
2913*fa9e4066Sahrens {
2914*fa9e4066Sahrens 	if (vp->v_type == VDIR)
2915*fa9e4066Sahrens 		return (0);
2916*fa9e4066Sahrens 	return ((*noffp < 0 || *noffp > MAXOFFSET_T) ? EINVAL : 0);
2917*fa9e4066Sahrens }
2918*fa9e4066Sahrens 
2919*fa9e4066Sahrens /*
2920*fa9e4066Sahrens  * Pre-filter the generic locking function to trap attempts to place
2921*fa9e4066Sahrens  * a mandatory lock on a memory mapped file.
2922*fa9e4066Sahrens  */
2923*fa9e4066Sahrens static int
2924*fa9e4066Sahrens zfs_frlock(vnode_t *vp, int cmd, flock64_t *bfp, int flag, offset_t offset,
2925*fa9e4066Sahrens     flk_callback_t *flk_cbp, cred_t *cr)
2926*fa9e4066Sahrens {
2927*fa9e4066Sahrens 	znode_t *zp = VTOZ(vp);
2928*fa9e4066Sahrens 	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
2929*fa9e4066Sahrens 	uint_t cnt = 1;
2930*fa9e4066Sahrens 	int error;
2931*fa9e4066Sahrens 
2932*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
2933*fa9e4066Sahrens 
2934*fa9e4066Sahrens 	/*
2935*fa9e4066Sahrens 	 * If file is being mapped, disallow frlock.  We set the mapcnt to
2936*fa9e4066Sahrens 	 * -1 here to signal that we are in the process of setting a lock.
2937*fa9e4066Sahrens 	 * This prevents a race with zfs_map().
2938*fa9e4066Sahrens 	 * XXX - well, sort of; since zfs_map() does not change z_mapcnt,
2939*fa9e4066Sahrens 	 * we could be in the middle of zfs_map() and still call fs_frlock().
2940*fa9e4066Sahrens 	 * Also, we are doing no checking in zfs_addmap() (where z_mapcnt
2941*fa9e4066Sahrens 	 * *is* manipulated).
2942*fa9e4066Sahrens 	 */
2943*fa9e4066Sahrens 	if (MANDMODE((mode_t)zp->z_phys->zp_mode) &&
2944*fa9e4066Sahrens 	    (int)(cnt = atomic_cas_32(&zp->z_mapcnt, 0, -1)) > 0) {
2945*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
2946*fa9e4066Sahrens 		return (EAGAIN);
2947*fa9e4066Sahrens 	}
2948*fa9e4066Sahrens 	error = fs_frlock(vp, cmd, bfp, flag, offset, flk_cbp, cr);
2949*fa9e4066Sahrens 	ASSERT((cnt != 0) || ((int)atomic_cas_32(&zp->z_mapcnt, -1, 0) == -1));
2950*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
2951*fa9e4066Sahrens 	return (error);
2952*fa9e4066Sahrens }
2953*fa9e4066Sahrens 
2954*fa9e4066Sahrens /*
2955*fa9e4066Sahrens  * If we can't find a page in the cache, we will create a new page
2956*fa9e4066Sahrens  * and fill it with file data.  For efficiency, we may try to fill
2957*fa9e4066Sahrens  * multiple pages as once (klustering).
2958*fa9e4066Sahrens  */
2959*fa9e4066Sahrens static int
2960*fa9e4066Sahrens zfs_fillpage(vnode_t *vp, u_offset_t off, struct seg *seg,
2961*fa9e4066Sahrens     caddr_t addr, page_t *pl[], size_t plsz, enum seg_rw rw)
2962*fa9e4066Sahrens {
2963*fa9e4066Sahrens 	znode_t *zp = VTOZ(vp);
2964*fa9e4066Sahrens 	page_t *pp, *cur_pp;
2965*fa9e4066Sahrens 	objset_t *os = zp->z_zfsvfs->z_os;
2966*fa9e4066Sahrens 	caddr_t va;
2967*fa9e4066Sahrens 	u_offset_t io_off, total;
2968*fa9e4066Sahrens 	uint64_t oid = zp->z_id;
2969*fa9e4066Sahrens 	size_t io_len;
2970*fa9e4066Sahrens 	int err;
2971*fa9e4066Sahrens 
2972*fa9e4066Sahrens 	/*
2973*fa9e4066Sahrens 	 * If we are only asking for a single page don't bother klustering.
2974*fa9e4066Sahrens 	 */
2975*fa9e4066Sahrens 	if (plsz == PAGESIZE || zp->z_blksz <= PAGESIZE ||
2976*fa9e4066Sahrens 	    off > zp->z_phys->zp_size) {
2977*fa9e4066Sahrens 		io_off = off;
2978*fa9e4066Sahrens 		io_len = PAGESIZE;
2979*fa9e4066Sahrens 		pp = page_create_va(vp, io_off, io_len, PG_WAIT, seg, addr);
2980*fa9e4066Sahrens 	} else {
2981*fa9e4066Sahrens 		/*
2982*fa9e4066Sahrens 		 * Try to fill a kluster of pages (a blocks worth).
2983*fa9e4066Sahrens 		 */
2984*fa9e4066Sahrens 		size_t klen;
2985*fa9e4066Sahrens 		u_offset_t koff;
2986*fa9e4066Sahrens 
2987*fa9e4066Sahrens 		if (!ISP2(zp->z_blksz)) {
2988*fa9e4066Sahrens 			/* Only one block in the file. */
2989*fa9e4066Sahrens 			klen = P2ROUNDUP((ulong_t)zp->z_blksz, PAGESIZE);
2990*fa9e4066Sahrens 			koff = 0;
2991*fa9e4066Sahrens 		} else {
2992*fa9e4066Sahrens 			klen = plsz;
2993*fa9e4066Sahrens 			koff = P2ALIGN(off, (u_offset_t)klen);
2994*fa9e4066Sahrens 		}
2995*fa9e4066Sahrens 		if (klen > zp->z_phys->zp_size)
2996*fa9e4066Sahrens 			klen = P2ROUNDUP(zp->z_phys->zp_size,
2997*fa9e4066Sahrens 			    (uint64_t)PAGESIZE);
2998*fa9e4066Sahrens 		pp = pvn_read_kluster(vp, off, seg, addr, &io_off,
2999*fa9e4066Sahrens 			    &io_len, koff, klen, 0);
3000*fa9e4066Sahrens 	}
3001*fa9e4066Sahrens 	if (pp == NULL) {
3002*fa9e4066Sahrens 		/*
3003*fa9e4066Sahrens 		 * Some other thread entered the page before us.
3004*fa9e4066Sahrens 		 * Return to zfs_getpage to retry the lookup.
3005*fa9e4066Sahrens 		 */
3006*fa9e4066Sahrens 		*pl = NULL;
3007*fa9e4066Sahrens 		return (0);
3008*fa9e4066Sahrens 	}
3009*fa9e4066Sahrens 
3010*fa9e4066Sahrens 	/*
3011*fa9e4066Sahrens 	 * Fill the pages in the kluster.
3012*fa9e4066Sahrens 	 */
3013*fa9e4066Sahrens 	cur_pp = pp;
3014*fa9e4066Sahrens 	for (total = io_off + io_len; io_off < total; io_off += PAGESIZE) {
3015*fa9e4066Sahrens 		ASSERT(io_off == cur_pp->p_offset);
3016*fa9e4066Sahrens 		va = ppmapin(cur_pp, PROT_READ | PROT_WRITE, (caddr_t)-1);
3017*fa9e4066Sahrens 		err = dmu_read_canfail(os, oid, io_off, PAGESIZE, va);
3018*fa9e4066Sahrens 		ppmapout(va);
3019*fa9e4066Sahrens 		if (err) {
3020*fa9e4066Sahrens 			/* On error, toss the entire kluster */
3021*fa9e4066Sahrens 			pvn_read_done(pp, B_ERROR);
3022*fa9e4066Sahrens 			return (err);
3023*fa9e4066Sahrens 		}
3024*fa9e4066Sahrens 		cur_pp = cur_pp->p_next;
3025*fa9e4066Sahrens 	}
3026*fa9e4066Sahrens out:
3027*fa9e4066Sahrens 	/*
3028*fa9e4066Sahrens 	 * Fill in the page list array from the kluster.  If
3029*fa9e4066Sahrens 	 * there are too many pages in the kluster, return
3030*fa9e4066Sahrens 	 * as many pages as possible starting from the desired
3031*fa9e4066Sahrens 	 * offset `off'.
3032*fa9e4066Sahrens 	 * NOTE: the page list will always be null terminated.
3033*fa9e4066Sahrens 	 */
3034*fa9e4066Sahrens 	pvn_plist_init(pp, pl, plsz, off, io_len, rw);
3035*fa9e4066Sahrens 
3036*fa9e4066Sahrens 	return (0);
3037*fa9e4066Sahrens }
3038*fa9e4066Sahrens 
3039*fa9e4066Sahrens /*
3040*fa9e4066Sahrens  * Return pointers to the pages for the file region [off, off + len]
3041*fa9e4066Sahrens  * in the pl array.  If plsz is greater than len, this function may
3042*fa9e4066Sahrens  * also return page pointers from before or after the specified
3043*fa9e4066Sahrens  * region (i.e. some region [off', off' + plsz]).  These additional
3044*fa9e4066Sahrens  * pages are only returned if they are already in the cache, or were
3045*fa9e4066Sahrens  * created as part of a klustered read.
3046*fa9e4066Sahrens  *
3047*fa9e4066Sahrens  *	IN:	vp	- vnode of file to get data from.
3048*fa9e4066Sahrens  *		off	- position in file to get data from.
3049*fa9e4066Sahrens  *		len	- amount of data to retrieve.
3050*fa9e4066Sahrens  *		plsz	- length of provided page list.
3051*fa9e4066Sahrens  *		seg	- segment to obtain pages for.
3052*fa9e4066Sahrens  *		addr	- virtual address of fault.
3053*fa9e4066Sahrens  *		rw	- mode of created pages.
3054*fa9e4066Sahrens  *		cr	- credentials of caller.
3055*fa9e4066Sahrens  *
3056*fa9e4066Sahrens  *	OUT:	protp	- protection mode of created pages.
3057*fa9e4066Sahrens  *		pl	- list of pages created.
3058*fa9e4066Sahrens  *
3059*fa9e4066Sahrens  *	RETURN:	0 if success
3060*fa9e4066Sahrens  *		error code if failure
3061*fa9e4066Sahrens  *
3062*fa9e4066Sahrens  * Timestamps:
3063*fa9e4066Sahrens  *	vp - atime updated
3064*fa9e4066Sahrens  */
3065*fa9e4066Sahrens /* ARGSUSED */
3066*fa9e4066Sahrens static int
3067*fa9e4066Sahrens zfs_getpage(vnode_t *vp, offset_t off, size_t len, uint_t *protp,
3068*fa9e4066Sahrens 	page_t *pl[], size_t plsz, struct seg *seg, caddr_t addr,
3069*fa9e4066Sahrens 	enum seg_rw rw, cred_t *cr)
3070*fa9e4066Sahrens {
3071*fa9e4066Sahrens 	znode_t		*zp = VTOZ(vp);
3072*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
3073*fa9e4066Sahrens 	page_t		*pp, **pl0 = pl;
3074*fa9e4066Sahrens 	int		cnt = 0, need_unlock = 0, err = 0;
3075*fa9e4066Sahrens 
3076*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
3077*fa9e4066Sahrens 
3078*fa9e4066Sahrens 	if (protp)
3079*fa9e4066Sahrens 		*protp = PROT_ALL;
3080*fa9e4066Sahrens 
3081*fa9e4066Sahrens 	ASSERT(zp->z_dbuf_held && zp->z_phys);
3082*fa9e4066Sahrens 
3083*fa9e4066Sahrens 	/* no faultahead (for now) */
3084*fa9e4066Sahrens 	if (pl == NULL) {
3085*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
3086*fa9e4066Sahrens 		return (0);
3087*fa9e4066Sahrens 	}
3088*fa9e4066Sahrens 
3089*fa9e4066Sahrens 	/* can't fault past EOF */
3090*fa9e4066Sahrens 	if (off >= zp->z_phys->zp_size) {
3091*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
3092*fa9e4066Sahrens 		return (EFAULT);
3093*fa9e4066Sahrens 	}
3094*fa9e4066Sahrens 
3095*fa9e4066Sahrens 	/*
3096*fa9e4066Sahrens 	 * Make sure nobody restructures the file (changes block size)
3097*fa9e4066Sahrens 	 * in the middle of the getpage.
3098*fa9e4066Sahrens 	 */
3099*fa9e4066Sahrens 	rw_enter(&zp->z_grow_lock, RW_READER);
3100*fa9e4066Sahrens 
3101*fa9e4066Sahrens 	/*
3102*fa9e4066Sahrens 	 * If we already own the lock, then we must be page faulting
3103*fa9e4066Sahrens 	 * in the middle of a write to this file (i.e., we are writing
3104*fa9e4066Sahrens 	 * to this file using data from a mapped region of the file).
3105*fa9e4066Sahrens 	 */
3106*fa9e4066Sahrens 	if (!rw_owner(&zp->z_map_lock)) {
3107*fa9e4066Sahrens 		rw_enter(&zp->z_map_lock, RW_WRITER);
3108*fa9e4066Sahrens 		need_unlock = TRUE;
3109*fa9e4066Sahrens 	}
3110*fa9e4066Sahrens 
3111*fa9e4066Sahrens 	/*
3112*fa9e4066Sahrens 	 * Loop through the requested range [off, off + len] looking
3113*fa9e4066Sahrens 	 * for pages.  If we don't find a page, we will need to create
3114*fa9e4066Sahrens 	 * a new page and fill it with data from the file.
3115*fa9e4066Sahrens 	 */
3116*fa9e4066Sahrens 	while (len > 0) {
3117*fa9e4066Sahrens 		if (plsz < PAGESIZE)
3118*fa9e4066Sahrens 			break;
3119*fa9e4066Sahrens 		if (pp = page_lookup(vp, off, SE_SHARED)) {
3120*fa9e4066Sahrens 			*pl++ = pp;
3121*fa9e4066Sahrens 			off += PAGESIZE;
3122*fa9e4066Sahrens 			addr += PAGESIZE;
3123*fa9e4066Sahrens 			len -= PAGESIZE;
3124*fa9e4066Sahrens 			plsz -= PAGESIZE;
3125*fa9e4066Sahrens 		} else {
3126*fa9e4066Sahrens 			err = zfs_fillpage(vp, off, seg, addr, pl, plsz, rw);
3127*fa9e4066Sahrens 			/*
3128*fa9e4066Sahrens 			 * klustering may have changed our region
3129*fa9e4066Sahrens 			 * to be block aligned.
3130*fa9e4066Sahrens 			 */
3131*fa9e4066Sahrens 			if (((pp = *pl) != 0) && (off != pp->p_offset)) {
3132*fa9e4066Sahrens 				int delta = off - pp->p_offset;
3133*fa9e4066Sahrens 				len += delta;
3134*fa9e4066Sahrens 				off -= delta;
3135*fa9e4066Sahrens 				addr -= delta;
3136*fa9e4066Sahrens 			}
3137*fa9e4066Sahrens 			while (*pl) {
3138*fa9e4066Sahrens 				pl++;
3139*fa9e4066Sahrens 				cnt++;
3140*fa9e4066Sahrens 				off += PAGESIZE;
3141*fa9e4066Sahrens 				addr += PAGESIZE;
3142*fa9e4066Sahrens 				plsz -= PAGESIZE;
3143*fa9e4066Sahrens 				if (len > PAGESIZE)
3144*fa9e4066Sahrens 					len -= PAGESIZE;
3145*fa9e4066Sahrens 				else
3146*fa9e4066Sahrens 					len = 0;
3147*fa9e4066Sahrens 			}
3148*fa9e4066Sahrens 		}
3149*fa9e4066Sahrens 		if (err)
3150*fa9e4066Sahrens 			goto out;
3151*fa9e4066Sahrens 	}
3152*fa9e4066Sahrens 
3153*fa9e4066Sahrens 	/*
3154*fa9e4066Sahrens 	 * Fill out the page array with any pages already in the cache.
3155*fa9e4066Sahrens 	 */
3156*fa9e4066Sahrens 	while (plsz > 0) {
3157*fa9e4066Sahrens 		pp = page_lookup_nowait(vp, off, SE_SHARED);
3158*fa9e4066Sahrens 		if (pp == NULL)
3159*fa9e4066Sahrens 			break;
3160*fa9e4066Sahrens 		*pl++ = pp;
3161*fa9e4066Sahrens 		off += PAGESIZE;
3162*fa9e4066Sahrens 		plsz -= PAGESIZE;
3163*fa9e4066Sahrens 	}
3164*fa9e4066Sahrens 
3165*fa9e4066Sahrens 	ZFS_ACCESSTIME_STAMP(zfsvfs, zp);
3166*fa9e4066Sahrens out:
3167*fa9e4066Sahrens 	if (err) {
3168*fa9e4066Sahrens 		/*
3169*fa9e4066Sahrens 		 * Release any pages we have locked.
3170*fa9e4066Sahrens 		 */
3171*fa9e4066Sahrens 		while (pl > pl0)
3172*fa9e4066Sahrens 			page_unlock(*--pl);
3173*fa9e4066Sahrens 	}
3174*fa9e4066Sahrens 	*pl = NULL;
3175*fa9e4066Sahrens 
3176*fa9e4066Sahrens 	if (need_unlock)
3177*fa9e4066Sahrens 		rw_exit(&zp->z_map_lock);
3178*fa9e4066Sahrens 	rw_exit(&zp->z_grow_lock);
3179*fa9e4066Sahrens 
3180*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
3181*fa9e4066Sahrens 	return (err);
3182*fa9e4066Sahrens }
3183*fa9e4066Sahrens 
3184*fa9e4066Sahrens static int
3185*fa9e4066Sahrens zfs_map(vnode_t *vp, offset_t off, struct as *as, caddr_t *addrp,
3186*fa9e4066Sahrens     size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, cred_t *cr)
3187*fa9e4066Sahrens {
3188*fa9e4066Sahrens 	znode_t *zp = VTOZ(vp);
3189*fa9e4066Sahrens 	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
3190*fa9e4066Sahrens 	segvn_crargs_t	vn_a;
3191*fa9e4066Sahrens 	int		error;
3192*fa9e4066Sahrens 
3193*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
3194*fa9e4066Sahrens 
3195*fa9e4066Sahrens 	if (vp->v_flag & VNOMAP) {
3196*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
3197*fa9e4066Sahrens 		return (ENOSYS);
3198*fa9e4066Sahrens 	}
3199*fa9e4066Sahrens 
3200*fa9e4066Sahrens 	if (off < 0 || len > MAXOFFSET_T - off) {
3201*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
3202*fa9e4066Sahrens 		return (ENXIO);
3203*fa9e4066Sahrens 	}
3204*fa9e4066Sahrens 
3205*fa9e4066Sahrens 	if (vp->v_type != VREG) {
3206*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
3207*fa9e4066Sahrens 		return (ENODEV);
3208*fa9e4066Sahrens 	}
3209*fa9e4066Sahrens 
3210*fa9e4066Sahrens 	/*
3211*fa9e4066Sahrens 	 * If file is locked, disallow mapping.
3212*fa9e4066Sahrens 	 * XXX - since we don't modify z_mapcnt here, there is nothing
3213*fa9e4066Sahrens 	 * to stop a file lock being placed immediately after we complete
3214*fa9e4066Sahrens 	 * this check.
3215*fa9e4066Sahrens 	 */
3216*fa9e4066Sahrens 	if (MANDMODE((mode_t)zp->z_phys->zp_mode)) {
3217*fa9e4066Sahrens 		if (vn_has_flocks(vp) || zp->z_mapcnt == -1) {
3218*fa9e4066Sahrens 			ZFS_EXIT(zfsvfs);
3219*fa9e4066Sahrens 			return (EAGAIN);
3220*fa9e4066Sahrens 		}
3221*fa9e4066Sahrens 	}
3222*fa9e4066Sahrens 
3223*fa9e4066Sahrens 	as_rangelock(as);
3224*fa9e4066Sahrens 	if ((flags & MAP_FIXED) == 0) {
3225*fa9e4066Sahrens 		map_addr(addrp, len, off, 1, flags);
3226*fa9e4066Sahrens 		if (*addrp == NULL) {
3227*fa9e4066Sahrens 			as_rangeunlock(as);
3228*fa9e4066Sahrens 			ZFS_EXIT(zfsvfs);
3229*fa9e4066Sahrens 			return (ENOMEM);
3230*fa9e4066Sahrens 		}
3231*fa9e4066Sahrens 	} else {
3232*fa9e4066Sahrens 		/*
3233*fa9e4066Sahrens 		 * User specified address - blow away any previous mappings
3234*fa9e4066Sahrens 		 */
3235*fa9e4066Sahrens 		(void) as_unmap(as, *addrp, len);
3236*fa9e4066Sahrens 	}
3237*fa9e4066Sahrens 
3238*fa9e4066Sahrens 	vn_a.vp = vp;
3239*fa9e4066Sahrens 	vn_a.offset = (u_offset_t)off;
3240*fa9e4066Sahrens 	vn_a.type = flags & MAP_TYPE;
3241*fa9e4066Sahrens 	vn_a.prot = prot;
3242*fa9e4066Sahrens 	vn_a.maxprot = maxprot;
3243*fa9e4066Sahrens 	vn_a.cred = cr;
3244*fa9e4066Sahrens 	vn_a.amp = NULL;
3245*fa9e4066Sahrens 	vn_a.flags = flags & ~MAP_TYPE;
3246*fa9e4066Sahrens 
3247*fa9e4066Sahrens 	error = as_map(as, *addrp, len, segvn_create, &vn_a);
3248*fa9e4066Sahrens 
3249*fa9e4066Sahrens 	as_rangeunlock(as);
3250*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
3251*fa9e4066Sahrens 	return (error);
3252*fa9e4066Sahrens }
3253*fa9e4066Sahrens 
3254*fa9e4066Sahrens /* ARGSUSED */
3255*fa9e4066Sahrens static int
3256*fa9e4066Sahrens zfs_addmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr,
3257*fa9e4066Sahrens     size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, cred_t *cr)
3258*fa9e4066Sahrens {
3259*fa9e4066Sahrens 	/*
3260*fa9e4066Sahrens 	 * XXX - shouldn't we be checking for file locks here?
3261*fa9e4066Sahrens 	 */
3262*fa9e4066Sahrens 	ASSERT3U(VTOZ(vp)->z_mapcnt, >=, 0);
3263*fa9e4066Sahrens 	atomic_add_32(&VTOZ(vp)->z_mapcnt, btopr(len));
3264*fa9e4066Sahrens 	return (0);
3265*fa9e4066Sahrens }
3266*fa9e4066Sahrens 
3267*fa9e4066Sahrens /* ARGSUSED */
3268*fa9e4066Sahrens static int
3269*fa9e4066Sahrens zfs_delmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr,
3270*fa9e4066Sahrens     size_t len, uint_t prot, uint_t maxprot, uint_t flags, cred_t *cr)
3271*fa9e4066Sahrens {
3272*fa9e4066Sahrens 	atomic_add_32(&VTOZ(vp)->z_mapcnt, -btopr(len));
3273*fa9e4066Sahrens 	ASSERT3U(VTOZ(vp)->z_mapcnt, >=, 0);
3274*fa9e4066Sahrens 	return (0);
3275*fa9e4066Sahrens }
3276*fa9e4066Sahrens 
3277*fa9e4066Sahrens /*
3278*fa9e4066Sahrens  * Free or allocate space in a file.  Currently, this function only
3279*fa9e4066Sahrens  * supports the `F_FREESP' command.  However, this command is somewhat
3280*fa9e4066Sahrens  * misnamed, as its functionality includes the ability to allocate as
3281*fa9e4066Sahrens  * well as free space.
3282*fa9e4066Sahrens  *
3283*fa9e4066Sahrens  *	IN:	vp	- vnode of file to free data in.
3284*fa9e4066Sahrens  *		cmd	- action to take (only F_FREESP supported).
3285*fa9e4066Sahrens  *		bfp	- section of file to free/alloc.
3286*fa9e4066Sahrens  *		flag	- current file open mode flags.
3287*fa9e4066Sahrens  *		offset	- current file offset.
3288*fa9e4066Sahrens  *		cr	- credentials of caller [UNUSED].
3289*fa9e4066Sahrens  *
3290*fa9e4066Sahrens  *	RETURN:	0 if success
3291*fa9e4066Sahrens  *		error code if failure
3292*fa9e4066Sahrens  *
3293*fa9e4066Sahrens  * Timestamps:
3294*fa9e4066Sahrens  *	vp - ctime|mtime updated
3295*fa9e4066Sahrens  *
3296*fa9e4066Sahrens  * NOTE: This function is limited in that it will only permit space to
3297*fa9e4066Sahrens  *   be freed at the end of a file.  In essence, this function simply
3298*fa9e4066Sahrens  *   allows one to set the file size.
3299*fa9e4066Sahrens  */
3300*fa9e4066Sahrens /* ARGSUSED */
3301*fa9e4066Sahrens static int
3302*fa9e4066Sahrens zfs_space(vnode_t *vp, int cmd, flock64_t *bfp, int flag,
3303*fa9e4066Sahrens     offset_t offset, cred_t *cr, caller_context_t *ct)
3304*fa9e4066Sahrens {
3305*fa9e4066Sahrens 	dmu_tx_t	*tx;
3306*fa9e4066Sahrens 	znode_t		*zp = VTOZ(vp);
3307*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
3308*fa9e4066Sahrens 	zilog_t		*zilog = zfsvfs->z_log;
3309*fa9e4066Sahrens 	uint64_t	seq = 0;
3310*fa9e4066Sahrens 	uint64_t	off, len;
3311*fa9e4066Sahrens 	int		error;
3312*fa9e4066Sahrens 
3313*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
3314*fa9e4066Sahrens 
3315*fa9e4066Sahrens top:
3316*fa9e4066Sahrens 	if (cmd != F_FREESP) {
3317*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
3318*fa9e4066Sahrens 		return (EINVAL);
3319*fa9e4066Sahrens 	}
3320*fa9e4066Sahrens 
3321*fa9e4066Sahrens 	if (error = convoff(vp, bfp, 0, offset)) {
3322*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
3323*fa9e4066Sahrens 		return (error);
3324*fa9e4066Sahrens 	}
3325*fa9e4066Sahrens 
3326*fa9e4066Sahrens 	if (bfp->l_len < 0) {
3327*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
3328*fa9e4066Sahrens 		return (EINVAL);
3329*fa9e4066Sahrens 	}
3330*fa9e4066Sahrens 
3331*fa9e4066Sahrens 	off = bfp->l_start;
3332*fa9e4066Sahrens 	len = bfp->l_len;
3333*fa9e4066Sahrens 	tx = dmu_tx_create(zfsvfs->z_os);
3334*fa9e4066Sahrens 	/*
3335*fa9e4066Sahrens 	 * Grab the grow_lock to serialize this change with
3336*fa9e4066Sahrens 	 * respect to other file size changes.
3337*fa9e4066Sahrens 	 */
3338*fa9e4066Sahrens 	dmu_tx_hold_bonus(tx, zp->z_id);
3339*fa9e4066Sahrens 	rw_enter(&zp->z_grow_lock, RW_WRITER);
3340*fa9e4066Sahrens 	if (off + len > zp->z_blksz && zp->z_blksz < zfsvfs->z_max_blksz &&
3341*fa9e4066Sahrens 	    off >= zp->z_phys->zp_size) {
3342*fa9e4066Sahrens 		/*
3343*fa9e4066Sahrens 		 * We are increasing the length of the file,
3344*fa9e4066Sahrens 		 * and this may mean a block size increase.
3345*fa9e4066Sahrens 		 */
3346*fa9e4066Sahrens 		dmu_tx_hold_write(tx, zp->z_id, 0,
3347*fa9e4066Sahrens 		    MIN(off + len, zfsvfs->z_max_blksz));
3348*fa9e4066Sahrens 	} else if (off < zp->z_phys->zp_size) {
3349*fa9e4066Sahrens 		/*
3350*fa9e4066Sahrens 		 * If len == 0, we are truncating the file.
3351*fa9e4066Sahrens 		 */
3352*fa9e4066Sahrens 		dmu_tx_hold_free(tx, zp->z_id, off, len ? len : DMU_OBJECT_END);
3353*fa9e4066Sahrens 	}
3354*fa9e4066Sahrens 
3355*fa9e4066Sahrens 	error = dmu_tx_assign(tx, zfsvfs->z_assign);
3356*fa9e4066Sahrens 	if (error) {
3357*fa9e4066Sahrens 		dmu_tx_abort(tx);
3358*fa9e4066Sahrens 		rw_exit(&zp->z_grow_lock);
3359*fa9e4066Sahrens 		if (error == ERESTART && zfsvfs->z_assign == TXG_NOWAIT) {
3360*fa9e4066Sahrens 			txg_wait_open(dmu_objset_pool(zfsvfs->z_os), 0);
3361*fa9e4066Sahrens 			goto top;
3362*fa9e4066Sahrens 		}
3363*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
3364*fa9e4066Sahrens 		return (error);
3365*fa9e4066Sahrens 	}
3366*fa9e4066Sahrens 
3367*fa9e4066Sahrens 	error = zfs_freesp(zp, off, len, flag, tx, cr);
3368*fa9e4066Sahrens 
3369*fa9e4066Sahrens 	if (error == 0) {
3370*fa9e4066Sahrens 		zfs_time_stamper(zp, CONTENT_MODIFIED, tx);
3371*fa9e4066Sahrens 		seq = zfs_log_truncate(zilog, tx, TX_TRUNCATE, zp, off, len);
3372*fa9e4066Sahrens 	}
3373*fa9e4066Sahrens 
3374*fa9e4066Sahrens 	rw_exit(&zp->z_grow_lock);
3375*fa9e4066Sahrens 
3376*fa9e4066Sahrens 	dmu_tx_commit(tx);
3377*fa9e4066Sahrens 
3378*fa9e4066Sahrens 	zil_commit(zilog, seq, 0);
3379*fa9e4066Sahrens 
3380*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
3381*fa9e4066Sahrens 	return (error);
3382*fa9e4066Sahrens }
3383*fa9e4066Sahrens 
3384*fa9e4066Sahrens static int
3385*fa9e4066Sahrens zfs_fid(vnode_t *vp, fid_t *fidp)
3386*fa9e4066Sahrens {
3387*fa9e4066Sahrens 	znode_t		*zp = VTOZ(vp);
3388*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs = zp->z_zfsvfs;
3389*fa9e4066Sahrens 	uint32_t	gen = (uint32_t)zp->z_phys->zp_gen;
3390*fa9e4066Sahrens 	uint64_t	object = zp->z_id;
3391*fa9e4066Sahrens 	zfid_short_t	*zfid;
3392*fa9e4066Sahrens 	int		size, i;
3393*fa9e4066Sahrens 
3394*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
3395*fa9e4066Sahrens 
3396*fa9e4066Sahrens 	size = (zfsvfs->z_parent != zfsvfs) ? LONG_FID_LEN : SHORT_FID_LEN;
3397*fa9e4066Sahrens 	if (fidp->fid_len < size) {
3398*fa9e4066Sahrens 		fidp->fid_len = size;
3399*fa9e4066Sahrens 		return (ENOSPC);
3400*fa9e4066Sahrens 	}
3401*fa9e4066Sahrens 
3402*fa9e4066Sahrens 	zfid = (zfid_short_t *)fidp;
3403*fa9e4066Sahrens 
3404*fa9e4066Sahrens 	zfid->zf_len = size;
3405*fa9e4066Sahrens 
3406*fa9e4066Sahrens 	for (i = 0; i < sizeof (zfid->zf_object); i++)
3407*fa9e4066Sahrens 		zfid->zf_object[i] = (uint8_t)(object >> (8 * i));
3408*fa9e4066Sahrens 
3409*fa9e4066Sahrens 	/* Must have a non-zero generation number to distinguish from .zfs */
3410*fa9e4066Sahrens 	if (gen == 0)
3411*fa9e4066Sahrens 		gen = 1;
3412*fa9e4066Sahrens 	for (i = 0; i < sizeof (zfid->zf_gen); i++)
3413*fa9e4066Sahrens 		zfid->zf_gen[i] = (uint8_t)(gen >> (8 * i));
3414*fa9e4066Sahrens 
3415*fa9e4066Sahrens 	if (size == LONG_FID_LEN) {
3416*fa9e4066Sahrens 		uint64_t	objsetid = dmu_objset_id(zfsvfs->z_os);
3417*fa9e4066Sahrens 		zfid_long_t	*zlfid;
3418*fa9e4066Sahrens 
3419*fa9e4066Sahrens 		zlfid = (zfid_long_t *)fidp;
3420*fa9e4066Sahrens 
3421*fa9e4066Sahrens 		for (i = 0; i < sizeof (zlfid->zf_setid); i++)
3422*fa9e4066Sahrens 			zlfid->zf_setid[i] = (uint8_t)(objsetid >> (8 * i));
3423*fa9e4066Sahrens 
3424*fa9e4066Sahrens 		/* XXX - this should be the generation number for the objset */
3425*fa9e4066Sahrens 		for (i = 0; i < sizeof (zlfid->zf_setgen); i++)
3426*fa9e4066Sahrens 			zlfid->zf_setgen[i] = 0;
3427*fa9e4066Sahrens 	}
3428*fa9e4066Sahrens 
3429*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
3430*fa9e4066Sahrens 	return (0);
3431*fa9e4066Sahrens }
3432*fa9e4066Sahrens 
3433*fa9e4066Sahrens static int
3434*fa9e4066Sahrens zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr)
3435*fa9e4066Sahrens {
3436*fa9e4066Sahrens 	znode_t		*zp, *xzp;
3437*fa9e4066Sahrens 	zfsvfs_t	*zfsvfs;
3438*fa9e4066Sahrens 	zfs_dirlock_t	*dl;
3439*fa9e4066Sahrens 	int		error;
3440*fa9e4066Sahrens 
3441*fa9e4066Sahrens 	switch (cmd) {
3442*fa9e4066Sahrens 	case _PC_LINK_MAX:
3443*fa9e4066Sahrens 		*valp = ULONG_MAX;
3444*fa9e4066Sahrens 		return (0);
3445*fa9e4066Sahrens 
3446*fa9e4066Sahrens 	case _PC_FILESIZEBITS:
3447*fa9e4066Sahrens 		*valp = 64;
3448*fa9e4066Sahrens 		return (0);
3449*fa9e4066Sahrens 
3450*fa9e4066Sahrens 	case _PC_XATTR_EXISTS:
3451*fa9e4066Sahrens 		zp = VTOZ(vp);
3452*fa9e4066Sahrens 		zfsvfs = zp->z_zfsvfs;
3453*fa9e4066Sahrens 		ZFS_ENTER(zfsvfs);
3454*fa9e4066Sahrens 		*valp = 0;
3455*fa9e4066Sahrens 		error = zfs_dirent_lock(&dl, zp, "", &xzp,
3456*fa9e4066Sahrens 		    ZXATTR | ZEXISTS | ZSHARED);
3457*fa9e4066Sahrens 		if (error == 0) {
3458*fa9e4066Sahrens 			zfs_dirent_unlock(dl);
3459*fa9e4066Sahrens 			if (!zfs_dirempty(xzp))
3460*fa9e4066Sahrens 				*valp = 1;
3461*fa9e4066Sahrens 			VN_RELE(ZTOV(xzp));
3462*fa9e4066Sahrens 		} else if (error == ENOENT) {
3463*fa9e4066Sahrens 			/*
3464*fa9e4066Sahrens 			 * If there aren't extended attributes, it's the
3465*fa9e4066Sahrens 			 * same as having zero of them.
3466*fa9e4066Sahrens 			 */
3467*fa9e4066Sahrens 			error = 0;
3468*fa9e4066Sahrens 		}
3469*fa9e4066Sahrens 		ZFS_EXIT(zfsvfs);
3470*fa9e4066Sahrens 		return (error);
3471*fa9e4066Sahrens 
3472*fa9e4066Sahrens 	case _PC_ACL_ENABLED:
3473*fa9e4066Sahrens 		*valp = _ACL_ACE_ENABLED;
3474*fa9e4066Sahrens 		return (0);
3475*fa9e4066Sahrens 
3476*fa9e4066Sahrens 	case _PC_MIN_HOLE_SIZE:
3477*fa9e4066Sahrens 		*valp = (ulong_t)SPA_MINBLOCKSIZE;
3478*fa9e4066Sahrens 		return (0);
3479*fa9e4066Sahrens 
3480*fa9e4066Sahrens 	default:
3481*fa9e4066Sahrens 		return (fs_pathconf(vp, cmd, valp, cr));
3482*fa9e4066Sahrens 	}
3483*fa9e4066Sahrens }
3484*fa9e4066Sahrens 
3485*fa9e4066Sahrens /*ARGSUSED*/
3486*fa9e4066Sahrens static int
3487*fa9e4066Sahrens zfs_getsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr)
3488*fa9e4066Sahrens {
3489*fa9e4066Sahrens 	znode_t *zp = VTOZ(vp);
3490*fa9e4066Sahrens 	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
3491*fa9e4066Sahrens 	int error;
3492*fa9e4066Sahrens 
3493*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
3494*fa9e4066Sahrens 	error = zfs_getacl(zp, vsecp, cr);
3495*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
3496*fa9e4066Sahrens 
3497*fa9e4066Sahrens 	return (error);
3498*fa9e4066Sahrens }
3499*fa9e4066Sahrens 
3500*fa9e4066Sahrens /*ARGSUSED*/
3501*fa9e4066Sahrens static int
3502*fa9e4066Sahrens zfs_setsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr)
3503*fa9e4066Sahrens {
3504*fa9e4066Sahrens 	znode_t *zp = VTOZ(vp);
3505*fa9e4066Sahrens 	zfsvfs_t *zfsvfs = zp->z_zfsvfs;
3506*fa9e4066Sahrens 	int error;
3507*fa9e4066Sahrens 
3508*fa9e4066Sahrens 	ZFS_ENTER(zfsvfs);
3509*fa9e4066Sahrens 	error = zfs_setacl(zp, vsecp, cr);
3510*fa9e4066Sahrens 	ZFS_EXIT(zfsvfs);
3511*fa9e4066Sahrens 	return (error);
3512*fa9e4066Sahrens }
3513*fa9e4066Sahrens 
3514*fa9e4066Sahrens /*
3515*fa9e4066Sahrens  * Predeclare these here so that the compiler assumes that
3516*fa9e4066Sahrens  * this is an "old style" function declaration that does
3517*fa9e4066Sahrens  * not include arguments => we won't get type mismatch errors
3518*fa9e4066Sahrens  * in the initializations that follow.
3519*fa9e4066Sahrens  */
3520*fa9e4066Sahrens static int zfs_inval();
3521*fa9e4066Sahrens static int zfs_isdir();
3522*fa9e4066Sahrens 
3523*fa9e4066Sahrens static int
3524*fa9e4066Sahrens zfs_inval()
3525*fa9e4066Sahrens {
3526*fa9e4066Sahrens 	return (EINVAL);
3527*fa9e4066Sahrens }
3528*fa9e4066Sahrens 
3529*fa9e4066Sahrens static int
3530*fa9e4066Sahrens zfs_isdir()
3531*fa9e4066Sahrens {
3532*fa9e4066Sahrens 	return (EISDIR);
3533*fa9e4066Sahrens }
3534*fa9e4066Sahrens /*
3535*fa9e4066Sahrens  * Directory vnode operations template
3536*fa9e4066Sahrens  */
3537*fa9e4066Sahrens vnodeops_t *zfs_dvnodeops;
3538*fa9e4066Sahrens const fs_operation_def_t zfs_dvnodeops_template[] = {
3539*fa9e4066Sahrens 	VOPNAME_OPEN, zfs_open,
3540*fa9e4066Sahrens 	VOPNAME_CLOSE, zfs_close,
3541*fa9e4066Sahrens 	VOPNAME_READ, zfs_isdir,
3542*fa9e4066Sahrens 	VOPNAME_WRITE, zfs_isdir,
3543*fa9e4066Sahrens 	VOPNAME_IOCTL, zfs_ioctl,
3544*fa9e4066Sahrens 	VOPNAME_GETATTR, zfs_getattr,
3545*fa9e4066Sahrens 	VOPNAME_SETATTR, zfs_setattr,
3546*fa9e4066Sahrens 	VOPNAME_ACCESS, zfs_access,
3547*fa9e4066Sahrens 	VOPNAME_LOOKUP, zfs_lookup,
3548*fa9e4066Sahrens 	VOPNAME_CREATE, zfs_create,
3549*fa9e4066Sahrens 	VOPNAME_REMOVE, zfs_remove,
3550*fa9e4066Sahrens 	VOPNAME_LINK, zfs_link,
3551*fa9e4066Sahrens 	VOPNAME_RENAME, zfs_rename,
3552*fa9e4066Sahrens 	VOPNAME_MKDIR, zfs_mkdir,
3553*fa9e4066Sahrens 	VOPNAME_RMDIR, zfs_rmdir,
3554*fa9e4066Sahrens 	VOPNAME_READDIR, zfs_readdir,
3555*fa9e4066Sahrens 	VOPNAME_SYMLINK, zfs_symlink,
3556*fa9e4066Sahrens 	VOPNAME_FSYNC, zfs_fsync,
3557*fa9e4066Sahrens 	VOPNAME_INACTIVE, (fs_generic_func_p) zfs_inactive,
3558*fa9e4066Sahrens 	VOPNAME_FID, zfs_fid,
3559*fa9e4066Sahrens 	VOPNAME_SEEK, zfs_seek,
3560*fa9e4066Sahrens 	VOPNAME_PATHCONF, zfs_pathconf,
3561*fa9e4066Sahrens 	VOPNAME_GETSECATTR, zfs_getsecattr,
3562*fa9e4066Sahrens 	VOPNAME_SETSECATTR, zfs_setsecattr,
3563*fa9e4066Sahrens 	NULL, NULL
3564*fa9e4066Sahrens };
3565*fa9e4066Sahrens 
3566*fa9e4066Sahrens /*
3567*fa9e4066Sahrens  * Regular file vnode operations template
3568*fa9e4066Sahrens  */
3569*fa9e4066Sahrens vnodeops_t *zfs_fvnodeops;
3570*fa9e4066Sahrens const fs_operation_def_t zfs_fvnodeops_template[] = {
3571*fa9e4066Sahrens 	VOPNAME_OPEN, zfs_open,
3572*fa9e4066Sahrens 	VOPNAME_CLOSE, zfs_close,
3573*fa9e4066Sahrens 	VOPNAME_READ, zfs_read,
3574*fa9e4066Sahrens 	VOPNAME_WRITE, zfs_write,
3575*fa9e4066Sahrens 	VOPNAME_IOCTL, zfs_ioctl,
3576*fa9e4066Sahrens 	VOPNAME_GETATTR, zfs_getattr,
3577*fa9e4066Sahrens 	VOPNAME_SETATTR, zfs_setattr,
3578*fa9e4066Sahrens 	VOPNAME_ACCESS, zfs_access,
3579*fa9e4066Sahrens 	VOPNAME_LOOKUP, zfs_lookup,
3580*fa9e4066Sahrens 	VOPNAME_RENAME, zfs_rename,
3581*fa9e4066Sahrens 	VOPNAME_FSYNC, zfs_fsync,
3582*fa9e4066Sahrens 	VOPNAME_INACTIVE, (fs_generic_func_p)zfs_inactive,
3583*fa9e4066Sahrens 	VOPNAME_FID, zfs_fid,
3584*fa9e4066Sahrens 	VOPNAME_SEEK, zfs_seek,
3585*fa9e4066Sahrens 	VOPNAME_FRLOCK, zfs_frlock,
3586*fa9e4066Sahrens 	VOPNAME_SPACE, zfs_space,
3587*fa9e4066Sahrens 	VOPNAME_GETPAGE, zfs_getpage,
3588*fa9e4066Sahrens 	VOPNAME_PUTPAGE, zfs_putpage,
3589*fa9e4066Sahrens 	VOPNAME_MAP, (fs_generic_func_p) zfs_map,
3590*fa9e4066Sahrens 	VOPNAME_ADDMAP, (fs_generic_func_p) zfs_addmap,
3591*fa9e4066Sahrens 	VOPNAME_DELMAP, zfs_delmap,
3592*fa9e4066Sahrens 	VOPNAME_PATHCONF, zfs_pathconf,
3593*fa9e4066Sahrens 	VOPNAME_GETSECATTR, zfs_getsecattr,
3594*fa9e4066Sahrens 	VOPNAME_SETSECATTR, zfs_setsecattr,
3595*fa9e4066Sahrens 	VOPNAME_VNEVENT, fs_vnevent_support,
3596*fa9e4066Sahrens 	NULL, NULL
3597*fa9e4066Sahrens };
3598*fa9e4066Sahrens 
3599*fa9e4066Sahrens /*
3600*fa9e4066Sahrens  * Symbolic link vnode operations template
3601*fa9e4066Sahrens  */
3602*fa9e4066Sahrens vnodeops_t *zfs_symvnodeops;
3603*fa9e4066Sahrens const fs_operation_def_t zfs_symvnodeops_template[] = {
3604*fa9e4066Sahrens 	VOPNAME_GETATTR, zfs_getattr,
3605*fa9e4066Sahrens 	VOPNAME_SETATTR, zfs_setattr,
3606*fa9e4066Sahrens 	VOPNAME_ACCESS, zfs_access,
3607*fa9e4066Sahrens 	VOPNAME_RENAME, zfs_rename,
3608*fa9e4066Sahrens 	VOPNAME_READLINK, zfs_readlink,
3609*fa9e4066Sahrens 	VOPNAME_INACTIVE, (fs_generic_func_p) zfs_inactive,
3610*fa9e4066Sahrens 	VOPNAME_FID, zfs_fid,
3611*fa9e4066Sahrens 	VOPNAME_PATHCONF, zfs_pathconf,
3612*fa9e4066Sahrens 	VOPNAME_VNEVENT, fs_vnevent_support,
3613*fa9e4066Sahrens 	NULL, NULL
3614*fa9e4066Sahrens };
3615*fa9e4066Sahrens 
3616*fa9e4066Sahrens /*
3617*fa9e4066Sahrens  * Extended attribute directory vnode operations template
3618*fa9e4066Sahrens  *	This template is identical to the directory vnodes
3619*fa9e4066Sahrens  *	operation template except for restricted operations:
3620*fa9e4066Sahrens  *		VOP_MKDIR()
3621*fa9e4066Sahrens  *		VOP_SYMLINK()
3622*fa9e4066Sahrens  * Note that there are other restrictions embedded in:
3623*fa9e4066Sahrens  *	zfs_create()	- restrict type to VREG
3624*fa9e4066Sahrens  *	zfs_link()	- no links into/out of attribute space
3625*fa9e4066Sahrens  *	zfs_rename()	- no moves into/out of attribute space
3626*fa9e4066Sahrens  */
3627*fa9e4066Sahrens vnodeops_t *zfs_xdvnodeops;
3628*fa9e4066Sahrens const fs_operation_def_t zfs_xdvnodeops_template[] = {
3629*fa9e4066Sahrens 	VOPNAME_OPEN, zfs_open,
3630*fa9e4066Sahrens 	VOPNAME_CLOSE, zfs_close,
3631*fa9e4066Sahrens 	VOPNAME_IOCTL, zfs_ioctl,
3632*fa9e4066Sahrens 	VOPNAME_GETATTR, zfs_getattr,
3633*fa9e4066Sahrens 	VOPNAME_SETATTR, zfs_setattr,
3634*fa9e4066Sahrens 	VOPNAME_ACCESS, zfs_access,
3635*fa9e4066Sahrens 	VOPNAME_LOOKUP, zfs_lookup,
3636*fa9e4066Sahrens 	VOPNAME_CREATE, zfs_create,
3637*fa9e4066Sahrens 	VOPNAME_REMOVE, zfs_remove,
3638*fa9e4066Sahrens 	VOPNAME_LINK, zfs_link,
3639*fa9e4066Sahrens 	VOPNAME_RENAME, zfs_rename,
3640*fa9e4066Sahrens 	VOPNAME_MKDIR, zfs_inval,
3641*fa9e4066Sahrens 	VOPNAME_RMDIR, zfs_rmdir,
3642*fa9e4066Sahrens 	VOPNAME_READDIR, zfs_readdir,
3643*fa9e4066Sahrens 	VOPNAME_SYMLINK, zfs_inval,
3644*fa9e4066Sahrens 	VOPNAME_FSYNC, zfs_fsync,
3645*fa9e4066Sahrens 	VOPNAME_INACTIVE, (fs_generic_func_p) zfs_inactive,
3646*fa9e4066Sahrens 	VOPNAME_FID, zfs_fid,
3647*fa9e4066Sahrens 	VOPNAME_SEEK, zfs_seek,
3648*fa9e4066Sahrens 	VOPNAME_PATHCONF, zfs_pathconf,
3649*fa9e4066Sahrens 	VOPNAME_GETSECATTR, zfs_getsecattr,
3650*fa9e4066Sahrens 	VOPNAME_SETSECATTR, zfs_setsecattr,
3651*fa9e4066Sahrens 	VOPNAME_VNEVENT, fs_vnevent_support,
3652*fa9e4066Sahrens 	NULL, NULL
3653*fa9e4066Sahrens };
3654*fa9e4066Sahrens 
3655*fa9e4066Sahrens /*
3656*fa9e4066Sahrens  * Error vnode operations template
3657*fa9e4066Sahrens  */
3658*fa9e4066Sahrens vnodeops_t *zfs_evnodeops;
3659*fa9e4066Sahrens const fs_operation_def_t zfs_evnodeops_template[] = {
3660*fa9e4066Sahrens 	VOPNAME_INACTIVE, (fs_generic_func_p) zfs_inactive,
3661*fa9e4066Sahrens 	VOPNAME_PATHCONF, zfs_pathconf,
3662*fa9e4066Sahrens 	NULL, NULL
3663*fa9e4066Sahrens };
3664