* 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_LISTENER_REPLY,
NOTIFY_SELECT_EVENT_REQUEST, NOTIFY_SELECT_EVENT_REQUEST,
NOTIFY_SELECT_EVENT_REPLY, NOTIFY_SELECT_EVENT_REPLY,
SEND_NOTIFICATION_REQUEST, NOTIFY_QUERY_REQUEST,
SEND_NOTIFICATION_REPLY, NOTIFY_QUERY_REPLY,
// vnodes // vnodes
GET_VNODE_REQUEST, GET_VNODE_REQUEST,
@@ -191,8 +191,8 @@ enum {
REMOVE_VNODE_REPLY, REMOVE_VNODE_REPLY,
UNREMOVE_VNODE_REQUEST, UNREMOVE_VNODE_REQUEST,
UNREMOVE_VNODE_REPLY, UNREMOVE_VNODE_REPLY,
IS_VNODE_REMOVED_REQUEST, GET_VNODE_REMOVED_REQUEST,
IS_VNODE_REMOVED_REPLY, GET_VNODE_REMOVED_REPLY,
// general reply // general reply
RECEIPT_ACK_REPLY, RECEIPT_ACK_REPLY,
@@ -1313,8 +1313,6 @@ public:
// #pragma mark - // #pragma mark -
// #pragma mark ----- notifications ----- // #pragma mark ----- notifications -----
// TODO: notify_listener() and send_notifications() are obsolete!
// NotifyListenerRequest // NotifyListenerRequest
class NotifyListenerRequest : public Request { class NotifyListenerRequest : public Request {
public: public:
@@ -1322,10 +1320,13 @@ public:
status_t GetAddressInfos(AddressInfo* infos, int32* count); status_t GetAddressInfos(AddressInfo* infos, int32* count);
int32 operation; int32 operation;
mount_id nsid; uint32 details; // for B_STAT_CHANGED:statFields
vnode_id vnida; // and B_ATTRIBUTE_CHANGED:cause
vnode_id vnidb; mount_id device;
vnode_id vnidc; vnode_id oldDirectory;
vnode_id directory;
vnode_id node;
Address oldName;
Address name; Address name;
}; };
@@ -1343,6 +1344,7 @@ public:
selectsync* sync; selectsync* sync;
uint32 ref; uint32 ref;
uint8 event; uint8 event;
bool unspecifiedEvent;
}; };
// NotifySelectEventReply // NotifySelectEventReply
@@ -1351,28 +1353,25 @@ public:
NotifySelectEventReply() : ReplyRequest(NOTIFY_SELECT_EVENT_REPLY) {} NotifySelectEventReply() : ReplyRequest(NOTIFY_SELECT_EVENT_REPLY) {}
}; };
// SendNotificationRequest // NotifyQueryRequest
class SendNotificationRequest : public Request { class NotifyQueryRequest : public Request {
public: public:
SendNotificationRequest() : Request(SEND_NOTIFICATION_REQUEST) {} NotifyQueryRequest() : Request(NOTIFY_QUERY_REQUEST) {}
status_t GetAddressInfos(AddressInfo* infos, int32* count); status_t GetAddressInfos(AddressInfo* infos, int32* count);
port_id port; port_id port;
int32 token; int32 token;
uint32 what; int32 operation; // B_ENTRY_{CREATED,REMOVED}
int32 operation; mount_id device;
mount_id nsida; vnode_id directory;
mount_id nsidb; vnode_id node;
vnode_id vnida;
vnode_id vnidb;
vnode_id vnidc;
Address name; Address name;
}; };
// SendNotificationReply // NotifyQueryReply
class SendNotificationReply : public ReplyRequest { class NotifyQueryReply : public ReplyRequest {
public: public:
SendNotificationReply() : ReplyRequest(SEND_NOTIFICATION_REPLY) {} NotifyQueryReply() : ReplyRequest(NOTIFY_QUERY_REPLY) {}
}; };
@@ -1473,21 +1472,21 @@ public:
UnremoveVNodeReply() : ReplyRequest(UNREMOVE_VNODE_REPLY) {} UnremoveVNodeReply() : ReplyRequest(UNREMOVE_VNODE_REPLY) {}
}; };
// IsVNodeRemovedRequest // GetVNodeRemovedRequest
class IsVNodeRemovedRequest : public Request { class GetVNodeRemovedRequest : public Request {
public: public:
IsVNodeRemovedRequest() : Request(IS_VNODE_REMOVED_REQUEST) {} GetVNodeRemovedRequest() : Request(GET_VNODE_REMOVED_REQUEST) {}
mount_id nsid; mount_id nsid;
vnode_id vnid; vnode_id vnid;
}; };
// IsVNodeRemovedReply // GetVNodeRemovedReply
class IsVNodeRemovedReply : public ReplyRequest { class GetVNodeRemovedReply : public ReplyRequest {
public: 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); return task((NotifySelectEventRequest*)request);
case NOTIFY_SELECT_EVENT_REPLY: case NOTIFY_SELECT_EVENT_REPLY:
return task((NotifySelectEventReply*)request); return task((NotifySelectEventReply*)request);
case SEND_NOTIFICATION_REQUEST: case NOTIFY_QUERY_REQUEST:
return task((SendNotificationRequest*)request); return task((NotifyQueryRequest*)request);
case SEND_NOTIFICATION_REPLY: case NOTIFY_QUERY_REPLY:
return task((SendNotificationReply*)request); return task((NotifyQueryReply*)request);
// vnodes // vnodes
case GET_VNODE_REQUEST: case GET_VNODE_REQUEST:
return task((GetVNodeRequest*)request); return task((GetVNodeRequest*)request);
@@ -1818,10 +1817,10 @@ do_for_request(Request* request, Task& task)
return task((UnremoveVNodeRequest*)request); return task((UnremoveVNodeRequest*)request);
case UNREMOVE_VNODE_REPLY: case UNREMOVE_VNODE_REPLY:
return task((UnremoveVNodeReply*)request); return task((UnremoveVNodeReply*)request);
case IS_VNODE_REMOVED_REQUEST: case GET_VNODE_REMOVED_REQUEST:
return task((IsVNodeRemovedRequest*)request); return task((GetVNodeRemovedRequest*)request);
case IS_VNODE_REMOVED_REPLY: case GET_VNODE_REMOVED_REPLY:
return task((IsVNodeRemovedReply*)request); return task((GetVNodeRemovedReply*)request);
// general reply // general reply
case RECEIPT_ACK_REPLY: case RECEIPT_ACK_REPLY:
return task((ReceiptAckReply*)request); return task((ReceiptAckReply*)request);
@@ -1992,8 +1991,8 @@ using UserlandFSUtil::NotifyListenerRequest;
using UserlandFSUtil::NotifyListenerReply; using UserlandFSUtil::NotifyListenerReply;
using UserlandFSUtil::NotifySelectEventRequest; using UserlandFSUtil::NotifySelectEventRequest;
using UserlandFSUtil::NotifySelectEventReply; using UserlandFSUtil::NotifySelectEventReply;
using UserlandFSUtil::SendNotificationRequest; using UserlandFSUtil::NotifyQueryRequest;
using UserlandFSUtil::SendNotificationReply; using UserlandFSUtil::NotifyQueryReply;
// vnodes // vnodes
using UserlandFSUtil::GetVNodeRequest; using UserlandFSUtil::GetVNodeRequest;
using UserlandFSUtil::GetVNodeReply; using UserlandFSUtil::GetVNodeReply;
@@ -2007,8 +2006,8 @@ using UserlandFSUtil::RemoveVNodeRequest;
using UserlandFSUtil::RemoveVNodeReply; using UserlandFSUtil::RemoveVNodeReply;
using UserlandFSUtil::UnremoveVNodeRequest; using UserlandFSUtil::UnremoveVNodeRequest;
using UserlandFSUtil::UnremoveVNodeReply; using UserlandFSUtil::UnremoveVNodeReply;
using UserlandFSUtil::IsVNodeRemovedRequest; using UserlandFSUtil::GetVNodeRemovedRequest;
using UserlandFSUtil::IsVNodeRemovedReply; using UserlandFSUtil::GetVNodeRemovedReply;
// general reply // general reply
using UserlandFSUtil::ReceiptAckReply; using UserlandFSUtil::ReceiptAckReply;
@@ -62,8 +62,8 @@ KernelRequestHandler::HandleRequest(Request* request)
return _HandleRequest((NotifyListenerRequest*)request); return _HandleRequest((NotifyListenerRequest*)request);
case NOTIFY_SELECT_EVENT_REQUEST: case NOTIFY_SELECT_EVENT_REQUEST:
return _HandleRequest((NotifySelectEventRequest*)request); return _HandleRequest((NotifySelectEventRequest*)request);
case SEND_NOTIFICATION_REQUEST: case NOTIFY_QUERY_REQUEST:
return _HandleRequest((SendNotificationRequest*)request); return _HandleRequest((NotifyQueryRequest*)request);
// vnodes // vnodes
case GET_VNODE_REQUEST: case GET_VNODE_REQUEST:
return _HandleRequest((GetVNodeRequest*)request); return _HandleRequest((GetVNodeRequest*)request);
@@ -77,8 +77,8 @@ KernelRequestHandler::HandleRequest(Request* request)
return _HandleRequest((RemoveVNodeRequest*)request); return _HandleRequest((RemoveVNodeRequest*)request);
case UNREMOVE_VNODE_REQUEST: case UNREMOVE_VNODE_REQUEST:
return _HandleRequest((UnremoveVNodeRequest*)request); return _HandleRequest((UnremoveVNodeRequest*)request);
case IS_VNODE_REMOVED_REQUEST: case GET_VNODE_REMOVED_REQUEST:
return _HandleRequest((IsVNodeRemovedRequest*)request); return _HandleRequest((GetVNodeRemovedRequest*)request);
} }
PRINT(("KernelRequestHandler::HandleRequest(): unexpected request: %lu\n", PRINT(("KernelRequestHandler::HandleRequest(): unexpected request: %lu\n",
request->GetType())); request->GetType()));
@@ -94,44 +94,109 @@ KernelRequestHandler::_HandleRequest(NotifyListenerRequest* request)
{ {
// check and executed the request // check and executed the request
status_t result = B_OK; status_t result = B_OK;
if (fVolume && request->nsid != fVolume->GetID()) if (fVolume && request->device != fVolume->GetID())
result = B_BAD_VALUE; result = B_BAD_VALUE;
// check the name
// get the names
// name
char* name = (char*)request->name.GetData(); char* name = (char*)request->name.GetData();
int32 nameLen = request->name.GetSize(); int32 nameLen = request->name.GetSize();
if (name && (nameLen <= 0 || strnlen(name, nameLen) < 1)) if (name && (nameLen <= 0))
name = NULL; name = NULL;
else if (name) else if (name)
name[nameLen - 1] = '\0'; name[nameLen - 1] = '\0'; // NULL-terminate to be safe
if (!name) {
// 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) { switch (request->operation) {
case B_ENTRY_CREATED:
case B_ENTRY_MOVED: case B_ENTRY_MOVED:
case B_ATTR_CHANGED: if (!oldName) {
ERROR(("notify_listener(): NULL name for opcode: %ld\n", ERROR(("NotifyListenerRequest: NULL oldName for "
request->operation)); "B_ENTRY_MOVED\n"));
result = B_BAD_VALUE; result = B_BAD_VALUE;
break; break;
}
// fall through...
case B_ENTRY_CREATED:
case B_ENTRY_REMOVED: 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: case B_STAT_CHANGED:
break; break;
} }
} }
// execute the request // execute the request
if (result == B_OK) { if (result == B_OK) {
PRINT(("notify_listener(%ld, %ld, %Ld, %Ld, %Ld, `%s')\n", switch (request->operation) {
request->operation, request->nsid, request->vnida, request->vnidb, case B_ENTRY_CREATED:
request->vnidc, name)); PRINT(("notify_entry_created(%ld, %lld, \"%s\", %lld)\n",
result = notify_listener(request->operation, request->nsid, request->device, request->directory, name, request->node));
request->vnida, request->vnidb, request->vnidc, name); 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 // prepare the reply
RequestAllocator allocator(fPort->GetPort()); RequestAllocator allocator(fPort->GetPort());
NotifyListenerReply* reply; NotifyListenerReply* reply;
status_t error = AllocateRequest(allocator, &reply); status_t error = AllocateRequest(allocator, &reply);
if (error != B_OK) if (error != B_OK)
return error; return error;
reply->error = result; reply->error = result;
// send the reply // send the reply
return fPort->SendRequest(&allocator); return fPort->SendRequest(&allocator);
} }
@@ -143,67 +208,90 @@ KernelRequestHandler::_HandleRequest(NotifySelectEventRequest* request)
// check and executed the request // check and executed the request
status_t result = B_OK; status_t result = B_OK;
if (fFileSystem->KnowsSelectSyncEntry(request->sync)) { if (fFileSystem->KnowsSelectSyncEntry(request->sync)) {
PRINT(("notify_select_event(%p, %lu)\n", request->sync, request->ref)); if (request->unspecifiedEvent) {
notify_select_event(request->sync, request->ref, request->event); // 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 } else
result = B_BAD_VALUE; result = B_BAD_VALUE;
// prepare the reply // prepare the reply
RequestAllocator allocator(fPort->GetPort()); RequestAllocator allocator(fPort->GetPort());
NotifySelectEventReply* reply; NotifySelectEventReply* reply;
status_t error = AllocateRequest(allocator, &reply); status_t error = AllocateRequest(allocator, &reply);
if (error != B_OK) if (error != B_OK)
return error; return error;
reply->error = result; reply->error = result;
// send the reply // send the reply
return fPort->SendRequest(&allocator); return fPort->SendRequest(&allocator);
} }
// _HandleRequest // _HandleRequest
status_t status_t
KernelRequestHandler::_HandleRequest(SendNotificationRequest* request) KernelRequestHandler::_HandleRequest(NotifyQueryRequest* request)
{ {
// check and executed the request // check and executed the request
status_t result = B_OK; status_t result = B_OK;
if (fVolume && request->nsida != fVolume->GetID() if (fVolume && request->device != fVolume->GetID())
&& request->nsidb != fVolume->GetID()) {
result = B_BAD_VALUE; result = B_BAD_VALUE;
}
// check the name // check the name
char* name = (char*)request->name.GetData(); char* name = (char*)request->name.GetData();
int32 nameLen = request->name.GetSize(); int32 nameLen = request->name.GetSize();
if (name && (nameLen <= 0 || strnlen(name, nameLen) < 1)) if (!name || nameLen <= 0) {
name = NULL; ERROR(("NotifyQueryRequest: NULL name!\n"));
else if (name) result = B_BAD_VALUE;
name[nameLen - 1] = '\0'; } else
if (!name) { name[nameLen - 1] = '\0'; // NULL-terminate to be safe
// execute the request
if (result == B_OK) {
switch (request->operation) { switch (request->operation) {
case B_ENTRY_CREATED: 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: case B_ENTRY_MOVED:
ERROR(("send_notification(): NULL name for opcode: %ld\n", default:
ERROR(("NotifyQueryRequest: unsupported operation: %ld\n",
request->operation)); request->operation));
result = B_BAD_VALUE; result = B_BAD_VALUE;
break; 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 // prepare the reply
RequestAllocator allocator(fPort->GetPort()); RequestAllocator allocator(fPort->GetPort());
SendNotificationReply* reply; NotifyQueryReply* reply;
status_t error = AllocateRequest(allocator, &reply); status_t error = AllocateRequest(allocator, &reply);
if (error != B_OK) if (error != B_OK)
return error; return error;
reply->error = result; reply->error = result;
// send the reply // send the reply
return fPort->SendRequest(&allocator); return fPort->SendRequest(&allocator);
} }
@@ -344,22 +432,26 @@ KernelRequestHandler::_HandleRequest(UnremoveVNodeRequest* request)
// _HandleRequest // _HandleRequest
status_t status_t
KernelRequestHandler::_HandleRequest(IsVNodeRemovedRequest* request) KernelRequestHandler::_HandleRequest(GetVNodeRemovedRequest* request)
{ {
// check and executed the request // check and executed the request
Volume* volume = NULL; Volume* volume = NULL;
status_t result = _GetVolume(request->nsid, &volume); status_t result = _GetVolume(request->nsid, &volume);
VolumePutter _(volume); VolumePutter _(volume);
bool removed = false;
if (result == B_OK) if (result == B_OK)
result = volume->IsVNodeRemoved(request->vnid); result = volume->GetVNodeRemoved(request->vnid, &removed);
// prepare the reply // prepare the reply
RequestAllocator allocator(fPort->GetPort()); RequestAllocator allocator(fPort->GetPort());
IsVNodeRemovedReply* reply; GetVNodeRemovedReply* reply;
status_t error = AllocateRequest(allocator, &reply); status_t error = AllocateRequest(allocator, &reply);
if (error != B_OK) if (error != B_OK)
return error; return error;
reply->error = (result < 0 ? result : B_OK);
reply->result = result; reply->error = result;
reply->removed = removed;
// send the reply // send the reply
return fPort->SendRequest(&allocator); return fPort->SendRequest(&allocator);
} }
@@ -9,28 +9,28 @@
namespace UserlandFSUtil { namespace UserlandFSUtil {
class GetVNodeRemovedRequest;
class GetVNodeRequest; class GetVNodeRequest;
class IsVNodeRemovedRequest;
class NewVNodeRequest; class NewVNodeRequest;
class NotifyListenerRequest; class NotifyListenerRequest;
class NotifyQueryRequest;
class NotifySelectEventRequest; class NotifySelectEventRequest;
class PublishVNodeRequest; class PublishVNodeRequest;
class PutVNodeRequest; class PutVNodeRequest;
class RemoveVNodeRequest; class RemoveVNodeRequest;
class SendNotificationRequest;
class UnremoveVNodeRequest; class UnremoveVNodeRequest;
} }
using UserlandFSUtil::GetVNodeRemovedRequest;
using UserlandFSUtil::GetVNodeRequest; using UserlandFSUtil::GetVNodeRequest;
using UserlandFSUtil::IsVNodeRemovedRequest;
using UserlandFSUtil::NewVNodeRequest; using UserlandFSUtil::NewVNodeRequest;
using UserlandFSUtil::NotifyListenerRequest; using UserlandFSUtil::NotifyListenerRequest;
using UserlandFSUtil::NotifyQueryRequest;
using UserlandFSUtil::NotifySelectEventRequest; using UserlandFSUtil::NotifySelectEventRequest;
using UserlandFSUtil::PublishVNodeRequest; using UserlandFSUtil::PublishVNodeRequest;
using UserlandFSUtil::PutVNodeRequest; using UserlandFSUtil::PutVNodeRequest;
using UserlandFSUtil::RemoveVNodeRequest; using UserlandFSUtil::RemoveVNodeRequest;
using UserlandFSUtil::SendNotificationRequest;
using UserlandFSUtil::UnremoveVNodeRequest; using UserlandFSUtil::UnremoveVNodeRequest;
class Volume; class Volume;
@@ -50,8 +50,7 @@ private:
status_t _HandleRequest(NotifyListenerRequest* request); status_t _HandleRequest(NotifyListenerRequest* request);
status_t _HandleRequest( status_t _HandleRequest(
NotifySelectEventRequest* request); NotifySelectEventRequest* request);
status_t _HandleRequest( status_t _HandleRequest(NotifyQueryRequest* request);
SendNotificationRequest* request);
// vnodes // vnodes
status_t _HandleRequest(GetVNodeRequest* request); status_t _HandleRequest(GetVNodeRequest* request);
status_t _HandleRequest(PutVNodeRequest* request); status_t _HandleRequest(PutVNodeRequest* request);
@@ -59,7 +58,7 @@ private:
status_t _HandleRequest(PublishVNodeRequest* request); status_t _HandleRequest(PublishVNodeRequest* request);
status_t _HandleRequest(RemoveVNodeRequest* request); status_t _HandleRequest(RemoveVNodeRequest* request);
status_t _HandleRequest(UnremoveVNodeRequest* request); status_t _HandleRequest(UnremoveVNodeRequest* request);
status_t _HandleRequest(IsVNodeRemovedRequest* request); status_t _HandleRequest(GetVNodeRemovedRequest* request);
status_t _GetVolume(mount_id id, Volume** volume); status_t _GetVolume(mount_id id, Volume** volume);
@@ -129,7 +129,7 @@ Volume::IsMounting() const
status_t status_t
Volume::GetVNode(vnode_id vnid, fs_vnode* node) 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)) { if (IsMounting() && !fMountVNodes->ContainsKey(vnid)) {
ERROR(("Volume::GetVNode(): get_vnode() invoked for unknown vnode " ERROR(("Volume::GetVNode(): get_vnode() invoked for unknown vnode "
"while mounting!\n")); "while mounting!\n"));
@@ -144,7 +144,7 @@ PRINT(("get_vnode(%ld, %Ld)\n", fID, vnid));
status_t status_t
Volume::PutVNode(vnode_id vnid) 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); status_t error = put_vnode(fID, vnid);
if (error == B_OK) if (error == B_OK)
_DecrementVNodeCount(vnid); _DecrementVNodeCount(vnid);
@@ -155,7 +155,7 @@ PRINT(("put_vnode(%ld, %Ld)\n", fID, vnid));
status_t status_t
Volume::NewVNode(vnode_id vnid, fs_vnode node) 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); status_t error = new_vnode(fID, vnid, node);
if (error == B_OK) { if (error == B_OK) {
if (IsMounting()) { if (IsMounting()) {
@@ -168,7 +168,7 @@ PRINT(("new_vnode(%ld, %Ld)\n", fID, vnid));
return error; 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); // _IncrementVNodeCount(vnid);
} }
return error; return error;
@@ -178,7 +178,7 @@ PRINT(("new_vnode(%ld, %Ld)\n", fID, vnid));
status_t status_t
Volume::PublishVNode(vnode_id vnid, fs_vnode node) 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); status_t error = publish_vnode(fID, vnid, node);
if (error == B_OK) { if (error == B_OK) {
if (IsMounting()) { if (IsMounting()) {
@@ -199,7 +199,7 @@ PRINT(("publish_vnode(%ld, %Ld)\n", fID, vnid));
status_t status_t
Volume::RemoveVNode(vnode_id vnid) 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); return remove_vnode(fID, vnid);
} }
@@ -207,16 +207,16 @@ PRINT(("remove_vnode(%ld, %Ld)\n", fID, vnid));
status_t status_t
Volume::UnremoveVNode(vnode_id vnid) 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); return unremove_vnode(fID, vnid);
} }
// IsVNodeRemoved // GetVNodeRemoved
status_t status_t
Volume::IsVNodeRemoved(vnode_id vnid) Volume::GetVNodeRemoved(vnode_id vnid, bool* removed)
{ {
PRINT(("is_vnode_removed(%ld, %Ld)\n", fID, vnid)); PRINT(("get_vnode_removed(%ld, %lld, %p)\n", fID, vnid, removed));
return is_vnode_removed(fID, vnid); return get_vnode_removed(fID, vnid, removed);
} }
@@ -41,7 +41,7 @@ public:
status_t PublishVNode(vnode_id vnid, fs_vnode node); status_t PublishVNode(vnode_id vnid, fs_vnode node);
status_t RemoveVNode(vnode_id vnid); status_t RemoveVNode(vnode_id vnid);
status_t UnremoveVNode(vnode_id vnid); status_t UnremoveVNode(vnode_id vnid);
status_t IsVNodeRemoved(vnode_id vnid); status_t GetVNodeRemoved(vnode_id vnid, bool* removed);
// FS // FS
status_t Mount(const char* device, uint32 flags, status_t Mount(const char* device, uint32 flags,
@@ -276,13 +276,14 @@ ReadQueryReply::GetAddressInfos(AddressInfo* infos, int32* count)
status_t status_t
NotifyListenerRequest::GetAddressInfos(AddressInfo* infos, int32* count) NotifyListenerRequest::GetAddressInfos(AddressInfo* infos, int32* count)
{ {
ADD_STRING(oldName);
ADD_STRING(name); ADD_STRING(name);
return B_OK; return B_OK;
} }
// SendNotificationRequest // NotifyQueryRequest
status_t status_t
SendNotificationRequest::GetAddressInfos(AddressInfo* infos, int32* count) NotifyQueryRequest::GetAddressInfos(AddressInfo* infos, int32* count)
{ {
ADD_STRING(name); ADD_STRING(name);
return B_OK; return B_OK;
@@ -635,11 +636,11 @@ UserlandFSUtil::is_kernel_request(uint32 type)
// notifications // notifications
case NOTIFY_LISTENER_REQUEST: case NOTIFY_LISTENER_REQUEST:
case NOTIFY_SELECT_EVENT_REQUEST: case NOTIFY_SELECT_EVENT_REQUEST:
case SEND_NOTIFICATION_REQUEST: case NOTIFY_QUERY_REQUEST:
return false; return false;
case NOTIFY_LISTENER_REPLY: case NOTIFY_LISTENER_REPLY:
case NOTIFY_SELECT_EVENT_REPLY: case NOTIFY_SELECT_EVENT_REPLY:
case SEND_NOTIFICATION_REPLY: case NOTIFY_QUERY_REPLY:
return true; return true;
// vnodes // vnodes
case GET_VNODE_REQUEST: case GET_VNODE_REQUEST:
@@ -648,7 +649,7 @@ UserlandFSUtil::is_kernel_request(uint32 type)
case PUBLISH_VNODE_REQUEST: case PUBLISH_VNODE_REQUEST:
case REMOVE_VNODE_REQUEST: case REMOVE_VNODE_REQUEST:
case UNREMOVE_VNODE_REQUEST: case UNREMOVE_VNODE_REQUEST:
case IS_VNODE_REMOVED_REQUEST: case GET_VNODE_REMOVED_REQUEST:
return false; return false;
case GET_VNODE_REPLY: case GET_VNODE_REPLY:
case PUT_VNODE_REPLY: case PUT_VNODE_REPLY:
@@ -656,7 +657,7 @@ UserlandFSUtil::is_kernel_request(uint32 type)
case PUBLISH_VNODE_REPLY: case PUBLISH_VNODE_REPLY:
case REMOVE_VNODE_REPLY: case REMOVE_VNODE_REPLY:
case UNREMOVE_VNODE_REPLY: case UNREMOVE_VNODE_REPLY:
case IS_VNODE_REMOVED_REPLY: case GET_VNODE_REMOVED_REPLY:
return true; return true;
// general reply // general reply
@@ -835,11 +836,11 @@ UserlandFSUtil::is_userland_request(uint32 type)
// notifications // notifications
case NOTIFY_LISTENER_REQUEST: case NOTIFY_LISTENER_REQUEST:
case NOTIFY_SELECT_EVENT_REQUEST: case NOTIFY_SELECT_EVENT_REQUEST:
case SEND_NOTIFICATION_REQUEST: case NOTIFY_QUERY_REQUEST:
return true; return true;
case NOTIFY_LISTENER_REPLY: case NOTIFY_LISTENER_REPLY:
case NOTIFY_SELECT_EVENT_REPLY: case NOTIFY_SELECT_EVENT_REPLY:
case SEND_NOTIFICATION_REPLY: case NOTIFY_QUERY_REPLY:
return false; return false;
// vnodes // vnodes
case GET_VNODE_REQUEST: case GET_VNODE_REQUEST:
@@ -848,7 +849,7 @@ UserlandFSUtil::is_userland_request(uint32 type)
case PUBLISH_VNODE_REQUEST: case PUBLISH_VNODE_REQUEST:
case REMOVE_VNODE_REQUEST: case REMOVE_VNODE_REQUEST:
case UNREMOVE_VNODE_REQUEST: case UNREMOVE_VNODE_REQUEST:
case IS_VNODE_REMOVED_REQUEST: case GET_VNODE_REMOVED_REQUEST:
return true; return true;
case GET_VNODE_REPLY: case GET_VNODE_REPLY:
case PUT_VNODE_REPLY: case PUT_VNODE_REPLY:
@@ -856,7 +857,7 @@ UserlandFSUtil::is_userland_request(uint32 type)
case PUBLISH_VNODE_REPLY: case PUBLISH_VNODE_REPLY:
case REMOVE_VNODE_REPLY: case REMOVE_VNODE_REPLY:
case UNREMOVE_VNODE_REPLY: case UNREMOVE_VNODE_REPLY:
case IS_VNODE_REMOVED_REPLY: case GET_VNODE_REMOVED_REPLY:
return false; return false;
// general reply // general reply
@@ -213,7 +213,7 @@ BeOSKernelVolume::Select(fs_vnode node, fs_cookie cookie, uint8 event,
uint32 ref, selectsync* sync) uint32 ref, selectsync* sync)
{ {
if (!fFSOps->select) { if (!fFSOps->select) {
UserlandFS::KernelEmu::notify_select_event(sync, ref, event); UserlandFS::KernelEmu::notify_select_event(sync, ref, event, false);
return B_OK; return B_OK;
} }
return fFSOps->select(fVolumeCookie, node, cookie, event, ref, sync); return fFSOps->select(fVolumeCookie, node, cookie, event, ref, sync);
@@ -4,12 +4,15 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <NodeMonitor.h>
#include <legacy/cache.h> #include <legacy/cache.h>
#include <legacy/fsproto.h> #include <legacy/fsproto.h>
#include <legacy/lock.h> #include <legacy/lock.h>
#include "beos_fs_cache.h" #include "beos_fs_cache.h"
#include "beos_lock.h" #include "beos_lock.h"
#include "Debug.h"
#include "kernel_emu.h" #include "kernel_emu.h"
@@ -39,26 +42,83 @@ int
notify_listener(int op, nspace_id nsid, vnode_id vnida, vnode_id vnidb, notify_listener(int op, nspace_id nsid, vnode_id vnida, vnode_id vnidb,
vnode_id vnidc, const char *name) vnode_id vnidc, const char *name)
{ {
return UserlandFS::KernelEmu::notify_listener(op, nsid, vnida, vnidb, vnidc, switch (op) {
name); 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 // notify_select_event
void void
notify_select_event(selectsync *sync, uint32 ref) notify_select_event(selectsync *sync, uint32 ref)
{ {
// TODO: Check what best to supply as event arg! UserlandFS::KernelEmu::notify_select_event(sync, ref, 0, true);
UserlandFS::KernelEmu::notify_select_event(sync, ref, 0);
} }
// send_notification // send_notification
int int
send_notification(port_id port, long token, ulong what, long op, 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) vnode_id vnidc, const char *name)
{ {
return UserlandFS::KernelEmu::send_notification(port, token, what, op, if (what != B_QUERY_UPDATE)
nsida, nsidb, vnida, vnidb, vnidc, name); 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 int
is_vnode_removed(nspace_id nsid, vnode_id vnid) 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 // notify_listener
status_t status_t
UserlandFS::KernelEmu::notify_listener(int op, mount_id nsid, vnode_id vnida, UserlandFS::KernelEmu::notify_listener(int32 operation, uint32 details,
vnode_id vnidb, vnode_id vnidc, const char *name) 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 // get the request port and the file system
RequestPort* port; RequestPort* port;
@@ -140,11 +141,15 @@ UserlandFS::KernelEmu::notify_listener(int op, mount_id nsid, vnode_id vnida,
if (error != B_OK) if (error != B_OK)
return error; return error;
request->operation = op; request->operation = operation;
request->nsid = nsid; request->details = details;
request->vnida = vnida; request->device = device;
request->vnidb = vnidb; request->oldDirectory = oldDirectory;
request->vnidc = vnidc; request->directory = directory;
request->node = node;
error = allocator.AllocateString(request->oldName, oldName);
if (error != B_OK)
return error;
error = allocator.AllocateString(request->name, name); error = allocator.AllocateString(request->name, name);
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -166,7 +171,7 @@ UserlandFS::KernelEmu::notify_listener(int op, mount_id nsid, vnode_id vnida,
// notify_select_event // notify_select_event
void void
UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint32 ref, UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint32 ref,
uint8 event) uint8 event, bool unspecifiedEvent)
{ {
// get the request port and the file system // get the request port and the file system
RequestPort* port; RequestPort* port;
@@ -185,6 +190,7 @@ UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint32 ref,
request->sync = sync; request->sync = sync;
request->ref = ref; request->ref = ref;
request->event = event; request->event = event;
request->unspecifiedEvent = unspecifiedEvent;
// send the request // send the request
UserlandRequestHandler handler(fileSystem, NOTIFY_SELECT_EVENT_REPLY); UserlandRequestHandler handler(fileSystem, NOTIFY_SELECT_EVENT_REPLY);
@@ -199,9 +205,9 @@ UserlandFS::KernelEmu::notify_select_event(selectsync *sync, uint32 ref,
// send_notification // send_notification
status_t status_t
UserlandFS::KernelEmu::send_notification(port_id targetPort, long token, UserlandFS::KernelEmu::notify_query(port_id targetPort, int32 token,
ulong what, long op, mount_id nsida, mount_id nsidb, vnode_id vnida, int32 operation, mount_id device, vnode_id directory, const char* name,
vnode_id vnidb, vnode_id vnidc, const char *name) vnode_id node)
{ {
// get the request port and the file system // get the request port and the file system
RequestPort* port; RequestPort* port;
@@ -212,27 +218,24 @@ UserlandFS::KernelEmu::send_notification(port_id targetPort, long token,
// prepare the request // prepare the request
RequestAllocator allocator(port->GetPort()); RequestAllocator allocator(port->GetPort());
SendNotificationRequest* request; NotifyQueryRequest* request;
error = AllocateRequest(allocator, &request); error = AllocateRequest(allocator, &request);
if (error != B_OK) if (error != B_OK)
return error; return error;
request->port = targetPort; request->port = targetPort;
request->token = token; request->token = token;
request->what = what; request->operation = operation;
request->operation = op; request->device = device;
request->nsida = nsida; request->directory = directory;
request->nsidb = nsidb; request->node = node;
request->vnida = vnida;
request->vnidb = vnidb;
request->vnidc = vnidc;
error = allocator.AllocateString(request->name, name); error = allocator.AllocateString(request->name, name);
if (error != B_OK) if (error != B_OK)
return error; return error;
// send the request // send the request
UserlandRequestHandler handler(fileSystem, SEND_NOTIFICATION_REPLY); UserlandRequestHandler handler(fileSystem, NOTIFY_QUERY_REPLY);
SendNotificationReply* reply; NotifyQueryReply* reply;
error = port->SendRequest(&allocator, &handler, (Request**)&reply); error = port->SendRequest(&allocator, &handler, (Request**)&reply);
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -462,9 +465,10 @@ UserlandFS::KernelEmu::unremove_vnode(mount_id nsid, vnode_id vnid)
return error; return error;
} }
// is_vnode_removed // get_vnode_removed
status_t 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 // get the request port and the file system
RequestPort* port; RequestPort* port;
@@ -475,7 +479,7 @@ UserlandFS::KernelEmu::is_vnode_removed(mount_id nsid, vnode_id vnid)
// prepare the request // prepare the request
RequestAllocator allocator(port->GetPort()); RequestAllocator allocator(port->GetPort());
IsVNodeRemovedRequest* request; GetVNodeRemovedRequest* request;
error = AllocateRequest(allocator, &request); error = AllocateRequest(allocator, &request);
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -484,17 +488,16 @@ UserlandFS::KernelEmu::is_vnode_removed(mount_id nsid, vnode_id vnid)
request->vnid = vnid; request->vnid = vnid;
// send the request // send the request
UserlandRequestHandler handler(fileSystem, IS_VNODE_REMOVED_REPLY); UserlandRequestHandler handler(fileSystem, GET_VNODE_REMOVED_REPLY);
IsVNodeRemovedReply* reply; GetVNodeRemovedReply* reply;
error = port->SendRequest(&allocator, &handler, (Request**)&reply); error = port->SendRequest(&allocator, &handler, (Request**)&reply);
if (error != B_OK) if (error != B_OK)
return error; return error;
RequestReleaser requestReleaser(port, reply); RequestReleaser requestReleaser(port, reply);
// process the reply // process the reply
if (reply->error != B_OK) *removed = reply->removed;
return reply->error; return reply->error;
return reply->result;
} }
// #pragma mark - // #pragma mark -
@@ -14,12 +14,13 @@ typedef void* fs_vnode;
int new_path(const char *path, char **copy); int new_path(const char *path, char **copy);
void free_path(char *p); void free_path(char *p);
status_t notify_listener(int op, mount_id nsid, vnode_id vnida, vnode_id vnidb, status_t notify_listener(int32 operation, uint32 details, mount_id device,
vnode_id vnidc, const char *name); vnode_id oldDirectory, vnode_id directory, vnode_id node,
void notify_select_event(selectsync *sync, uint32 ref, uint8 event); const char* oldName, const char* name);
status_t send_notification(port_id targetPort, long token, ulong what, long op, void notify_select_event(selectsync *sync, uint32 ref, uint8 event,
mount_id nsida, mount_id nsidb, vnode_id vnida, vnode_id vnidb, bool unspecifiedEvent);
vnode_id vnidc, const char *name); 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 get_vnode(mount_id nsid, vnode_id vnid, fs_vnode* data);
status_t put_vnode(mount_id nsid, vnode_id vnid); 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 publish_vnode(mount_id nsid, vnode_id vnid, fs_vnode data);
status_t remove_vnode(mount_id nsid, vnode_id vnid); status_t remove_vnode(mount_id nsid, vnode_id vnid);
status_t unremove_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 kernel_debugger(const char *message);
void panic(const char *format, ...); void panic(const char *format, ...);