int xfs_root_common(struct mount *mp, struct vnode **vpp, d_thread_t *proc, struct ucred *cred) { struct xfs *xfsp = VFS_TO_NNPFS(mp); struct xfs_message_getroot msg; int error; do { if (xfsp->root != NULL) { *vpp = XNODE_TO_VNODE(xfsp->root); xfs_do_vget(*vpp, LK_EXCLUSIVE, proc); return 0; } msg.header.opcode = NNPFS_MSG_GETROOT; msg.cred.uid = cred->cr_uid; msg.cred.pag = xfs_get_pag(cred); error = xfs_message_rpc(xfsp->fd, &msg.header, sizeof(msg), proc); if (error == 0) error = ((struct xfs_message_wakeup *) & msg)->error; } while (error == 0); /* * Failed to get message through, need to pretend that all went well * and return a fake dead vnode to be able to unmount. */ if ((error = xfs_make_dead_vnode(mp, vpp))) return error; NNPFS_MAKE_VROOT(*vpp); return 0; }
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 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; }
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 free_all_nnpfs_nodes(struct nnpfs *nnpfsp, int flags, int unmountp) { int error = 0; struct mount *mp = NNPFS_TO_VFS(nnpfsp); if (mp == NULL) { NNPFSDEB(XDEBNODE, ("free_all_nnpfs_nodes already freed\n")); return 0; } NNPFSDEB(XDEBNODE, ("free_all_nnpfs_nodes starting\n")); nnpfs_dnlc_purge_mp(mp); if (nnpfsp->root) { NNPFSDEB(XDEBNODE, ("free_all_nnpfs_nodes now removing root\n")); vgone(XNODE_TO_VNODE(nnpfsp->root)); nnpfsp->root = NULL; } NNPFSDEB(XDEBNODE, ("free_all_nnpfs_nodes root removed\n")); NNPFSDEB(XDEBNODE, ("free_all_nnpfs_nodes now killing all remaining nodes\n")); /* * If we have a syncer vnode, release it (to emulate dounmount) * and the create it again when if we are going to need it. */ #ifdef HAVE_STRUCT_MOUNT_MNT_SYNCER if (!unmountp) { if (mp->mnt_syncer != NULL) { #ifdef HAVE_KERNEL_VFS_DEALLOCATE_SYNCVNODE vfs_deallocate_syncvnode(mp); #else /* * FreeBSD and OpenBSD uses different semantics, * FreeBSD does vrele, and OpenBSD does vgone. */ #if defined(__OpenBSD__) vgone(mp->mnt_syncer); #elif defined(__FreeBSD__) vrele(mp->mnt_syncer); #else #error what os do you use ? #endif mp->mnt_syncer = NULL; #endif } } #endif error = nnpfs_vflush(mp, flags); #ifdef HAVE_STRUCT_MOUNT_MNT_SYNCER if (!unmountp) { NNPFSDEB(XDEBNODE, ("free_all_nnpfs_nodes not flushing syncer vnode\n")); if (mp->mnt_syncer == NULL) if (vfs_allocate_syncvnode(mp)) panic("failed to allocate syncer node when nnpfs daemon died"); } #endif if (error) { NNPFSDEB(XDEBNODE, ("xfree_all_nnpfs_nodes: vflush() error == %d\n", error)); return error; } NNPFSDEB(XDEBNODE, ("free_all_nnpfs_nodes done\n")); return error; }