| // Copyright 2017 The ChromiumOS Authors | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "smbprovider/mount_tracker.h" | |
| #include <base/check.h> | |
| #include <base/check_op.h> | |
| #include <base/strings/string_util.h> | |
| namespace smbprovider { | |
| MountTracker::MountTracker(std::unique_ptr<base::TickClock> tick_clock, | |
| bool metadata_cache_enabled) | |
| : mounts_(kInitialMountId), | |
| tick_clock_(std::move(tick_clock)), | |
| metadata_cache_enabled_(metadata_cache_enabled) {} | |
| MountTracker::~MountTracker() = default; | |
| bool MountTracker::IsAlreadyMounted(int32_t mount_id) const { | |
| const auto mount_iter = mounts_.Find(mount_id); | |
| if (mount_iter == mounts_.End()) { | |
| return false; | |
| } | |
| return true; | |
| } | |
| bool MountTracker::IsAlreadyMounted( | |
| const SambaInterface::SambaInterfaceId samba_interface_id) const { | |
| const bool id_exist = samba_interface_map_.count(samba_interface_id) > 0; | |
| if (!id_exist) { | |
| return false; | |
| } | |
| // Ensure |samba_interface_map_| and |mounts_| are in sync. | |
| DCHECK(IsAlreadyMounted(samba_interface_map_.at(samba_interface_id))); | |
| return true; | |
| } | |
| bool MountTracker::ExistsInSambaInterfaceMap(const int32_t mount_id) const { | |
| for (const auto& samba_iter : samba_interface_map_) { | |
| if (samba_iter.second == mount_id) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| void MountTracker::AddMount(const std::string& mount_root, | |
| SmbCredential credential, | |
| std::unique_ptr<SambaInterface> samba_interface, | |
| int32_t* mount_id) { | |
| DCHECK(mount_id); | |
| *mount_id = mounts_.Insert(CreateMountInfo(mount_root, std::move(credential), | |
| std::move(samba_interface))); | |
| AddSambaInterfaceIdToSambaInterfaceMap(*mount_id); | |
| } | |
| bool MountTracker::RemoveMount(int32_t mount_id) { | |
| const auto mount_iter = mounts_.Find(mount_id); | |
| if (mount_iter == mounts_.End()) { | |
| DCHECK(!ExistsInSambaInterfaceMap(mount_id)); | |
| return false; | |
| } | |
| DeleteSambaInterfaceIdFromSambaInterfaceMap(mount_id); | |
| mounts_.Remove(mount_iter->first); | |
| return true; | |
| } | |
| bool MountTracker::GetFullPath(int32_t mount_id, | |
| const std::string& entry_path, | |
| std::string* full_path) const { | |
| DCHECK(full_path); | |
| const auto mount_iter = mounts_.Find(mount_id); | |
| if (mount_iter == mounts_.End()) { | |
| return false; | |
| } | |
| *full_path = AppendPath(mounts_.At(mount_id).mount_root, entry_path); | |
| return true; | |
| } | |
| bool MountTracker::GetMountRootPath(int32_t mount_id, | |
| std::string* mount_root) const { | |
| DCHECK_GE(mount_id, 0); | |
| const auto mount_iter = mounts_.Find(mount_id); | |
| if (mount_iter == mounts_.End()) { | |
| return false; | |
| } | |
| *mount_root = mount_iter->second.mount_root; | |
| return true; | |
| } | |
| std::string MountTracker::GetRelativePath(int32_t mount_id, | |
| const std::string& full_path) const { | |
| const auto mount_iter = mounts_.Find(mount_id); | |
| DCHECK(mount_iter != mounts_.End()); | |
| DCHECK(StartsWith(full_path, mount_iter->second.mount_root, | |
| base::CompareCase::INSENSITIVE_ASCII)); | |
| return full_path.substr(mounts_.At(mount_id).mount_root.length()); | |
| } | |
| const SmbCredential& MountTracker::GetCredential( | |
| SambaInterface::SambaInterfaceId samba_interface_id) const { | |
| DCHECK(IsAlreadyMounted(samba_interface_id)); | |
| // Double lookup of SambaInterfaceId => MountId followed by MountId => | |
| // MountInfo.credential | |
| const int32_t mount_id = samba_interface_map_.at(samba_interface_id); | |
| DCHECK(mounts_.Contains(mount_id)); | |
| return mounts_.At(mount_id).credential; | |
| } | |
| bool MountTracker::GetSambaInterface(int32_t mount_id, | |
| SambaInterface** samba_interface) const { | |
| DCHECK(samba_interface); | |
| const auto mount_iter = mounts_.Find(mount_id); | |
| if (mount_iter == mounts_.End()) { | |
| return false; | |
| } | |
| *samba_interface = mount_iter->second.samba_interface.get(); | |
| DCHECK(*samba_interface); | |
| return true; | |
| } | |
| bool MountTracker::GetMetadataCache(int32_t mount_id, | |
| MetadataCache** cache) const { | |
| DCHECK(cache); | |
| const auto mount_iter = mounts_.Find(mount_id); | |
| if (mount_iter == mounts_.End()) { | |
| return false; | |
| } | |
| *cache = mount_iter->second.cache.get(); | |
| DCHECK(*cache); | |
| return true; | |
| } | |
| bool MountTracker::UpdateCredential(int32_t mount_id, | |
| SmbCredential credential) { | |
| const auto mount_iter = mounts_.Find(mount_id); | |
| if (mount_iter == mounts_.End()) { | |
| return false; | |
| } | |
| mount_iter->second.credential = std::move(credential); | |
| return true; | |
| } | |
| bool MountTracker::UpdateSharePath(int32_t mount_id, | |
| const std::string& share_path) { | |
| const auto mount_iter = mounts_.Find(mount_id); | |
| if (mount_iter == mounts_.End()) { | |
| return false; | |
| } | |
| mount_iter->second.mount_root = share_path; | |
| return true; | |
| } | |
| MountTracker::MountInfo MountTracker::CreateMountInfo( | |
| const std::string& mount_root, | |
| SmbCredential credential, | |
| std::unique_ptr<SambaInterface> samba_interface) { | |
| return MountInfo(mount_root, tick_clock_.get(), std::move(credential), | |
| std::move(samba_interface), metadata_cache_enabled_); | |
| } | |
| void MountTracker::AddSambaInterfaceIdToSambaInterfaceMap(int32_t mount_id) { | |
| const SambaInterface::SambaInterfaceId samba_interface_id = | |
| GetSambaInterfaceIdForMountId(mount_id); | |
| DCHECK(!IsAlreadyMounted(samba_interface_id)); | |
| samba_interface_map_[samba_interface_id] = mount_id; | |
| } | |
| SambaInterface::SambaInterfaceId MountTracker::GetSambaInterfaceIdForMountId( | |
| int32_t mount_id) const { | |
| DCHECK(mounts_.Contains(mount_id)); | |
| const MountTracker::MountInfo& mount_info = mounts_.At(mount_id); | |
| return mount_info.samba_interface->GetSambaInterfaceId(); | |
| } | |
| void MountTracker::DeleteSambaInterfaceIdFromSambaInterfaceMap( | |
| int32_t mount_id) { | |
| const SambaInterface::SambaInterfaceId samba_interface_id = | |
| GetSambaInterfaceIdForMountId(mount_id); | |
| bool erase_succeeded = samba_interface_map_.erase(samba_interface_id); | |
| DCHECK(erase_succeeded); | |
| } | |
| } // namespace smbprovider |