diff --git a/headers/private/userlandfs/private/Requests.h b/headers/private/userlandfs/private/Requests.h index 316a5f8912..d5f4178c90 100644 --- a/headers/private/userlandfs/private/Requests.h +++ b/headers/private/userlandfs/private/Requests.h @@ -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; diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp index 2059c47b88..3fa3139645 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.cpp @@ -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); } diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h index 9d32f894ca..a96fc1ed97 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/KernelRequestHandler.h @@ -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); diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp index 5f141683c6..eda414990a 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.cpp @@ -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); } diff --git a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h index 15ddf6c62c..bc86cf6d3e 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h +++ b/src/add-ons/kernel/file_systems/userlandfs/kernel_add_on/Volume.h @@ -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, diff --git a/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp b/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp index 1e52bb875b..31afd22299 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/private/Requests.cpp @@ -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 diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/BeOSKernelVolume.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/BeOSKernelVolume.cpp index bdb9e8d32e..3d77a1ac69 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/BeOSKernelVolume.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/BeOSKernelVolume.cpp @@ -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); diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/beos_kernel_emu.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/beos_kernel_emu.cpp index 97a9da7023..e100312402 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/beos_kernel_emu.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/beos_kernel_emu.cpp @@ -4,12 +4,15 @@ #include #include +#include + #include #include #include #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); } diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp index f4f43d5539..e88426182e 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.cpp @@ -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 - diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.h b/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.h index dd5688f033..172ed9e2fe 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.h +++ b/src/add-ons/kernel/file_systems/userlandfs/server/kernel_emu.h @@ -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, ...);