* Adjusted according to the is_vnode_removed() -> get_vnode_removed()

change.
* The new notification functions are used instead of send_notification()
  and notify_listener() now. Mapped them in the BeOS kernel emulation
  accordingly. RamFS node monitoring seems to work now. 


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20298 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2007-03-02 00:41:09 +00:00
parent 9481e62bdb
commit 97dd0fe3c8
10 changed files with 326 additions and 166 deletions
+41 -42
View File
@@ -175,8 +175,8 @@ enum {
NOTIFY_LISTENER_REPLY,
NOTIFY_SELECT_EVENT_REQUEST,
NOTIFY_SELECT_EVENT_REPLY,
SEND_NOTIFICATION_REQUEST,
SEND_NOTIFICATION_REPLY,
NOTIFY_QUERY_REQUEST,
NOTIFY_QUERY_REPLY,
// vnodes
GET_VNODE_REQUEST,
@@ -191,8 +191,8 @@ enum {
REMOVE_VNODE_REPLY,
UNREMOVE_VNODE_REQUEST,
UNREMOVE_VNODE_REPLY,
IS_VNODE_REMOVED_REQUEST,
IS_VNODE_REMOVED_REPLY,
GET_VNODE_REMOVED_REQUEST,
GET_VNODE_REMOVED_REPLY,
// general reply
RECEIPT_ACK_REPLY,
@@ -1313,8 +1313,6 @@ public:
// #pragma mark -
// #pragma mark ----- notifications -----
// TODO: notify_listener() and send_notifications() are obsolete!
// NotifyListenerRequest
class NotifyListenerRequest : public Request {
public:
@@ -1322,10 +1320,13 @@ public:
status_t GetAddressInfos(AddressInfo* infos, int32* count);
int32 operation;
mount_id nsid;
vnode_id vnida;
vnode_id vnidb;
vnode_id vnidc;
uint32 details; // for B_STAT_CHANGED:statFields
// and B_ATTRIBUTE_CHANGED:cause
mount_id device;
vnode_id oldDirectory;
vnode_id directory;
vnode_id node;
Address oldName;
Address name;
};
@@ -1343,6 +1344,7 @@ public:
selectsync* sync;
uint32 ref;
uint8 event;
bool unspecifiedEvent;
};
// NotifySelectEventReply
@@ -1351,28 +1353,25 @@ public:
NotifySelectEventReply() : ReplyRequest(NOTIFY_SELECT_EVENT_REPLY) {}
};
// SendNotificationRequest
class SendNotificationRequest : public Request {
// NotifyQueryRequest
class NotifyQueryRequest : public Request {
public:
SendNotificationRequest() : Request(SEND_NOTIFICATION_REQUEST) {}
NotifyQueryRequest() : Request(NOTIFY_QUERY_REQUEST) {}
status_t GetAddressInfos(AddressInfo* infos, int32* count);
port_id port;
int32 token;
uint32 what;
int32 operation;
mount_id nsida;
mount_id nsidb;
vnode_id vnida;
vnode_id vnidb;
vnode_id vnidc;
int32 operation; // B_ENTRY_{CREATED,REMOVED}
mount_id device;
vnode_id directory;
vnode_id node;
Address name;
};
// SendNotificationReply
class SendNotificationReply : public ReplyRequest {
// NotifyQueryReply
class NotifyQueryReply : public ReplyRequest {
public:
SendNotificationReply() : ReplyRequest(SEND_NOTIFICATION_REPLY) {}
NotifyQueryReply() : ReplyRequest(NOTIFY_QUERY_REPLY) {}
};
@@ -1473,21 +1472,21 @@ public:
UnremoveVNodeReply() : ReplyRequest(UNREMOVE_VNODE_REPLY) {}
};
// IsVNodeRemovedRequest
class IsVNodeRemovedRequest : public Request {
// GetVNodeRemovedRequest
class GetVNodeRemovedRequest : public Request {
public:
IsVNodeRemovedRequest() : Request(IS_VNODE_REMOVED_REQUEST) {}
GetVNodeRemovedRequest() : Request(GET_VNODE_REMOVED_REQUEST) {}
mount_id nsid;
vnode_id vnid;
};
// IsVNodeRemovedReply
class IsVNodeRemovedReply : public ReplyRequest {
// GetVNodeRemovedReply
class GetVNodeRemovedReply : public ReplyRequest {
public:
IsVNodeRemovedReply() : ReplyRequest(IS_VNODE_REMOVED_REPLY) {}
GetVNodeRemovedReply() : ReplyRequest(GET_VNODE_REMOVED_REPLY) {}
int result;
bool removed;
};
@@ -1789,10 +1788,10 @@ do_for_request(Request* request, Task& task)
return task((NotifySelectEventRequest*)request);
case NOTIFY_SELECT_EVENT_REPLY:
return task((NotifySelectEventReply*)request);
case SEND_NOTIFICATION_REQUEST:
return task((SendNotificationRequest*)request);
case SEND_NOTIFICATION_REPLY:
return task((SendNotificationReply*)request);
case NOTIFY_QUERY_REQUEST:
return task((NotifyQueryRequest*)request);
case NOTIFY_QUERY_REPLY:
return task((NotifyQueryReply*)request);
// vnodes
case GET_VNODE_REQUEST:
return task((GetVNodeRequest*)request);
@@ -1818,10 +1817,10 @@ do_for_request(Request* request, Task& task)
return task((UnremoveVNodeRequest*)request);
case UNREMOVE_VNODE_REPLY:
return task((UnremoveVNodeReply*)request);
case IS_VNODE_REMOVED_REQUEST:
return task((IsVNodeRemovedRequest*)request);
case IS_VNODE_REMOVED_REPLY:
return task((IsVNodeRemovedReply*)request);
case GET_VNODE_REMOVED_REQUEST:
return task((GetVNodeRemovedRequest*)request);
case GET_VNODE_REMOVED_REPLY:
return task((GetVNodeRemovedReply*)request);
// general reply
case RECEIPT_ACK_REPLY:
return task((ReceiptAckReply*)request);
@@ -1992,8 +1991,8 @@ using UserlandFSUtil::NotifyListenerRequest;
using UserlandFSUtil::NotifyListenerReply;
using UserlandFSUtil::NotifySelectEventRequest;
using UserlandFSUtil::NotifySelectEventReply;
using UserlandFSUtil::SendNotificationRequest;
using UserlandFSUtil::SendNotificationReply;
using UserlandFSUtil::NotifyQueryRequest;
using UserlandFSUtil::NotifyQueryReply;
// vnodes
using UserlandFSUtil::GetVNodeRequest;
using UserlandFSUtil::GetVNodeReply;
@@ -2007,8 +2006,8 @@ using UserlandFSUtil::RemoveVNodeRequest;
using UserlandFSUtil::RemoveVNodeReply;
using UserlandFSUtil::UnremoveVNodeRequest;
using UserlandFSUtil::UnremoveVNodeReply;
using UserlandFSUtil::IsVNodeRemovedRequest;
using UserlandFSUtil::IsVNodeRemovedReply;
using UserlandFSUtil::GetVNodeRemovedRequest;
using UserlandFSUtil::GetVNodeRemovedReply;
// general reply
using UserlandFSUtil::ReceiptAckReply;
@@ -62,8 +62,8 @@ KernelRequestHandler::HandleRequest(Request* request)
return _HandleRequest((NotifyListenerRequest*)request);
case NOTIFY_SELECT_EVENT_REQUEST:
return _HandleRequest((NotifySelectEventRequest*)request);
case SEND_NOTIFICATION_REQUEST:
return _HandleRequest((SendNotificationRequest*)request);
case NOTIFY_QUERY_REQUEST:
return _HandleRequest((NotifyQueryRequest*)request);
// vnodes
case GET_VNODE_REQUEST:
return _HandleRequest((GetVNodeRequest*)request);
@@ -77,8 +77,8 @@ KernelRequestHandler::HandleRequest(Request* request)
return _HandleRequest((RemoveVNodeRequest*)request);
case UNREMOVE_VNODE_REQUEST:
return _HandleRequest((UnremoveVNodeRequest*)request);
case IS_VNODE_REMOVED_REQUEST:
return _HandleRequest((IsVNodeRemovedRequest*)request);
case GET_VNODE_REMOVED_REQUEST:
return _HandleRequest((GetVNodeRemovedRequest*)request);
}
PRINT(("KernelRequestHandler::HandleRequest(): unexpected request: %lu\n",
request->GetType()));
@@ -94,44 +94,109 @@ KernelRequestHandler::_HandleRequest(NotifyListenerRequest* request)
{
// check and executed the request
status_t result = B_OK;
if (fVolume && request->nsid != fVolume->GetID())
if (fVolume && request->device != fVolume->GetID())
result = B_BAD_VALUE;
// check the name
// get the names
// name
char* name = (char*)request->name.GetData();
int32 nameLen = request->name.GetSize();
if (name && (nameLen <= 0 || strnlen(name, nameLen) < 1))
if (name && (nameLen <= 0))
name = NULL;
else if (name)
name[nameLen - 1] = '\0';
if (!name) {
name[nameLen - 1] = '\0'; // NULL-terminate to be safe
// old name
char* oldName = (char*)request->oldName.GetData();
int32 oldNameLen = request->oldName.GetSize();
if (oldName && (oldNameLen <= 0))
oldName = NULL;
else if (oldName)
oldName[oldNameLen - 1] = '\0'; // NULL-terminate to be safe
// check the names
if (result == B_OK) {
switch (request->operation) {
case B_ENTRY_CREATED:
case B_ENTRY_MOVED:
case B_ATTR_CHANGED:
ERROR(("notify_listener(): NULL name for opcode: %ld\n",
request->operation));
result = B_BAD_VALUE;
break;
if (!oldName) {
ERROR(("NotifyListenerRequest: NULL oldName for "
"B_ENTRY_MOVED\n"));
result = B_BAD_VALUE;
break;
}
// fall through...
case B_ENTRY_CREATED:
case B_ENTRY_REMOVED:
case B_ATTR_CHANGED:
if (!name) {
ERROR(("NotifyListenerRequest: NULL name for opcode: %ld\n",
request->operation));
result = B_BAD_VALUE;
}
break;
case B_STAT_CHANGED:
break;
}
}
// execute the request
if (result == B_OK) {
PRINT(("notify_listener(%ld, %ld, %Ld, %Ld, %Ld, `%s')\n",
request->operation, request->nsid, request->vnida, request->vnidb,
request->vnidc, name));
result = notify_listener(request->operation, request->nsid,
request->vnida, request->vnidb, request->vnidc, name);
switch (request->operation) {
case B_ENTRY_CREATED:
PRINT(("notify_entry_created(%ld, %lld, \"%s\", %lld)\n",
request->device, request->directory, name, request->node));
result = notify_entry_created(request->device,
request->directory, name, request->node);
break;
case B_ENTRY_REMOVED:
PRINT(("notify_entry_removed(%ld, %lld, \"%s\", %lld)\n",
request->device, request->directory, name, request->node));
result = notify_entry_removed(request->device,
request->directory, name, request->node);
break;
case B_ENTRY_MOVED:
PRINT(("notify_entry_moved(%ld, %lld, \"%s\", %lld, \"%s\", "
"%lld)\n", request->device, request->oldDirectory, oldName,
request->directory, name, request->node));
result = notify_entry_moved(request->device,
request->oldDirectory, oldName, request->directory, name,
request->node);
break;
case B_STAT_CHANGED:
PRINT(("notify_stat_changed(%ld, %lld, 0x%lx)\n",
request->device, request->node, request->details));
result = notify_stat_changed(request->device, request->node,
request->details);
break;
case B_ATTR_CHANGED:
PRINT(("notify_attribute_changed(%ld, %lld, \"%s\", 0x%lx)\n",
request->device, request->node, name,
(int32)request->details));
result = notify_attribute_changed(request->device,
request->node, name, (int32)request->details);
break;
default:
ERROR(("NotifyQueryRequest: unsupported operation: %ld\n",
request->operation));
result = B_BAD_VALUE;
break;
}
}
// prepare the reply
RequestAllocator allocator(fPort->GetPort());
NotifyListenerReply* reply;
status_t error = AllocateRequest(allocator, &reply);
if (error != B_OK)
return error;
reply->error = result;
// send the reply
return fPort->SendRequest(&allocator);
}
@@ -143,67 +208,90 @@ KernelRequestHandler::_HandleRequest(NotifySelectEventRequest* request)
// check and executed the request
status_t result = B_OK;
if (fFileSystem->KnowsSelectSyncEntry(request->sync)) {
PRINT(("notify_select_event(%p, %lu)\n", request->sync, request->ref));
notify_select_event(request->sync, request->ref, request->event);
if (request->unspecifiedEvent) {
// old style add-ons can't provide an event argument; we shoot
// all events
notify_select_event(request->sync, request->ref, B_SELECT_READ);
notify_select_event(request->sync, request->ref, B_SELECT_WRITE);
notify_select_event(request->sync, request->ref, B_SELECT_ERROR);
} else {
PRINT(("notify_select_event(%p, %lu, %d)\n", request->sync,
request->ref, (int)request->event));
notify_select_event(request->sync, request->ref, request->event);
}
} else
result = B_BAD_VALUE;
// prepare the reply
RequestAllocator allocator(fPort->GetPort());
NotifySelectEventReply* reply;
status_t error = AllocateRequest(allocator, &reply);
if (error != B_OK)
return error;
reply->error = result;
// send the reply
return fPort->SendRequest(&allocator);
}
// _HandleRequest
status_t
KernelRequestHandler::_HandleRequest(SendNotificationRequest* request)
KernelRequestHandler::_HandleRequest(NotifyQueryRequest* request)
{
// check and executed the request
status_t result = B_OK;
if (fVolume && request->nsida != fVolume->GetID()
&& request->nsidb != fVolume->GetID()) {
if (fVolume && request->device != fVolume->GetID())
result = B_BAD_VALUE;
}
// check the name
char* name = (char*)request->name.GetData();
int32 nameLen = request->name.GetSize();
if (name && (nameLen <= 0 || strnlen(name, nameLen) < 1))
name = NULL;
else if (name)
name[nameLen - 1] = '\0';
if (!name) {
if (!name || nameLen <= 0) {
ERROR(("NotifyQueryRequest: NULL name!\n"));
result = B_BAD_VALUE;
} else
name[nameLen - 1] = '\0'; // NULL-terminate to be safe
// execute the request
if (result == B_OK) {
switch (request->operation) {
case B_ENTRY_CREATED:
PRINT(("notify_query_entry_created(%ld, %ld, %ld, %lld,"
" \"%s\", %lld)\n", request->port, request->token,
request->device, request->directory, name, request->node));
result = notify_query_entry_created(request->port,
request->token, request->device, request->directory, name,
request->node);
break;
case B_ENTRY_REMOVED:
PRINT(("notify_query_entry_removed(%ld, %ld, %ld, %lld,"
" \"%s\", %lld)\n", request->port, request->token,
request->device, request->directory, name, request->node));
result = notify_query_entry_removed(request->port,
request->token, request->device, request->directory, name,
request->node);
break;
case B_ENTRY_MOVED:
ERROR(("send_notification(): NULL name for opcode: %ld\n",
default:
ERROR(("NotifyQueryRequest: unsupported operation: %ld\n",
request->operation));
result = B_BAD_VALUE;
break;
case B_ENTRY_REMOVED:
break;
}
}
// execute the request
if (result == B_OK) {
PRINT(("send_notification(%ld, %ld, %lu, %ld, %ld, %ld, %Ld, %Ld, %Ld, "
"`%s')\n", request->port, request->token, request->what,
request->operation, request->nsida, request->nsidb, request->vnida,
request->vnidb, request->vnidc, name));
result = send_notification(request->port, request->token, request->what,
request->operation, request->nsida, request->nsidb, request->vnida,
request->vnidb, request->vnidc, name);
}
// prepare the reply
RequestAllocator allocator(fPort->GetPort());
SendNotificationReply* reply;
NotifyQueryReply* reply;
status_t error = AllocateRequest(allocator, &reply);
if (error != B_OK)
return error;
reply->error = result;
// send the reply
return fPort->SendRequest(&allocator);
}
@@ -344,22 +432,26 @@ KernelRequestHandler::_HandleRequest(UnremoveVNodeRequest* request)
// _HandleRequest
status_t
KernelRequestHandler::_HandleRequest(IsVNodeRemovedRequest* request)
KernelRequestHandler::_HandleRequest(GetVNodeRemovedRequest* request)
{
// check and executed the request
Volume* volume = NULL;
status_t result = _GetVolume(request->nsid, &volume);
VolumePutter _(volume);
bool removed = false;
if (result == B_OK)
result = volume->IsVNodeRemoved(request->vnid);
result = volume->GetVNodeRemoved(request->vnid, &removed);
// prepare the reply
RequestAllocator allocator(fPort->GetPort());
IsVNodeRemovedReply* reply;
GetVNodeRemovedReply* reply;
status_t error = AllocateRequest(allocator, &reply);
if (error != B_OK)
return error;
reply->error = (result < 0 ? result : B_OK);
reply->result = result;
reply->error = result;
reply->removed = removed;
// send the reply
return fPort->SendRequest(&allocator);
}
@@ -9,28 +9,28 @@
namespace UserlandFSUtil {
class GetVNodeRemovedRequest;
class GetVNodeRequest;
class IsVNodeRemovedRequest;
class NewVNodeRequest;
class NotifyListenerRequest;
class NotifyQueryRequest;
class NotifySelectEventRequest;
class PublishVNodeRequest;
class PutVNodeRequest;
class RemoveVNodeRequest;
class SendNotificationRequest;
class UnremoveVNodeRequest;
}
using UserlandFSUtil::GetVNodeRemovedRequest;
using UserlandFSUtil::GetVNodeRequest;
using UserlandFSUtil::IsVNodeRemovedRequest;
using UserlandFSUtil::NewVNodeRequest;
using UserlandFSUtil::NotifyListenerRequest;
using UserlandFSUtil::NotifyQueryRequest;
using UserlandFSUtil::NotifySelectEventRequest;
using UserlandFSUtil::PublishVNodeRequest;
using UserlandFSUtil::PutVNodeRequest;
using UserlandFSUtil::RemoveVNodeRequest;
using UserlandFSUtil::SendNotificationRequest;
using UserlandFSUtil::UnremoveVNodeRequest;
class Volume;
@@ -50,8 +50,7 @@ private:
status_t _HandleRequest(NotifyListenerRequest* request);
status_t _HandleRequest(
NotifySelectEventRequest* request);
status_t _HandleRequest(
SendNotificationRequest* request);
status_t _HandleRequest(NotifyQueryRequest* request);
// vnodes
status_t _HandleRequest(GetVNodeRequest* request);
status_t _HandleRequest(PutVNodeRequest* request);
@@ -59,7 +58,7 @@ private:
status_t _HandleRequest(PublishVNodeRequest* request);
status_t _HandleRequest(RemoveVNodeRequest* request);
status_t _HandleRequest(UnremoveVNodeRequest* request);
status_t _HandleRequest(IsVNodeRemovedRequest* request);
status_t _HandleRequest(GetVNodeRemovedRequest* request);
status_t _GetVolume(mount_id id, Volume** volume);
@@ -129,7 +129,7 @@ Volume::IsMounting() const
status_t
Volume::GetVNode(vnode_id vnid, fs_vnode* node)
{
PRINT(("get_vnode(%ld, %Ld)\n", fID, vnid));
PRINT(("get_vnode(%ld, %lld)\n", fID, vnid));
if (IsMounting() && !fMountVNodes->ContainsKey(vnid)) {
ERROR(("Volume::GetVNode(): get_vnode() invoked for unknown vnode "
"while mounting!\n"));
@@ -144,7 +144,7 @@ PRINT(("get_vnode(%ld, %Ld)\n", fID, vnid));
status_t
Volume::PutVNode(vnode_id vnid)
{
PRINT(("put_vnode(%ld, %Ld)\n", fID, vnid));
PRINT(("put_vnode(%ld, %lld)\n", fID, vnid));
status_t error = put_vnode(fID, vnid);
if (error == B_OK)
_DecrementVNodeCount(vnid);
@@ -155,7 +155,7 @@ PRINT(("put_vnode(%ld, %Ld)\n", fID, vnid));
status_t
Volume::NewVNode(vnode_id vnid, fs_vnode node)
{
PRINT(("new_vnode(%ld, %Ld)\n", fID, vnid));
PRINT(("new_vnode(%ld, %lld)\n", fID, vnid));
status_t error = new_vnode(fID, vnid, node);
if (error == B_OK) {
if (IsMounting()) {
@@ -168,7 +168,7 @@ PRINT(("new_vnode(%ld, %Ld)\n", fID, vnid));
return error;
}
}
// TODO: Check what need to do according to the new semantics.
// TODO: Check what we need to do according to the new semantics.
// _IncrementVNodeCount(vnid);
}
return error;
@@ -178,7 +178,7 @@ PRINT(("new_vnode(%ld, %Ld)\n", fID, vnid));
status_t
Volume::PublishVNode(vnode_id vnid, fs_vnode node)
{
PRINT(("publish_vnode(%ld, %Ld)\n", fID, vnid));
PRINT(("publish_vnode(%ld, %lld)\n", fID, vnid));
status_t error = publish_vnode(fID, vnid, node);
if (error == B_OK) {
if (IsMounting()) {
@@ -199,7 +199,7 @@ PRINT(("publish_vnode(%ld, %Ld)\n", fID, vnid));
status_t
Volume::RemoveVNode(vnode_id vnid)
{
PRINT(("remove_vnode(%ld, %Ld)\n", fID, vnid));
PRINT(("remove_vnode(%ld, %lld)\n", fID, vnid));
return remove_vnode(fID, vnid);
}
@@ -207,16 +207,16 @@ PRINT(("remove_vnode(%ld, %Ld)\n", fID, vnid));
status_t
Volume::UnremoveVNode(vnode_id vnid)
{
PRINT(("unremove_vnode(%ld, %Ld)\n", fID, vnid));
PRINT(("unremove_vnode(%ld, %lld)\n", fID, vnid));
return unremove_vnode(fID, vnid);
}
// IsVNodeRemoved
// GetVNodeRemoved
status_t
Volume::IsVNodeRemoved(vnode_id vnid)
Volume::GetVNodeRemoved(vnode_id vnid, bool* removed)
{
PRINT(("is_vnode_removed(%ld, %Ld)\n", fID, vnid));
return is_vnode_removed(fID, vnid);
PRINT(("get_vnode_removed(%ld, %lld, %p)\n", fID, vnid, removed));
return get_vnode_removed(fID, vnid, removed);
}
@@ -41,7 +41,7 @@ public:
status_t PublishVNode(vnode_id vnid, fs_vnode node);
status_t RemoveVNode(vnode_id vnid);
status_t UnremoveVNode(vnode_id vnid);
status_t IsVNodeRemoved(vnode_id vnid);
status_t GetVNodeRemoved(vnode_id vnid, bool* removed);
// FS
status_t Mount(const char* device, uint32 flags,
@@ -276,13 +276,14 @@ ReadQueryReply::GetAddressInfos(AddressInfo* infos, int32* count)
status_t
NotifyListenerRequest::GetAddressInfos(AddressInfo* infos, int32* count)
{
ADD_STRING(oldName);
ADD_STRING(name);
return B_OK;
}
// SendNotificationRequest
// NotifyQueryRequest
status_t
SendNotificationRequest::GetAddressInfos(AddressInfo* infos, int32* count)
NotifyQueryRequest::GetAddressInfos(AddressInfo* infos, int32* count)
{
ADD_STRING(name);
return B_OK;
@@ -635,11 +636,11 @@ UserlandFSUtil::is_kernel_request(uint32 type)
// notifications
case NOTIFY_LISTENER_REQUEST:
case NOTIFY_SELECT_EVENT_REQUEST:
case SEND_NOTIFICATION_REQUEST:
case NOTIFY_QUERY_REQUEST:
return false;
case NOTIFY_LISTENER_REPLY:
case NOTIFY_SELECT_EVENT_REPLY:
case SEND_NOTIFICATION_REPLY:
case NOTIFY_QUERY_REPLY:
return true;
// vnodes
case GET_VNODE_REQUEST:
@@ -648,7 +649,7 @@ UserlandFSUtil::is_kernel_request(uint32 type)
case PUBLISH_VNODE_REQUEST:
case REMOVE_VNODE_REQUEST:
case UNREMOVE_VNODE_REQUEST:
case IS_VNODE_REMOVED_REQUEST:
case GET_VNODE_REMOVED_REQUEST:
return false;
case GET_VNODE_REPLY:
case PUT_VNODE_REPLY:
@@ -656,7 +657,7 @@ UserlandFSUtil::is_kernel_request(uint32 type)
case PUBLISH_VNODE_REPLY:
case REMOVE_VNODE_REPLY:
case UNREMOVE_VNODE_REPLY:
case IS_VNODE_REMOVED_REPLY:
case GET_VNODE_REMOVED_REPLY:
return true;
// general reply
@@ -835,11 +836,11 @@ UserlandFSUtil::is_userland_request(uint32 type)
// notifications
case NOTIFY_LISTENER_REQUEST:
case NOTIFY_SELECT_EVENT_REQUEST:
case SEND_NOTIFICATION_REQUEST:
case NOTIFY_QUERY_REQUEST:
return true;
case NOTIFY_LISTENER_REPLY:
case NOTIFY_SELECT_EVENT_REPLY:
case SEND_NOTIFICATION_REPLY:
case NOTIFY_QUERY_REPLY:
return false;
// vnodes
case GET_VNODE_REQUEST:
@@ -848,7 +849,7 @@ UserlandFSUtil::is_userland_request(uint32 type)
case PUBLISH_VNODE_REQUEST:
case REMOVE_VNODE_REQUEST:
case UNREMOVE_VNODE_REQUEST:
case IS_VNODE_REMOVED_REQUEST:
case GET_VNODE_REMOVED_REQUEST:
return true;
case GET_VNODE_REPLY:
case PUT_VNODE_REPLY:
@@ -856,7 +857,7 @@ UserlandFSUtil::is_userland_request(uint32 type)
case PUBLISH_VNODE_REPLY:
case REMOVE_VNODE_REPLY:
case UNREMOVE_VNODE_REPLY:
case IS_VNODE_REMOVED_REPLY:
case GET_VNODE_REMOVED_REPLY:
return false;
// general reply
@@ -213,7 +213,7 @@ BeOSKernelVolume::Select(fs_vnode node, fs_cookie cookie, uint8 event,
uint32 ref, selectsync* sync)
{
if (!fFSOps->select) {
UserlandFS::KernelEmu::notify_select_event(sync, ref, event);
UserlandFS::KernelEmu::notify_select_event(sync, ref, event, false);
return B_OK;
}
return fFSOps->select(fVolumeCookie, node, cookie, event, ref, sync);
@@ -4,12 +4,15 @@
#include <stdio.h>
#include <stdlib.h>
#include <NodeMonitor.h>
#include <legacy/cache.h>
#include <legacy/fsproto.h>
#include <legacy/lock.h>
#include "beos_fs_cache.h"
#include "beos_lock.h"
#include "Debug.h"
#include "kernel_emu.h"
@@ -39,26 +42,83 @@ int
notify_listener(int op, nspace_id nsid, vnode_id vnida, vnode_id vnidb,
vnode_id vnidc, const char *name)
{
return UserlandFS::KernelEmu::notify_listener(op, nsid, vnida, vnidb, vnidc,
name);
switch (op) {
case B_ENTRY_CREATED:
case B_ENTRY_REMOVED:
if (!name)
name = "";
return UserlandFS::KernelEmu::notify_listener(op, 0, nsid, 0,
vnida, vnidc, NULL, name);
case B_ENTRY_MOVED:
if (!name)
name = "";
// the old entry name is not available with the old interface
return UserlandFS::KernelEmu::notify_listener(op, 0, nsid, vnida,
vnidb, vnidc, "", name);
case B_STAT_CHANGED:
{
// we don't know what stat field changed, so we mark them all
uint32 statFields = B_STAT_MODE | B_STAT_UID | B_STAT_GID
| B_STAT_SIZE | B_STAT_ACCESS_TIME | B_STAT_MODIFICATION_TIME
| B_STAT_CREATION_TIME | B_STAT_CHANGE_TIME;
return UserlandFS::KernelEmu::notify_listener(op, statFields, nsid,
0, vnida, vnidc, NULL, NULL);
}
case B_ATTR_CHANGED:
if (!name)
name = "";
return UserlandFS::KernelEmu::notify_listener(op, B_ATTR_CHANGED,
nsid, 0, vnida, vnidc, NULL, name);
default:
return B_BAD_VALUE;
}
}
// notify_select_event
void
notify_select_event(selectsync *sync, uint32 ref)
{
// TODO: Check what best to supply as event arg!
UserlandFS::KernelEmu::notify_select_event(sync, ref, 0);
UserlandFS::KernelEmu::notify_select_event(sync, ref, 0, true);
}
// send_notification
int
send_notification(port_id port, long token, ulong what, long op,
nspace_id nsida, nspace_id nsidb, vnode_id vnida, vnode_id vnidb,
nspace_id nsida, nspace_id /*nsidb*/, vnode_id vnida, vnode_id vnidb,
vnode_id vnidc, const char *name)
{
return UserlandFS::KernelEmu::send_notification(port, token, what, op,
nsida, nsidb, vnida, vnidb, vnidc, name);
if (what != B_QUERY_UPDATE)
return B_BAD_VALUE;
// check the name
if (!name)
name = "";
switch (op) {
case B_ENTRY_CREATED:
case B_ENTRY_REMOVED:
return UserlandFS::KernelEmu::notify_query(port, token, op, nsida,
vnida, name, vnidc);
case B_ENTRY_MOVED:
{
// translate to a B_ENTRY_REMOVED + B_ENTRY_CREATED pair
// We do at least miss the original name though.
status_t error = UserlandFS::KernelEmu::notify_query(port, token,
B_ENTRY_REMOVED, nsida, vnida, "", vnidc);
if (error != B_OK)
return error;
return UserlandFS::KernelEmu::notify_query(port, token,
B_ENTRY_CREATED, nsida, vnidb, name, vnidc);
}
default:
return B_BAD_VALUE;
}
}
@@ -106,7 +166,12 @@ unremove_vnode(nspace_id nsid, vnode_id vnid)
int
is_vnode_removed(nspace_id nsid, vnode_id vnid)
{
return UserlandFS::KernelEmu::is_vnode_removed(nsid, vnid);
bool removed;
status_t error = UserlandFS::KernelEmu::get_vnode_removed(nsid, vnid,
&removed);
if (error != B_OK)
return error;
return (removed ? 1 : 0);
}
@@ -123,8 +123,9 @@ get_port_and_fs(RequestPort** port, FileSystem** fileSystem)
// notify_listener
status_t
UserlandFS::KernelEmu::notify_listener(int op, mount_id nsid, vnode_id vnida,
vnode_id vnidb, vnode_id vnidc, const char *name)
UserlandFS::KernelEmu::notify_listener(int32 operation, uint32 details,
mount_id device, vnode_id oldDirectory, vnode_id directory,
vnode_id node, const char* oldName, const char* name)
{
// get the request port and the file system
RequestPort* port;
@@ -140,11 +141,15 @@ UserlandFS::KernelEmu::notify_listener(int op, mount_id nsid, vnode_id vnida,
if (error != B_OK)
return error;
request->operation = op;
request->nsid = nsid;
request->vnida = vnida;
request->vnidb = vnidb;
request->vnidc = vnidc;
request->operation = operation;
request->details = details;
request->device = device;
request->oldDirectory = oldDirectory;
request->directory = directory;
request->node = node;
error = allocator.AllocateString(request->oldName, oldName);
if (error != B_OK)
return error;
error = allocator.AllocateString(request->name, name);
if (error != B_OK)
return error;
@@ -166,7 +171,7 @@ UserlandFS::KernelEmu::notify_listener(int op, mount_id nsid, vnode_id vnida,
// notify_select_event
void
UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint32 ref,
uint8 event)
uint8 event, bool unspecifiedEvent)
{
// get the request port and the file system
RequestPort* port;
@@ -185,6 +190,7 @@ UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint32 ref,
request->sync = sync;
request->ref = ref;
request->event = event;
request->unspecifiedEvent = unspecifiedEvent;
// send the request
UserlandRequestHandler handler(fileSystem, NOTIFY_SELECT_EVENT_REPLY);
@@ -199,9 +205,9 @@ UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint32 ref,
// send_notification
status_t
UserlandFS::KernelEmu::send_notification(port_id targetPort, long token,
ulong what, long op, mount_id nsida, mount_id nsidb, vnode_id vnida,
vnode_id vnidb, vnode_id vnidc, const char *name)
UserlandFS::KernelEmu::notify_query(port_id targetPort, int32 token,
int32 operation, mount_id device, vnode_id directory, const char* name,
vnode_id node)
{
// get the request port and the file system
RequestPort* port;
@@ -212,27 +218,24 @@ UserlandFS::KernelEmu::send_notification(port_id targetPort, long token,
// prepare the request
RequestAllocator allocator(port->GetPort());
SendNotificationRequest* request;
NotifyQueryRequest* request;
error = AllocateRequest(allocator, &request);
if (error != B_OK)
return error;
request->port = targetPort;
request->token = token;
request->what = what;
request->operation = op;
request->nsida = nsida;
request->nsidb = nsidb;
request->vnida = vnida;
request->vnidb = vnidb;
request->vnidc = vnidc;
request->operation = operation;
request->device = device;
request->directory = directory;
request->node = node;
error = allocator.AllocateString(request->name, name);
if (error != B_OK)
return error;
// send the request
UserlandRequestHandler handler(fileSystem, SEND_NOTIFICATION_REPLY);
SendNotificationReply* reply;
UserlandRequestHandler handler(fileSystem, NOTIFY_QUERY_REPLY);
NotifyQueryReply* reply;
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
if (error != B_OK)
return error;
@@ -462,9 +465,10 @@ UserlandFS::KernelEmu::unremove_vnode(mount_id nsid, vnode_id vnid)
return error;
}
// is_vnode_removed
// get_vnode_removed
status_t
UserlandFS::KernelEmu::is_vnode_removed(mount_id nsid, vnode_id vnid)
UserlandFS::KernelEmu::get_vnode_removed(mount_id nsid, vnode_id vnid,
bool* removed)
{
// get the request port and the file system
RequestPort* port;
@@ -475,7 +479,7 @@ UserlandFS::KernelEmu::is_vnode_removed(mount_id nsid, vnode_id vnid)
// prepare the request
RequestAllocator allocator(port->GetPort());
IsVNodeRemovedRequest* request;
GetVNodeRemovedRequest* request;
error = AllocateRequest(allocator, &request);
if (error != B_OK)
return error;
@@ -484,17 +488,16 @@ UserlandFS::KernelEmu::is_vnode_removed(mount_id nsid, vnode_id vnid)
request->vnid = vnid;
// send the request
UserlandRequestHandler handler(fileSystem, IS_VNODE_REMOVED_REPLY);
IsVNodeRemovedReply* reply;
UserlandRequestHandler handler(fileSystem, GET_VNODE_REMOVED_REPLY);
GetVNodeRemovedReply* reply;
error = port->SendRequest(&allocator, &handler, (Request**)&reply);
if (error != B_OK)
return error;
RequestReleaser requestReleaser(port, reply);
// process the reply
if (reply->error != B_OK)
return reply->error;
return reply->result;
*removed = reply->removed;
return reply->error;
}
// #pragma mark -
@@ -14,12 +14,13 @@ typedef void* fs_vnode;
int new_path(const char *path, char **copy);
void free_path(char *p);
status_t notify_listener(int op, mount_id nsid, vnode_id vnida, vnode_id vnidb,
vnode_id vnidc, const char *name);
void notify_select_event(selectsync *sync, uint32 ref, uint8 event);
status_t send_notification(port_id targetPort, long token, ulong what, long op,
mount_id nsida, mount_id nsidb, vnode_id vnida, vnode_id vnidb,
vnode_id vnidc, const char *name);
status_t notify_listener(int32 operation, uint32 details, mount_id device,
vnode_id oldDirectory, vnode_id directory, vnode_id node,
const char* oldName, const char* name);
void notify_select_event(selectsync *sync, uint32 ref, uint8 event,
bool unspecifiedEvent);
status_t notify_query(port_id port, int32 token, int32 operation,
mount_id device, vnode_id directory, const char* name, vnode_id node);
status_t get_vnode(mount_id nsid, vnode_id vnid, fs_vnode* data);
status_t put_vnode(mount_id nsid, vnode_id vnid);
@@ -27,7 +28,7 @@ status_t new_vnode(mount_id nsid, vnode_id vnid, fs_vnode data);
status_t publish_vnode(mount_id nsid, vnode_id vnid, fs_vnode data);
status_t remove_vnode(mount_id nsid, vnode_id vnid);
status_t unremove_vnode(mount_id nsid, vnode_id vnid);
status_t is_vnode_removed(mount_id nsid, vnode_id vnid);
status_t get_vnode_removed(mount_id nsid, vnode_id vnid, bool* removed);
void kernel_debugger(const char *message);
void panic(const char *format, ...);