8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / smbsrv / libfksmbsrv / common / fake_vop.c
blob41c301fbaaded314f4d7e431e3dc844391ad255a
1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
16 #include <sys/types.h>
17 #include <sys/param.h>
18 #include <sys/t_lock.h>
19 #include <sys/errno.h>
20 #include <sys/cred.h>
21 #include <sys/user.h>
22 #include <sys/uio.h>
23 #include <sys/file.h>
24 #include <sys/pathname.h>
25 #include <sys/vfs.h>
26 #include <sys/vnode.h>
27 #include <sys/stat.h>
28 #include <sys/mode.h>
29 #include <sys/kmem.h>
30 #include <sys/debug.h>
31 #include <sys/atomic.h>
32 #include <sys/acl.h>
33 #include <sys/flock.h>
34 #include <sys/nbmlock.h>
35 #include <sys/fcntl.h>
36 #include <sys/poll.h>
37 #include <sys/time.h>
39 #include <errno.h>
40 #include <fcntl.h>
41 #include <unistd.h>
43 #include "vncache.h"
45 #define O_RWMASK (O_WRONLY | O_RDWR) /* == 3 */
47 int fop_shrlock_enable = 0;
49 int stat_to_vattr(const struct stat *, vattr_t *);
50 int fop__getxvattr(vnode_t *, xvattr_t *);
51 int fop__setxvattr(vnode_t *, xvattr_t *);
54 /* ARGSUSED */
55 int
56 fop_open(
57 vnode_t **vpp,
58 int mode,
59 cred_t *cr,
60 caller_context_t *ct)
63 if ((*vpp)->v_type == VREG) {
64 if (mode & FREAD)
65 atomic_add_32(&((*vpp)->v_rdcnt), 1);
66 if (mode & FWRITE)
67 atomic_add_32(&((*vpp)->v_wrcnt), 1);
70 /* call to ->vop_open was here */
72 return (0);
75 /* ARGSUSED */
76 int
77 fop_close(
78 vnode_t *vp,
79 int flag,
80 int count,
81 offset_t offset,
82 cred_t *cr,
83 caller_context_t *ct)
86 /* call to ->vop_close was here */
89 * Check passed in count to handle possible dups. Vnode counts are only
90 * kept on regular files
92 if ((vp->v_type == VREG) && (count == 1)) {
93 if (flag & FREAD) {
94 ASSERT(vp->v_rdcnt > 0);
95 atomic_add_32(&(vp->v_rdcnt), -1);
97 if (flag & FWRITE) {
98 ASSERT(vp->v_wrcnt > 0);
99 atomic_add_32(&(vp->v_wrcnt), -1);
102 return (0);
105 /* ARGSUSED */
107 fop_read(
108 vnode_t *vp,
109 uio_t *uio,
110 int ioflag,
111 cred_t *cr,
112 caller_context_t *ct)
114 struct stat st;
115 struct iovec *iov;
116 ssize_t resid;
117 size_t cnt;
118 int n;
121 * If that caller asks for read beyond end of file,
122 * that causes the pread call to block. (Ugh!)
123 * Get the file size and return what we can.
125 (void) fstat(vp->v_fd, &st);
126 resid = uio->uio_resid;
127 if ((uio->uio_loffset + resid) > st.st_size)
128 resid = st.st_size - uio->uio_loffset;
130 while (resid > 0) {
132 ASSERT(uio->uio_iovcnt > 0);
133 iov = uio->uio_iov;
135 if (iov->iov_len == 0) {
136 uio->uio_iov++;
137 uio->uio_iovcnt--;
138 continue;
140 cnt = iov->iov_len;
141 if (cnt > resid)
142 cnt = resid;
144 n = pread(vp->v_fd, iov->iov_base, cnt, uio->uio_loffset);
145 if (n < 0)
146 return (errno);
148 iov->iov_base += n;
149 iov->iov_len -= n;
151 uio->uio_resid -= n;
152 uio->uio_loffset += n;
154 resid -= n;
157 return (0);
160 /* ARGSUSED */
162 fop_write(
163 vnode_t *vp,
164 uio_t *uio,
165 int ioflag,
166 cred_t *cr,
167 caller_context_t *ct)
169 struct iovec *iov;
170 size_t cnt;
171 int n;
173 while (uio->uio_resid > 0) {
175 ASSERT(uio->uio_iovcnt > 0);
176 iov = uio->uio_iov;
178 if (iov->iov_len == 0) {
179 uio->uio_iov++;
180 uio->uio_iovcnt--;
181 continue;
183 cnt = iov->iov_len;
184 if (cnt > uio->uio_resid)
185 cnt = uio->uio_resid;
187 n = pwrite(vp->v_fd, iov->iov_base, iov->iov_len,
188 uio->uio_loffset);
189 if (n < 0)
190 return (errno);
192 iov->iov_base += n;
193 iov->iov_len -= n;
195 uio->uio_resid -= n;
196 uio->uio_loffset += n;
199 if (ioflag == FSYNC) {
200 (void) fsync(vp->v_fd);
203 return (0);
206 /* ARGSUSED */
208 fop_ioctl(
209 vnode_t *vp,
210 int cmd,
211 intptr_t arg,
212 int flag,
213 cred_t *cr,
214 int *rvalp,
215 caller_context_t *ct)
217 return (ENOSYS);
220 /* ARGSUSED */
222 fop_setfl(
223 vnode_t *vp,
224 int oflags,
225 int nflags,
226 cred_t *cr,
227 caller_context_t *ct)
229 /* allow any flags? See fs_setfl */
230 return (0);
233 /* ARGSUSED */
235 fop_getattr(
236 vnode_t *vp,
237 vattr_t *vap,
238 int flags,
239 cred_t *cr,
240 caller_context_t *ct)
242 int error;
243 struct stat st;
245 if (fstat(vp->v_fd, &st) == -1)
246 return (errno);
247 error = stat_to_vattr(&st, vap);
249 if (vap->va_mask & AT_XVATTR)
250 (void) fop__getxvattr(vp, (xvattr_t *)vap);
252 return (error);
255 /* ARGSUSED */
257 fop_setattr(
258 vnode_t *vp,
259 vattr_t *vap,
260 int flags,
261 cred_t *cr,
262 caller_context_t *ct)
264 timespec_t times[2];
266 if (vap->va_mask & AT_SIZE) {
267 if (ftruncate(vp->v_fd, vap->va_size) == -1)
268 return (errno);
271 /* AT_MODE or anything else? */
273 if (vap->va_mask & AT_XVATTR)
274 (void) fop__setxvattr(vp, (xvattr_t *)vap);
276 if (vap->va_mask & (AT_ATIME | AT_MTIME)) {
277 if (vap->va_mask & AT_ATIME) {
278 times[0] = vap->va_atime;
279 } else {
280 times[0].tv_sec = 0;
281 times[0].tv_nsec = UTIME_OMIT;
283 if (vap->va_mask & AT_MTIME) {
284 times[1] = vap->va_mtime;
285 } else {
286 times[1].tv_sec = 0;
287 times[1].tv_nsec = UTIME_OMIT;
290 (void) futimens(vp->v_fd, times);
293 return (0);
296 /* ARGSUSED */
298 fop_access(
299 vnode_t *vp,
300 int mode,
301 int flags,
302 cred_t *cr,
303 caller_context_t *ct)
305 return (0);
308 /* ARGSUSED */
310 fop_lookup(
311 vnode_t *dvp,
312 char *name,
313 vnode_t **vpp,
314 pathname_t *pnp,
315 int flags,
316 vnode_t *rdir,
317 cred_t *cr,
318 caller_context_t *ct,
319 int *deflags, /* Returned per-dirent flags */
320 pathname_t *ppnp) /* Returned case-preserved name in directory */
322 int fd;
323 int omode = O_RDWR | O_NOFOLLOW;
324 vnode_t *vp;
325 struct stat st;
327 if (flags & LOOKUP_XATTR)
328 return (ENOENT);
331 * If lookup is for "", just return dvp.
333 if (name[0] == '\0') {
334 vn_hold(dvp);
335 *vpp = dvp;
336 return (0);
339 if (fstatat(dvp->v_fd, name, &st, AT_SYMLINK_NOFOLLOW) == -1)
340 return (errno);
342 vp = vncache_lookup(&st);
343 if (vp != NULL) {
344 /* lookup gave us a hold */
345 *vpp = vp;
346 return (0);
349 if (S_ISDIR(st.st_mode))
350 omode = O_RDONLY | O_NOFOLLOW;
352 again:
353 fd = openat(dvp->v_fd, name, omode, 0);
354 if (fd < 0) {
355 if ((omode & O_RWMASK) == O_RDWR) {
356 omode &= ~O_RWMASK;
357 omode |= O_RDONLY;
358 goto again;
360 return (errno);
363 if (fstat(fd, &st) == -1) {
364 (void) close(fd);
365 return (errno);
368 vp = vncache_enter(&st, dvp, name, fd);
370 *vpp = vp;
371 return (0);
374 /* ARGSUSED */
376 fop_create(
377 vnode_t *dvp,
378 char *name,
379 vattr_t *vap,
380 vcexcl_t excl,
381 int mode,
382 vnode_t **vpp,
383 cred_t *cr,
384 int flags,
385 caller_context_t *ct,
386 vsecattr_t *vsecp) /* ACL to set during create */
388 struct stat st;
389 vnode_t *vp;
390 int err, fd, omode;
393 * If creating "", just return dvp.
395 if (name[0] == '\0') {
396 vn_hold(dvp);
397 *vpp = dvp;
398 return (0);
401 err = fstatat(dvp->v_fd, name, &st, AT_SYMLINK_NOFOLLOW);
402 if (err != 0)
403 err = errno;
405 vp = NULL;
406 if (err == 0) {
407 /* The file already exists. */
408 if (excl == EXCL)
409 return (EEXIST);
411 vp = vncache_lookup(&st);
412 /* vp gained a hold */
415 if (vp == NULL) {
417 * Open it. (may or may not exist)
419 omode = O_RDWR | O_CREAT | O_NOFOLLOW;
420 if (excl == EXCL)
421 omode |= O_EXCL;
422 open_again:
423 fd = openat(dvp->v_fd, name, omode, mode);
424 if (fd < 0) {
425 if ((omode & O_RWMASK) == O_RDWR) {
426 omode &= ~O_RWMASK;
427 omode |= O_RDONLY;
428 goto open_again;
430 return (errno);
432 (void) fstat(fd, &st);
434 vp = vncache_enter(&st, dvp, name, fd);
435 /* vp has its initial hold */
438 /* Should have the vp now. */
439 if (vp == NULL)
440 return (EFAULT);
442 if (vp->v_type == VDIR && vap->va_type != VDIR) {
443 vn_rele(vp);
444 return (EISDIR);
446 if (vp->v_type != VDIR && vap->va_type == VDIR) {
447 vn_rele(vp);
448 return (ENOTDIR);
452 * Might need to set attributes.
454 (void) fop_setattr(vp, vap, 0, cr, ct);
456 *vpp = vp;
457 return (0);
460 /* ARGSUSED */
462 fop_remove(
463 vnode_t *dvp,
464 char *name,
465 cred_t *cr,
466 caller_context_t *ct,
467 int flags)
470 if (unlinkat(dvp->v_fd, name, 0))
471 return (errno);
473 return (0);
476 /* ARGSUSED */
478 fop_link(
479 vnode_t *to_dvp,
480 vnode_t *fr_vp,
481 char *to_name,
482 cred_t *cr,
483 caller_context_t *ct,
484 int flags)
486 int err;
489 * Would prefer to specify "from" as the combination:
490 * (fr_vp->v_fd, NULL) but linkat does not permit it.
492 err = linkat(AT_FDCWD, fr_vp->v_path, to_dvp->v_fd, to_name,
493 AT_SYMLINK_FOLLOW);
494 if (err == -1)
495 err = errno;
497 return (err);
500 /* ARGSUSED */
502 fop_rename(
503 vnode_t *from_dvp,
504 char *from_name,
505 vnode_t *to_dvp,
506 char *to_name,
507 cred_t *cr,
508 caller_context_t *ct,
509 int flags)
511 struct stat st;
512 vnode_t *vp;
513 int err;
515 if (fstatat(from_dvp->v_fd, from_name, &st,
516 AT_SYMLINK_NOFOLLOW) == -1)
517 return (errno);
519 vp = vncache_lookup(&st);
520 if (vp == NULL)
521 return (ENOENT);
523 err = renameat(from_dvp->v_fd, from_name, to_dvp->v_fd, to_name);
524 if (err == -1)
525 err = errno;
526 else
527 vncache_renamed(vp, to_dvp, to_name);
529 vn_rele(vp);
531 return (err);
534 /* ARGSUSED */
536 fop_mkdir(
537 vnode_t *dvp,
538 char *name,
539 vattr_t *vap,
540 vnode_t **vpp,
541 cred_t *cr,
542 caller_context_t *ct,
543 int flags,
544 vsecattr_t *vsecp) /* ACL to set during create */
546 struct stat st;
547 int err, fd;
549 mode_t mode = vap->va_mode & 0777;
551 if (mkdirat(dvp->v_fd, name, mode) == -1)
552 return (errno);
554 if ((fd = openat(dvp->v_fd, name, O_RDONLY)) == -1)
555 return (errno);
556 if (fstat(fd, &st) == -1) {
557 err = errno;
558 (void) close(fd);
559 return (err);
562 *vpp = vncache_enter(&st, dvp, name, fd);
565 * Might need to set attributes.
567 (void) fop_setattr(*vpp, vap, 0, cr, ct);
569 return (0);
572 /* ARGSUSED */
574 fop_rmdir(
575 vnode_t *dvp,
576 char *name,
577 vnode_t *cdir,
578 cred_t *cr,
579 caller_context_t *ct,
580 int flags)
583 if (unlinkat(dvp->v_fd, name, AT_REMOVEDIR) == -1)
584 return (errno);
586 return (0);
589 /* ARGSUSED */
591 fop_readdir(
592 vnode_t *vp,
593 uio_t *uiop,
594 cred_t *cr,
595 int *eofp,
596 caller_context_t *ct,
597 int flags)
599 struct iovec *iov;
600 int cnt;
601 int error = 0;
602 int fd = vp->v_fd;
604 if (eofp) {
605 *eofp = 0;
608 error = lseek(fd, uiop->uio_loffset, SEEK_SET);
609 if (error == -1)
610 return (errno);
612 ASSERT(uiop->uio_iovcnt > 0);
613 iov = uiop->uio_iov;
614 if (iov->iov_len < sizeof (struct dirent))
615 return (EINVAL);
617 /* LINTED E_BAD_PTR_CAST_ALIGN */
618 cnt = getdents(fd, (struct dirent *)(uiop->uio_iov->iov_base),
619 uiop->uio_resid);
620 if (cnt == -1)
621 return (errno);
622 if (cnt == 0) {
623 if (eofp) {
624 *eofp = 1;
626 return (ENOENT);
629 iov->iov_base += cnt;
630 iov->iov_len -= cnt;
631 uiop->uio_resid -= cnt;
632 uiop->uio_loffset = lseek(fd, 0LL, SEEK_CUR);
634 return (0);
637 /* ARGSUSED */
639 fop_symlink(
640 vnode_t *dvp,
641 char *linkname,
642 vattr_t *vap,
643 char *target,
644 cred_t *cr,
645 caller_context_t *ct,
646 int flags)
648 return (ENOSYS);
651 /* ARGSUSED */
653 fop_readlink(
654 vnode_t *vp,
655 uio_t *uiop,
656 cred_t *cr,
657 caller_context_t *ct)
659 return (ENOSYS);
662 /* ARGSUSED */
664 fop_fsync(
665 vnode_t *vp,
666 int syncflag,
667 cred_t *cr,
668 caller_context_t *ct)
671 if (fsync(vp->v_fd) == -1)
672 return (errno);
674 return (0);
677 /* ARGSUSED */
678 void
679 fop_inactive(
680 vnode_t *vp,
681 cred_t *cr,
682 caller_context_t *ct)
684 vncache_inactive(vp);
687 /* ARGSUSED */
689 fop_fid(
690 vnode_t *vp,
691 fid_t *fidp,
692 caller_context_t *ct)
694 return (ENOSYS);
697 /* ARGSUSED */
699 fop_rwlock(
700 vnode_t *vp,
701 int write_lock,
702 caller_context_t *ct)
704 /* See: fs_rwlock */
705 return (-1);
708 /* ARGSUSED */
709 void
710 fop_rwunlock(
711 vnode_t *vp,
712 int write_lock,
713 caller_context_t *ct)
715 /* See: fs_rwunlock */
718 /* ARGSUSED */
720 fop_seek(
721 vnode_t *vp,
722 offset_t ooff,
723 offset_t *noffp,
724 caller_context_t *ct)
726 return (ENOSYS);
729 /* ARGSUSED */
731 fop_cmp(
732 vnode_t *vp1,
733 vnode_t *vp2,
734 caller_context_t *ct)
736 /* See fs_cmp */
737 return (vncache_cmp(vp1, vp2));
740 /* ARGSUSED */
742 fop_frlock(
743 vnode_t *vp,
744 int cmd,
745 flock64_t *bfp,
746 int flag,
747 offset_t offset,
748 struct flk_callback *flk_cbp,
749 cred_t *cr,
750 caller_context_t *ct)
752 /* See fs_frlock */
754 switch (cmd) {
755 case F_GETLK:
756 case F_SETLK_NBMAND:
757 case F_SETLK:
758 case F_SETLKW:
759 break;
760 default:
761 return (EINVAL);
764 if (fcntl(vp->v_fd, cmd, bfp) == -1)
765 return (errno);
767 return (0);
770 /* ARGSUSED */
772 fop_space(
773 vnode_t *vp,
774 int cmd,
775 flock64_t *bfp,
776 int flag,
777 offset_t offset,
778 cred_t *cr,
779 caller_context_t *ct)
781 /* See fs_frlock */
783 switch (cmd) {
784 case F_ALLOCSP:
785 case F_FREESP:
786 break;
787 default:
788 return (EINVAL);
791 if (fcntl(vp->v_fd, cmd, bfp) == -1)
792 return (errno);
794 return (0);
797 /* ARGSUSED */
799 fop_realvp(
800 vnode_t *vp,
801 vnode_t **vpp,
802 caller_context_t *ct)
804 return (ENOSYS);
807 /* ARGSUSED */
809 fop_getpage(
810 vnode_t *vp,
811 offset_t off,
812 size_t len,
813 uint_t *protp,
814 struct page **plarr,
815 size_t plsz,
816 struct seg *seg,
817 caddr_t addr,
818 enum seg_rw rw,
819 cred_t *cr,
820 caller_context_t *ct)
822 return (ENOSYS);
825 /* ARGSUSED */
827 fop_putpage(
828 vnode_t *vp,
829 offset_t off,
830 size_t len,
831 int flags,
832 cred_t *cr,
833 caller_context_t *ct)
835 return (ENOSYS);
838 /* ARGSUSED */
840 fop_map(
841 vnode_t *vp,
842 offset_t off,
843 struct as *as,
844 caddr_t *addrp,
845 size_t len,
846 uchar_t prot,
847 uchar_t maxprot,
848 uint_t flags,
849 cred_t *cr,
850 caller_context_t *ct)
852 return (ENOSYS);
855 /* ARGSUSED */
857 fop_addmap(
858 vnode_t *vp,
859 offset_t off,
860 struct as *as,
861 caddr_t addr,
862 size_t len,
863 uchar_t prot,
864 uchar_t maxprot,
865 uint_t flags,
866 cred_t *cr,
867 caller_context_t *ct)
869 return (ENOSYS);
872 /* ARGSUSED */
874 fop_delmap(
875 vnode_t *vp,
876 offset_t off,
877 struct as *as,
878 caddr_t addr,
879 size_t len,
880 uint_t prot,
881 uint_t maxprot,
882 uint_t flags,
883 cred_t *cr,
884 caller_context_t *ct)
886 return (ENOSYS);
889 /* ARGSUSED */
891 fop_poll(
892 vnode_t *vp,
893 short events,
894 int anyyet,
895 short *reventsp,
896 struct pollhead **phpp,
897 caller_context_t *ct)
899 *reventsp = 0;
900 if (events & POLLIN)
901 *reventsp |= POLLIN;
902 if (events & POLLRDNORM)
903 *reventsp |= POLLRDNORM;
904 if (events & POLLRDBAND)
905 *reventsp |= POLLRDBAND;
906 if (events & POLLOUT)
907 *reventsp |= POLLOUT;
908 if (events & POLLWRBAND)
909 *reventsp |= POLLWRBAND;
910 *phpp = NULL; /* or fake_pollhead? */
912 return (0);
915 /* ARGSUSED */
917 fop_dump(
918 vnode_t *vp,
919 caddr_t addr,
920 offset_t lbdn,
921 offset_t dblks,
922 caller_context_t *ct)
924 return (ENOSYS);
928 * See fs_pathconf
930 /* ARGSUSED */
932 fop_pathconf(
933 vnode_t *vp,
934 int cmd,
935 ulong_t *valp,
936 cred_t *cr,
937 caller_context_t *ct)
939 register ulong_t val;
940 register int error = 0;
942 switch (cmd) {
944 case _PC_LINK_MAX:
945 val = MAXLINK;
946 break;
948 case _PC_MAX_CANON:
949 val = MAX_CANON;
950 break;
952 case _PC_MAX_INPUT:
953 val = MAX_INPUT;
954 break;
956 case _PC_NAME_MAX:
957 val = MAXNAMELEN;
958 break;
960 case _PC_PATH_MAX:
961 case _PC_SYMLINK_MAX:
962 val = MAXPATHLEN;
963 break;
965 case _PC_PIPE_BUF:
966 val = PIPE_BUF;
967 break;
969 case _PC_NO_TRUNC:
970 val = (ulong_t)-1;
971 break;
973 case _PC_VDISABLE:
974 val = _POSIX_VDISABLE;
975 break;
977 case _PC_CHOWN_RESTRICTED:
978 val = 1; /* chown restricted enabled */
979 break;
981 case _PC_FILESIZEBITS:
982 val = (ulong_t)-1; /* large file support */
983 break;
985 case _PC_ACL_ENABLED:
986 val = 0;
987 break;
989 case _PC_CASE_BEHAVIOR:
990 val = _CASE_SENSITIVE;
991 break;
993 case _PC_SATTR_ENABLED:
994 case _PC_SATTR_EXISTS:
995 val = 0;
996 break;
998 case _PC_ACCESS_FILTERING:
999 val = 0;
1000 break;
1002 default:
1003 error = EINVAL;
1004 break;
1007 if (error == 0)
1008 *valp = val;
1009 return (error);
1012 /* ARGSUSED */
1014 fop_pageio(
1015 vnode_t *vp,
1016 struct page *pp,
1017 u_offset_t io_off,
1018 size_t io_len,
1019 int flags,
1020 cred_t *cr,
1021 caller_context_t *ct)
1023 return (ENOSYS);
1026 /* ARGSUSED */
1028 fop_dumpctl(
1029 vnode_t *vp,
1030 int action,
1031 offset_t *blkp,
1032 caller_context_t *ct)
1034 return (ENOSYS);
1037 /* ARGSUSED */
1038 void
1039 fop_dispose(
1040 vnode_t *vp,
1041 struct page *pp,
1042 int flag,
1043 int dn,
1044 cred_t *cr,
1045 caller_context_t *ct)
1049 /* ARGSUSED */
1051 fop_setsecattr(
1052 vnode_t *vp,
1053 vsecattr_t *vsap,
1054 int flag,
1055 cred_t *cr,
1056 caller_context_t *ct)
1058 return (0);
1062 * Fake up just enough of this so we can test get/set SDs.
1064 /* ARGSUSED */
1066 fop_getsecattr(
1067 vnode_t *vp,
1068 vsecattr_t *vsecattr,
1069 int flag,
1070 cred_t *cr,
1071 caller_context_t *ct)
1074 vsecattr->vsa_aclcnt = 0;
1075 vsecattr->vsa_aclentsz = 0;
1076 vsecattr->vsa_aclentp = NULL;
1077 vsecattr->vsa_dfaclcnt = 0; /* Default ACLs are not fabricated */
1078 vsecattr->vsa_dfaclentp = NULL;
1080 if (vsecattr->vsa_mask & (VSA_ACLCNT | VSA_ACL)) {
1081 aclent_t *aclentp;
1082 size_t aclsize;
1084 aclsize = sizeof (aclent_t);
1085 vsecattr->vsa_aclcnt = 1;
1086 vsecattr->vsa_aclentp = kmem_zalloc(aclsize, KM_SLEEP);
1087 aclentp = vsecattr->vsa_aclentp;
1089 aclentp->a_type = OTHER_OBJ;
1090 aclentp->a_perm = 0777;
1091 aclentp->a_id = (gid_t)-1;
1092 aclentp++;
1093 } else if (vsecattr->vsa_mask & (VSA_ACECNT | VSA_ACE)) {
1094 ace_t *acl;
1096 acl = kmem_alloc(sizeof (ace_t), KM_SLEEP);
1097 acl->a_who = (uint32_t)-1;
1098 acl->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
1099 acl->a_flags = ACE_EVERYONE;
1100 acl->a_access_mask = ACE_MODIFY_PERMS;
1102 vsecattr->vsa_aclentp = (void *)acl;
1103 vsecattr->vsa_aclcnt = 1;
1104 vsecattr->vsa_aclentsz = sizeof (ace_t);
1107 return (0);
1110 /* ARGSUSED */
1112 fop_shrlock(
1113 vnode_t *vp,
1114 int cmd,
1115 struct shrlock *shr,
1116 int flag,
1117 cred_t *cr,
1118 caller_context_t *ct)
1121 switch (cmd) {
1122 case F_SHARE:
1123 case F_SHARE_NBMAND:
1124 case F_UNSHARE:
1125 break;
1126 default:
1127 return (EINVAL);
1130 if (!fop_shrlock_enable)
1131 return (0);
1133 if (fcntl(vp->v_fd, cmd, shr) == -1)
1134 return (errno);
1136 return (0);
1139 /* ARGSUSED */
1141 fop_vnevent(vnode_t *vp, vnevent_t vnevent, vnode_t *dvp, char *fnm,
1142 caller_context_t *ct)
1144 return (ENOSYS);
1147 /* ARGSUSED */
1149 fop_reqzcbuf(vnode_t *vp, enum uio_rw ioflag, xuio_t *uiop, cred_t *cr,
1150 caller_context_t *ct)
1152 return (ENOSYS);
1155 /* ARGSUSED */
1157 fop_retzcbuf(vnode_t *vp, xuio_t *uiop, cred_t *cr, caller_context_t *ct)
1159 return (ENOSYS);
1164 * ***************************************************************
1165 * other VOP support
1169 * Convert stat(2) formats to vnode types and vice versa. (Knows about
1170 * numerical order of S_IFMT and vnode types.)
1172 enum vtype iftovt_tab[] = {
1173 VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
1174 VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VNON
1177 ushort_t vttoif_tab[] = {
1178 0, S_IFREG, S_IFDIR, S_IFBLK, S_IFCHR, S_IFLNK, S_IFIFO,
1179 S_IFDOOR, 0, S_IFSOCK, S_IFPORT, 0
1183 * stat_to_vattr()
1185 * Convert from a stat structure to an vattr structure
1186 * Note: only set fields according to va_mask
1190 stat_to_vattr(const struct stat *st, vattr_t *vap)
1193 if (vap->va_mask & AT_TYPE)
1194 vap->va_type = IFTOVT(st->st_mode);
1196 if (vap->va_mask & AT_MODE)
1197 vap->va_mode = st->st_mode;
1199 if (vap->va_mask & AT_UID)
1200 vap->va_uid = st->st_uid;
1202 if (vap->va_mask & AT_GID)
1203 vap->va_gid = st->st_gid;
1205 if (vap->va_mask & AT_FSID)
1206 vap->va_fsid = st->st_dev;
1208 if (vap->va_mask & AT_NODEID)
1209 vap->va_nodeid = st->st_ino;
1211 if (vap->va_mask & AT_NLINK)
1212 vap->va_nlink = st->st_nlink;
1214 if (vap->va_mask & AT_SIZE)
1215 vap->va_size = (u_offset_t)st->st_size;
1217 if (vap->va_mask & AT_ATIME) {
1218 vap->va_atime.tv_sec = st->st_atim.tv_sec;
1219 vap->va_atime.tv_nsec = st->st_atim.tv_nsec;
1222 if (vap->va_mask & AT_MTIME) {
1223 vap->va_mtime.tv_sec = st->st_mtim.tv_sec;
1224 vap->va_mtime.tv_nsec = st->st_mtim.tv_nsec;
1227 if (vap->va_mask & AT_CTIME) {
1228 vap->va_ctime.tv_sec = st->st_ctim.tv_sec;
1229 vap->va_ctime.tv_nsec = st->st_ctim.tv_nsec;
1232 if (vap->va_mask & AT_RDEV)
1233 vap->va_rdev = st->st_rdev;
1235 if (vap->va_mask & AT_BLKSIZE)
1236 vap->va_blksize = (uint_t)st->st_blksize;
1239 if (vap->va_mask & AT_NBLOCKS)
1240 vap->va_nblocks = (u_longlong_t)st->st_blocks;
1242 if (vap->va_mask & AT_SEQ)
1243 vap->va_seq = 0;
1245 return (0);
1248 /* ARGSUSED */
1249 void
1250 flk_init_callback(flk_callback_t *flk_cb,
1251 callb_cpr_t *(*cb_fcn)(flk_cb_when_t, void *), void *cbdata)
1255 void
1256 vn_hold(vnode_t *vp)
1258 mutex_enter(&vp->v_lock);
1259 vp->v_count++;
1260 mutex_exit(&vp->v_lock);
1263 void
1264 vn_rele(vnode_t *vp)
1266 VERIFY3U(vp->v_count, !=, 0);
1267 mutex_enter(&vp->v_lock);
1268 if (vp->v_count == 1) {
1269 mutex_exit(&vp->v_lock);
1270 vncache_inactive(vp);
1271 } else {
1272 vp->v_count--;
1273 mutex_exit(&vp->v_lock);
1278 vn_has_other_opens(
1279 vnode_t *vp,
1280 v_mode_t mode)
1283 switch (mode) {
1284 case V_WRITE:
1285 if (vp->v_wrcnt > 1)
1286 return (V_TRUE);
1287 break;
1288 case V_RDORWR:
1289 if ((vp->v_rdcnt > 1) || (vp->v_wrcnt > 1))
1290 return (V_TRUE);
1291 break;
1292 case V_RDANDWR:
1293 if ((vp->v_rdcnt > 1) && (vp->v_wrcnt > 1))
1294 return (V_TRUE);
1295 break;
1296 case V_READ:
1297 if (vp->v_rdcnt > 1)
1298 return (V_TRUE);
1299 break;
1302 return (V_FALSE);
1306 * vn_is_opened() checks whether a particular file is opened and
1307 * whether the open is for read and/or write.
1309 * Vnode counts are only kept on regular files (v_type=VREG).
1312 vn_is_opened(
1313 vnode_t *vp,
1314 v_mode_t mode)
1317 ASSERT(vp != NULL);
1319 switch (mode) {
1320 case V_WRITE:
1321 if (vp->v_wrcnt)
1322 return (V_TRUE);
1323 break;
1324 case V_RDANDWR:
1325 if (vp->v_rdcnt && vp->v_wrcnt)
1326 return (V_TRUE);
1327 break;
1328 case V_RDORWR:
1329 if (vp->v_rdcnt || vp->v_wrcnt)
1330 return (V_TRUE);
1331 break;
1332 case V_READ:
1333 if (vp->v_rdcnt)
1334 return (V_TRUE);
1335 break;
1338 return (V_FALSE);
1342 * vn_is_mapped() checks whether a particular file is mapped and whether
1343 * the file is mapped read and/or write.
1345 /* ARGSUSED */
1347 vn_is_mapped(
1348 vnode_t *vp,
1349 v_mode_t mode)
1351 return (V_FALSE);