status_t HaikuKernelVolume::DoIO(void* _node, void* cookie, const IORequestInfo& requestInfo) { HaikuKernelNode* node = (HaikuKernelNode*)_node; if (!node->ops->io) return B_BAD_VALUE; // create a request object HaikuKernelIORequest* request = new(std::nothrow) HaikuKernelIORequest(this, requestInfo); if (request == NULL) RETURN_ERROR(B_NO_MEMORY); status_t error = _FileSystem()->AddIORequest(request); if (error != B_OK) { delete request; RETURN_ERROR(error); } // call the hook error = node->ops->io(&fVolume, node, cookie, (io_request*)request); // directly put our reference to the request, if the call failed if (error != B_OK) { _FileSystem()->PutIORequest(request); RETURN_ERROR(error); } // TODO: ATM we don't release our reference when the request is finished // normally! return B_OK; }
// IterativeIOFinished status_t HaikuKernelVolume::IterativeIOFinished(void* _cookie, int32 requestID, status_t status, bool partialTransfer, size_t bytesTransferred) { HaikuKernelIterativeFDIOCookie* cookie = (HaikuKernelIterativeFDIOCookie*)_cookie; // we're definitely done with the cookie, now ObjectDeleter<HaikuKernelIterativeFDIOCookie> _(cookie); // get the request HaikuKernelIORequest* request = _FileSystem()->GetIORequest(requestID); if (request == NULL) RETURN_ERROR(B_BAD_VALUE); // call the callback status_t error = cookie->finished(cookie->cookie, (io_request*)request, status, partialTransfer, bytesTransferred); // We're done with the request, too, so put the reference we got above and // the one added by DoIO(). _FileSystem()->PutIORequest(request, 2); return error; }
// IterativeIOGetVecs status_t HaikuKernelVolume::IterativeIOGetVecs(void* _cookie, int32 requestID, off_t offset, size_t size, struct file_io_vec* vecs, size_t* _count) { HaikuKernelIterativeFDIOCookie* cookie = (HaikuKernelIterativeFDIOCookie*)_cookie; // get the request HaikuKernelIORequest* request = _FileSystem()->GetIORequest(requestID); if (request == NULL) RETURN_ERROR(B_BAD_VALUE); // call the callback status_t error = cookie->getVecs(cookie->cookie, (io_request*)request, offset, size, vecs, _count); // put the reference we got above _FileSystem()->PutIORequest(request, 1); return error; }
// PublishVNode status_t HaikuKernelVolume::PublishVNode(ino_t vnodeID, void* privateNode, fs_vnode_ops* ops, int type, uint32 flags, HaikuKernelNode** _node) { AutoLocker<NodeMap> _(fNodes); // check whether we do already know the node HaikuKernelNode* node = fNodes->Get(vnodeID); if (node != NULL) { if (node->published) return B_BAD_VALUE; } else { // get node capabilities HaikuKernelNode::Capabilities* capabilities = _FileSystem()->GetNodeCapabilities(ops); if (capabilities == NULL) return B_NO_MEMORY; // create a new node node = new(std::nothrow) HaikuKernelNode(this, vnodeID, privateNode, ops, capabilities); if (node == NULL) { _FileSystem()->PutNodeCapabilities(capabilities); return B_NO_MEMORY; } // add to map status_t error = fNodes->Put(vnodeID, node); if (error != B_OK) { delete node; return error; } } node->published = true; *_node = node; return B_OK; }
// ReadVNode status_t HaikuKernelVolume::ReadVNode(ino_t vnid, bool reenter, void** _node, int* type, uint32* flags, FSVNodeCapabilities* _capabilities) { if (!fVolume.ops->get_vnode) return B_BAD_VALUE; // create a new wrapper node and add it to the map HaikuKernelNode* node = new(std::nothrow) HaikuKernelNode(this, vnid, NULL, NULL, NULL); if (node == NULL) return B_NO_MEMORY; ObjectDeleter<HaikuKernelNode> nodeDeleter(node); AutoLocker<NodeMap> locker(fNodes); if (fNodes->Get(vnid) != NULL) return B_BAD_VALUE; status_t error = fNodes->Put(vnid, node); if (error != B_OK) return error; locker.Unlock(); // get the node error = fVolume.ops->get_vnode(&fVolume, vnid, node, type, flags, reenter); if (error != B_OK) { locker.Lock(); fNodes->Remove(vnid); return error; } // get node capabilities HaikuKernelNode::Capabilities* capabilities = _FileSystem()->GetNodeCapabilities(node->ops); if (capabilities == NULL) { node->ops->put_vnode(&fVolume, node, reenter); locker.Lock(); fNodes->Remove(vnid); return B_NO_MEMORY; } locker.Lock(); node->capabilities = capabilities; node->published = true; nodeDeleter.Detach(); *_node = node; *_capabilities = capabilities->capabilities; return B_OK; }
status_t HaikuKernelVolume::CancelIO(void* _node, void* cookie, int32 ioRequestID) { HaikuKernelNode* node = (HaikuKernelNode*)_node; if (!node->ops->cancel_io) return B_BAD_VALUE; // get the request HaikuKernelIORequest* request = _FileSystem()->GetIORequest(ioRequestID); if (request == NULL) RETURN_ERROR(B_BAD_VALUE); // call the hook status_t error = node->ops->cancel_io(&fVolume, node, cookie, (io_request*)request); // put the request -- once for the reference we got above, once for the // reference we've got in DoIO() _FileSystem()->PutIORequest(request, 2); return error; }
// NewVNode status_t AntaresKernelVolume::NewVNode(ino_t vnodeID, void* privateNode, fs_vnode_ops* ops, AntaresKernelNode** _node) { AutoLocker<NodeMap> _(fNodes); // check whether we do already know the node AntaresKernelNode* node = fNodes->Get(vnodeID); if (node != NULL) return B_BAD_VALUE; // get node capabilities AntaresKernelNode::Capabilities* capabilities = _FileSystem()->GetNodeCapabilities(ops); if (capabilities == NULL) return B_NO_MEMORY; // create a new node node = new(std::nothrow) AntaresKernelNode(this, vnodeID, privateNode, ops, capabilities); if (node == NULL) { _FileSystem()->PutNodeCapabilities(capabilities); return B_NO_MEMORY; } // add to map status_t error = fNodes->Put(vnodeID, node); if (error != B_OK) { delete node; return error; } *_node = node; return B_OK; }