static int nnpfs_dnlc_lookup_int(struct vnode *dvp, nnpfs_componentname *cnp, struct vnode **res) { int error; u_long saved_flags; NNPFSDEB(XDEBDNLC, ("nnpfs_dnlc_lookup(%lx, \"%s\")\n", (unsigned long)dvp, cnp->cn_nameptr)); NNPFSDEB(XDEBDNLC, ("nnpfs_dnlc_lookup: v_id = %lu\n", (u_long)dvp->v_id)); NNPFSDEB(XDEBDNLC, ("nnpfs_dnlc_lookup: calling cache_lookup:" "dvp = %lx, cnp = (%s, %ld), flags = %lx\n", (unsigned long)dvp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_flags)); saved_flags = cnp->cn_flags; cnp->cn_flags |= MAKEENTRY | LOCKPARENT | ISLASTCN; error = cache_lookup(dvp, res, cnp); cnp->cn_flags = saved_flags; NNPFSDEB(XDEBDNLC, ("nnpfs_dnlc_lookup: cache_lookup returned. " "error = %d, *res = %lx\n", error, (unsigned long)*res)); return error; }
void free_nnpfs_node(struct nnpfs_node *node) { struct nnpfs *nnpfsp = NNPFS_FROM_XNODE(node); NNPFSDEB(XDEBNODE, ("free_nnpfs_node(%lx) (%d,%d,%d,%d)\n", (unsigned long)node, node->handle.a, node->handle.b, node->handle.c, node->handle.d)); /* XXX Really need to put back dirty data first. */ if (DATA_FROM_XNODE(node)) { vrele(DATA_FROM_XNODE(node)); DATA_FROM_XNODE(node) = NULL; } nnpfsp->nnodes--; XNODE_TO_VNODE(node)->v_data = NULL; if (node->rd_cred) { crfree (node->rd_cred); node->rd_cred = NULL; } if (node->wr_cred) { crfree (node->wr_cred); node->wr_cred = NULL; } nnpfs_free(node, sizeof(*node), M_NNPFS_NODE); NNPFSDEB(XDEBNODE, ("free_nnpfs_node done\n")); }
int xfs_vptofh(struct vnode * vp, struct fid * fhp) { #ifdef ARLA_KNFS struct xfs_node *xn; NNPFSDEB(XDEBVFOPS, ("xfs_vptofh\n")); if (MAXFIDSZ < 16) return EOPNOTSUPP; xn = VNODE_TO_XNODE(vp); if (xn == NULL) return EINVAL; fhp->fid_len = 16; memcpy(fhp->fid_data, &xn->handle, 16); return 0; #else NNPFSDEB(XDEBVFOPS, ("xfs_vptofh\n")); return EOPNOTSUPP; #endif }
int new_nnpfs_node(struct nnpfs *nnpfsp, struct nnpfs_msg_node *node, struct nnpfs_node **xpp, d_thread_t *p) { struct nnpfs_node *result; NNPFSDEB(XDEBNODE, ("new_nnpfs_node (%d,%d,%d,%d)\n", node->handle.a, node->handle.b, node->handle.c, node->handle.d)); retry: /* Does not allow duplicates */ result = nnpfs_node_find(&nnpfsp->nodehead, &node->handle); if (result == 0) { int error; struct vnode *v; error = nnpfs_getnewvnode(nnpfsp, &v, &node->handle); if (error) return error; result = VNODE_TO_XNODE(v); result->anonrights = node->anonrights; nnpfsp->nnodes++; } else { /* Node is already cached */ if(nnpfs_do_vget(XNODE_TO_VNODE(result), 0, p)) goto retry; } /* Init other fields */ nnpfs_attr2vattr(&node->attr, &result->attr, 1); result->vn->v_type = result->attr.va_type; result->tokens = node->tokens; bcopy(node->id, result->id, sizeof(result->id)); bcopy(node->rights, result->rights, sizeof(result->rights)); #ifdef __APPLE__ if (result->vn->v_type == VREG && (!UBCINFOEXISTS(result->vn))) ubc_info_init(result->vn); #endif *xpp = result; NNPFSDEB(XDEBNODE, ("return: new_nnpfs_node\n")); return 0; }
int nnpfs_pioctl_call(d_thread_t *proc, struct sys_pioctl_args *arg, register_t *return_value) { int error; struct ViceIoctl vice_ioctl; char *pathptr; struct vnode *vp = NULL; NNPFSDEB(XDEBSYS, ("nnpfs_syscall(%d, %lx, %d, %lx, %d)\n", SCARG(arg, operation), (unsigned long)SCARG(arg, a_pathP), SCARG(arg, a_opcode), (unsigned long)SCARG(arg, a_paramsP), SCARG(arg, a_followSymlinks))); /* Copy in the data structure for us */ error = copyin(SCARG(arg, a_paramsP), &vice_ioctl, sizeof(vice_ioctl)); if (error) return error; pathptr = SCARG(arg, a_pathP); if (pathptr != NULL) { error = lookup_node (pathptr, SCARG(arg, a_followSymlinks), &vp, proc); if(error) return error; } switch (SCARG(arg, a_opcode)) { case VIOC_FHGET : return fhget_call (proc, &vice_ioctl, vp); case VIOC_FHOPEN : return fhopen_call (proc, &vice_ioctl, vp, SCARG(arg, a_followSymlinks), return_value); case VIOC_NNPFSDEBUG : if (vp != NULL) vrele (vp); return nnpfs_debug (proc, &vice_ioctl); default : NNPFSDEB(XDEBSYS, ("a_opcode = %x\n", SCARG(arg, a_opcode))); return remote_pioctl (proc, arg, &vice_ioctl, vp); } }
int xfs_devopen(dev_t dev, int flag, int devtype, d_thread_t *proc) { NNPFSDEB(XDEBDEV, ("xfsopen dev = %d.%d, flag = %d, devtype = %d\n", major(dev), minor(dev), flag, devtype)); return xfs_devopen_common(dev); }
int xfs_start(struct mount * mp, int flags, d_thread_t * p) { NNPFSDEB(XDEBVFOPS, ("xfs_start mp = %lx, flags = %d, proc = %lx\n", (unsigned long)mp, flags, (unsigned long)p)); return 0; }
static int fhget_call (d_thread_t *p, struct ViceIoctl *vice_ioctl, struct vnode *vp) { int error; NNPFSDEB(XDEBSYS, ("fhget_call\n")); if (vp == NULL) return EBADF; #if defined(__APPLE__) || defined(__osf__) error = EINVAL; /* XXX: Leaks vnodes if fhget/fhopen is used */ goto out; #endif error = nnpfs_suser (p); if (error) goto out; #if (defined(HAVE_GETFH) && defined(HAVE_FHOPEN)) || defined(__osf__) error = getfh_compat (p, vice_ioctl, vp); #else error = trad_fhget (p, vice_ioctl, vp); #endif /* HAVE_GETFH && HAVE_FHOPEN */ out: vrele(vp); return error; }
int xfs_unmount(struct mount * mp, int mntflags, d_thread_t *p) { NNPFSDEB(XDEBVFOPS, ("xfs_umount: mp = %lx, mntflags = %d, proc = %lx\n", (unsigned long)mp, mntflags, (unsigned long)p)); return xfs_unmount_common(mp, mntflags); }
int nnpfspioctl(syscall_d_thread_t *proc, void *varg, register_t *return_value) #endif { #ifdef NNPFS_NOT_LKM struct sys_nnpfspioctl_args *arg = (struct sys_nnpfspioctl_args *) varg; #else struct sys_pioctl_args *arg = (struct sys_pioctl_args *) varg; #endif int error = EINVAL; switch (SCARG(arg, operation)) { case AFSCALL_PIOCTL: error = nnpfs_pioctl_call(syscall_thread_to_thread(proc), varg, return_value); break; case AFSCALL_SETPAG: #ifdef HAVE_FREEBSD_THREAD error = nnpfs_setpag_call(&nnpfs_thread_to_cred(proc)); #else error = nnpfs_setpag_call(&nnpfs_proc_to_cred(syscall_thread_to_thread(proc))); #endif break; default: NNPFSDEB(XDEBSYS, ("Unimplemeted nnpfspioctl: %d\n", SCARG(arg, operation))); error = EINVAL; break; } return error; }
void nnpfs_dnlc_purge_mp(struct mount *mp) { NNPFSDEB(XDEBDNLC, ("nnpfs_dnlc_purge_mp()\n")); tbl_clear (); cache_purgevfs(mp); }
int xfs_devclose(dev_t dev, int flag, int devtype, d_thread_t *p) { NNPFSDEB(XDEBDEV, ("xfs_devclose dev = %d(%d), flag = 0x%x\n", major(dev), minor(dev), flag)); return xfs_devclose_common(dev, p); }
int xfs_devioctl(dev_t dev, u_long cmd, caddr_t data, int flags, d_thread_t *p) { NNPFSDEB(XDEBDEV, ("xfs_devioctl dev = %d.%d, cmd = %lu, " "data = %lx, flags = %x\n", major(dev), minor(dev), (unsigned long)cmd, (unsigned long)data, flags)); return ENOTTY; }
int xfs_quotactl(struct mount *mp, int cmd, uid_t uid, caddr_t arg, d_thread_t *p) { NNPFSDEB(XDEBVFOPS, ("xfs_quotactl: mp = %lx, cmd = %d, uid = %u, " "arg = %lx, proc = %lx\n", (unsigned long)mp, cmd, uid, (unsigned long)arg, (unsigned long)p)); return EOPNOTSUPP; }
void nnpfs_dnlc_purge (struct vnode *vp) { NNPFSDEB(XDEBDNLC, ("nnpfs_dnlc_purge\n")); if (tbl.dvp == vp || tbl.vp == vp) tbl_clear (); cache_purge(vp); }
int xfs_root(struct mount *mp, struct vnode **vpp) { NNPFSDEB(XDEBVFOPS, ("xfs_root mp = %lx\n", (unsigned long)mp)); #ifdef HAVE_FREEBSD_THREAD return xfs_root_common(mp, vpp, xfs_curthread(), xfs_curthread()->td_proc->p_ucred); #else return xfs_root_common(mp, vpp, xfs_curproc(), xfs_curproc()->p_ucred); #endif }
int xfs_statfs(struct mount *mp, struct statfs *sbp, d_thread_t *p) { NNPFSDEB(XDEBVFOPS, ("xfs_statfs: mp = %lx, sbp = %lx, proc = %lx\n", (unsigned long)mp, (unsigned long)sbp, (unsigned long)p)); bcopy(&mp->mnt_stat, sbp, sizeof(*sbp)); return 0; }
static int lookup_node (const char *pathptr, int follow_links_p, struct vnode **res, d_thread_t *proc) { int error; char path[MAXPATHLEN]; #ifdef __osf__ struct nameidata *ndp = &u.u_nd; #else struct nameidata nd, *ndp = &nd; #endif struct vnode *vp; size_t count; NNPFSDEB(XDEBSYS, ("nnpfs_syscall: looking up: %lx\n", (unsigned long)pathptr)); error = copyinstr((char *) pathptr, path, MAXPATHLEN, &count); NNPFSDEB(XDEBSYS, ("nnpfs_syscall: looking up: %s, error: %d\n", path, error)); if (error) return error; NDINIT(ndp, LOOKUP, follow_links_p ? FOLLOW : 0, UIO_SYSSPACE, path, proc); error = namei(ndp); if (error != 0) { NNPFSDEB(XDEBSYS, ("nnpfs_syscall: error during namei: %d\n", error)); return EINVAL; } vp = ndp->ni_vp; *res = vp; return 0; }
int xfs_sync(struct mount *mp, int waitfor, struct ucred *cred, d_thread_t *p) { NNPFSDEB(XDEBVFOPS, ("xfs_sync: mp = %lx, waitfor = %d, " "cred = %lx, proc = %lx\n", (unsigned long)mp, waitfor, (unsigned long)cred, (unsigned long)p)); return 0; }
int xfs_vget(struct mount * mp, #ifdef __APPLE__ void *ino, #else ino_t ino, #endif struct vnode ** vpp) { NNPFSDEB(XDEBVFOPS, ("xfs_vget\n")); return EOPNOTSUPP; }
int xfs_install_device(void) { int i; for (i = 0; i < NNNPFS; i++) { NNPFSDEB(XDEBDEV, ("before initq(messageq and sleepq)\n")); xfs_initq(&xfs_channel[i].messageq); xfs_initq(&xfs_channel[i].sleepq); xfs_channel[i].status = 0; } return 0; }
int nnpfs_dnlc_enter_name(struct vnode *dvp, const char *name, struct vnode *vp) { struct componentname cn; NNPFSDEB(XDEBDNLC, ("nnpfs_dnlc_enter_name(%lx, \"%s\", %lx)\n", (unsigned long)dvp, name, (unsigned long)vp)); nnpfs_cnp_init (&cn, name, NULL, NULL, LOOKUP); return nnpfs_dnlc_enter (dvp, &cn, vp); }
int xfs_uninstall_device(void) { int i; struct xfs_channel *chan; int ret = 0; for (i = 0; i < NNNPFS; i++) { chan = &xfs_channel[i]; if (chan->status & CHANNEL_OPENED) xfs_devclose(makedev(0, i), 0, 0, NULL); } NNPFSDEB(XDEBLKM, ("xfs_uninstall_device error %d\n", ret)); return ret; }
int xfs_devpoll(dev_t dev, int events, d_thread_t * p) { struct xfs_channel *chan = &xfs_channel[minor(dev)]; NNPFSDEB(XDEBDEV, ("xfs_devpoll dev = %d(%d), events = 0x%x\n", major(dev), minor(dev), events)); if ((events & (POLLIN | POLLRDNORM)) == 0) return 0; /* only supports read */ if (!xfs_emptyq(&chan->messageq)) return (events & (POLLIN | POLLRDNORM)); selrecord (p, &chan->selinfo); return 0; }
int xfs_checkexp (struct mount *mp, #ifdef __FreeBSD__ struct sockaddr *nam, #else struct mbuf *nam, #endif int *exflagsp, struct ucred **credanonp) { NNPFSDEB(XDEBVFOPS, ("xfs_checkexp\n")); #if 0 np = vfs_export_lookup(mp, &ump->um_export, nam); if (np == NULL) return EACCES; #endif return 0; }
static int trad_fhget (d_thread_t *p, struct ViceIoctl *vice_ioctl, struct vnode *vp) { int error; struct mount *mnt; struct vattr vattr; size_t len; struct nnpfs_fhandle_t nnpfs_handle; struct nnpfs_fh_args fh_args; #ifdef HAVE_FREEBSD_THREAD nnpfs_vop_getattr(vp, &vattr, nnpfs_thread_to_cred(p), p, error); #else nnpfs_vop_getattr(vp, &vattr, nnpfs_proc_to_cred(p), p, error); #endif if (error) return error; mnt = vp->v_mount; SCARG(&fh_args, fsid) = mnt->mnt_stat.f_fsid; SCARG(&fh_args, fileid) = vattr.va_fileid; SCARG(&fh_args, gen) = vattr.va_gen; nnpfs_handle.len = sizeof(fh_args); memcpy (nnpfs_handle.fhdata, &fh_args, sizeof(fh_args)); len = sizeof(nnpfs_handle); if (vice_ioctl->out_size < len) return EINVAL; error = copyout (&nnpfs_handle, vice_ioctl->out, len); if (error) { NNPFSDEB(XDEBSYS, ("fhget_call: copyout failed: %d\n", error)); } return error; }
static int fhopen_call (d_thread_t *p, struct ViceIoctl *vice_ioctl, struct vnode *vp, int flags, register_t *retval) { NNPFSDEB(XDEBSYS, ("fhopen_call: flags = %d\n", flags)); if (vp != NULL) { vrele (vp); return EINVAL; } #if defined(__APPLE__) || defined(__osf__) return EINVAL; /* XXX: Leaks vnodes if fhget/fhopen is used */ #endif return nnpfs_fhopen (p, (struct nnpfs_fhandle_t *)vice_ioctl->in, flags, retval); }
static int common_fhtovp(struct mount * mp, struct fid * fhp, struct vnode ** vpp) { #ifdef ARLA_KNFS struct netcred *np = NULL; struct xfs_node *xn; struct vnode *vp; xfs_handle handle; int error; NNPFSDEB(XDEBVFOPS, ("xfs_fhtovp\n")); if (fhp->fid_len != 16) { printf("xfs_fhtovp: *PANIC* got a invalid length of a fid\n"); return EINVAL; } memcpy(&handle, fhp->fid_data, sizeof(handle)); NNPFSDEB(XDEBVFOPS, ("xfs_fhtovp: fid: %d.%d.%d.%d\n", handle.a, handle.d, handle.c, handle.d)); NNPFSDEB(XDEBVFOPS, ("xfs_fhtovp: xfs_vnode_find\n")); xn = xfs_node_find(&xfs[0].nodehead, &handle); if (xn == NULL) { struct xfs_message_getattr msg; error = xfs_getnewvnode(xfs[0].mp, &vp, &handle); if (error) return error; xfs_do_vget(vp, 0, curproc); } else { /* XXX access ? */ vp = XNODE_TO_VNODE(xn); /* XXX wrong ? (we tell arla below) */ if (vp->v_usecount <= 0) xfs_do_vget(vp, 0, curproc); else VREF(vp); error = 0; } *vpp = vp; if (error == 0) { NNPFSDEB(XDEBVFOPS, ("xfs_fhtovp done\n")); /* * XXX tell arla about this node is hold by nfsd. * There need to be code in xfs_write too. */ } else NNPFSDEB(XDEBVFOPS, ("xfs_fhtovp failed (%d)\n", error)); return error; #else /* !ARLA_KNFS */ return EOPNOTSUPP; #endif /* !ARLA_KNFS */ }
int xfs_fhopen (d_thread_t *proc, struct xfs_fhandle_t *fhp, int user_flags, register_t *retval) { int error; struct vnode *vp; #ifdef HAVE_FREEBSD_THREAD struct ucred *cred = proc->td_proc->p_ucred; #else struct ucred *cred = proc->p_ucred; #endif int flags = FFLAGS(user_flags); int index; struct file *fp; int mode; struct xfs_fhandle_t fh; NNPFSDEB(XDEBVFOPS, ("xfs_fhopen: flags = %d\n", user_flags)); error = copyin (fhp, &fh, sizeof(fh)); if (error) return error; error = xfs_fhlookup (proc, &fh, &vp); NNPFSDEB(XDEBVFOPS, ("xfs_fhlookup returned %d\n", error)); if (error) return error; switch (vp->v_type) { case VDIR : case VREG : break; case VLNK : error = EMLINK; goto out; default : error = EOPNOTSUPP; goto out; } mode = 0; if (flags & FWRITE) { switch (vp->v_type) { case VREG : break; case VDIR : error = EISDIR; goto out; default : error = EOPNOTSUPP; goto out; } error = vn_writechk (vp); if (error) goto out; mode |= VWRITE; } if (flags & FREAD) mode |= VREAD; if (mode) { error = VOP_ACCESS(vp, mode, cred, proc); if (error) goto out; } error = VOP_OPEN(vp, flags, cred, proc); if (error) goto out; error = falloc(proc, &fp, &index); if (error) goto out; if (flags & FWRITE) vp->v_writecount++; #if defined(__FreeBSD_version) && __FreeBSD_version >= 300000 if (vp->v_type == VREG) { #ifdef HAVE_FREEBSD_THREAD error = xfs_vfs_object_create(vp, proc, proc->td_proc->p_ucred); #else error = xfs_vfs_object_create(vp, proc, proc->p_ucred); #endif if (error) goto out; } #endif fp->f_flag = flags & FMASK; fp->f_type = DTYPE_VNODE; fp->f_ops = &vnops; fp->f_data = (caddr_t)vp; xfs_vfs_unlock(vp, proc); *retval = index; #ifdef FILE_UNUSE FILE_UNUSE(fp, proc); #endif #ifdef __APPLE__ *fdflags(proc, index) &= ~UF_RESERVED; #endif return 0; out: NNPFSDEB(XDEBVFOPS, ("xfs_fhopen: error = %d\n", error)); vput(vp); return error; }
int xfs_fhlookup (d_thread_t *proc, struct xfs_fhandle_t *fhp, struct vnode **vpp) { int error; struct mount *mp; #if !(defined(HAVE_GETFH) && defined(HAVE_FHOPEN)) struct ucred *cred = proc->p_ucred; struct vattr vattr; fsid_t fsid; struct xfs_fh_args *fh_args = (struct xfs_fh_args *)fhp->fhdata; NNPFSDEB(XDEBVFOPS, ("xfs_fhlookup (xfs)\n")); error = xfs_suser (proc); if (error) return EPERM; if (fhp->len < sizeof(struct xfs_fh_args)) return EINVAL; fsid = SCARG(fh_args, fsid); mp = xfs_vfs_getvfs (&fsid); if (mp == NULL) return ENXIO; #ifdef __APPLE__ { uint32_t ino = SCARG(fh_args, fileid); error = VFS_VGET(mp, &ino, vpp); } #else error = VFS_VGET(mp, SCARG(fh_args, fileid), vpp); #endif if (error) return error; if (*vpp == NULL) return ENOENT; error = VOP_GETATTR(*vpp, &vattr, cred, proc); if (error) { vput(*vpp); return error; } if (vattr.va_gen != SCARG(fh_args, gen)) { vput(*vpp); return ENOENT; } #else /* HAVE_GETFH && HAVE_FHOPEN */ { fhandle_t *fh = (fhandle_t *) fhp; NNPFSDEB(XDEBVFOPS, ("xfs_fhlookup (native)\n")); mp = xfs_vfs_getvfs (&fh->fh_fsid); if (mp == NULL) return ESTALE; if ((error = VFS_FHTOVP(mp, &fh->fh_fid, vpp)) != 0) { *vpp = NULL; return error; } } #endif /* HAVE_GETFH && HAVE_FHOPEN */ #ifdef HAVE_KERNEL_VFS_OBJECT_CREATE if ((*vpp)->v_type == VREG && (*vpp)->v_object == NULL) #ifdef HAVE_FREEBSD_THREAD xfs_vfs_object_create (*vpp, proc, proc->td_proc->p_ucred); #else xfs_vfs_object_create (*vpp, proc, proc->p_ucred); #endif #elif __APPLE__ if ((*vpp)->v_type == VREG && (!UBCINFOEXISTS(*vpp))) { ubc_info_init(*vpp); } ubc_hold(*vpp); #endif return 0; }