diff --git a/headers/os/storage/DiskDeviceDefs.h b/headers/os/storage/DiskDeviceDefs.h index ae626d6c13..d79a253194 100644 --- a/headers/os/storage/DiskDeviceDefs.h +++ b/headers/os/storage/DiskDeviceDefs.h @@ -21,7 +21,6 @@ enum { B_PARTITION_READ_ONLY = 0x08, B_PARTITION_MOUNTED = 0x10, // needed? B_PARTITION_BUSY = 0x20, - B_PARTITION_DESCENDANT_BUSY = 0x40, }; // partition statuses diff --git a/headers/private/kernel/disk_device_manager/KPartition.h b/headers/private/kernel/disk_device_manager/KPartition.h index f1c24efe27..d9162aa6f3 100644 --- a/headers/private/kernel/disk_device_manager/KPartition.h +++ b/headers/private/kernel/disk_device_manager/KPartition.h @@ -52,12 +52,8 @@ public: void SetBusy(bool busy); bool IsBusy() const; - // == jobs which may affect this partition are scheduled/in progress - void SetDescendantBusy(bool busy); - bool IsDescendantBusy() const; - // == jobs which may affect a descendant of this partition are - // scheduled/in progress; IsBusy() => IsDescendantBusy() - // In the userland API, both can probably be mapped to one flag. + bool CheckAndMarkBusy(bool includeDescendants); + void UnmarkBusy(bool includeDescendants); void SetOffset(off_t offset); off_t Offset() const; // 0 for devices diff --git a/src/kits/storage/disk_device/Partition.cpp b/src/kits/storage/disk_device/Partition.cpp index 73593aa05b..06db7ae3b7 100644 --- a/src/kits/storage/disk_device/Partition.cpp +++ b/src/kits/storage/disk_device/Partition.cpp @@ -197,8 +197,7 @@ BPartition::IsMounted() const bool BPartition::IsBusy() const { - return _PartitionData()->flags - & (B_PARTITION_BUSY | B_PARTITION_DESCENDANT_BUSY); + return _PartitionData()->flags & B_PARTITION_BUSY; } diff --git a/src/system/kernel/disk_device_manager/KDiskDeviceManager.cpp b/src/system/kernel/disk_device_manager/KDiskDeviceManager.cpp index 84cc0d9578..aa9a6eaacf 100644 --- a/src/system/kernel/disk_device_manager/KDiskDeviceManager.cpp +++ b/src/system/kernel/disk_device_manager/KDiskDeviceManager.cpp @@ -1032,16 +1032,7 @@ KDiskDeviceManager::_ScanPartition(KPartition *partition, bool async) // TODO: This is not quite correct here. Partitions are created marked "busy", // hence the one creating it should be responsible for clearing the flag, not // us. - struct UnmarkBusyVisitor : KPartitionVisitor { - virtual bool VisitPre(KPartition* partition) - { - partition->ClearFlags(B_PARTITION_BUSY - | B_PARTITION_DESCENDANT_BUSY); - return false; - } - } visitor; - - partition->VisitEachDescendant(&visitor); + partition->UnmarkBusy(true); return error; } diff --git a/src/system/kernel/disk_device_manager/KPartition.cpp b/src/system/kernel/disk_device_manager/KPartition.cpp index 0ccc45382d..c698f4fee0 100644 --- a/src/system/kernel/disk_device_manager/KPartition.cpp +++ b/src/system/kernel/disk_device_manager/KPartition.cpp @@ -58,7 +58,7 @@ KPartition::KPartition(partition_id id) fPartitionData.child_count = 0; fPartitionData.index = -1; fPartitionData.status = B_PARTITION_UNRECOGNIZED; - fPartitionData.flags = B_PARTITION_BUSY | B_PARTITION_DESCENDANT_BUSY; + fPartitionData.flags = B_PARTITION_BUSY; fPartitionData.volume = -1; fPartitionData.mount_cookie = NULL; fPartitionData.name = NULL; @@ -238,6 +238,7 @@ KPartition::SetBusy(bool busy) ClearFlags(B_PARTITION_BUSY); } + // IsBusy bool KPartition::IsBusy() const @@ -245,23 +246,63 @@ KPartition::IsBusy() const return (fPartitionData.flags & B_PARTITION_BUSY); } -// SetDescendantBusy -void -KPartition::SetDescendantBusy(bool busy) + +// CheckAndMarkBusy +bool +KPartition::CheckAndMarkBusy(bool includeDescendants) { - if (busy) - SetFlags(B_PARTITION_DESCENDANT_BUSY); - else - ClearFlags(B_PARTITION_DESCENDANT_BUSY); + if (includeDescendants) { + // check + struct IsBusyVisitor : KPartitionVisitor { + virtual bool VisitPre(KPartition* partition) + { + return partition->IsBusy(); + } + } checkVisitor; + + if (VisitEachDescendant(&checkVisitor)) + return false; + + // mark busy + struct MarkBusyVisitor : KPartitionVisitor { + virtual bool VisitPre(KPartition* partition) + { + partition->AddFlags(B_PARTITION_BUSY); + return false; + } + } markVisitor; + + VisitEachDescendant(&markVisitor); + } else { + if (IsBusy()) + return false; + + SetBusy(true); + } + + return true; } -// IsDescendantBusy -bool -KPartition::IsDescendantBusy() const + +// UnmarkBusy +void +KPartition::UnmarkBusy(bool includeDescendants) { - return (fPartitionData.flags & B_PARTITION_DESCENDANT_BUSY); + if (includeDescendants) { + struct UnmarkBusyVisitor : KPartitionVisitor { + virtual bool VisitPre(KPartition* partition) + { + partition->ClearFlags(B_PARTITION_BUSY); + return false; + } + } visitor; + + VisitEachDescendant(&visitor); + } else + SetBusy(false); } + // SetOffset void KPartition::SetOffset(off_t offset) diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index b843df19d9..d762699914 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -5387,7 +5387,7 @@ fs_mount(char *path, const char *device, const char *fsName, uint32 flags, if (partition) { // make sure, that the partition is not busy - if (partition->IsBusy() || partition->IsDescendantBusy()) { + if (partition->IsBusy()) { TRACE(("fs_mount(): Partition is busy.\n")); return B_BUSY; } @@ -5601,7 +5601,7 @@ fs_unmount(char *path, uint32 flags, bool kernel) // make sure, that the partition is not busy if (partition) { - if (partition->IsBusy() || partition->IsDescendantBusy()) { + if (partition->IsBusy()) { TRACE(("fs_unmount(): Partition is busy.\n")); return B_BUSY; }