/* * getf(int fd) - hold a lock on a file descriptor, to be released by calling * releasef(). On OSX we will also look up the vnode of the fd for calls * to spl_vn_rdwr(). */ void *getf(int fd) { struct fileproc *fp = NULL; struct spl_fileproc *sfp = NULL; struct vnode *vp; uint32_t vid; /* * We keep the "fp" pointer as well, both for unlocking in releasef() and * used in vn_rdwr(). */ sfp = kmem_alloc(sizeof(*sfp), KM_SLEEP); if (!sfp) return NULL; if (fp_lookup(current_proc(), fd, &fp, 0/*!locked*/)) { kmem_free(sfp, sizeof(*sfp)); return (NULL); } /* * The f_vnode ptr is used to point back to the "sfp" node itself, as it is * the only information passed to vn_rdwr. */ sfp->f_vnode = sfp; sfp->f_fd = fd; sfp->f_offset = 0; sfp->f_proc = current_proc(); sfp->f_fp = fp; /* Also grab vnode, so we can fish out the minor, for onexit */ if (!file_vnode_withvid(fd, &vp, &vid)) { if (vnode_vtype(vp) != VDIR) { sfp->f_file = minor(vnode_specrdev(vp)); } file_drop(fd); } mutex_enter(&spl_getf_lock); list_insert_tail(&spl_getf_list, sfp); mutex_exit(&spl_getf_lock); //printf("SPL: new getf(%d) ret %p fp is %p so vnode set to %p\n", // fd, sfp, fp, sfp->f_vnode); return sfp; }
int spec_kqfilter(vnode_t vp, struct knote *kn) { dev_t dev; int err = EINVAL; /* * For a few special kinds of devices, we can attach knotes. * Each filter function must check whether the dev type matches it. */ dev = vnode_specrdev(vp); if (vnode_istty(vp)) { /* We can hook into the slave side of a tty */ err = ptsd_kqfilter(dev, kn); } else { /* Try a bpf device, as defined in bsd/net/bpf.c */ err = bpfkqfilter(dev, kn); } return err; }