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; }
static int xfs_dnlc_lock(struct vnode *dvp, xfs_componentname *cnp, struct vnode **res) { int error = 0; /* * Try to handle the (complex) BSD locking protocol. */ if (*res == dvp) { /* "." */ VREF(dvp); } else if (cnp->cn_flags & ISDOTDOT) { /* ".." */ u_long vpid = dvp->v_id; #ifdef HAVE_FREEBSD_THREAD xfs_vfs_unlock(dvp, xfs_cnp_to_thread(cnp)); error = xfs_do_vget(*res, LK_EXCLUSIVE, xfs_cnp_to_thread(cnp)); xfs_vfs_writelock(dvp, xfs_cnp_to_thread(cnp)); #else xfs_vfs_unlock(dvp, xfs_cnp_to_proc(cnp)); error = xfs_do_vget(*res, LK_EXCLUSIVE, xfs_cnp_to_proc(cnp)); xfs_vfs_writelock(dvp, xfs_cnp_to_proc(cnp)); #endif if (error == 0 && dvp->v_id != vpid) { vput(*res); return 0; } } else { #ifdef HAVE_FREEBSD_THREAD error = xfs_do_vget(*res, LK_EXCLUSIVE, xfs_cnp_to_thread(cnp)); #else error = xfs_do_vget(*res, LK_EXCLUSIVE, xfs_cnp_to_proc(cnp)); #endif } if (error == 0) return -1; else return 0; }
int new_xfs_node(struct xfs *xfsp, struct xfs_msg_node *node, struct xfs_node **xpp, d_thread_t *p) { struct xfs_node *result; NNPFSDEB(XDEBNODE, ("new_xfs_node (%d,%d,%d,%d)\n", node->handle.a, node->handle.b, node->handle.c, node->handle.d)); retry: /* Does not allow duplicates */ result = xfs_node_find(&xfsp->nodehead, &node->handle); if (result == 0) { int error; struct vnode *v; error = xfs_getnewvnode(xfsp, &v, &node->handle); if (error) return error; result = VNODE_TO_XNODE(v); result->anonrights = node->anonrights; xfsp->nnodes++; } else { /* Node is already cached */ if(xfs_do_vget(XNODE_TO_VNODE(result), 0, p)) goto retry; } /* Init other fields */ xfs_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_xfs_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 */ }