int vn_fromfd(int fd, char *path, int flags, struct vnode **vpp, boolean_t fromfd) { vnode_t *vp; *vpp = vp = kmem_cache_alloc(vnode_cache, KM_SLEEP); memset(vp, 0, sizeof(vnode_t)); if (fstat64(fd, &vp->v_stat) == -1) { close(fd); return (errno); } (void) fcntl(fd, F_SETFD, FD_CLOEXEC); vp->v_fd = fd; if(S_ISBLK(vp->v_stat.st_mode)) { /* LINUX */ if(ioctl(fd, BLKGETSIZE64, &vp->v_size) != 0) return errno; } else vp->v_size = vp->v_stat.st_size; vp->v_path = strdup(path); vp->v_type = VNON; if(fromfd) vn_setops(vp, fd_fvnodeops); else vn_setops(vp, root_fvnodeops); if(S_ISREG(vp->v_stat.st_mode)) { vp->v_type = VREG; if (flags & FREAD) atomic_add_32(&((*vpp)->v_rdcnt), 1); if (flags & FWRITE) atomic_add_32(&((*vpp)->v_wrcnt), 1); } else if(S_ISDIR(vp->v_stat.st_mode)) vp->v_type = VDIR; else if(S_ISCHR(vp->v_stat.st_mode)) vp->v_type = VCHR; else if(S_ISBLK(vp->v_stat.st_mode)) vp->v_type = VBLK; else if(S_ISFIFO(vp->v_stat.st_mode)) vp->v_type = VFIFO; else if(S_ISLNK(vp->v_stat.st_mode)) vp->v_type = VLNK; else if(S_ISSOCK(vp->v_stat.st_mode)) vp->v_type = VSOCK; VERIFY(vp->v_type != VNON); zmutex_init(&vp->v_lock); rwst_init(&vp->v_vfsmhlock.ve_lock, NULL, RW_DEFAULT, NULL); vp->v_count = 1; vp->v_vfsp = rootvfs; /*fprintf(stderr, "VNode %p created at vn_open (%s)\n", *vpp, path);*/ return (0); }
vnode_t *vn_alloc(int kmflag) { ASSERT(kmflag == 0 || kmflag == UMEM_NOFAIL); vnode_t *vp; vp = kmem_cache_alloc(vnode_cache, kmflag); /* taken from vn_cache_constructor */ mutex_init(&vp->v_lock, NULL, MUTEX_DEFAULT, NULL); rwst_init(&vp->v_vfsmhlock.ve_lock, NULL, RW_DEFAULT, NULL); if(vp != NULL) { vp->v_path = NULL; vp->v_data = NULL; vn_reinit(vp); } /*fprintf(stderr, "VNode %p alloc'ed\n", vp);*/ return vp; }