ReadVNode(): We need to create the VNode object before sending the request
to userland, since typically the file cache for the node is created there and our FileCacheCreate() method requires and existing VNode object. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29554 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -51,13 +51,15 @@ struct Volume::VNode : HashTableLink<VNode> {
|
|||||||
void* clientNode;
|
void* clientNode;
|
||||||
void* fileCache;
|
void* fileCache;
|
||||||
int32 useCount;
|
int32 useCount;
|
||||||
|
bool valid;
|
||||||
|
|
||||||
VNode(ino_t id, void* clientNode)
|
VNode(ino_t id, void* clientNode)
|
||||||
:
|
:
|
||||||
id(id),
|
id(id),
|
||||||
clientNode(clientNode),
|
clientNode(clientNode),
|
||||||
fileCache(NULL),
|
fileCache(NULL),
|
||||||
useCount(0)
|
useCount(0),
|
||||||
|
valid(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -955,27 +957,36 @@ Volume::ReadVNode(ino_t vnid, bool reenter, void** _node, int* type,
|
|||||||
request->vnid = vnid;
|
request->vnid = vnid;
|
||||||
request->reenter = reenter;
|
request->reenter = reenter;
|
||||||
|
|
||||||
|
// add the uninitialized node to our map
|
||||||
|
VNode* vnode = new(std::nothrow) VNode(vnid, NULL);
|
||||||
|
if (vnode == NULL)
|
||||||
|
RETURN_ERROR(B_NO_MEMORY);
|
||||||
|
vnode->valid = false;
|
||||||
|
|
||||||
|
MutexLocker locker(fLock);
|
||||||
|
fVNodes->Insert(vnode);
|
||||||
|
locker.Unlock();
|
||||||
|
|
||||||
// send the request
|
// send the request
|
||||||
KernelRequestHandler handler(this, READ_VNODE_REPLY);
|
KernelRequestHandler handler(this, READ_VNODE_REPLY);
|
||||||
ReadVNodeReply* reply;
|
ReadVNodeReply* reply;
|
||||||
error = _SendRequest(port, &allocator, &handler, (Request**)&reply);
|
error = _SendRequest(port, &allocator, &handler, (Request**)&reply);
|
||||||
if (error != B_OK)
|
if (error != B_OK) {
|
||||||
|
_RemoveInvalidVNode(vnid);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
RequestReleaser requestReleaser(port, reply);
|
RequestReleaser requestReleaser(port, reply);
|
||||||
|
|
||||||
// process the reply
|
// process the reply
|
||||||
if (reply->error != B_OK)
|
if (reply->error != B_OK) {
|
||||||
|
_RemoveInvalidVNode(vnid);
|
||||||
return reply->error;
|
return reply->error;
|
||||||
|
|
||||||
// everything went fine so far -- add the node to our map
|
|
||||||
VNode* vnode = new(std::nothrow) VNode(vnid, reply->node);
|
|
||||||
if (vnode == NULL) {
|
|
||||||
WriteVNode(reply->node, reenter);
|
|
||||||
RETURN_ERROR(B_NO_MEMORY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MutexLocker lock(fLock);
|
// everything went fine -- mark the node valid
|
||||||
fVNodes->Insert(vnode);
|
locker.Lock();
|
||||||
|
vnode->clientNode = reply->node;
|
||||||
|
vnode->valid = true;
|
||||||
|
|
||||||
*_node = vnode;
|
*_node = vnode;
|
||||||
*type = reply->type;
|
*type = reply->type;
|
||||||
@@ -4227,6 +4238,7 @@ Volume::_IncrementVNodeCount(ino_t vnid)
|
|||||||
//PRINT(("_IncrementVNodeCount(%Ld): count: %ld, fVNodeCountMap size: %ld\n", vnid, *count, fVNodeCountMap->Size()));
|
//PRINT(("_IncrementVNodeCount(%Ld): count: %ld, fVNodeCountMap size: %ld\n", vnid, *count, fVNodeCountMap->Size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// _DecrementVNodeCount
|
// _DecrementVNodeCount
|
||||||
void
|
void
|
||||||
Volume::_DecrementVNodeCount(ino_t vnid)
|
Volume::_DecrementVNodeCount(ino_t vnid)
|
||||||
@@ -4247,6 +4259,31 @@ Volume::_DecrementVNodeCount(ino_t vnid)
|
|||||||
//PRINT(("_DecrementVNodeCount(%Ld): count: %ld, fVNodeCountMap size: %ld\n", vnid, tmpCount, fVNodeCountMap->Size()));
|
//PRINT(("_DecrementVNodeCount(%Ld): count: %ld, fVNodeCountMap size: %ld\n", vnid, tmpCount, fVNodeCountMap->Size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// _RemoveInvalidVNode
|
||||||
|
void
|
||||||
|
Volume::_RemoveInvalidVNode(ino_t vnid)
|
||||||
|
{
|
||||||
|
MutexLocker locker(fLock);
|
||||||
|
|
||||||
|
VNode* vnode = fVNodes->Lookup(vnid);
|
||||||
|
if (vnode == NULL) {
|
||||||
|
ERROR(("Volume::_RemoveInvalidVNode(): Node with ID %lld not known!\n",
|
||||||
|
vnid));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fVNodes->Remove(vnode);
|
||||||
|
locker.Unlock();
|
||||||
|
|
||||||
|
// release all references acquired so far
|
||||||
|
for (; vnode->useCount > 0; vnode->useCount--)
|
||||||
|
put_vnode(fFSVolume, vnid);
|
||||||
|
|
||||||
|
delete vnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// _InternalIOCtl
|
// _InternalIOCtl
|
||||||
status_t
|
status_t
|
||||||
Volume::_InternalIOCtl(userlandfs_ioctl* buffer, int32 bufferSize)
|
Volume::_InternalIOCtl(userlandfs_ioctl* buffer, int32 bufferSize)
|
||||||
|
|||||||
@@ -257,6 +257,7 @@ private:
|
|||||||
|
|
||||||
void _IncrementVNodeCount(ino_t vnid);
|
void _IncrementVNodeCount(ino_t vnid);
|
||||||
void _DecrementVNodeCount(ino_t vnid);
|
void _DecrementVNodeCount(ino_t vnid);
|
||||||
|
void _RemoveInvalidVNode(ino_t vnid);
|
||||||
|
|
||||||
status_t _InternalIOCtl(userlandfs_ioctl* buffer,
|
status_t _InternalIOCtl(userlandfs_ioctl* buffer,
|
||||||
int32 bufferSize);
|
int32 bufferSize);
|
||||||
|
|||||||
Reference in New Issue
Block a user