status_t FileDevice::Open(const char* path, int openMode, void** _cookie) { // get the vnode struct vnode* vnode; status_t error = vfs_get_vnode_from_fd(fFD, true, &vnode); if (error != B_OK) return error; // open it int fd = vfs_open_vnode(vnode, openMode, true); if (fd < 0) { vfs_put_vnode(vnode); return fd; } // our vnode reference does now belong to the FD Cookie* cookie = new(std::nothrow) Cookie(fd); if (cookie == NULL) { close(fd); return B_NO_MEMORY; } *_cookie = cookie; return B_OK; }
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); }
status_t UnixEndpoint::_Unbind() { if (fState == UNIX_ENDPOINT_CONNECTED || fState == UNIX_ENDPOINT_LISTENING) RETURN_ERROR(B_BAD_VALUE); if (IsBound()) { UnixAddressManagerLocker addressLocker(gAddressManager); gAddressManager.Remove(this); if (struct vnode* vnode = fAddress.Vnode()) vfs_put_vnode(vnode); fAddress.Unset(); } RETURN_ERROR(B_OK); }
int nfs_unmount(fs_cookie fs) { nfs_fs *nfs = (nfs_fs *)fs; TRACE("nfs_unmount: fsid 0x%x\n", nfs->id); // put_vnode on the root to release the ref to it vfs_put_vnode(nfs->id, VNODETOVNID(nfs->root_vnode)); nfs_unmount_fs(nfs); hash_uninit(nfs->handle_hash); rpc_destroy_state(&nfs->rpc); mutex_destroy(&nfs->lock); kfree(nfs); return 0; }
status_t PackagesDirectory::_Init(struct vnode* vnode, struct stat& _st) { fDirFD = vfs_open_vnode(vnode, O_RDONLY, true); if (fDirFD < 0) { ERROR("Failed to open packages directory \"%s\"\n", strerror(fDirFD)); vfs_put_vnode(vnode); RETURN_ERROR(fDirFD); } // Our vnode reference has been transferred to the FD. // Is it a directory at all? struct stat& st = _st; if (fstat(fDirFD, &st) < 0) RETURN_ERROR(errno); fNodeRef.device = st.st_dev; fNodeRef.node = st.st_ino; // get a normalized path KPath normalizedPath; if (normalizedPath.InitCheck() != B_OK) RETURN_ERROR(normalizedPath.InitCheck()); char* normalizedPathBuffer = normalizedPath.LockBuffer(); status_t error = vfs_entry_ref_to_path(fNodeRef.device, fNodeRef.node, NULL, true, normalizedPathBuffer, normalizedPath.BufferSize()); if (error != B_OK) RETURN_ERROR(error); fPath = strdup(normalizedPathBuffer); if (fPath == NULL) RETURN_ERROR(B_NO_MEMORY); return B_OK; }
status_t UnixEndpoint::Bind(const struct sockaddr *_address) { if (_address->sa_family != AF_UNIX) RETURN_ERROR(EAFNOSUPPORT); TRACE("[%ld] %p->UnixEndpoint::Bind(\"%s\")\n", find_thread(NULL), this, ConstSocketAddress(&gAddressModule, _address).AsString().Data()); const sockaddr_un* address = (const sockaddr_un*)_address; UnixEndpointLocker endpointLocker(this); if (fState != UNIX_ENDPOINT_NOT_CONNECTED || IsBound()) RETURN_ERROR(B_BAD_VALUE); if (address->sun_path[0] == '\0') { UnixAddressManagerLocker addressLocker(gAddressManager); // internal address space (or empty address) int32 internalID; if (UnixAddress::IsEmptyAddress(*address)) internalID = gAddressManager.NextUnusedInternalID(); else internalID = UnixAddress::InternalID(*address); if (internalID < 0) RETURN_ERROR(internalID); status_t error = _Bind(internalID); if (error != B_OK) RETURN_ERROR(error); sockaddr_un* outAddress = (sockaddr_un*)&socket->address; outAddress->sun_path[0] = '\0'; sprintf(outAddress->sun_path + 1, "%05lx", internalID); outAddress->sun_len = INTERNAL_UNIX_ADDRESS_LEN; // null-byte + 5 hex digits gAddressManager.Add(this); } else { // FS address space size_t pathLen = strnlen(address->sun_path, sizeof(address->sun_path)); if (pathLen == 0 || pathLen == sizeof(address->sun_path)) RETURN_ERROR(B_BAD_VALUE); struct vnode* vnode; status_t error = vfs_create_special_node(address->sun_path, NULL, S_IFSOCK | 0644, 0, !gStackModule->is_syscall(), NULL, &vnode); if (error != B_OK) RETURN_ERROR(error == B_FILE_EXISTS ? EADDRINUSE : error); error = _Bind(vnode); if (error != B_OK) { vfs_put_vnode(vnode); RETURN_ERROR(error); } size_t addressLen = address->sun_path + pathLen + 1 - (char*)address; memcpy(&socket->address, address, addressLen); socket->address.ss_len = addressLen; UnixAddressManagerLocker addressLocker(gAddressManager); gAddressManager.Add(this); } RETURN_ERROR(B_OK); }