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