/* * Initialize a nlookup() structure, early error return for copyin faults * or a degenerate empty string (which is not allowed). * * The first process proc0's credentials are used if the calling thread * is not associated with a process context. * * MPSAFE */ int nlookup_init(struct nlookupdata *nd, const char *path, enum uio_seg seg, int flags) { size_t pathlen; struct proc *p; thread_t td; int error; td = curthread; p = td->td_proc; /* * note: the pathlen set by copy*str() includes the terminating \0. */ bzero(nd, sizeof(struct nlookupdata)); nd->nl_path = objcache_get(namei_oc, M_WAITOK); nd->nl_flags |= NLC_HASBUF; if (seg == UIO_SYSSPACE) error = copystr(path, nd->nl_path, MAXPATHLEN, &pathlen); else error = copyinstr(path, nd->nl_path, MAXPATHLEN, &pathlen); /* * Don't allow empty pathnames. * POSIX.1 requirement: "" is not a vaild file name. */ if (error == 0 && pathlen <= 1) error = ENOENT; if (error == 0) { if (p && p->p_fd) { cache_copy_ncdir(p, &nd->nl_nch); cache_copy(&p->p_fd->fd_nrdir, &nd->nl_rootnch); if (p->p_fd->fd_njdir.ncp) cache_copy(&p->p_fd->fd_njdir, &nd->nl_jailnch); nd->nl_cred = td->td_ucred; nd->nl_flags |= NLC_BORROWCRED | NLC_NCDIR; } else { cache_copy(&rootnch, &nd->nl_nch); cache_copy(&nd->nl_nch, &nd->nl_rootnch); cache_copy(&nd->nl_nch, &nd->nl_jailnch); nd->nl_cred = proc0.p_ucred; nd->nl_flags |= NLC_BORROWCRED; } nd->nl_td = td; nd->nl_flags |= flags; } else { nlookup_done(nd); } return(error); }
int ncast_reply(struct ncast_proto_context *context, const struct peer_cache *c, const struct peer_cache *local_cache) { int ret; struct peer_cache *send_cache; send_cache = cache_copy(local_cache); cache_update(send_cache); ret = topo_reply(context->context, c, send_cache, MSG_TYPE_TOPOLOGY, NCAST_REPLY, 0, 1); cache_free(send_cache); return ret; }
// allocate gadget cache by copy struct cache_t *cache_new_copy (struct cache_t *cache) { struct cache_t *copy, *res; // allocate copy copy = cache_new(cache_get_capacity(cache)); // make copy res = cache_copy(copy, cache); if (res == NULL) cache_destroy(©, NULL); return copy; }
/* * This works similarly to nlookup_init_raw() but does not rely * on rootnch being initialized yet. */ int nlookup_init_root(struct nlookupdata *nd, const char *path, enum uio_seg seg, int flags, struct ucred *cred, struct nchandle *ncstart, struct nchandle *ncroot) { size_t pathlen; thread_t td; int error; td = curthread; bzero(nd, sizeof(struct nlookupdata)); nd->nl_path = objcache_get(namei_oc, M_WAITOK); nd->nl_flags |= NLC_HASBUF; if (seg == UIO_SYSSPACE) error = copystr(path, nd->nl_path, MAXPATHLEN, &pathlen); else error = copyinstr(path, nd->nl_path, MAXPATHLEN, &pathlen); /* * Don't allow empty pathnames. * POSIX.1 requirement: "" is not a vaild file name. */ if (error == 0 && pathlen <= 1) error = ENOENT; if (error == 0) { cache_copy(ncstart, &nd->nl_nch); cache_copy(ncroot, &nd->nl_rootnch); cache_copy(ncroot, &nd->nl_jailnch); nd->nl_cred = crhold(cred); nd->nl_td = td; nd->nl_flags |= flags; } else { nlookup_done(nd); } return(error); }
/* * nlookup_init() for "at" family of syscalls. * * Works similarly to nlookup_init() but if path is relative and fd is not * AT_FDCWD, path is interpreted relative to the directory pointed to by fd. * In this case, the file entry pointed to by fd is ref'ed and returned in * *fpp. * * If the call succeeds, nlookup_done_at() must be called to clean-up the nd * and release the ref to the file entry. */ int nlookup_init_at(struct nlookupdata *nd, struct file **fpp, int fd, const char *path, enum uio_seg seg, int flags) { struct thread *td = curthread; struct file* fp; struct vnode *vp; int error; *fpp = NULL; if ((error = nlookup_init(nd, path, seg, flags)) != 0) { return (error); } if (nd->nl_path[0] != '/' && fd != AT_FDCWD) { if ((error = holdvnode(td, fd, &fp)) != 0) goto done; vp = (struct vnode*)fp->f_data; if (vp->v_type != VDIR || fp->f_nchandle.ncp == NULL) { fdrop(fp); fp = NULL; error = ENOTDIR; goto done; } if (nd->nl_flags & NLC_NCDIR) { cache_drop_ncdir(&nd->nl_nch); nd->nl_flags &= ~NLC_NCDIR; } else { cache_drop(&nd->nl_nch); } cache_copy(&fp->f_nchandle, &nd->nl_nch); *fpp = fp; } done: if (error) nlookup_done(nd); return (error); }