From 3d2f3f00f15979f35296d8e4c5ef955ab05e25a8 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sat, 8 Feb 2003 00:48:15 +0000 Subject: [PATCH] The basic functionality is complete now (though untested). The user API requests (save the one concerning watching) are handled. Notification stuff is still missing and proper handling of changes to devices, too. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2661 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/registrar/DiskDeviceManager.cpp | 130 ++++++++++++++++++-- src/servers/registrar/DiskDeviceManager.h | 5 + src/servers/registrar/RDiskDevice.cpp | 48 ++++++++ src/servers/registrar/RDiskDevice.h | 7 ++ src/servers/registrar/RDiskDeviceList.cpp | 52 ++++++-- src/servers/registrar/RDiskDeviceList.h | 39 ++++-- src/servers/registrar/RPartition.cpp | 68 +++++++++- src/servers/registrar/RPartition.h | 12 ++ src/servers/registrar/RSession.cpp | 43 +++++++ src/servers/registrar/RSession.h | 6 + src/servers/registrar/RVolumeList.cpp | 45 +++++++ src/servers/registrar/RVolumeList.h | 5 + 12 files changed, 431 insertions(+), 29 deletions(-) diff --git a/src/servers/registrar/DiskDeviceManager.cpp b/src/servers/registrar/DiskDeviceManager.cpp index c4c4e7db3e..648822389a 100644 --- a/src/servers/registrar/DiskDeviceManager.cpp +++ b/src/servers/registrar/DiskDeviceManager.cpp @@ -7,6 +7,11 @@ #include #include "DiskDeviceManager.h" +#include "RDiskDevice.h" +#include "RDiskDeviceList.h" +#include "RPartition.h" +#include "RSession.h" +#include "Debug.h" enum { REQUEST_PRIORITY = 0, @@ -73,6 +78,114 @@ DiskDeviceManager::MessageReceived(BMessage *message) } } +// _NextDiskDeviceRequest +void +DiskDeviceManager::_NextDiskDeviceRequest(BMessage *message) +{ + status_t error = B_OK; + int32 cookie = 0; + BMessage reply(B_REG_RESULT); + if (message->FindInt32("cookie", &cookie) == B_OK) { + // get next device + if (RDiskDevice *device = fDeviceList.DeviceWithID(cookie, false)) { + // archive device + BMessage deviceArchive; + error = device->Archive(&deviceArchive); + // add archived device and next cookie to reply message + if (error == B_OK) + error = reply.AddMessage("device", &deviceArchive); + if (error == B_OK) + error = reply.AddInt32("cookie", device->ID() + 1); + } else + error = B_ENTRY_NOT_FOUND; + } else + SET_ERROR(error, B_BAD_VALUE); + // add result and send reply + reply.AddInt32("result", error); + message->SendReply(&reply); +} + +// _GetDiskDeviceRequest +void +DiskDeviceManager::_GetDiskDeviceRequest(BMessage *message) +{ + status_t error = B_ENTRY_NOT_FOUND; + // get the device + RDiskDevice *device = NULL; + int32 id = 0; + if (message->FindInt32("device_id", &id) == B_OK) + device = fDeviceList.DeviceWithID(id); + else if (message->FindInt32("session_id", &id) == B_OK) { + if (RSession *session = fDeviceList.SessionWithID(id)) + device = session->Device(); + } else if (message->FindInt32("partition_id", &id) == B_OK) { + if (RPartition *partition = fDeviceList.PartitionWithID(id)) + device = partition->Device(); + } else + error = B_BAD_VALUE; + // archive device and add it to the reply message + BMessage reply(B_REG_RESULT); + if (device) { + BMessage deviceArchive; + error = device->Archive(&deviceArchive); + if (error == B_OK) + error = reply.AddMessage("device", &deviceArchive); + } + // add result and send reply + reply.AddInt32("result", error); + message->SendReply(&reply); +} + +// _UpdateDiskDeviceRequest +void +DiskDeviceManager::_UpdateDiskDeviceRequest(BMessage *message) +{ + status_t error = B_ENTRY_NOT_FOUND; + // get the device and check the object is up to date + bool upToDate = false; + RDiskDevice *device = NULL; + int32 id = 0; + int32 changeCounter = 0; + uint32 policy = 0; + if (message->FindInt32("change_counter", &changeCounter) != B_OK + || message->FindInt32("update_policy", (int32*)&policy) != B_OK) { + // bad request message + SET_ERROR(error, B_BAD_VALUE); + } else if (message->FindInt32("device_id", &id) == B_OK) { + device = fDeviceList.DeviceWithID(id); + if (device) + upToDate = (device->ChangeCounter() == changeCounter); + } else if (message->FindInt32("session_id", &id) == B_OK) { + if (RSession *session = fDeviceList.SessionWithID(id)) { + device = session->Device(); + upToDate = (session->ChangeCounter() == changeCounter); + } + } else if (message->FindInt32("partition_id", &id) == B_OK) { + if (RPartition *partition = fDeviceList.PartitionWithID(id)) { + device = partition->Device(); + upToDate = (partition->ChangeCounter() == changeCounter); + } + } else // bad request message + SET_ERROR(error, B_BAD_VALUE); + // archive device and add it to the reply message + BMessage reply(B_REG_RESULT); + if (device) { + if (policy == B_REG_DEVICE_UPDATE_DEVICE_CHANGED) + upToDate = (device->ChangeCounter() == changeCounter); + if (!upToDate && policy != B_REG_DEVICE_UPDATE_CHECK) { + BMessage deviceArchive; + error = device->Archive(&deviceArchive); + if (error == B_OK) + error = reply.AddMessage("device", &deviceArchive); + } + } + // add result and send reply + if (error == B_OK) + error = reply.AddBool("up_to_date", upToDate); + reply.AddInt32("result", error); + message->SendReply(&reply); +} + // _PushMessage bool DiskDeviceManager::_PushMessage(BMessage *message, int32 priority) @@ -110,23 +223,20 @@ DiskDeviceManager::_Worker() // dispatch the message switch (message->what) { case B_REG_NEXT_DISK_DEVICE: + _NextDiskDeviceRequest(message); + break; case B_REG_GET_DISK_DEVICE: + _GetDiskDeviceRequest(message); + break; case B_REG_UPDATE_DISK_DEVICE: + _UpdateDiskDeviceRequest(message); + break; case B_REG_DEVICE_START_WATCHING: case B_REG_DEVICE_STOP_WATCHING: - fDeviceList.HandleMessage(message); break; case B_NODE_MONITOR: { - int32 opcode = 0; - if (message->FindInt32("opcode", &opcode) == B_OK) { - if (opcode == B_DEVICE_MOUNTED - || opcode == B_DEVICE_UNMOUNTED) { - fVolumeList.HandleMessage(message); - } else { - fDeviceList.HandleMessage(message); - } - } + fVolumeList.HandleMessage(message); break; } default: diff --git a/src/servers/registrar/DiskDeviceManager.h b/src/servers/registrar/DiskDeviceManager.h index a9af8678cc..6f98d314d7 100644 --- a/src/servers/registrar/DiskDeviceManager.h +++ b/src/servers/registrar/DiskDeviceManager.h @@ -22,6 +22,11 @@ public: virtual void MessageReceived(BMessage *message); private: + // requests + void _NextDiskDeviceRequest(BMessage *message); + void _GetDiskDeviceRequest(BMessage *message); + void _UpdateDiskDeviceRequest(BMessage *message); + bool _PushMessage(BMessage *message, int32 priority); BMessage *_PopMessage(); diff --git a/src/servers/registrar/RDiskDevice.cpp b/src/servers/registrar/RDiskDevice.cpp index e254ae87b6..4473126307 100644 --- a/src/servers/registrar/RDiskDevice.cpp +++ b/src/servers/registrar/RDiskDevice.cpp @@ -110,6 +110,14 @@ RDiskDevice::Unset() } } +// Size +off_t +RDiskDevice::Size() const +{ + return (off_t)fGeometry.bytes_per_sector * fGeometry.sectors_per_track + * fGeometry.cylinder_count * fGeometry.head_count; +} + // AddSession bool RDiskDevice::AddSession(RSession *session) @@ -161,6 +169,46 @@ RDiskDevice::Update() return B_ERROR; } +// Archive +status_t +RDiskDevice::Archive(BMessage *archive) const +{ + status_t error = (archive ? B_OK : B_BAD_VALUE); + // ID and change counter + if (error == B_OK) + error = archive->AddInt32("id", fID); + if (error == B_OK) + error = archive->AddInt32("change_counter", fChangeCounter); + // geometry + if (error == B_OK) + error = archive->AddInt64("size", Size()); + if (error == B_OK) + error = archive->AddInt32("block_size", BlockSize()); + if (error == B_OK) + error = archive->AddInt8("type", (int8)fGeometry.device_type); + if (error == B_OK) + error = archive->AddBool("removable", fGeometry.removable); + if (error == B_OK) + error = archive->AddBool("read_only", fGeometry.read_only); + if (error == B_OK) + error = archive->AddBool("write_once", fGeometry.write_once); + // other data + if (error == B_OK) + error = archive->AddString("path", fPath.String()); + if (error == B_OK) + error = archive->AddInt32("media_status", fMediaStatus); + // sessions + for (int32 i = 0; const RSession *session = SessionAt(i); i++) { + BMessage sessionArchive; + error = session->Archive(&sessionArchive); + if (error == B_OK) + error = archive->AddMessage("sessions", &sessionArchive); + if (error != B_OK) + break; + } + return error; +} + // Dump void RDiskDevice::Dump() const diff --git a/src/servers/registrar/RDiskDevice.h b/src/servers/registrar/RDiskDevice.h index 922bcddbf2..45dfc72f5a 100644 --- a/src/servers/registrar/RDiskDevice.h +++ b/src/servers/registrar/RDiskDevice.h @@ -33,6 +33,9 @@ public: void SetTouched(bool touched) { fTouched = touched; } bool Touched() const { return fTouched; } + off_t Size() const; + int32 BlockSize() const { return fGeometry.bytes_per_sector; } + const char *Path() const { return fPath.String(); } bool AddSession(RSession *session); @@ -40,9 +43,13 @@ public: bool RemoveSession(RSession *session); int32 CountSessions() const { return fSessions.CountItems(); } RSession *SessionAt(int32 index) const { return fSessions.ItemAt(index); } + int32 IndexOfSession(const RSession *session) const + { return fSessions.IndexOf(session); } status_t Update(); + status_t Archive(BMessage *archive) const; + void Dump() const; private: diff --git a/src/servers/registrar/RDiskDeviceList.cpp b/src/servers/registrar/RDiskDeviceList.cpp index 4ab39aa115..9b8cb06083 100644 --- a/src/servers/registrar/RDiskDeviceList.cpp +++ b/src/servers/registrar/RDiskDeviceList.cpp @@ -119,6 +119,13 @@ RDiskDeviceList::VolumeUnmounted(const RVolume *volume) PRINT(("RDiskDeviceList::VolumeUnmounted(%ld)\n", volume->ID())); } +// MountPointMoved +void +RDiskDeviceList::MountPointMoved(const RVolume *volume) +{ + PRINT(("RDiskDeviceList::MountPointMoved(%ld)\n", volume->ID())); +} + // AddDevice bool RDiskDeviceList::AddDevice(RDiskDevice *device) @@ -162,12 +169,12 @@ RDiskDeviceList::RemoveDevice(RDiskDevice *device) // DeviceWithID RDiskDevice * -RDiskDeviceList::DeviceWithID(int32 id) const +RDiskDeviceList::DeviceWithID(int32 id, bool exact) const { bool inList = false; int32 index = fDevices.FindBinaryInsertionIndex( CompareIDPredicate(id), &inList); - return (inList ? DeviceAt(index) : NULL); + return (inList || !exact ? DeviceAt(index) : NULL); } // SessionWithID @@ -242,38 +249,67 @@ RDiskDeviceList::Unlock() // DeviceAdded void -RDiskDeviceList::DeviceAdded(RDiskDevice *device) +RDiskDeviceList::DeviceAdded(RDiskDevice *device, uint32 cause) { + // propagate to sessions + for (int32 i = 0; RSession *session = device->SessionAt(i); i++) + SessionAdded(session, B_DEVICE_CAUSE_PARENT_CHANGED); + // notifications + // ... } // DeviceRemoved void -RDiskDeviceList::DeviceRemoved(RDiskDevice *device) +RDiskDeviceList::DeviceRemoved(RDiskDevice *device, uint32 cause) { + // propagate to sessions + for (int32 i = 0; RSession *session = device->SessionAt(i); i++) + SessionRemoved(session, B_DEVICE_CAUSE_PARENT_CHANGED); + // notifications + // ... } // SessionAdded void -RDiskDeviceList::SessionAdded(RSession *session) +RDiskDeviceList::SessionAdded(RSession *session, uint32 cause) { + // propagate to partitions + for (int32 i = 0; RPartition *partition = session->PartitionAt(i); i++) + PartitionAdded(partition, B_DEVICE_CAUSE_PARENT_CHANGED); + // notifications + // ... } // SessionRemoved void -RDiskDeviceList::SessionRemoved(RSession *session) +RDiskDeviceList::SessionRemoved(RSession *session, uint32 cause) { + // propagate to partitions + for (int32 i = 0; RPartition *partition = session->PartitionAt(i); i++) + PartitionRemoved(partition, B_DEVICE_CAUSE_PARENT_CHANGED); + // notifications + // ... } // PartitionAdded void -RDiskDeviceList::PartitionAdded(RPartition *partition) +RDiskDeviceList::PartitionAdded(RPartition *partition, uint32 cause) { + // get the corresponding volume, if partition is mounted + char path[B_FILE_NAME_LENGTH]; + partition->GetPath(path); + if (const RVolume *volume = fVolumeList.VolumeForDevicePath(path)) + partition->SetVolume(volume); + // notifications + // ... } // PartitionRemoved void -RDiskDeviceList::PartitionRemoved(RPartition *partition) +RDiskDeviceList::PartitionRemoved(RPartition *partition, uint32 cause) { + // notifications + // ... } // Dump diff --git a/src/servers/registrar/RDiskDeviceList.h b/src/servers/registrar/RDiskDeviceList.h index bf3988c71f..1e7edc57d6 100644 --- a/src/servers/registrar/RDiskDeviceList.h +++ b/src/servers/registrar/RDiskDeviceList.h @@ -20,6 +20,20 @@ class RDiskDevice; class RPartition; class RSession; +// device list modification causes +// TODO: to be moved to +enum { + // helpful causes + B_DEVICE_CAUSE_MEDIA_CHANGED, + B_DEVICE_CAUSE_FORMATTED, + B_DEVICE_CAUSE_PARTITIONED, + B_DEVICE_CAUSE_INITIALIZED, + // unknown cause + B_DEVICE_CAUSE_UNKNOWN, + // for internal use only (e.g.: partition added, because device added) + B_DEVICE_CAUSE_PARENT_CHANGED, +}; + class RDiskDeviceList : public MessageHandler, public RVolumeListListener { public: RDiskDeviceList(BMessenger target, BLocker &lock, RVolumeList &volumeList); @@ -27,8 +41,9 @@ public: virtual void HandleMessage(BMessage *message); - void RDiskDeviceList::VolumeMounted(const RVolume *volume); - void RDiskDeviceList::VolumeUnmounted(const RVolume *volume); + virtual void VolumeMounted(const RVolume *volume); + virtual void VolumeUnmounted(const RVolume *volume); + virtual void MountPointMoved(const RVolume *volume); bool AddDevice(RDiskDevice *device); bool RemoveDevice(int32 index); @@ -43,7 +58,7 @@ public: RPartition *PartitionAt(int32 index) const { return fPartitions.ItemAt(index); } - RDiskDevice *DeviceWithID(int32 id) const; + RDiskDevice *DeviceWithID(int32 id, bool exact = true) const; RSession *SessionWithID(int32 id) const; RPartition *PartitionWithID(int32 id) const; @@ -54,12 +69,18 @@ public: bool Lock(); void Unlock(); - void DeviceAdded(RDiskDevice *device); - void DeviceRemoved(RDiskDevice *device); - void SessionAdded(RSession *session); - void SessionRemoved(RSession *session); - void PartitionAdded(RPartition *partition); - void PartitionRemoved(RPartition *partition); + void DeviceAdded(RDiskDevice *device, + uint32 cause = B_DEVICE_CAUSE_UNKNOWN); + void DeviceRemoved(RDiskDevice *device, + uint32 cause = B_DEVICE_CAUSE_UNKNOWN); + void SessionAdded(RSession *session, + uint32 cause = B_DEVICE_CAUSE_UNKNOWN); + void SessionRemoved(RSession *session, + uint32 cause = B_DEVICE_CAUSE_UNKNOWN); + void PartitionAdded(RPartition *partition, + uint32 cause = B_DEVICE_CAUSE_UNKNOWN); + void PartitionRemoved(RPartition *partition, + uint32 cause = B_DEVICE_CAUSE_UNKNOWN); void Dump() const; diff --git a/src/servers/registrar/RPartition.cpp b/src/servers/registrar/RPartition.cpp index 46f9b1aaae..8b2f1c45e5 100644 --- a/src/servers/registrar/RPartition.cpp +++ b/src/servers/registrar/RPartition.cpp @@ -12,7 +12,8 @@ RPartition::RPartition() : fSession(NULL), fID(-1), - fChangeCounter(0) + fChangeCounter(0), + fVolume(NULL) { } @@ -54,6 +55,69 @@ RPartition::Device() const return (fSession ? fSession->Device() : NULL); } +// Index +int32 +RPartition::Index() const +{ + if (fSession) + return fSession->IndexOfPartition(this); + return -1; +} + +// GetPath +void +RPartition::GetPath(char *path) const +{ + RDiskDevice *device = Device(); + if (path && device) { + strcpy(path, device->Path()); + if (char *lastSlash = strrchr(path, '/')) + sprintf(lastSlash + 1, "%ld_%ld", Session()->Index(), Index()); + } +} + +// Archive +status_t +RPartition::Archive(BMessage *archive) const +{ + status_t error = (archive ? B_OK : B_BAD_VALUE); + // ID, change counter and index + if (error == B_OK) + error = archive->AddInt32("id", fID); + if (error == B_OK) + error = archive->AddInt32("change_counter", fChangeCounter); + if (error == B_OK) + error = archive->AddInt32("index", Index()); + // fInfo.info.* + if (error == B_OK) + error = archive->AddInt64("offset", fInfo.info.offset); + if (error == B_OK) + error = archive->AddInt64("size", fInfo.info.size); + // fInfo.* + if (error == B_OK) + error = archive->AddInt32("flags", (int32)fInfo.flags); + if (error == B_OK) + error = archive->AddString("name", fInfo.partition_name); + if (error == B_OK) + error = archive->AddString("type", fInfo.partition_type); + if (error == B_OK) { + error = archive->AddString("fs_short_name", + fInfo.file_system_short_name); + } + if (error == B_OK) { + error = archive->AddString("fs_long_name", + fInfo.file_system_long_name); + } + if (error == B_OK) + error = archive->AddString("volume_name", fInfo.volume_name); + if (error == B_OK) + error = archive->AddInt32("fs_flags", (int32)fInfo.file_system_flags); + // dev_t, if mounted + if (error == B_OK && fVolume) + error = archive->AddInt32("volume_id", fVolume->ID()); + return error; +} + // print_partition_info static void @@ -72,7 +136,7 @@ print_partition_info(const char *prefix, const extended_partition_info &info) printf("%sFS short name: `%s'\n", prefix, info.file_system_short_name); printf("%sFS long name: `%s'\n", prefix, info.file_system_long_name); printf("%svolume name: `%s'\n", prefix, info.volume_name); - printf("%smounted at: `%s'\n", prefix, info.mounted_at); +// printf("%smounted at: `%s'\n", prefix, info.mounted_at); printf("%sFS flags: 0x%lx\n", prefix, info.file_system_flags); } diff --git a/src/servers/registrar/RPartition.h b/src/servers/registrar/RPartition.h index 3c13574691..39d570f58b 100644 --- a/src/servers/registrar/RPartition.h +++ b/src/servers/registrar/RPartition.h @@ -9,9 +9,12 @@ #include #include +class BMessage; + class RDiskDevice; class RDiskDeviceList; class RSession; +class RVolume; class RPartition { public: @@ -29,7 +32,15 @@ public: int32 ID() const { return fID; } int32 ChangeCounter() const { return fChangeCounter; } + int32 Index() const; + const extended_partition_info *Info() const { return &fInfo; } + void GetPath(char *path) const; + + void SetVolume(const RVolume *volume) { fVolume = volume; } + const RVolume *Volume() const { return fVolume; } + + status_t Archive(BMessage *archive) const; void Dump() const; @@ -41,6 +52,7 @@ private: int32 fID; int32 fChangeCounter; extended_partition_info fInfo; + const RVolume *fVolume; static vint32 fNextID; }; diff --git a/src/servers/registrar/RSession.cpp b/src/servers/registrar/RSession.cpp index f620f23b40..1f27b83003 100644 --- a/src/servers/registrar/RSession.cpp +++ b/src/servers/registrar/RSession.cpp @@ -78,6 +78,15 @@ RSession::DeviceList() const return (fDevice ? fDevice->DeviceList() : NULL); } +// Index +int32 +RSession::Index() const +{ + if (fDevice) + return fDevice->IndexOfSession(this); + return -1; +} + // AddPartition bool RSession::AddPartition(RPartition *partition) @@ -134,6 +143,40 @@ print_session_info(const char *prefix, const session_info &info) printf("%sflags: %lx\n", prefix, info.flags); } +// Archive +status_t +RSession::Archive(BMessage *archive) const +{ + status_t error = (archive ? B_OK : B_BAD_VALUE); + // ID, change counter and index + if (error == B_OK) + error = archive->AddInt32("id", fID); + if (error == B_OK) + error = archive->AddInt32("change_counter", fChangeCounter); + if (error == B_OK) + error = archive->AddInt32("index", Index()); + // fInfo.* + if (error == B_OK) + error = archive->AddInt64("offset", fInfo.offset); + if (error == B_OK) + error = archive->AddInt64("size", fInfo.size); + if (error == B_OK) + error = archive->AddInt32("flags", (int32)fInfo.flags); + // other data + if (error == B_OK) + error = archive->AddString("partitioning", fPartitioningSystem); + // partitions + for (int32 i = 0; const RPartition *partition = PartitionAt(i); i++) { + BMessage partitionArchive; + error = partition->Archive(&partitionArchive); + if (error == B_OK) + error = archive->AddMessage("partitions", &partitionArchive); + if (error != B_OK) + break; + } + return error; +} + // Dump void RSession::Dump() const diff --git a/src/servers/registrar/RSession.h b/src/servers/registrar/RSession.h index 726c2ea2e1..3a730706bf 100644 --- a/src/servers/registrar/RSession.h +++ b/src/servers/registrar/RSession.h @@ -28,15 +28,21 @@ public: int32 ID() const { return fID; } int32 ChangeCounter() const { return fChangeCounter; } + int32 Index() const; + bool AddPartition(RPartition *partition); bool RemovePartition(int32 index); bool RemovePartition(RPartition *partition); int32 CountPartitions() const { return fPartitions.CountItems(); } RPartition *PartitionAt(int32 index) const { return fPartitions.ItemAt(index); } + int32 IndexOfPartition(const RPartition *partition) const + { return fPartitions.IndexOf(partition); } const session_info *Info() const { return &fInfo; } + status_t Archive(BMessage *archive) const; + void Dump() const; private: diff --git a/src/servers/registrar/RVolumeList.cpp b/src/servers/registrar/RVolumeList.cpp index b7cc288e38..550e0db9ab 100644 --- a/src/servers/registrar/RVolumeList.cpp +++ b/src/servers/registrar/RVolumeList.cpp @@ -79,6 +79,26 @@ RVolume::Unset() fRootNode = -1; } +// StartWatching +status_t +RVolume::StartWatching(BMessenger target) const +{ + node_ref ref; + ref.device = fID; + ref.node = fRootNode; + return watch_node(&ref, B_WATCH_NAME, target); +} + +// StopWatching +status_t +RVolume::StopWatching(BMessenger target) const +{ + node_ref ref; + ref.device = fID; + ref.node = fRootNode; + return watch_node(&ref, B_STOP_WATCHING, target); +} + // RVolumeListListener @@ -104,6 +124,12 @@ RVolumeListListener::VolumeUnmounted(const RVolume *volume) { } +// MountPointMoved +void +RVolumeListListener::MountPointMoved(const RVolume *volume) +{ +} + // RVolumeList @@ -149,6 +175,9 @@ RVolumeList::HandleMessage(BMessage *message) case B_DEVICE_UNMOUNTED: _DeviceUnmounted(message); break; + case B_ENTRY_MOVED: + _MountPointMoved(message); + break; } } break; @@ -231,6 +260,7 @@ RVolumeList::_AddVolume(dev_t id) if (error == B_OK) { fVolumes.BinaryInsert(volume, CompareDevicePathPredicate(volume->DevicePath())); + volume->StartWatching(fTarget); } else { delete volume; volume = NULL; @@ -264,6 +294,7 @@ RVolumeList::_DeviceUnmounted(BMessage *message) if (message->FindInt32("device", &device) == B_OK) { PRINT(("RVolumeList::_DeviceUnmounted(%ld)\n", device)); if (RVolume *volume = fVolumes.FindIf(CompareIDPredicate(device))) { + volume->StopWatching(fTarget); fVolumes.RemoveItem(volume, false); if (fListener) fListener->VolumeUnmounted(volume); @@ -272,3 +303,17 @@ RVolumeList::_DeviceUnmounted(BMessage *message) } } +// _MountPointMoved +void +RVolumeList::_MountPointMoved(BMessage *message) +{ + dev_t device; + if (message->FindInt32("device", &device) == B_OK) { + PRINT(("RVolumeList::_MountPointMoved(%ld)\n", device)); + if (RVolume *volume = fVolumes.FindIf(CompareIDPredicate(device))) { + if (fListener) + fListener->MountPointMoved(volume); + } + } +} + diff --git a/src/servers/registrar/RVolumeList.h b/src/servers/registrar/RVolumeList.h index 9315c6dff3..7555ffc006 100644 --- a/src/servers/registrar/RVolumeList.h +++ b/src/servers/registrar/RVolumeList.h @@ -30,6 +30,9 @@ public: { ref->device = fID; ref->node = fRootNode; } const char *DevicePath() const { return fDevicePath; } + status_t StartWatching(BMessenger target) const; + status_t StopWatching(BMessenger target) const; + private: dev_t fID; ino_t fRootNode; @@ -44,6 +47,7 @@ public: virtual void VolumeMounted(const RVolume *volume); virtual void VolumeUnmounted(const RVolume *volume); + virtual void MountPointMoved(const RVolume *volume); }; // RVolumeList @@ -69,6 +73,7 @@ private: RVolume *_AddVolume(dev_t id); void _DeviceMounted(BMessage *message); void _DeviceUnmounted(BMessage *message); + void _MountPointMoved(BMessage *message); private: mutable BLocker &fLock;