xref: /titanic_44/usr/src/lib/smbsrv/libfksmbsrv/common/fake_vop.c (revision b819cea2f73f98c5662230cc9affc8cc84f77fcf)
1*b819cea2SGordon Ross /*
2*b819cea2SGordon Ross  * This file and its contents are supplied under the terms of the
3*b819cea2SGordon Ross  * Common Development and Distribution License ("CDDL"), version 1.0.
4*b819cea2SGordon Ross  * You may only use this file in accordance with the terms of version
5*b819cea2SGordon Ross  * 1.0 of the CDDL.
6*b819cea2SGordon Ross  *
7*b819cea2SGordon Ross  * A full copy of the text of the CDDL should have accompanied this
8*b819cea2SGordon Ross  * source.  A copy of the CDDL is also available via the Internet at
9*b819cea2SGordon Ross  * http://www.illumos.org/license/CDDL.
10*b819cea2SGordon Ross  */
11*b819cea2SGordon Ross 
12*b819cea2SGordon Ross /*
13*b819cea2SGordon Ross  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
14*b819cea2SGordon Ross  */
15*b819cea2SGordon Ross 
16*b819cea2SGordon Ross #include <sys/types.h>
17*b819cea2SGordon Ross #include <sys/param.h>
18*b819cea2SGordon Ross #include <sys/t_lock.h>
19*b819cea2SGordon Ross #include <sys/errno.h>
20*b819cea2SGordon Ross #include <sys/cred.h>
21*b819cea2SGordon Ross #include <sys/user.h>
22*b819cea2SGordon Ross #include <sys/uio.h>
23*b819cea2SGordon Ross #include <sys/file.h>
24*b819cea2SGordon Ross #include <sys/pathname.h>
25*b819cea2SGordon Ross #include <sys/vfs.h>
26*b819cea2SGordon Ross #include <sys/vnode.h>
27*b819cea2SGordon Ross #include <sys/stat.h>
28*b819cea2SGordon Ross #include <sys/mode.h>
29*b819cea2SGordon Ross #include <sys/kmem.h>
30*b819cea2SGordon Ross #include <sys/debug.h>
31*b819cea2SGordon Ross #include <sys/atomic.h>
32*b819cea2SGordon Ross #include <sys/acl.h>
33*b819cea2SGordon Ross #include <sys/flock.h>
34*b819cea2SGordon Ross #include <sys/nbmlock.h>
35*b819cea2SGordon Ross #include <sys/fcntl.h>
36*b819cea2SGordon Ross #include <sys/poll.h>
37*b819cea2SGordon Ross #include <sys/time.h>
38*b819cea2SGordon Ross 
39*b819cea2SGordon Ross #include <errno.h>
40*b819cea2SGordon Ross #include <fcntl.h>
41*b819cea2SGordon Ross #include <unistd.h>
42*b819cea2SGordon Ross 
43*b819cea2SGordon Ross #include "vncache.h"
44*b819cea2SGordon Ross 
45*b819cea2SGordon Ross #define	O_RWMASK	(O_WRONLY | O_RDWR) /* == 3 */
46*b819cea2SGordon Ross 
47*b819cea2SGordon Ross int fop_shrlock_enable = 0;
48*b819cea2SGordon Ross 
49*b819cea2SGordon Ross int stat_to_vattr(const struct stat *, vattr_t *);
50*b819cea2SGordon Ross int fop__getxvattr(vnode_t *, xvattr_t *);
51*b819cea2SGordon Ross int fop__setxvattr(vnode_t *, xvattr_t *);
52*b819cea2SGordon Ross 
53*b819cea2SGordon Ross 
54*b819cea2SGordon Ross /* ARGSUSED */
55*b819cea2SGordon Ross int
fop_open(vnode_t ** vpp,int mode,cred_t * cr,caller_context_t * ct)56*b819cea2SGordon Ross fop_open(
57*b819cea2SGordon Ross 	vnode_t **vpp,
58*b819cea2SGordon Ross 	int mode,
59*b819cea2SGordon Ross 	cred_t *cr,
60*b819cea2SGordon Ross 	caller_context_t *ct)
61*b819cea2SGordon Ross {
62*b819cea2SGordon Ross 
63*b819cea2SGordon Ross 	if ((*vpp)->v_type == VREG) {
64*b819cea2SGordon Ross 		if (mode & FREAD)
65*b819cea2SGordon Ross 			atomic_add_32(&((*vpp)->v_rdcnt), 1);
66*b819cea2SGordon Ross 		if (mode & FWRITE)
67*b819cea2SGordon Ross 			atomic_add_32(&((*vpp)->v_wrcnt), 1);
68*b819cea2SGordon Ross 	}
69*b819cea2SGordon Ross 
70*b819cea2SGordon Ross 	/* call to ->vop_open was here */
71*b819cea2SGordon Ross 
72*b819cea2SGordon Ross 	return (0);
73*b819cea2SGordon Ross }
74*b819cea2SGordon Ross 
75*b819cea2SGordon Ross /* ARGSUSED */
76*b819cea2SGordon Ross int
fop_close(vnode_t * vp,int flag,int count,offset_t offset,cred_t * cr,caller_context_t * ct)77*b819cea2SGordon Ross fop_close(
78*b819cea2SGordon Ross 	vnode_t *vp,
79*b819cea2SGordon Ross 	int flag,
80*b819cea2SGordon Ross 	int count,
81*b819cea2SGordon Ross 	offset_t offset,
82*b819cea2SGordon Ross 	cred_t *cr,
83*b819cea2SGordon Ross 	caller_context_t *ct)
84*b819cea2SGordon Ross {
85*b819cea2SGordon Ross 
86*b819cea2SGordon Ross 	/* call to ->vop_close was here */
87*b819cea2SGordon Ross 
88*b819cea2SGordon Ross 	/*
89*b819cea2SGordon Ross 	 * Check passed in count to handle possible dups. Vnode counts are only
90*b819cea2SGordon Ross 	 * kept on regular files
91*b819cea2SGordon Ross 	 */
92*b819cea2SGordon Ross 	if ((vp->v_type == VREG) && (count == 1))  {
93*b819cea2SGordon Ross 		if (flag & FREAD) {
94*b819cea2SGordon Ross 			ASSERT(vp->v_rdcnt > 0);
95*b819cea2SGordon Ross 			atomic_add_32(&(vp->v_rdcnt), -1);
96*b819cea2SGordon Ross 		}
97*b819cea2SGordon Ross 		if (flag & FWRITE) {
98*b819cea2SGordon Ross 			ASSERT(vp->v_wrcnt > 0);
99*b819cea2SGordon Ross 			atomic_add_32(&(vp->v_wrcnt), -1);
100*b819cea2SGordon Ross 		}
101*b819cea2SGordon Ross 	}
102*b819cea2SGordon Ross 	return (0);
103*b819cea2SGordon Ross }
104*b819cea2SGordon Ross 
105*b819cea2SGordon Ross /* ARGSUSED */
106*b819cea2SGordon Ross int
fop_read(vnode_t * vp,uio_t * uio,int ioflag,cred_t * cr,caller_context_t * ct)107*b819cea2SGordon Ross fop_read(
108*b819cea2SGordon Ross 	vnode_t *vp,
109*b819cea2SGordon Ross 	uio_t *uio,
110*b819cea2SGordon Ross 	int ioflag,
111*b819cea2SGordon Ross 	cred_t *cr,
112*b819cea2SGordon Ross 	caller_context_t *ct)
113*b819cea2SGordon Ross {
114*b819cea2SGordon Ross 	struct stat st;
115*b819cea2SGordon Ross 	struct iovec *iov;
116*b819cea2SGordon Ross 	ssize_t resid;
117*b819cea2SGordon Ross 	size_t cnt;
118*b819cea2SGordon Ross 	int n;
119*b819cea2SGordon Ross 
120*b819cea2SGordon Ross 	/*
121*b819cea2SGordon Ross 	 * If that caller asks for read beyond end of file,
122*b819cea2SGordon Ross 	 * that causes the pread call to block.  (Ugh!)
123*b819cea2SGordon Ross 	 * Get the file size and return what we can.
124*b819cea2SGordon Ross 	 */
125*b819cea2SGordon Ross 	(void) fstat(vp->v_fd, &st);
126*b819cea2SGordon Ross 	resid = uio->uio_resid;
127*b819cea2SGordon Ross 	if ((uio->uio_loffset + resid) > st.st_size)
128*b819cea2SGordon Ross 		resid = st.st_size - uio->uio_loffset;
129*b819cea2SGordon Ross 
130*b819cea2SGordon Ross 	while (resid > 0) {
131*b819cea2SGordon Ross 
132*b819cea2SGordon Ross 		ASSERT(uio->uio_iovcnt > 0);
133*b819cea2SGordon Ross 		iov = uio->uio_iov;
134*b819cea2SGordon Ross 
135*b819cea2SGordon Ross 		if (iov->iov_len == 0) {
136*b819cea2SGordon Ross 			uio->uio_iov++;
137*b819cea2SGordon Ross 			uio->uio_iovcnt--;
138*b819cea2SGordon Ross 			continue;
139*b819cea2SGordon Ross 		}
140*b819cea2SGordon Ross 		cnt = iov->iov_len;
141*b819cea2SGordon Ross 		if (cnt > resid)
142*b819cea2SGordon Ross 			cnt = resid;
143*b819cea2SGordon Ross 
144*b819cea2SGordon Ross 		n = pread(vp->v_fd, iov->iov_base, cnt, uio->uio_loffset);
145*b819cea2SGordon Ross 		if (n < 0)
146*b819cea2SGordon Ross 			return (errno);
147*b819cea2SGordon Ross 
148*b819cea2SGordon Ross 		iov->iov_base += n;
149*b819cea2SGordon Ross 		iov->iov_len -= n;
150*b819cea2SGordon Ross 
151*b819cea2SGordon Ross 		uio->uio_resid -= n;
152*b819cea2SGordon Ross 		uio->uio_loffset += n;
153*b819cea2SGordon Ross 
154*b819cea2SGordon Ross 		resid -= n;
155*b819cea2SGordon Ross 	}
156*b819cea2SGordon Ross 
157*b819cea2SGordon Ross 	return (0);
158*b819cea2SGordon Ross }
159*b819cea2SGordon Ross 
160*b819cea2SGordon Ross /* ARGSUSED */
161*b819cea2SGordon Ross int
fop_write(vnode_t * vp,uio_t * uio,int ioflag,cred_t * cr,caller_context_t * ct)162*b819cea2SGordon Ross fop_write(
163*b819cea2SGordon Ross 	vnode_t *vp,
164*b819cea2SGordon Ross 	uio_t *uio,
165*b819cea2SGordon Ross 	int ioflag,
166*b819cea2SGordon Ross 	cred_t *cr,
167*b819cea2SGordon Ross 	caller_context_t *ct)
168*b819cea2SGordon Ross {
169*b819cea2SGordon Ross 	struct iovec *iov;
170*b819cea2SGordon Ross 	size_t cnt;
171*b819cea2SGordon Ross 	int n;
172*b819cea2SGordon Ross 
173*b819cea2SGordon Ross 	while (uio->uio_resid > 0) {
174*b819cea2SGordon Ross 
175*b819cea2SGordon Ross 		ASSERT(uio->uio_iovcnt > 0);
176*b819cea2SGordon Ross 		iov = uio->uio_iov;
177*b819cea2SGordon Ross 
178*b819cea2SGordon Ross 		if (iov->iov_len == 0) {
179*b819cea2SGordon Ross 			uio->uio_iov++;
180*b819cea2SGordon Ross 			uio->uio_iovcnt--;
181*b819cea2SGordon Ross 			continue;
182*b819cea2SGordon Ross 		}
183*b819cea2SGordon Ross 		cnt = iov->iov_len;
184*b819cea2SGordon Ross 		if (cnt > uio->uio_resid)
185*b819cea2SGordon Ross 			cnt = uio->uio_resid;
186*b819cea2SGordon Ross 
187*b819cea2SGordon Ross 		n = pwrite(vp->v_fd, iov->iov_base, iov->iov_len,
188*b819cea2SGordon Ross 		    uio->uio_loffset);
189*b819cea2SGordon Ross 		if (n < 0)
190*b819cea2SGordon Ross 			return (errno);
191*b819cea2SGordon Ross 
192*b819cea2SGordon Ross 		iov->iov_base += n;
193*b819cea2SGordon Ross 		iov->iov_len -= n;
194*b819cea2SGordon Ross 
195*b819cea2SGordon Ross 		uio->uio_resid -= n;
196*b819cea2SGordon Ross 		uio->uio_loffset += n;
197*b819cea2SGordon Ross 	}
198*b819cea2SGordon Ross 
199*b819cea2SGordon Ross 	if (ioflag == FSYNC) {
200*b819cea2SGordon Ross 		(void) fsync(vp->v_fd);
201*b819cea2SGordon Ross 	}
202*b819cea2SGordon Ross 
203*b819cea2SGordon Ross 	return (0);
204*b819cea2SGordon Ross }
205*b819cea2SGordon Ross 
206*b819cea2SGordon Ross /* ARGSUSED */
207*b819cea2SGordon Ross int
fop_ioctl(vnode_t * vp,int cmd,intptr_t arg,int flag,cred_t * cr,int * rvalp,caller_context_t * ct)208*b819cea2SGordon Ross fop_ioctl(
209*b819cea2SGordon Ross 	vnode_t *vp,
210*b819cea2SGordon Ross 	int cmd,
211*b819cea2SGordon Ross 	intptr_t arg,
212*b819cea2SGordon Ross 	int flag,
213*b819cea2SGordon Ross 	cred_t *cr,
214*b819cea2SGordon Ross 	int *rvalp,
215*b819cea2SGordon Ross 	caller_context_t *ct)
216*b819cea2SGordon Ross {
217*b819cea2SGordon Ross 	return (ENOSYS);
218*b819cea2SGordon Ross }
219*b819cea2SGordon Ross 
220*b819cea2SGordon Ross /* ARGSUSED */
221*b819cea2SGordon Ross int
fop_setfl(vnode_t * vp,int oflags,int nflags,cred_t * cr,caller_context_t * ct)222*b819cea2SGordon Ross fop_setfl(
223*b819cea2SGordon Ross 	vnode_t *vp,
224*b819cea2SGordon Ross 	int oflags,
225*b819cea2SGordon Ross 	int nflags,
226*b819cea2SGordon Ross 	cred_t *cr,
227*b819cea2SGordon Ross 	caller_context_t *ct)
228*b819cea2SGordon Ross {
229*b819cea2SGordon Ross 	/* allow any flags? See fs_setfl */
230*b819cea2SGordon Ross 	return (0);
231*b819cea2SGordon Ross }
232*b819cea2SGordon Ross 
233*b819cea2SGordon Ross /* ARGSUSED */
234*b819cea2SGordon Ross int
fop_getattr(vnode_t * vp,vattr_t * vap,int flags,cred_t * cr,caller_context_t * ct)235*b819cea2SGordon Ross fop_getattr(
236*b819cea2SGordon Ross 	vnode_t *vp,
237*b819cea2SGordon Ross 	vattr_t *vap,
238*b819cea2SGordon Ross 	int flags,
239*b819cea2SGordon Ross 	cred_t *cr,
240*b819cea2SGordon Ross 	caller_context_t *ct)
241*b819cea2SGordon Ross {
242*b819cea2SGordon Ross 	int error;
243*b819cea2SGordon Ross 	struct stat st;
244*b819cea2SGordon Ross 
245*b819cea2SGordon Ross 	if (fstat(vp->v_fd, &st) == -1)
246*b819cea2SGordon Ross 		return (errno);
247*b819cea2SGordon Ross 	error = stat_to_vattr(&st, vap);
248*b819cea2SGordon Ross 
249*b819cea2SGordon Ross 	if (vap->va_mask & AT_XVATTR)
250*b819cea2SGordon Ross 		(void) fop__getxvattr(vp, (xvattr_t *)vap);
251*b819cea2SGordon Ross 
252*b819cea2SGordon Ross 	return (error);
253*b819cea2SGordon Ross }
254*b819cea2SGordon Ross 
255*b819cea2SGordon Ross /* ARGSUSED */
256*b819cea2SGordon Ross int
fop_setattr(vnode_t * vp,vattr_t * vap,int flags,cred_t * cr,caller_context_t * ct)257*b819cea2SGordon Ross fop_setattr(
258*b819cea2SGordon Ross 	vnode_t *vp,
259*b819cea2SGordon Ross 	vattr_t *vap,
260*b819cea2SGordon Ross 	int flags,
261*b819cea2SGordon Ross 	cred_t *cr,
262*b819cea2SGordon Ross 	caller_context_t *ct)
263*b819cea2SGordon Ross {
264*b819cea2SGordon Ross 	struct timeval times[2];
265*b819cea2SGordon Ross 
266*b819cea2SGordon Ross 	if (vap->va_mask & AT_SIZE) {
267*b819cea2SGordon Ross 		if (ftruncate(vp->v_fd, vap->va_size) == -1)
268*b819cea2SGordon Ross 			return (errno);
269*b819cea2SGordon Ross 	}
270*b819cea2SGordon Ross 
271*b819cea2SGordon Ross 	/* AT_MODE or anything else? */
272*b819cea2SGordon Ross 
273*b819cea2SGordon Ross 	if (vap->va_mask & AT_XVATTR)
274*b819cea2SGordon Ross 		(void) fop__setxvattr(vp, (xvattr_t *)vap);
275*b819cea2SGordon Ross 
276*b819cea2SGordon Ross 	if (vap->va_mask & (AT_ATIME | AT_MTIME)) {
277*b819cea2SGordon Ross 		times[0].tv_sec = 0;
278*b819cea2SGordon Ross 		times[0].tv_usec = UTIME_OMIT;
279*b819cea2SGordon Ross 		times[1].tv_sec = 0;
280*b819cea2SGordon Ross 		times[1].tv_usec = UTIME_OMIT;
281*b819cea2SGordon Ross 		if (vap->va_mask & AT_ATIME) {
282*b819cea2SGordon Ross 			times[0].tv_sec = vap->va_atime.tv_sec;
283*b819cea2SGordon Ross 			times[0].tv_usec = vap->va_atime.tv_nsec / 1000;
284*b819cea2SGordon Ross 		}
285*b819cea2SGordon Ross 		if (vap->va_mask & AT_MTIME) {
286*b819cea2SGordon Ross 			times[1].tv_sec = vap->va_mtime.tv_sec;
287*b819cea2SGordon Ross 			times[1].tv_usec = vap->va_mtime.tv_nsec / 1000;
288*b819cea2SGordon Ross 		}
289*b819cea2SGordon Ross 
290*b819cea2SGordon Ross 		(void) futimesat(vp->v_fd, NULL, times);
291*b819cea2SGordon Ross 	}
292*b819cea2SGordon Ross 
293*b819cea2SGordon Ross 	return (0);
294*b819cea2SGordon Ross }
295*b819cea2SGordon Ross 
296*b819cea2SGordon Ross /* ARGSUSED */
297*b819cea2SGordon Ross int
fop_access(vnode_t * vp,int mode,int flags,cred_t * cr,caller_context_t * ct)298*b819cea2SGordon Ross fop_access(
299*b819cea2SGordon Ross 	vnode_t *vp,
300*b819cea2SGordon Ross 	int mode,
301*b819cea2SGordon Ross 	int flags,
302*b819cea2SGordon Ross 	cred_t *cr,
303*b819cea2SGordon Ross 	caller_context_t *ct)
304*b819cea2SGordon Ross {
305*b819cea2SGordon Ross 	return (0);
306*b819cea2SGordon Ross }
307*b819cea2SGordon Ross 
308*b819cea2SGordon Ross /* ARGSUSED */
309*b819cea2SGordon Ross int
fop_lookup(vnode_t * dvp,char * name,vnode_t ** vpp,pathname_t * pnp,int flags,vnode_t * rdir,cred_t * cr,caller_context_t * ct,int * deflags,pathname_t * ppnp)310*b819cea2SGordon Ross fop_lookup(
311*b819cea2SGordon Ross 	vnode_t *dvp,
312*b819cea2SGordon Ross 	char *name,
313*b819cea2SGordon Ross 	vnode_t **vpp,
314*b819cea2SGordon Ross 	pathname_t *pnp,
315*b819cea2SGordon Ross 	int flags,
316*b819cea2SGordon Ross 	vnode_t *rdir,
317*b819cea2SGordon Ross 	cred_t *cr,
318*b819cea2SGordon Ross 	caller_context_t *ct,
319*b819cea2SGordon Ross 	int *deflags,		/* Returned per-dirent flags */
320*b819cea2SGordon Ross 	pathname_t *ppnp)	/* Returned case-preserved name in directory */
321*b819cea2SGordon Ross {
322*b819cea2SGordon Ross 	int fd;
323*b819cea2SGordon Ross 	int omode = O_RDWR | O_NOFOLLOW;
324*b819cea2SGordon Ross 	vnode_t *vp;
325*b819cea2SGordon Ross 	struct stat st;
326*b819cea2SGordon Ross 
327*b819cea2SGordon Ross 	if (flags & LOOKUP_XATTR)
328*b819cea2SGordon Ross 		return (ENOENT);
329*b819cea2SGordon Ross 
330*b819cea2SGordon Ross 	/*
331*b819cea2SGordon Ross 	 * If lookup is for "", just return dvp.
332*b819cea2SGordon Ross 	 */
333*b819cea2SGordon Ross 	if (name[0] == '\0') {
334*b819cea2SGordon Ross 		vn_hold(dvp);
335*b819cea2SGordon Ross 		*vpp = dvp;
336*b819cea2SGordon Ross 		return (0);
337*b819cea2SGordon Ross 	}
338*b819cea2SGordon Ross 
339*b819cea2SGordon Ross 	if (fstatat(dvp->v_fd, name, &st, AT_SYMLINK_NOFOLLOW) == -1)
340*b819cea2SGordon Ross 		return (errno);
341*b819cea2SGordon Ross 
342*b819cea2SGordon Ross 	vp = vncache_lookup(&st);
343*b819cea2SGordon Ross 	if (vp != NULL) {
344*b819cea2SGordon Ross 		/* lookup gave us a hold */
345*b819cea2SGordon Ross 		*vpp = vp;
346*b819cea2SGordon Ross 		return (0);
347*b819cea2SGordon Ross 	}
348*b819cea2SGordon Ross 
349*b819cea2SGordon Ross 	if (S_ISDIR(st.st_mode))
350*b819cea2SGordon Ross 		omode = O_RDONLY | O_NOFOLLOW;
351*b819cea2SGordon Ross 
352*b819cea2SGordon Ross again:
353*b819cea2SGordon Ross 	fd = openat(dvp->v_fd, name, omode, 0);
354*b819cea2SGordon Ross 	if (fd < 0) {
355*b819cea2SGordon Ross 		if ((omode & O_RWMASK) == O_RDWR) {
356*b819cea2SGordon Ross 			omode &= ~O_RWMASK;
357*b819cea2SGordon Ross 			omode |= O_RDONLY;
358*b819cea2SGordon Ross 			goto again;
359*b819cea2SGordon Ross 		}
360*b819cea2SGordon Ross 		return (errno);
361*b819cea2SGordon Ross 	}
362*b819cea2SGordon Ross 
363*b819cea2SGordon Ross 	if (fstat(fd, &st) == -1) {
364*b819cea2SGordon Ross 		(void) close(fd);
365*b819cea2SGordon Ross 		return (errno);
366*b819cea2SGordon Ross 	}
367*b819cea2SGordon Ross 
368*b819cea2SGordon Ross 	vp = vncache_enter(&st, dvp, name, fd);
369*b819cea2SGordon Ross 
370*b819cea2SGordon Ross 	*vpp = vp;
371*b819cea2SGordon Ross 	return (0);
372*b819cea2SGordon Ross }
373*b819cea2SGordon Ross 
374*b819cea2SGordon Ross /* ARGSUSED */
375*b819cea2SGordon Ross int
fop_create(vnode_t * dvp,char * name,vattr_t * vap,vcexcl_t excl,int mode,vnode_t ** vpp,cred_t * cr,int flags,caller_context_t * ct,vsecattr_t * vsecp)376*b819cea2SGordon Ross fop_create(
377*b819cea2SGordon Ross 	vnode_t *dvp,
378*b819cea2SGordon Ross 	char *name,
379*b819cea2SGordon Ross 	vattr_t *vap,
380*b819cea2SGordon Ross 	vcexcl_t excl,
381*b819cea2SGordon Ross 	int mode,
382*b819cea2SGordon Ross 	vnode_t **vpp,
383*b819cea2SGordon Ross 	cred_t *cr,
384*b819cea2SGordon Ross 	int flags,
385*b819cea2SGordon Ross 	caller_context_t *ct,
386*b819cea2SGordon Ross 	vsecattr_t *vsecp)	/* ACL to set during create */
387*b819cea2SGordon Ross {
388*b819cea2SGordon Ross 	struct stat st;
389*b819cea2SGordon Ross 	vnode_t *vp;
390*b819cea2SGordon Ross 	int err, fd, omode;
391*b819cea2SGordon Ross 
392*b819cea2SGordon Ross 	/*
393*b819cea2SGordon Ross 	 * If creating "", just return dvp.
394*b819cea2SGordon Ross 	 */
395*b819cea2SGordon Ross 	if (name[0] == '\0') {
396*b819cea2SGordon Ross 		vn_hold(dvp);
397*b819cea2SGordon Ross 		*vpp = dvp;
398*b819cea2SGordon Ross 		return (0);
399*b819cea2SGordon Ross 	}
400*b819cea2SGordon Ross 
401*b819cea2SGordon Ross 	err = fstatat(dvp->v_fd, name, &st, AT_SYMLINK_NOFOLLOW);
402*b819cea2SGordon Ross 	if (err != 0)
403*b819cea2SGordon Ross 		err = errno;
404*b819cea2SGordon Ross 
405*b819cea2SGordon Ross 	vp = NULL;
406*b819cea2SGordon Ross 	if (err == 0) {
407*b819cea2SGordon Ross 		/* The file already exists. */
408*b819cea2SGordon Ross 		if (excl == EXCL)
409*b819cea2SGordon Ross 			return (EEXIST);
410*b819cea2SGordon Ross 
411*b819cea2SGordon Ross 		vp = vncache_lookup(&st);
412*b819cea2SGordon Ross 		/* vp gained a hold */
413*b819cea2SGordon Ross 	}
414*b819cea2SGordon Ross 
415*b819cea2SGordon Ross 	if (vp == NULL) {
416*b819cea2SGordon Ross 		/*
417*b819cea2SGordon Ross 		 * Open it. (may or may not exist)
418*b819cea2SGordon Ross 		 */
419*b819cea2SGordon Ross 		omode = O_RDWR | O_CREAT | O_NOFOLLOW;
420*b819cea2SGordon Ross 		if (excl == EXCL)
421*b819cea2SGordon Ross 			omode |= O_EXCL;
422*b819cea2SGordon Ross 	open_again:
423*b819cea2SGordon Ross 		fd = openat(dvp->v_fd, name, omode, mode);
424*b819cea2SGordon Ross 		if (fd < 0) {
425*b819cea2SGordon Ross 			if ((omode & O_RWMASK) == O_RDWR) {
426*b819cea2SGordon Ross 				omode &= ~O_RWMASK;
427*b819cea2SGordon Ross 				omode |= O_RDONLY;
428*b819cea2SGordon Ross 				goto open_again;
429*b819cea2SGordon Ross 			}
430*b819cea2SGordon Ross 			return (errno);
431*b819cea2SGordon Ross 		}
432*b819cea2SGordon Ross 		(void) fstat(fd, &st);
433*b819cea2SGordon Ross 
434*b819cea2SGordon Ross 		vp = vncache_enter(&st, dvp, name, fd);
435*b819cea2SGordon Ross 		/* vp has its initial hold */
436*b819cea2SGordon Ross 	}
437*b819cea2SGordon Ross 
438*b819cea2SGordon Ross 	/* Should have the vp now. */
439*b819cea2SGordon Ross 	if (vp == NULL)
440*b819cea2SGordon Ross 		return (EFAULT);
441*b819cea2SGordon Ross 
442*b819cea2SGordon Ross 	if (vp->v_type == VDIR && vap->va_type != VDIR) {
443*b819cea2SGordon Ross 		vn_rele(vp);
444*b819cea2SGordon Ross 		return (EISDIR);
445*b819cea2SGordon Ross 	}
446*b819cea2SGordon Ross 	if (vp->v_type != VDIR && vap->va_type == VDIR) {
447*b819cea2SGordon Ross 		vn_rele(vp);
448*b819cea2SGordon Ross 		return (ENOTDIR);
449*b819cea2SGordon Ross 	}
450*b819cea2SGordon Ross 
451*b819cea2SGordon Ross 	/*
452*b819cea2SGordon Ross 	 * Truncate (if requested).
453*b819cea2SGordon Ross 	 */
454*b819cea2SGordon Ross 	if ((vap->va_mask & AT_SIZE) && vap->va_size == 0) {
455*b819cea2SGordon Ross 		(void) ftruncate(vp->v_fd, 0);
456*b819cea2SGordon Ross 	}
457*b819cea2SGordon Ross 
458*b819cea2SGordon Ross 	*vpp = vp;
459*b819cea2SGordon Ross 	return (0);
460*b819cea2SGordon Ross }
461*b819cea2SGordon Ross 
462*b819cea2SGordon Ross /* ARGSUSED */
463*b819cea2SGordon Ross int
fop_remove(vnode_t * dvp,char * name,cred_t * cr,caller_context_t * ct,int flags)464*b819cea2SGordon Ross fop_remove(
465*b819cea2SGordon Ross 	vnode_t *dvp,
466*b819cea2SGordon Ross 	char *name,
467*b819cea2SGordon Ross 	cred_t *cr,
468*b819cea2SGordon Ross 	caller_context_t *ct,
469*b819cea2SGordon Ross 	int flags)
470*b819cea2SGordon Ross {
471*b819cea2SGordon Ross 
472*b819cea2SGordon Ross 	if (unlinkat(dvp->v_fd, name, 0))
473*b819cea2SGordon Ross 		return (errno);
474*b819cea2SGordon Ross 
475*b819cea2SGordon Ross 	return (0);
476*b819cea2SGordon Ross }
477*b819cea2SGordon Ross 
478*b819cea2SGordon Ross /* ARGSUSED */
479*b819cea2SGordon Ross int
fop_link(vnode_t * to_dvp,vnode_t * fr_vp,char * to_name,cred_t * cr,caller_context_t * ct,int flags)480*b819cea2SGordon Ross fop_link(
481*b819cea2SGordon Ross 	vnode_t *to_dvp,
482*b819cea2SGordon Ross 	vnode_t *fr_vp,
483*b819cea2SGordon Ross 	char *to_name,
484*b819cea2SGordon Ross 	cred_t *cr,
485*b819cea2SGordon Ross 	caller_context_t *ct,
486*b819cea2SGordon Ross 	int flags)
487*b819cea2SGordon Ross {
488*b819cea2SGordon Ross 	int err;
489*b819cea2SGordon Ross 
490*b819cea2SGordon Ross 	/*
491*b819cea2SGordon Ross 	 * Would prefer to specify "from" as the combination:
492*b819cea2SGordon Ross 	 * (fr_vp->v_fd, NULL) but linkat does not permit it.
493*b819cea2SGordon Ross 	 */
494*b819cea2SGordon Ross 	err = linkat(AT_FDCWD, fr_vp->v_path, to_dvp->v_fd, to_name,
495*b819cea2SGordon Ross 	    AT_SYMLINK_FOLLOW);
496*b819cea2SGordon Ross 	if (err == -1)
497*b819cea2SGordon Ross 		err = errno;
498*b819cea2SGordon Ross 
499*b819cea2SGordon Ross 	return (err);
500*b819cea2SGordon Ross }
501*b819cea2SGordon Ross 
502*b819cea2SGordon Ross /* ARGSUSED */
503*b819cea2SGordon Ross int
fop_rename(vnode_t * from_dvp,char * from_name,vnode_t * to_dvp,char * to_name,cred_t * cr,caller_context_t * ct,int flags)504*b819cea2SGordon Ross fop_rename(
505*b819cea2SGordon Ross 	vnode_t *from_dvp,
506*b819cea2SGordon Ross 	char *from_name,
507*b819cea2SGordon Ross 	vnode_t *to_dvp,
508*b819cea2SGordon Ross 	char *to_name,
509*b819cea2SGordon Ross 	cred_t *cr,
510*b819cea2SGordon Ross 	caller_context_t *ct,
511*b819cea2SGordon Ross 	int flags)
512*b819cea2SGordon Ross {
513*b819cea2SGordon Ross 	struct stat st;
514*b819cea2SGordon Ross 	vnode_t *vp;
515*b819cea2SGordon Ross 	int err;
516*b819cea2SGordon Ross 
517*b819cea2SGordon Ross 	if (fstatat(from_dvp->v_fd, from_name, &st,
518*b819cea2SGordon Ross 	    AT_SYMLINK_NOFOLLOW) == -1)
519*b819cea2SGordon Ross 		return (errno);
520*b819cea2SGordon Ross 
521*b819cea2SGordon Ross 	vp = vncache_lookup(&st);
522*b819cea2SGordon Ross 	if (vp == NULL)
523*b819cea2SGordon Ross 		return (ENOENT);
524*b819cea2SGordon Ross 
525*b819cea2SGordon Ross 	err = renameat(from_dvp->v_fd, from_name, to_dvp->v_fd, to_name);
526*b819cea2SGordon Ross 	if (err == -1)
527*b819cea2SGordon Ross 		err = errno;
528*b819cea2SGordon Ross 	else
529*b819cea2SGordon Ross 		vncache_renamed(vp, to_dvp, to_name);
530*b819cea2SGordon Ross 
531*b819cea2SGordon Ross 	vn_rele(vp);
532*b819cea2SGordon Ross 
533*b819cea2SGordon Ross 	return (err);
534*b819cea2SGordon Ross }
535*b819cea2SGordon Ross 
536*b819cea2SGordon Ross /* ARGSUSED */
537*b819cea2SGordon Ross int
fop_mkdir(vnode_t * dvp,char * name,vattr_t * vap,vnode_t ** vpp,cred_t * cr,caller_context_t * ct,int flags,vsecattr_t * vsecp)538*b819cea2SGordon Ross fop_mkdir(
539*b819cea2SGordon Ross 	vnode_t *dvp,
540*b819cea2SGordon Ross 	char *name,
541*b819cea2SGordon Ross 	vattr_t *vap,
542*b819cea2SGordon Ross 	vnode_t **vpp,
543*b819cea2SGordon Ross 	cred_t *cr,
544*b819cea2SGordon Ross 	caller_context_t *ct,
545*b819cea2SGordon Ross 	int flags,
546*b819cea2SGordon Ross 	vsecattr_t *vsecp)	/* ACL to set during create */
547*b819cea2SGordon Ross {
548*b819cea2SGordon Ross 	struct stat st;
549*b819cea2SGordon Ross 	int err, fd;
550*b819cea2SGordon Ross 
551*b819cea2SGordon Ross 	mode_t mode = vap->va_mode & 0777;
552*b819cea2SGordon Ross 
553*b819cea2SGordon Ross 	if (mkdirat(dvp->v_fd, name, mode) == -1)
554*b819cea2SGordon Ross 		return (errno);
555*b819cea2SGordon Ross 
556*b819cea2SGordon Ross 	if ((fd = openat(dvp->v_fd, name, O_RDONLY)) == -1)
557*b819cea2SGordon Ross 		return (errno);
558*b819cea2SGordon Ross 	if (fstat(fd, &st) == -1) {
559*b819cea2SGordon Ross 		err = errno;
560*b819cea2SGordon Ross 		(void) close(fd);
561*b819cea2SGordon Ross 		return (err);
562*b819cea2SGordon Ross 	}
563*b819cea2SGordon Ross 
564*b819cea2SGordon Ross 	*vpp = vncache_enter(&st, dvp, name, fd);
565*b819cea2SGordon Ross 
566*b819cea2SGordon Ross 	return (0);
567*b819cea2SGordon Ross }
568*b819cea2SGordon Ross 
569*b819cea2SGordon Ross /* ARGSUSED */
570*b819cea2SGordon Ross int
fop_rmdir(vnode_t * dvp,char * name,vnode_t * cdir,cred_t * cr,caller_context_t * ct,int flags)571*b819cea2SGordon Ross fop_rmdir(
572*b819cea2SGordon Ross 	vnode_t *dvp,
573*b819cea2SGordon Ross 	char *name,
574*b819cea2SGordon Ross 	vnode_t *cdir,
575*b819cea2SGordon Ross 	cred_t *cr,
576*b819cea2SGordon Ross 	caller_context_t *ct,
577*b819cea2SGordon Ross 	int flags)
578*b819cea2SGordon Ross {
579*b819cea2SGordon Ross 
580*b819cea2SGordon Ross 	if (unlinkat(dvp->v_fd, name, AT_REMOVEDIR) == -1)
581*b819cea2SGordon Ross 		return (errno);
582*b819cea2SGordon Ross 
583*b819cea2SGordon Ross 	return (0);
584*b819cea2SGordon Ross }
585*b819cea2SGordon Ross 
586*b819cea2SGordon Ross /* ARGSUSED */
587*b819cea2SGordon Ross int
fop_readdir(vnode_t * vp,uio_t * uiop,cred_t * cr,int * eofp,caller_context_t * ct,int flags)588*b819cea2SGordon Ross fop_readdir(
589*b819cea2SGordon Ross 	vnode_t *vp,
590*b819cea2SGordon Ross 	uio_t *uiop,
591*b819cea2SGordon Ross 	cred_t *cr,
592*b819cea2SGordon Ross 	int *eofp,
593*b819cea2SGordon Ross 	caller_context_t *ct,
594*b819cea2SGordon Ross 	int flags)
595*b819cea2SGordon Ross {
596*b819cea2SGordon Ross 	struct iovec *iov;
597*b819cea2SGordon Ross 	int cnt;
598*b819cea2SGordon Ross 	int error = 0;
599*b819cea2SGordon Ross 	int fd = vp->v_fd;
600*b819cea2SGordon Ross 
601*b819cea2SGordon Ross 	if (eofp) {
602*b819cea2SGordon Ross 		*eofp = 0;
603*b819cea2SGordon Ross 	}
604*b819cea2SGordon Ross 
605*b819cea2SGordon Ross 	error = lseek(fd, uiop->uio_loffset, SEEK_SET);
606*b819cea2SGordon Ross 	if (error == -1)
607*b819cea2SGordon Ross 		return (errno);
608*b819cea2SGordon Ross 
609*b819cea2SGordon Ross 	ASSERT(uiop->uio_iovcnt > 0);
610*b819cea2SGordon Ross 	iov = uiop->uio_iov;
611*b819cea2SGordon Ross 	if (iov->iov_len < sizeof (struct dirent))
612*b819cea2SGordon Ross 		return (EINVAL);
613*b819cea2SGordon Ross 
614*b819cea2SGordon Ross 	/* LINTED E_BAD_PTR_CAST_ALIGN */
615*b819cea2SGordon Ross 	cnt = getdents(fd, (struct dirent *)(uiop->uio_iov->iov_base),
616*b819cea2SGordon Ross 	    uiop->uio_resid);
617*b819cea2SGordon Ross 	if (cnt == -1)
618*b819cea2SGordon Ross 		return (errno);
619*b819cea2SGordon Ross 	if (cnt == 0) {
620*b819cea2SGordon Ross 		if (eofp) {
621*b819cea2SGordon Ross 			*eofp = 1;
622*b819cea2SGordon Ross 		}
623*b819cea2SGordon Ross 		return (ENOENT);
624*b819cea2SGordon Ross 	}
625*b819cea2SGordon Ross 
626*b819cea2SGordon Ross 	iov->iov_base += cnt;
627*b819cea2SGordon Ross 	iov->iov_len  -= cnt;
628*b819cea2SGordon Ross 	uiop->uio_resid -= cnt;
629*b819cea2SGordon Ross 	uiop->uio_loffset = lseek(fd, 0LL, SEEK_CUR);
630*b819cea2SGordon Ross 
631*b819cea2SGordon Ross 	return (0);
632*b819cea2SGordon Ross }
633*b819cea2SGordon Ross 
634*b819cea2SGordon Ross /* ARGSUSED */
635*b819cea2SGordon Ross int
fop_symlink(vnode_t * dvp,char * linkname,vattr_t * vap,char * target,cred_t * cr,caller_context_t * ct,int flags)636*b819cea2SGordon Ross fop_symlink(
637*b819cea2SGordon Ross 	vnode_t *dvp,
638*b819cea2SGordon Ross 	char *linkname,
639*b819cea2SGordon Ross 	vattr_t *vap,
640*b819cea2SGordon Ross 	char *target,
641*b819cea2SGordon Ross 	cred_t *cr,
642*b819cea2SGordon Ross 	caller_context_t *ct,
643*b819cea2SGordon Ross 	int flags)
644*b819cea2SGordon Ross {
645*b819cea2SGordon Ross 	return (ENOSYS);
646*b819cea2SGordon Ross }
647*b819cea2SGordon Ross 
648*b819cea2SGordon Ross /* ARGSUSED */
649*b819cea2SGordon Ross int
fop_readlink(vnode_t * vp,uio_t * uiop,cred_t * cr,caller_context_t * ct)650*b819cea2SGordon Ross fop_readlink(
651*b819cea2SGordon Ross 	vnode_t *vp,
652*b819cea2SGordon Ross 	uio_t *uiop,
653*b819cea2SGordon Ross 	cred_t *cr,
654*b819cea2SGordon Ross 	caller_context_t *ct)
655*b819cea2SGordon Ross {
656*b819cea2SGordon Ross 	return (ENOSYS);
657*b819cea2SGordon Ross }
658*b819cea2SGordon Ross 
659*b819cea2SGordon Ross /* ARGSUSED */
660*b819cea2SGordon Ross int
fop_fsync(vnode_t * vp,int syncflag,cred_t * cr,caller_context_t * ct)661*b819cea2SGordon Ross fop_fsync(
662*b819cea2SGordon Ross 	vnode_t *vp,
663*b819cea2SGordon Ross 	int syncflag,
664*b819cea2SGordon Ross 	cred_t *cr,
665*b819cea2SGordon Ross 	caller_context_t *ct)
666*b819cea2SGordon Ross {
667*b819cea2SGordon Ross 
668*b819cea2SGordon Ross 	if (fsync(vp->v_fd) == -1)
669*b819cea2SGordon Ross 		return (errno);
670*b819cea2SGordon Ross 
671*b819cea2SGordon Ross 	return (0);
672*b819cea2SGordon Ross }
673*b819cea2SGordon Ross 
674*b819cea2SGordon Ross /* ARGSUSED */
675*b819cea2SGordon Ross void
fop_inactive(vnode_t * vp,cred_t * cr,caller_context_t * ct)676*b819cea2SGordon Ross fop_inactive(
677*b819cea2SGordon Ross 	vnode_t *vp,
678*b819cea2SGordon Ross 	cred_t *cr,
679*b819cea2SGordon Ross 	caller_context_t *ct)
680*b819cea2SGordon Ross {
681*b819cea2SGordon Ross 	vncache_inactive(vp);
682*b819cea2SGordon Ross }
683*b819cea2SGordon Ross 
684*b819cea2SGordon Ross /* ARGSUSED */
685*b819cea2SGordon Ross int
fop_fid(vnode_t * vp,fid_t * fidp,caller_context_t * ct)686*b819cea2SGordon Ross fop_fid(
687*b819cea2SGordon Ross 	vnode_t *vp,
688*b819cea2SGordon Ross 	fid_t *fidp,
689*b819cea2SGordon Ross 	caller_context_t *ct)
690*b819cea2SGordon Ross {
691*b819cea2SGordon Ross 	return (ENOSYS);
692*b819cea2SGordon Ross }
693*b819cea2SGordon Ross 
694*b819cea2SGordon Ross /* ARGSUSED */
695*b819cea2SGordon Ross int
fop_rwlock(vnode_t * vp,int write_lock,caller_context_t * ct)696*b819cea2SGordon Ross fop_rwlock(
697*b819cea2SGordon Ross 	vnode_t *vp,
698*b819cea2SGordon Ross 	int write_lock,
699*b819cea2SGordon Ross 	caller_context_t *ct)
700*b819cea2SGordon Ross {
701*b819cea2SGordon Ross 	/* See: fs_rwlock */
702*b819cea2SGordon Ross 	return (-1);
703*b819cea2SGordon Ross }
704*b819cea2SGordon Ross 
705*b819cea2SGordon Ross /* ARGSUSED */
706*b819cea2SGordon Ross void
fop_rwunlock(vnode_t * vp,int write_lock,caller_context_t * ct)707*b819cea2SGordon Ross fop_rwunlock(
708*b819cea2SGordon Ross 	vnode_t *vp,
709*b819cea2SGordon Ross 	int write_lock,
710*b819cea2SGordon Ross 	caller_context_t *ct)
711*b819cea2SGordon Ross {
712*b819cea2SGordon Ross 	/* See: fs_rwunlock */
713*b819cea2SGordon Ross }
714*b819cea2SGordon Ross 
715*b819cea2SGordon Ross /* ARGSUSED */
716*b819cea2SGordon Ross int
fop_seek(vnode_t * vp,offset_t ooff,offset_t * noffp,caller_context_t * ct)717*b819cea2SGordon Ross fop_seek(
718*b819cea2SGordon Ross 	vnode_t *vp,
719*b819cea2SGordon Ross 	offset_t ooff,
720*b819cea2SGordon Ross 	offset_t *noffp,
721*b819cea2SGordon Ross 	caller_context_t *ct)
722*b819cea2SGordon Ross {
723*b819cea2SGordon Ross 	return (ENOSYS);
724*b819cea2SGordon Ross }
725*b819cea2SGordon Ross 
726*b819cea2SGordon Ross /* ARGSUSED */
727*b819cea2SGordon Ross int
fop_cmp(vnode_t * vp1,vnode_t * vp2,caller_context_t * ct)728*b819cea2SGordon Ross fop_cmp(
729*b819cea2SGordon Ross 	vnode_t *vp1,
730*b819cea2SGordon Ross 	vnode_t *vp2,
731*b819cea2SGordon Ross 	caller_context_t *ct)
732*b819cea2SGordon Ross {
733*b819cea2SGordon Ross 	/* See fs_cmp */
734*b819cea2SGordon Ross 	return (vncache_cmp(vp1, vp2));
735*b819cea2SGordon Ross }
736*b819cea2SGordon Ross 
737*b819cea2SGordon Ross /* ARGSUSED */
738*b819cea2SGordon Ross int
fop_frlock(vnode_t * vp,int cmd,flock64_t * bfp,int flag,offset_t offset,struct flk_callback * flk_cbp,cred_t * cr,caller_context_t * ct)739*b819cea2SGordon Ross fop_frlock(
740*b819cea2SGordon Ross 	vnode_t *vp,
741*b819cea2SGordon Ross 	int cmd,
742*b819cea2SGordon Ross 	flock64_t *bfp,
743*b819cea2SGordon Ross 	int flag,
744*b819cea2SGordon Ross 	offset_t offset,
745*b819cea2SGordon Ross 	struct flk_callback *flk_cbp,
746*b819cea2SGordon Ross 	cred_t *cr,
747*b819cea2SGordon Ross 	caller_context_t *ct)
748*b819cea2SGordon Ross {
749*b819cea2SGordon Ross 	/* See fs_frlock */
750*b819cea2SGordon Ross 
751*b819cea2SGordon Ross 	switch (cmd) {
752*b819cea2SGordon Ross 	case F_GETLK:
753*b819cea2SGordon Ross 	case F_SETLK_NBMAND:
754*b819cea2SGordon Ross 	case F_SETLK:
755*b819cea2SGordon Ross 	case F_SETLKW:
756*b819cea2SGordon Ross 		break;
757*b819cea2SGordon Ross 	default:
758*b819cea2SGordon Ross 		return (EINVAL);
759*b819cea2SGordon Ross 	}
760*b819cea2SGordon Ross 
761*b819cea2SGordon Ross 	if (fcntl(vp->v_fd, cmd, bfp) == -1)
762*b819cea2SGordon Ross 		return (errno);
763*b819cea2SGordon Ross 
764*b819cea2SGordon Ross 	return (0);
765*b819cea2SGordon Ross }
766*b819cea2SGordon Ross 
767*b819cea2SGordon Ross /* ARGSUSED */
768*b819cea2SGordon Ross int
fop_space(vnode_t * vp,int cmd,flock64_t * bfp,int flag,offset_t offset,cred_t * cr,caller_context_t * ct)769*b819cea2SGordon Ross fop_space(
770*b819cea2SGordon Ross 	vnode_t *vp,
771*b819cea2SGordon Ross 	int cmd,
772*b819cea2SGordon Ross 	flock64_t *bfp,
773*b819cea2SGordon Ross 	int flag,
774*b819cea2SGordon Ross 	offset_t offset,
775*b819cea2SGordon Ross 	cred_t *cr,
776*b819cea2SGordon Ross 	caller_context_t *ct)
777*b819cea2SGordon Ross {
778*b819cea2SGordon Ross 	/* See fs_frlock */
779*b819cea2SGordon Ross 
780*b819cea2SGordon Ross 	switch (cmd) {
781*b819cea2SGordon Ross 	case F_ALLOCSP:
782*b819cea2SGordon Ross 	case F_FREESP:
783*b819cea2SGordon Ross 		break;
784*b819cea2SGordon Ross 	default:
785*b819cea2SGordon Ross 		return (EINVAL);
786*b819cea2SGordon Ross 	}
787*b819cea2SGordon Ross 
788*b819cea2SGordon Ross 	if (fcntl(vp->v_fd, cmd, bfp) == -1)
789*b819cea2SGordon Ross 		return (errno);
790*b819cea2SGordon Ross 
791*b819cea2SGordon Ross 	return (0);
792*b819cea2SGordon Ross }
793*b819cea2SGordon Ross 
794*b819cea2SGordon Ross /* ARGSUSED */
795*b819cea2SGordon Ross int
fop_realvp(vnode_t * vp,vnode_t ** vpp,caller_context_t * ct)796*b819cea2SGordon Ross fop_realvp(
797*b819cea2SGordon Ross 	vnode_t *vp,
798*b819cea2SGordon Ross 	vnode_t **vpp,
799*b819cea2SGordon Ross 	caller_context_t *ct)
800*b819cea2SGordon Ross {
801*b819cea2SGordon Ross 	return (ENOSYS);
802*b819cea2SGordon Ross }
803*b819cea2SGordon Ross 
804*b819cea2SGordon Ross /* ARGSUSED */
805*b819cea2SGordon Ross int
fop_getpage(vnode_t * vp,offset_t off,size_t len,uint_t * protp,struct page ** plarr,size_t plsz,struct seg * seg,caddr_t addr,enum seg_rw rw,cred_t * cr,caller_context_t * ct)806*b819cea2SGordon Ross fop_getpage(
807*b819cea2SGordon Ross 	vnode_t *vp,
808*b819cea2SGordon Ross 	offset_t off,
809*b819cea2SGordon Ross 	size_t len,
810*b819cea2SGordon Ross 	uint_t *protp,
811*b819cea2SGordon Ross 	struct page **plarr,
812*b819cea2SGordon Ross 	size_t plsz,
813*b819cea2SGordon Ross 	struct seg *seg,
814*b819cea2SGordon Ross 	caddr_t addr,
815*b819cea2SGordon Ross 	enum seg_rw rw,
816*b819cea2SGordon Ross 	cred_t *cr,
817*b819cea2SGordon Ross 	caller_context_t *ct)
818*b819cea2SGordon Ross {
819*b819cea2SGordon Ross 	return (ENOSYS);
820*b819cea2SGordon Ross }
821*b819cea2SGordon Ross 
822*b819cea2SGordon Ross /* ARGSUSED */
823*b819cea2SGordon Ross int
fop_putpage(vnode_t * vp,offset_t off,size_t len,int flags,cred_t * cr,caller_context_t * ct)824*b819cea2SGordon Ross fop_putpage(
825*b819cea2SGordon Ross 	vnode_t *vp,
826*b819cea2SGordon Ross 	offset_t off,
827*b819cea2SGordon Ross 	size_t len,
828*b819cea2SGordon Ross 	int flags,
829*b819cea2SGordon Ross 	cred_t *cr,
830*b819cea2SGordon Ross 	caller_context_t *ct)
831*b819cea2SGordon Ross {
832*b819cea2SGordon Ross 	return (ENOSYS);
833*b819cea2SGordon Ross }
834*b819cea2SGordon Ross 
835*b819cea2SGordon Ross /* ARGSUSED */
836*b819cea2SGordon Ross int
fop_map(vnode_t * vp,offset_t off,struct as * as,caddr_t * addrp,size_t len,uchar_t prot,uchar_t maxprot,uint_t flags,cred_t * cr,caller_context_t * ct)837*b819cea2SGordon Ross fop_map(
838*b819cea2SGordon Ross 	vnode_t *vp,
839*b819cea2SGordon Ross 	offset_t off,
840*b819cea2SGordon Ross 	struct as *as,
841*b819cea2SGordon Ross 	caddr_t *addrp,
842*b819cea2SGordon Ross 	size_t len,
843*b819cea2SGordon Ross 	uchar_t prot,
844*b819cea2SGordon Ross 	uchar_t maxprot,
845*b819cea2SGordon Ross 	uint_t flags,
846*b819cea2SGordon Ross 	cred_t *cr,
847*b819cea2SGordon Ross 	caller_context_t *ct)
848*b819cea2SGordon Ross {
849*b819cea2SGordon Ross 	return (ENOSYS);
850*b819cea2SGordon Ross }
851*b819cea2SGordon Ross 
852*b819cea2SGordon Ross /* ARGSUSED */
853*b819cea2SGordon Ross int
fop_addmap(vnode_t * vp,offset_t off,struct as * as,caddr_t addr,size_t len,uchar_t prot,uchar_t maxprot,uint_t flags,cred_t * cr,caller_context_t * ct)854*b819cea2SGordon Ross fop_addmap(
855*b819cea2SGordon Ross 	vnode_t *vp,
856*b819cea2SGordon Ross 	offset_t off,
857*b819cea2SGordon Ross 	struct as *as,
858*b819cea2SGordon Ross 	caddr_t addr,
859*b819cea2SGordon Ross 	size_t len,
860*b819cea2SGordon Ross 	uchar_t prot,
861*b819cea2SGordon Ross 	uchar_t maxprot,
862*b819cea2SGordon Ross 	uint_t flags,
863*b819cea2SGordon Ross 	cred_t *cr,
864*b819cea2SGordon Ross 	caller_context_t *ct)
865*b819cea2SGordon Ross {
866*b819cea2SGordon Ross 	return (ENOSYS);
867*b819cea2SGordon Ross }
868*b819cea2SGordon Ross 
869*b819cea2SGordon Ross /* ARGSUSED */
870*b819cea2SGordon Ross int
fop_delmap(vnode_t * vp,offset_t off,struct as * as,caddr_t addr,size_t len,uint_t prot,uint_t maxprot,uint_t flags,cred_t * cr,caller_context_t * ct)871*b819cea2SGordon Ross fop_delmap(
872*b819cea2SGordon Ross 	vnode_t *vp,
873*b819cea2SGordon Ross 	offset_t off,
874*b819cea2SGordon Ross 	struct as *as,
875*b819cea2SGordon Ross 	caddr_t addr,
876*b819cea2SGordon Ross 	size_t len,
877*b819cea2SGordon Ross 	uint_t prot,
878*b819cea2SGordon Ross 	uint_t maxprot,
879*b819cea2SGordon Ross 	uint_t flags,
880*b819cea2SGordon Ross 	cred_t *cr,
881*b819cea2SGordon Ross 	caller_context_t *ct)
882*b819cea2SGordon Ross {
883*b819cea2SGordon Ross 	return (ENOSYS);
884*b819cea2SGordon Ross }
885*b819cea2SGordon Ross 
886*b819cea2SGordon Ross /* ARGSUSED */
887*b819cea2SGordon Ross int
fop_poll(vnode_t * vp,short events,int anyyet,short * reventsp,struct pollhead ** phpp,caller_context_t * ct)888*b819cea2SGordon Ross fop_poll(
889*b819cea2SGordon Ross 	vnode_t *vp,
890*b819cea2SGordon Ross 	short events,
891*b819cea2SGordon Ross 	int anyyet,
892*b819cea2SGordon Ross 	short *reventsp,
893*b819cea2SGordon Ross 	struct pollhead **phpp,
894*b819cea2SGordon Ross 	caller_context_t *ct)
895*b819cea2SGordon Ross {
896*b819cea2SGordon Ross 	*reventsp = 0;
897*b819cea2SGordon Ross 	if (events & POLLIN)
898*b819cea2SGordon Ross 		*reventsp |= POLLIN;
899*b819cea2SGordon Ross 	if (events & POLLRDNORM)
900*b819cea2SGordon Ross 		*reventsp |= POLLRDNORM;
901*b819cea2SGordon Ross 	if (events & POLLRDBAND)
902*b819cea2SGordon Ross 		*reventsp |= POLLRDBAND;
903*b819cea2SGordon Ross 	if (events & POLLOUT)
904*b819cea2SGordon Ross 		*reventsp |= POLLOUT;
905*b819cea2SGordon Ross 	if (events & POLLWRBAND)
906*b819cea2SGordon Ross 		*reventsp |= POLLWRBAND;
907*b819cea2SGordon Ross 	*phpp = NULL; /* or fake_pollhead? */
908*b819cea2SGordon Ross 
909*b819cea2SGordon Ross 	return (0);
910*b819cea2SGordon Ross }
911*b819cea2SGordon Ross 
912*b819cea2SGordon Ross /* ARGSUSED */
913*b819cea2SGordon Ross int
fop_dump(vnode_t * vp,caddr_t addr,offset_t lbdn,offset_t dblks,caller_context_t * ct)914*b819cea2SGordon Ross fop_dump(
915*b819cea2SGordon Ross 	vnode_t *vp,
916*b819cea2SGordon Ross 	caddr_t addr,
917*b819cea2SGordon Ross 	offset_t lbdn,
918*b819cea2SGordon Ross 	offset_t dblks,
919*b819cea2SGordon Ross 	caller_context_t *ct)
920*b819cea2SGordon Ross {
921*b819cea2SGordon Ross 	return (ENOSYS);
922*b819cea2SGordon Ross }
923*b819cea2SGordon Ross 
924*b819cea2SGordon Ross /*
925*b819cea2SGordon Ross  * See fs_pathconf
926*b819cea2SGordon Ross  */
927*b819cea2SGordon Ross /* ARGSUSED */
928*b819cea2SGordon Ross int
fop_pathconf(vnode_t * vp,int cmd,ulong_t * valp,cred_t * cr,caller_context_t * ct)929*b819cea2SGordon Ross fop_pathconf(
930*b819cea2SGordon Ross 	vnode_t *vp,
931*b819cea2SGordon Ross 	int cmd,
932*b819cea2SGordon Ross 	ulong_t *valp,
933*b819cea2SGordon Ross 	cred_t *cr,
934*b819cea2SGordon Ross 	caller_context_t *ct)
935*b819cea2SGordon Ross {
936*b819cea2SGordon Ross 	register ulong_t val;
937*b819cea2SGordon Ross 	register int error = 0;
938*b819cea2SGordon Ross 
939*b819cea2SGordon Ross 	switch (cmd) {
940*b819cea2SGordon Ross 
941*b819cea2SGordon Ross 	case _PC_LINK_MAX:
942*b819cea2SGordon Ross 		val = MAXLINK;
943*b819cea2SGordon Ross 		break;
944*b819cea2SGordon Ross 
945*b819cea2SGordon Ross 	case _PC_MAX_CANON:
946*b819cea2SGordon Ross 		val = MAX_CANON;
947*b819cea2SGordon Ross 		break;
948*b819cea2SGordon Ross 
949*b819cea2SGordon Ross 	case _PC_MAX_INPUT:
950*b819cea2SGordon Ross 		val = MAX_INPUT;
951*b819cea2SGordon Ross 		break;
952*b819cea2SGordon Ross 
953*b819cea2SGordon Ross 	case _PC_NAME_MAX:
954*b819cea2SGordon Ross 		val = MAXNAMELEN;
955*b819cea2SGordon Ross 		break;
956*b819cea2SGordon Ross 
957*b819cea2SGordon Ross 	case _PC_PATH_MAX:
958*b819cea2SGordon Ross 	case _PC_SYMLINK_MAX:
959*b819cea2SGordon Ross 		val = MAXPATHLEN;
960*b819cea2SGordon Ross 		break;
961*b819cea2SGordon Ross 
962*b819cea2SGordon Ross 	case _PC_PIPE_BUF:
963*b819cea2SGordon Ross 		val = PIPE_BUF;
964*b819cea2SGordon Ross 		break;
965*b819cea2SGordon Ross 
966*b819cea2SGordon Ross 	case _PC_NO_TRUNC:
967*b819cea2SGordon Ross 		val = (ulong_t)-1;
968*b819cea2SGordon Ross 		break;
969*b819cea2SGordon Ross 
970*b819cea2SGordon Ross 	case _PC_VDISABLE:
971*b819cea2SGordon Ross 		val = _POSIX_VDISABLE;
972*b819cea2SGordon Ross 		break;
973*b819cea2SGordon Ross 
974*b819cea2SGordon Ross 	case _PC_CHOWN_RESTRICTED:
975*b819cea2SGordon Ross 		val = 1; /* chown restricted enabled */
976*b819cea2SGordon Ross 		break;
977*b819cea2SGordon Ross 
978*b819cea2SGordon Ross 	case _PC_FILESIZEBITS:
979*b819cea2SGordon Ross 		val = (ulong_t)-1;    /* large file support */
980*b819cea2SGordon Ross 		break;
981*b819cea2SGordon Ross 
982*b819cea2SGordon Ross 	case _PC_ACL_ENABLED:
983*b819cea2SGordon Ross 		val = 0;
984*b819cea2SGordon Ross 		break;
985*b819cea2SGordon Ross 
986*b819cea2SGordon Ross 	case _PC_CASE_BEHAVIOR:
987*b819cea2SGordon Ross 		val = _CASE_SENSITIVE;
988*b819cea2SGordon Ross 		break;
989*b819cea2SGordon Ross 
990*b819cea2SGordon Ross 	case _PC_SATTR_ENABLED:
991*b819cea2SGordon Ross 	case _PC_SATTR_EXISTS:
992*b819cea2SGordon Ross 		val = 0;
993*b819cea2SGordon Ross 		break;
994*b819cea2SGordon Ross 
995*b819cea2SGordon Ross 	case _PC_ACCESS_FILTERING:
996*b819cea2SGordon Ross 		val = 0;
997*b819cea2SGordon Ross 		break;
998*b819cea2SGordon Ross 
999*b819cea2SGordon Ross 	default:
1000*b819cea2SGordon Ross 		error = EINVAL;
1001*b819cea2SGordon Ross 		break;
1002*b819cea2SGordon Ross 	}
1003*b819cea2SGordon Ross 
1004*b819cea2SGordon Ross 	if (error == 0)
1005*b819cea2SGordon Ross 		*valp = val;
1006*b819cea2SGordon Ross 	return (error);
1007*b819cea2SGordon Ross }
1008*b819cea2SGordon Ross 
1009*b819cea2SGordon Ross /* ARGSUSED */
1010*b819cea2SGordon Ross int
fop_pageio(vnode_t * vp,struct page * pp,u_offset_t io_off,size_t io_len,int flags,cred_t * cr,caller_context_t * ct)1011*b819cea2SGordon Ross fop_pageio(
1012*b819cea2SGordon Ross 	vnode_t *vp,
1013*b819cea2SGordon Ross 	struct page *pp,
1014*b819cea2SGordon Ross 	u_offset_t io_off,
1015*b819cea2SGordon Ross 	size_t io_len,
1016*b819cea2SGordon Ross 	int flags,
1017*b819cea2SGordon Ross 	cred_t *cr,
1018*b819cea2SGordon Ross 	caller_context_t *ct)
1019*b819cea2SGordon Ross {
1020*b819cea2SGordon Ross 	return (ENOSYS);
1021*b819cea2SGordon Ross }
1022*b819cea2SGordon Ross 
1023*b819cea2SGordon Ross /* ARGSUSED */
1024*b819cea2SGordon Ross int
fop_dumpctl(vnode_t * vp,int action,offset_t * blkp,caller_context_t * ct)1025*b819cea2SGordon Ross fop_dumpctl(
1026*b819cea2SGordon Ross 	vnode_t *vp,
1027*b819cea2SGordon Ross 	int action,
1028*b819cea2SGordon Ross 	offset_t *blkp,
1029*b819cea2SGordon Ross 	caller_context_t *ct)
1030*b819cea2SGordon Ross {
1031*b819cea2SGordon Ross 	return (ENOSYS);
1032*b819cea2SGordon Ross }
1033*b819cea2SGordon Ross 
1034*b819cea2SGordon Ross /* ARGSUSED */
1035*b819cea2SGordon Ross void
fop_dispose(vnode_t * vp,struct page * pp,int flag,int dn,cred_t * cr,caller_context_t * ct)1036*b819cea2SGordon Ross fop_dispose(
1037*b819cea2SGordon Ross 	vnode_t *vp,
1038*b819cea2SGordon Ross 	struct page *pp,
1039*b819cea2SGordon Ross 	int flag,
1040*b819cea2SGordon Ross 	int dn,
1041*b819cea2SGordon Ross 	cred_t *cr,
1042*b819cea2SGordon Ross 	caller_context_t *ct)
1043*b819cea2SGordon Ross {
1044*b819cea2SGordon Ross }
1045*b819cea2SGordon Ross 
1046*b819cea2SGordon Ross /* ARGSUSED */
1047*b819cea2SGordon Ross int
fop_setsecattr(vnode_t * vp,vsecattr_t * vsap,int flag,cred_t * cr,caller_context_t * ct)1048*b819cea2SGordon Ross fop_setsecattr(
1049*b819cea2SGordon Ross 	vnode_t *vp,
1050*b819cea2SGordon Ross 	vsecattr_t *vsap,
1051*b819cea2SGordon Ross 	int flag,
1052*b819cea2SGordon Ross 	cred_t *cr,
1053*b819cea2SGordon Ross 	caller_context_t *ct)
1054*b819cea2SGordon Ross {
1055*b819cea2SGordon Ross 	return (0);
1056*b819cea2SGordon Ross }
1057*b819cea2SGordon Ross 
1058*b819cea2SGordon Ross /*
1059*b819cea2SGordon Ross  * Fake up just enough of this so we can test get/set SDs.
1060*b819cea2SGordon Ross  */
1061*b819cea2SGordon Ross /* ARGSUSED */
1062*b819cea2SGordon Ross int
fop_getsecattr(vnode_t * vp,vsecattr_t * vsecattr,int flag,cred_t * cr,caller_context_t * ct)1063*b819cea2SGordon Ross fop_getsecattr(
1064*b819cea2SGordon Ross 	vnode_t *vp,
1065*b819cea2SGordon Ross 	vsecattr_t *vsecattr,
1066*b819cea2SGordon Ross 	int flag,
1067*b819cea2SGordon Ross 	cred_t *cr,
1068*b819cea2SGordon Ross 	caller_context_t *ct)
1069*b819cea2SGordon Ross {
1070*b819cea2SGordon Ross 
1071*b819cea2SGordon Ross 	vsecattr->vsa_aclcnt	= 0;
1072*b819cea2SGordon Ross 	vsecattr->vsa_aclentsz	= 0;
1073*b819cea2SGordon Ross 	vsecattr->vsa_aclentp	= NULL;
1074*b819cea2SGordon Ross 	vsecattr->vsa_dfaclcnt	= 0;	/* Default ACLs are not fabricated */
1075*b819cea2SGordon Ross 	vsecattr->vsa_dfaclentp	= NULL;
1076*b819cea2SGordon Ross 
1077*b819cea2SGordon Ross 	if (vsecattr->vsa_mask & (VSA_ACLCNT | VSA_ACL)) {
1078*b819cea2SGordon Ross 		aclent_t *aclentp;
1079*b819cea2SGordon Ross 		size_t aclsize;
1080*b819cea2SGordon Ross 
1081*b819cea2SGordon Ross 		aclsize = sizeof (aclent_t);
1082*b819cea2SGordon Ross 		vsecattr->vsa_aclcnt = 1;
1083*b819cea2SGordon Ross 		vsecattr->vsa_aclentp = kmem_zalloc(aclsize, KM_SLEEP);
1084*b819cea2SGordon Ross 		aclentp = vsecattr->vsa_aclentp;
1085*b819cea2SGordon Ross 
1086*b819cea2SGordon Ross 		aclentp->a_type = OTHER_OBJ;
1087*b819cea2SGordon Ross 		aclentp->a_perm = 0777;
1088*b819cea2SGordon Ross 		aclentp->a_id = (gid_t)-1;
1089*b819cea2SGordon Ross 		aclentp++;
1090*b819cea2SGordon Ross 	} else if (vsecattr->vsa_mask & (VSA_ACECNT | VSA_ACE)) {
1091*b819cea2SGordon Ross 		ace_t *acl;
1092*b819cea2SGordon Ross 
1093*b819cea2SGordon Ross 		acl = kmem_alloc(sizeof (ace_t), KM_SLEEP);
1094*b819cea2SGordon Ross 		acl->a_who = (uint32_t)-1;
1095*b819cea2SGordon Ross 		acl->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
1096*b819cea2SGordon Ross 		acl->a_flags = ACE_EVERYONE;
1097*b819cea2SGordon Ross 		acl->a_access_mask  = ACE_MODIFY_PERMS;
1098*b819cea2SGordon Ross 
1099*b819cea2SGordon Ross 		vsecattr->vsa_aclentp = (void *)acl;
1100*b819cea2SGordon Ross 		vsecattr->vsa_aclcnt = 1;
1101*b819cea2SGordon Ross 		vsecattr->vsa_aclentsz = sizeof (ace_t);
1102*b819cea2SGordon Ross 	}
1103*b819cea2SGordon Ross 
1104*b819cea2SGordon Ross 	return (0);
1105*b819cea2SGordon Ross }
1106*b819cea2SGordon Ross 
1107*b819cea2SGordon Ross /* ARGSUSED */
1108*b819cea2SGordon Ross int
fop_shrlock(vnode_t * vp,int cmd,struct shrlock * shr,int flag,cred_t * cr,caller_context_t * ct)1109*b819cea2SGordon Ross fop_shrlock(
1110*b819cea2SGordon Ross 	vnode_t *vp,
1111*b819cea2SGordon Ross 	int cmd,
1112*b819cea2SGordon Ross 	struct shrlock *shr,
1113*b819cea2SGordon Ross 	int flag,
1114*b819cea2SGordon Ross 	cred_t *cr,
1115*b819cea2SGordon Ross 	caller_context_t *ct)
1116*b819cea2SGordon Ross {
1117*b819cea2SGordon Ross 
1118*b819cea2SGordon Ross 	switch (cmd) {
1119*b819cea2SGordon Ross 	case F_SHARE:
1120*b819cea2SGordon Ross 	case F_SHARE_NBMAND:
1121*b819cea2SGordon Ross 	case F_UNSHARE:
1122*b819cea2SGordon Ross 		break;
1123*b819cea2SGordon Ross 	default:
1124*b819cea2SGordon Ross 		return (EINVAL);
1125*b819cea2SGordon Ross 	}
1126*b819cea2SGordon Ross 
1127*b819cea2SGordon Ross 	if (!fop_shrlock_enable)
1128*b819cea2SGordon Ross 		return (0);
1129*b819cea2SGordon Ross 
1130*b819cea2SGordon Ross 	if (fcntl(vp->v_fd, cmd, shr) == -1)
1131*b819cea2SGordon Ross 		return (errno);
1132*b819cea2SGordon Ross 
1133*b819cea2SGordon Ross 	return (0);
1134*b819cea2SGordon Ross }
1135*b819cea2SGordon Ross 
1136*b819cea2SGordon Ross /* ARGSUSED */
1137*b819cea2SGordon Ross int
fop_vnevent(vnode_t * vp,vnevent_t vnevent,vnode_t * dvp,char * fnm,caller_context_t * ct)1138*b819cea2SGordon Ross fop_vnevent(vnode_t *vp, vnevent_t vnevent, vnode_t *dvp, char *fnm,
1139*b819cea2SGordon Ross     caller_context_t *ct)
1140*b819cea2SGordon Ross {
1141*b819cea2SGordon Ross 	return (ENOSYS);
1142*b819cea2SGordon Ross }
1143*b819cea2SGordon Ross 
1144*b819cea2SGordon Ross /* ARGSUSED */
1145*b819cea2SGordon Ross int
fop_reqzcbuf(vnode_t * vp,enum uio_rw ioflag,xuio_t * uiop,cred_t * cr,caller_context_t * ct)1146*b819cea2SGordon Ross fop_reqzcbuf(vnode_t *vp, enum uio_rw ioflag, xuio_t *uiop, cred_t *cr,
1147*b819cea2SGordon Ross     caller_context_t *ct)
1148*b819cea2SGordon Ross {
1149*b819cea2SGordon Ross 	return (ENOSYS);
1150*b819cea2SGordon Ross }
1151*b819cea2SGordon Ross 
1152*b819cea2SGordon Ross /* ARGSUSED */
1153*b819cea2SGordon Ross int
fop_retzcbuf(vnode_t * vp,xuio_t * uiop,cred_t * cr,caller_context_t * ct)1154*b819cea2SGordon Ross fop_retzcbuf(vnode_t *vp, xuio_t *uiop, cred_t *cr, caller_context_t *ct)
1155*b819cea2SGordon Ross {
1156*b819cea2SGordon Ross 	return (ENOSYS);
1157*b819cea2SGordon Ross }
1158*b819cea2SGordon Ross 
1159*b819cea2SGordon Ross 
1160*b819cea2SGordon Ross /*
1161*b819cea2SGordon Ross  * ***************************************************************
1162*b819cea2SGordon Ross  * other VOP support
1163*b819cea2SGordon Ross  */
1164*b819cea2SGordon Ross 
1165*b819cea2SGordon Ross /*
1166*b819cea2SGordon Ross  * Convert stat(2) formats to vnode types and vice versa.  (Knows about
1167*b819cea2SGordon Ross  * numerical order of S_IFMT and vnode types.)
1168*b819cea2SGordon Ross  */
1169*b819cea2SGordon Ross enum vtype iftovt_tab[] = {
1170*b819cea2SGordon Ross 	VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
1171*b819cea2SGordon Ross 	VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VNON
1172*b819cea2SGordon Ross };
1173*b819cea2SGordon Ross 
1174*b819cea2SGordon Ross ushort_t vttoif_tab[] = {
1175*b819cea2SGordon Ross 	0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFIFO,
1176*b819cea2SGordon Ross 	S_IFDOOR, 0, S_IFSOCK, S_IFPORT, 0
1177*b819cea2SGordon Ross };
1178*b819cea2SGordon Ross 
1179*b819cea2SGordon Ross /*
1180*b819cea2SGordon Ross  * stat_to_vattr()
1181*b819cea2SGordon Ross  *
1182*b819cea2SGordon Ross  * Convert from a stat structure to an vattr structure
1183*b819cea2SGordon Ross  * Note: only set fields according to va_mask
1184*b819cea2SGordon Ross  */
1185*b819cea2SGordon Ross 
1186*b819cea2SGordon Ross int
stat_to_vattr(const struct stat * st,vattr_t * vap)1187*b819cea2SGordon Ross stat_to_vattr(const struct stat *st, vattr_t *vap)
1188*b819cea2SGordon Ross {
1189*b819cea2SGordon Ross 
1190*b819cea2SGordon Ross 	if (vap->va_mask & AT_TYPE)
1191*b819cea2SGordon Ross 		vap->va_type = IFTOVT(st->st_mode);
1192*b819cea2SGordon Ross 
1193*b819cea2SGordon Ross 	if (vap->va_mask & AT_MODE)
1194*b819cea2SGordon Ross 		vap->va_mode = st->st_mode;
1195*b819cea2SGordon Ross 
1196*b819cea2SGordon Ross 	if (vap->va_mask & AT_UID)
1197*b819cea2SGordon Ross 		vap->va_uid = st->st_uid;
1198*b819cea2SGordon Ross 
1199*b819cea2SGordon Ross 	if (vap->va_mask & AT_GID)
1200*b819cea2SGordon Ross 		vap->va_gid = st->st_gid;
1201*b819cea2SGordon Ross 
1202*b819cea2SGordon Ross 	if (vap->va_mask & AT_FSID)
1203*b819cea2SGordon Ross 		vap->va_fsid = st->st_dev;
1204*b819cea2SGordon Ross 
1205*b819cea2SGordon Ross 	if (vap->va_mask & AT_NODEID)
1206*b819cea2SGordon Ross 		vap->va_nodeid = st->st_ino;
1207*b819cea2SGordon Ross 
1208*b819cea2SGordon Ross 	if (vap->va_mask & AT_NLINK)
1209*b819cea2SGordon Ross 		vap->va_nlink = st->st_nlink;
1210*b819cea2SGordon Ross 
1211*b819cea2SGordon Ross 	if (vap->va_mask & AT_SIZE)
1212*b819cea2SGordon Ross 		vap->va_size = (u_offset_t)st->st_size;
1213*b819cea2SGordon Ross 
1214*b819cea2SGordon Ross 	if (vap->va_mask & AT_ATIME) {
1215*b819cea2SGordon Ross 		vap->va_atime.tv_sec  = st->st_atim.tv_sec;
1216*b819cea2SGordon Ross 		vap->va_atime.tv_nsec = st->st_atim.tv_nsec;
1217*b819cea2SGordon Ross 	}
1218*b819cea2SGordon Ross 
1219*b819cea2SGordon Ross 	if (vap->va_mask & AT_MTIME) {
1220*b819cea2SGordon Ross 		vap->va_mtime.tv_sec  = st->st_mtim.tv_sec;
1221*b819cea2SGordon Ross 		vap->va_mtime.tv_nsec = st->st_mtim.tv_nsec;
1222*b819cea2SGordon Ross 	}
1223*b819cea2SGordon Ross 
1224*b819cea2SGordon Ross 	if (vap->va_mask & AT_CTIME) {
1225*b819cea2SGordon Ross 		vap->va_ctime.tv_sec  = st->st_ctim.tv_sec;
1226*b819cea2SGordon Ross 		vap->va_ctime.tv_nsec = st->st_ctim.tv_nsec;
1227*b819cea2SGordon Ross 	}
1228*b819cea2SGordon Ross 
1229*b819cea2SGordon Ross 	if (vap->va_mask & AT_RDEV)
1230*b819cea2SGordon Ross 		vap->va_rdev = st->st_rdev;
1231*b819cea2SGordon Ross 
1232*b819cea2SGordon Ross 	if (vap->va_mask & AT_BLKSIZE)
1233*b819cea2SGordon Ross 		vap->va_blksize = (uint_t)st->st_blksize;
1234*b819cea2SGordon Ross 
1235*b819cea2SGordon Ross 
1236*b819cea2SGordon Ross 	if (vap->va_mask & AT_NBLOCKS)
1237*b819cea2SGordon Ross 		vap->va_nblocks = (u_longlong_t)st->st_blocks;
1238*b819cea2SGordon Ross 
1239*b819cea2SGordon Ross 	if (vap->va_mask & AT_SEQ)
1240*b819cea2SGordon Ross 		vap->va_seq = 0;
1241*b819cea2SGordon Ross 
1242*b819cea2SGordon Ross 	return (0);
1243*b819cea2SGordon Ross }
1244*b819cea2SGordon Ross 
1245*b819cea2SGordon Ross /* ARGSUSED */
1246*b819cea2SGordon Ross void
flk_init_callback(flk_callback_t * flk_cb,callb_cpr_t * (* cb_fcn)(flk_cb_when_t,void *),void * cbdata)1247*b819cea2SGordon Ross flk_init_callback(flk_callback_t *flk_cb,
1248*b819cea2SGordon Ross 	callb_cpr_t *(*cb_fcn)(flk_cb_when_t, void *), void *cbdata)
1249*b819cea2SGordon Ross {
1250*b819cea2SGordon Ross }
1251*b819cea2SGordon Ross 
1252*b819cea2SGordon Ross void
vn_hold(vnode_t * vp)1253*b819cea2SGordon Ross vn_hold(vnode_t *vp)
1254*b819cea2SGordon Ross {
1255*b819cea2SGordon Ross 	mutex_enter(&vp->v_lock);
1256*b819cea2SGordon Ross 	vp->v_count++;
1257*b819cea2SGordon Ross 	mutex_exit(&vp->v_lock);
1258*b819cea2SGordon Ross }
1259*b819cea2SGordon Ross 
1260*b819cea2SGordon Ross void
vn_rele(vnode_t * vp)1261*b819cea2SGordon Ross vn_rele(vnode_t *vp)
1262*b819cea2SGordon Ross {
1263*b819cea2SGordon Ross 	VERIFY3U(vp->v_count, !=, 0);
1264*b819cea2SGordon Ross 	mutex_enter(&vp->v_lock);
1265*b819cea2SGordon Ross 	if (vp->v_count == 1) {
1266*b819cea2SGordon Ross 		mutex_exit(&vp->v_lock);
1267*b819cea2SGordon Ross 		vncache_inactive(vp);
1268*b819cea2SGordon Ross 	} else {
1269*b819cea2SGordon Ross 		vp->v_count--;
1270*b819cea2SGordon Ross 		mutex_exit(&vp->v_lock);
1271*b819cea2SGordon Ross 	}
1272*b819cea2SGordon Ross }
1273*b819cea2SGordon Ross 
1274*b819cea2SGordon Ross int
vn_has_other_opens(vnode_t * vp,v_mode_t mode)1275*b819cea2SGordon Ross vn_has_other_opens(
1276*b819cea2SGordon Ross 	vnode_t *vp,
1277*b819cea2SGordon Ross 	v_mode_t mode)
1278*b819cea2SGordon Ross {
1279*b819cea2SGordon Ross 
1280*b819cea2SGordon Ross 	switch (mode) {
1281*b819cea2SGordon Ross 	case V_WRITE:
1282*b819cea2SGordon Ross 		if (vp->v_wrcnt > 1)
1283*b819cea2SGordon Ross 			return (V_TRUE);
1284*b819cea2SGordon Ross 		break;
1285*b819cea2SGordon Ross 	case V_RDORWR:
1286*b819cea2SGordon Ross 		if ((vp->v_rdcnt > 1) || (vp->v_wrcnt > 1))
1287*b819cea2SGordon Ross 			return (V_TRUE);
1288*b819cea2SGordon Ross 		break;
1289*b819cea2SGordon Ross 	case V_RDANDWR:
1290*b819cea2SGordon Ross 		if ((vp->v_rdcnt > 1) && (vp->v_wrcnt > 1))
1291*b819cea2SGordon Ross 			return (V_TRUE);
1292*b819cea2SGordon Ross 		break;
1293*b819cea2SGordon Ross 	case V_READ:
1294*b819cea2SGordon Ross 		if (vp->v_rdcnt > 1)
1295*b819cea2SGordon Ross 			return (V_TRUE);
1296*b819cea2SGordon Ross 		break;
1297*b819cea2SGordon Ross 	}
1298*b819cea2SGordon Ross 
1299*b819cea2SGordon Ross 	return (V_FALSE);
1300*b819cea2SGordon Ross }
1301*b819cea2SGordon Ross 
1302*b819cea2SGordon Ross /*
1303*b819cea2SGordon Ross  * vn_is_opened() checks whether a particular file is opened and
1304*b819cea2SGordon Ross  * whether the open is for read and/or write.
1305*b819cea2SGordon Ross  *
1306*b819cea2SGordon Ross  * Vnode counts are only kept on regular files (v_type=VREG).
1307*b819cea2SGordon Ross  */
1308*b819cea2SGordon Ross int
vn_is_opened(vnode_t * vp,v_mode_t mode)1309*b819cea2SGordon Ross vn_is_opened(
1310*b819cea2SGordon Ross 	vnode_t *vp,
1311*b819cea2SGordon Ross 	v_mode_t mode)
1312*b819cea2SGordon Ross {
1313*b819cea2SGordon Ross 
1314*b819cea2SGordon Ross 	ASSERT(vp != NULL);
1315*b819cea2SGordon Ross 
1316*b819cea2SGordon Ross 	switch (mode) {
1317*b819cea2SGordon Ross 	case V_WRITE:
1318*b819cea2SGordon Ross 		if (vp->v_wrcnt)
1319*b819cea2SGordon Ross 			return (V_TRUE);
1320*b819cea2SGordon Ross 		break;
1321*b819cea2SGordon Ross 	case V_RDANDWR:
1322*b819cea2SGordon Ross 		if (vp->v_rdcnt && vp->v_wrcnt)
1323*b819cea2SGordon Ross 			return (V_TRUE);
1324*b819cea2SGordon Ross 		break;
1325*b819cea2SGordon Ross 	case V_RDORWR:
1326*b819cea2SGordon Ross 		if (vp->v_rdcnt || vp->v_wrcnt)
1327*b819cea2SGordon Ross 			return (V_TRUE);
1328*b819cea2SGordon Ross 		break;
1329*b819cea2SGordon Ross 	case V_READ:
1330*b819cea2SGordon Ross 		if (vp->v_rdcnt)
1331*b819cea2SGordon Ross 			return (V_TRUE);
1332*b819cea2SGordon Ross 		break;
1333*b819cea2SGordon Ross 	}
1334*b819cea2SGordon Ross 
1335*b819cea2SGordon Ross 	return (V_FALSE);
1336*b819cea2SGordon Ross }
1337*b819cea2SGordon Ross 
1338*b819cea2SGordon Ross /*
1339*b819cea2SGordon Ross  * vn_is_mapped() checks whether a particular file is mapped and whether
1340*b819cea2SGordon Ross  * the file is mapped read and/or write.
1341*b819cea2SGordon Ross  */
1342*b819cea2SGordon Ross /* ARGSUSED */
1343*b819cea2SGordon Ross int
vn_is_mapped(vnode_t * vp,v_mode_t mode)1344*b819cea2SGordon Ross vn_is_mapped(
1345*b819cea2SGordon Ross 	vnode_t *vp,
1346*b819cea2SGordon Ross 	v_mode_t mode)
1347*b819cea2SGordon Ross {
1348*b819cea2SGordon Ross 	return (V_FALSE);
1349*b819cea2SGordon Ross }
1350