static int pipefs_lookup(fs_cookie _fs, fs_vnode _dir, const char *name, vnode_id *id) { struct pipefs *fs = (struct pipefs *)_fs; struct pipefs_vnode *dir = (struct pipefs_vnode *)_dir; struct pipefs_vnode *v; struct pipefs_vnode *v1; int err; TRACE(("pipefs_lookup: entry dir 0x%x, name '%s'\n", dir, name)); if(dir->stream.type != STREAM_TYPE_DIR) return ERR_VFS_NOT_DIR; // look it up mutex_lock(&dir->stream.u.dir.dir_lock); v = pipefs_find_in_dir(dir, name); mutex_unlock(&dir->stream.u.dir.dir_lock); if(!v) { err = ERR_NOT_FOUND; goto err; } err = vfs_get_vnode(fs->id, v->id, (fs_vnode *)&v1); if(err < 0) { goto err; } *id = v->id; err = NO_ERROR; err: return err; }
extern "C" void cache_prefetch(dev_t mountID, ino_t vnodeID, off_t offset, size_t size) { // ToDo: schedule prefetch TRACE(("cache_prefetch(vnode %ld:%Ld)\n", mountID, vnodeID)); // get the vnode for the object, this also grabs a ref to it struct vnode* vnode; if (vfs_get_vnode(mountID, vnodeID, true, &vnode) != B_OK) return; cache_prefetch_vnode(vnode, offset, size); vfs_put_vnode(vnode); }
int nfs_lookup(fs_cookie fs, fs_vnode _dir, const char *name, vnode_id *id) { nfs_fs *nfs = (nfs_fs *)fs; nfs_vnode *dir = (nfs_vnode *)_dir; int err; TRACE("nfs_lookup: fsid 0x%x, dirvnid 0x%Lx, name '%s'\n", nfs->id, VNODETOVNID(dir), name); mutex_lock(&dir->lock); { uint8 sendbuf[NFS_DIROPARGS_MAXLEN]; nfs_diropargs args; size_t arglen; uint8 resbuf[NFS_DIROPRES_MAXLEN]; nfs_diropres res; /* set up the args structure */ args.dir = &dir->nfs_handle; args.name.name = name; arglen = nfs_pack_diropargs(sendbuf, &args); err = rpc_call(&nfs->rpc, NFSPROG, NFSVERS, NFSPROC_LOOKUP, sendbuf, arglen, resbuf, sizeof(resbuf)); if(err < 0) { err = ERR_NOT_FOUND; goto out; } nfs_unpack_diropres(resbuf, &res); /* see if the lookup was successful */ if(res.status == NFS_OK) { nfs_vnode *v; nfs_vnode *v2; bool newvnode; /* successful lookup */ #if NFS_TRACE dprintf("nfs_lookup: result of lookup of '%s'\n", name); dprintf("\tfhandle: "); dump_fhandle(res.file); dprintf("\n"); dprintf("\tsize: %d\n", res.attributes->size); nfs_handle_hash(NULL, res.file, 1024); #endif /* see if the vnode already exists */ newvnode = false; v = hash_lookup(nfs->handle_hash, res.file); if (v == NULL) { /* didn't find it, create a new one */ v = new_vnode_struct(nfs); if(v == NULL) { err = ERR_NO_MEMORY; goto out; } /* copy the file handle over */ memcpy(&v->nfs_handle, res.file, sizeof(v->nfs_handle)); /* figure out the stream type from the return value and cache it */ switch(res.attributes->ftype) { case NFREG: v->st = STREAM_TYPE_FILE; break; case NFDIR: v->st = STREAM_TYPE_DIR; break; default: v->st = -1; } /* add it to the handle -> vnode lookup table */ mutex_lock(&nfs->lock); hash_insert(nfs->handle_hash, v); mutex_unlock(&nfs->lock); newvnode = true; } /* request that the vfs layer look it up */ err = vfs_get_vnode(nfs->id, VNODETOVNID(v), (fs_vnode *)(void *)&v2); if(err < 0) { if (newvnode) { mutex_lock(&nfs->lock); hash_remove(nfs->handle_hash, v); mutex_unlock(&nfs->lock); destroy_vnode_struct(v); } err = ERR_NOT_FOUND; goto out; } ASSERT(v == v2); *id = VNODETOVNID(v); } else { TRACE("nfs_lookup: '%s' not found\n", name); err = ERR_NOT_FOUND; goto out; } } err = NO_ERROR; out: mutex_unlock(&dir->lock); return err; }
static int _nfs_create(nfs_fs *nfs, nfs_vnode *dir, const char *name, stream_type type, vnode_id *new_vnid) { int err; uint8 argbuf[NFS_CREATEARGS_MAXLEN]; nfs_createargs args; size_t arglen; uint8 resbuf[NFS_DIROPRES_MAXLEN]; nfs_diropres res; nfs_vnode *v, *v2; int proc; /* start building the args */ args.where.dir = &dir->nfs_handle; args.where.name.name = name; args.attributes.mode = 0777; args.attributes.uid = 0; args.attributes.gid = 0; args.attributes.size = 0; args.attributes.atime.seconds = 0; args.attributes.atime.useconds = 0; args.attributes.mtime.seconds = 0; args.attributes.mtime.useconds = 0; arglen = nfs_pack_createopargs(argbuf, &args); switch (type) { case STREAM_TYPE_FILE: proc = NFSPROC_CREATE; break; case STREAM_TYPE_DIR: proc = NFSPROC_MKDIR; break; default: panic("_nfs_create asked to make file type it doesn't understand\n"); } err = rpc_call(&nfs->rpc, NFSPROG, NFSVERS, proc, argbuf, arglen, resbuf, sizeof(resbuf)); if (err < 0) return err; nfs_unpack_diropres(resbuf, &res); if (res.status != NFS_OK) { err = nfs_status_to_error(res.status); goto err; } /* if new_vnid is null, the layers above us aren't requesting that we bring the vnode into existence */ if (new_vnid == NULL) { err = 0; goto out; } /* create a new vnode */ v = new_vnode_struct(nfs); if (v == NULL) { err = ERR_NO_MEMORY; /* weird state here. we've created a file but failed */ goto err; } /* copy the file handle over */ memcpy(&v->nfs_handle, res.file, sizeof(v->nfs_handle)); /* figure out the stream type from the return value and cache it */ switch (res.attributes->ftype) { case NFREG: v->st = STREAM_TYPE_FILE; break; case NFDIR: v->st = STREAM_TYPE_DIR; break; default: v->st = -1; } /* add it to the handle -> vnode lookup table */ mutex_lock(&nfs->lock); hash_insert(nfs->handle_hash, v); mutex_unlock(&nfs->lock); /* request that the vfs layer look it up */ err = vfs_get_vnode(nfs->id, VNODETOVNID(v), (fs_vnode *)(void *)&v2); if (err < 0) { mutex_lock(&nfs->lock); hash_remove(nfs->handle_hash, v); mutex_unlock(&nfs->lock); destroy_vnode_struct(v); err = ERR_NOT_FOUND; goto err; } *new_vnid = VNODETOVNID(v); err = 0; out: err: return err; }