OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chromeos/disks/disk_mount_manager.h" | 5 #include "chromeos/disks/disk_mount_manager.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 #include <set> | 8 #include <set> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 base::Bind(&DiskMountManagerImpl::OnMountCompleted, | 76 base::Bind(&DiskMountManagerImpl::OnMountCompleted, |
77 weak_ptr_factory_.GetWeakPtr(), | 77 weak_ptr_factory_.GetWeakPtr(), |
78 MOUNT_ERROR_INTERNAL, | 78 MOUNT_ERROR_INTERNAL, |
79 source_path, | 79 source_path, |
80 type, | 80 type, |
81 "")); | 81 "")); |
82 } | 82 } |
83 | 83 |
84 // DiskMountManager override. | 84 // DiskMountManager override. |
85 virtual void UnmountPath(const std::string& mount_path, | 85 virtual void UnmountPath(const std::string& mount_path, |
86 UnmountOptions options) OVERRIDE { | 86 UnmountOptions options, |
| 87 const UnmountPathCallback& callback) OVERRIDE { |
87 UnmountChildMounts(mount_path); | 88 UnmountChildMounts(mount_path); |
88 cros_disks_client_->Unmount(mount_path, options, | 89 cros_disks_client_->Unmount(mount_path, options, |
89 base::Bind(&DiskMountManagerImpl::OnUnmountPath, | 90 base::Bind(&DiskMountManagerImpl::OnUnmountPath, |
90 weak_ptr_factory_.GetWeakPtr(), | 91 weak_ptr_factory_.GetWeakPtr(), |
| 92 callback, |
91 true), | 93 true), |
92 base::Bind(&DiskMountManagerImpl::OnUnmountPath, | 94 base::Bind(&DiskMountManagerImpl::OnUnmountPath, |
93 weak_ptr_factory_.GetWeakPtr(), | 95 weak_ptr_factory_.GetWeakPtr(), |
| 96 callback, |
94 false)); | 97 false)); |
95 } | 98 } |
96 | 99 |
97 // DiskMountManager override. | 100 // DiskMountManager override. |
98 virtual void FormatMountedDevice(const std::string& mount_path) OVERRIDE { | 101 virtual void FormatMountedDevice(const std::string& mount_path) OVERRIDE { |
99 MountPointMap::const_iterator mount_point = mount_points_.find(mount_path); | 102 MountPointMap::const_iterator mount_point = mount_points_.find(mount_path); |
100 if (mount_point == mount_points_.end()) { | 103 if (mount_point == mount_points_.end()) { |
101 LOG(ERROR) << "Mount point with path \"" << mount_path << "\" not found."; | 104 LOG(ERROR) << "Mount point with path \"" << mount_path << "\" not found."; |
102 OnFormatDevice(mount_path, false); | 105 OnFormatDevice(mount_path, false); |
103 return; | 106 return; |
104 } | 107 } |
105 | 108 |
106 std::string device_path = mount_point->second.source_path; | 109 std::string device_path = mount_point->second.source_path; |
107 DiskMap::const_iterator disk = disks_.find(device_path); | 110 DiskMap::const_iterator disk = disks_.find(device_path); |
108 if (disk == disks_.end()) { | 111 if (disk == disks_.end()) { |
109 LOG(ERROR) << "Device with path \"" << device_path << "\" not found."; | 112 LOG(ERROR) << "Device with path \"" << device_path << "\" not found."; |
110 OnFormatDevice(device_path, false); | 113 OnFormatDevice(device_path, false); |
111 return; | 114 return; |
112 } | 115 } |
113 | 116 |
114 if (formatting_pending_.find(device_path) != formatting_pending_.end()) { | 117 UnmountPath(disk->second->mount_path(), |
115 LOG(ERROR) << "Formatting is already pending: " << mount_path; | 118 UNMOUNT_OPTIONS_NONE, |
116 OnFormatDevice(device_path, false); | 119 base::Bind(&DiskMountManagerImpl::OnUnmountPathForFormat, |
117 return; | 120 weak_ptr_factory_.GetWeakPtr(), |
118 } | 121 device_path)); |
119 | |
120 // Formatting process continues, after unmounting. | |
121 formatting_pending_.insert(device_path); | |
122 UnmountPath(disk->second->mount_path(), UNMOUNT_OPTIONS_NONE); | |
123 } | 122 } |
124 | 123 |
125 // DiskMountManager override. | 124 // DiskMountManager override. |
126 virtual void UnmountDeviceRecursively( | 125 virtual void UnmountDeviceRecursively( |
127 const std::string& device_path, | 126 const std::string& device_path, |
128 const UnmountDeviceRecursivelyCallbackType& callback) OVERRIDE { | 127 const UnmountDeviceRecursivelyCallbackType& callback) OVERRIDE { |
129 std::vector<std::string> devices_to_unmount; | 128 std::vector<std::string> devices_to_unmount; |
130 | 129 |
131 // Get list of all devices to unmount. | 130 // Get list of all devices to unmount. |
132 int device_path_len = device_path.length(); | 131 int device_path_len = device_path.length(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 std::string mount_path = mount_path_in; | 250 std::string mount_path = mount_path_in; |
252 // Let's make sure mount path has trailing slash. | 251 // Let's make sure mount path has trailing slash. |
253 if (mount_path[mount_path.length() - 1] != '/') | 252 if (mount_path[mount_path.length() - 1] != '/') |
254 mount_path += '/'; | 253 mount_path += '/'; |
255 | 254 |
256 for (MountPointMap::iterator it = mount_points_.begin(); | 255 for (MountPointMap::iterator it = mount_points_.begin(); |
257 it != mount_points_.end(); | 256 it != mount_points_.end(); |
258 ++it) { | 257 ++it) { |
259 if (StartsWithASCII(it->second.source_path, mount_path, | 258 if (StartsWithASCII(it->second.source_path, mount_path, |
260 true /*case sensitive*/)) { | 259 true /*case sensitive*/)) { |
261 UnmountPath(it->second.mount_path, UNMOUNT_OPTIONS_NONE); | 260 // TODO(tbarzic): Handle the case where this fails. |
| 261 UnmountPath(it->second.mount_path, |
| 262 UNMOUNT_OPTIONS_NONE, |
| 263 UnmountPathCallback()); |
262 } | 264 } |
263 } | 265 } |
264 } | 266 } |
265 | 267 |
266 // Callback for UnmountDeviceRecursively. | 268 // Callback for UnmountDeviceRecursively. |
267 void OnUnmountDeviceRecursively( | 269 void OnUnmountDeviceRecursively( |
268 UnmountDeviceRecursivelyCallbackData* cb_data, | 270 UnmountDeviceRecursivelyCallbackData* cb_data, |
269 bool success, | 271 bool success, |
270 const std::string& mount_path) { | 272 const std::string& mount_path) { |
271 if (success) { | 273 if (success) { |
272 // Do standard processing for Unmount event. | 274 // Do standard processing for Unmount event. |
273 OnUnmountPath(true, mount_path); | 275 OnUnmountPath(UnmountPathCallback(), true, mount_path); |
274 LOG(INFO) << mount_path << " unmounted."; | 276 LOG(INFO) << mount_path << " unmounted."; |
275 } | 277 } |
276 // This is safe as long as all callbacks are called on the same thread as | 278 // This is safe as long as all callbacks are called on the same thread as |
277 // UnmountDeviceRecursively. | 279 // UnmountDeviceRecursively. |
278 cb_data->num_pending_callbacks--; | 280 cb_data->num_pending_callbacks--; |
279 | 281 |
280 if (cb_data->num_pending_callbacks == 0) { | 282 if (cb_data->num_pending_callbacks == 0) { |
281 // This code has a problem that the |success| status used here is for the | 283 // This code has a problem that the |success| status used here is for the |
282 // last "unmount" callback, but not whether all unmounting is succeeded. | 284 // last "unmount" callback, but not whether all unmounting is succeeded. |
283 // TODO(hidehiko): Fix the issue. | 285 // TODO(hidehiko): Fix the issue. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 // disk might have been removed by now? | 323 // disk might have been removed by now? |
322 return; | 324 return; |
323 } | 325 } |
324 Disk* disk = iter->second; | 326 Disk* disk = iter->second; |
325 DCHECK(disk); | 327 DCHECK(disk); |
326 disk->set_mount_path(mount_info.mount_path); | 328 disk->set_mount_path(mount_info.mount_path); |
327 } | 329 } |
328 } | 330 } |
329 | 331 |
330 // Callback for UnmountPath. | 332 // Callback for UnmountPath. |
331 void OnUnmountPath(bool success, const std::string& mount_path) { | 333 void OnUnmountPath(const UnmountPathCallback& callback, |
| 334 bool success, |
| 335 const std::string& mount_path) { |
332 MountPointMap::iterator mount_points_it = mount_points_.find(mount_path); | 336 MountPointMap::iterator mount_points_it = mount_points_.find(mount_path); |
333 if (mount_points_it == mount_points_.end()) | 337 if (mount_points_it == mount_points_.end()) |
334 return; | 338 return; |
335 | 339 |
| 340 if (!callback.is_null()) |
| 341 callback.Run(success ? MOUNT_ERROR_NONE : MOUNT_ERROR_INTERNAL); |
| 342 |
336 NotifyMountStatusUpdate( | 343 NotifyMountStatusUpdate( |
337 UNMOUNTING, | 344 UNMOUNTING, |
338 success ? MOUNT_ERROR_NONE : MOUNT_ERROR_INTERNAL, | 345 success ? MOUNT_ERROR_NONE : MOUNT_ERROR_INTERNAL, |
339 MountPointInfo(mount_points_it->second.source_path, | 346 MountPointInfo(mount_points_it->second.source_path, |
340 mount_points_it->second.mount_path, | 347 mount_points_it->second.mount_path, |
341 mount_points_it->second.mount_type, | 348 mount_points_it->second.mount_type, |
342 mount_points_it->second.mount_condition)); | 349 mount_points_it->second.mount_condition)); |
343 | 350 |
344 std::string path(mount_points_it->second.source_path); | 351 std::string path(mount_points_it->second.source_path); |
345 if (success) | 352 if (success) |
346 mount_points_.erase(mount_points_it); | 353 mount_points_.erase(mount_points_it); |
347 | 354 |
348 DiskMap::iterator disk_iter = disks_.find(path); | 355 DiskMap::iterator disk_iter = disks_.find(path); |
349 if (disk_iter != disks_.end()) { | 356 if (disk_iter != disks_.end()) { |
350 DCHECK(disk_iter->second); | 357 DCHECK(disk_iter->second); |
351 if (success) | 358 if (success) |
352 disk_iter->second->clear_mount_path(); | 359 disk_iter->second->clear_mount_path(); |
353 } | 360 } |
| 361 } |
354 | 362 |
355 FormatTaskSet::iterator format_iter = formatting_pending_.find(path); | 363 void OnUnmountPathForFormat(const std::string& device_path, |
356 // Check if there is a formatting scheduled. | 364 MountError error_code) { |
357 if (format_iter != formatting_pending_.end()) { | 365 if (error_code == MOUNT_ERROR_NONE && |
358 formatting_pending_.erase(format_iter); | 366 disks_.find(device_path) != disks_.end()) { |
359 if (success && disk_iter != disks_.end()) { | 367 FormatUnmountedDevice(device_path); |
360 FormatUnmountedDevice(path); | 368 } else { |
361 } else { | 369 OnFormatDevice(device_path, false); |
362 OnFormatDevice(path, false); | |
363 } | |
364 } | 370 } |
365 } | 371 } |
366 | 372 |
367 // Starts device formatting. | 373 // Starts device formatting. |
368 void FormatUnmountedDevice(const std::string& device_path) { | 374 void FormatUnmountedDevice(const std::string& device_path) { |
369 DiskMap::const_iterator disk = disks_.find(device_path); | 375 DiskMap::const_iterator disk = disks_.find(device_path); |
370 DCHECK(disk != disks_.end() && disk->second->mount_path().empty()); | 376 DCHECK(disk != disks_.end() && disk->second->mount_path().empty()); |
371 | 377 |
372 const char kFormatVFAT[] = "vfat"; | 378 const char kFormatVFAT[] = "vfat"; |
373 cros_disks_client_->FormatDevice( | 379 cros_disks_client_->FormatDevice( |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 CrosDisksClient* cros_disks_client_; | 593 CrosDisksClient* cros_disks_client_; |
588 | 594 |
589 // The list of disks found. | 595 // The list of disks found. |
590 DiskMountManager::DiskMap disks_; | 596 DiskMountManager::DiskMap disks_; |
591 | 597 |
592 DiskMountManager::MountPointMap mount_points_; | 598 DiskMountManager::MountPointMap mount_points_; |
593 | 599 |
594 typedef std::set<std::string> SystemPathPrefixSet; | 600 typedef std::set<std::string> SystemPathPrefixSet; |
595 SystemPathPrefixSet system_path_prefixes_; | 601 SystemPathPrefixSet system_path_prefixes_; |
596 | 602 |
597 // A map from device path (e.g. /sys/devices/pci0000:00/.../sdb/sdb1)) to file | |
598 // path (e.g. /dev/sdb). | |
599 // Devices in this map are supposed to be formatted, but are currently waiting | |
600 // to be unmounted. When device is in this map, the formatting process HAVEN'T | |
601 // started yet. | |
602 typedef std::set<std::string> FormatTaskSet; | |
603 FormatTaskSet formatting_pending_; | |
604 | |
605 base::WeakPtrFactory<DiskMountManagerImpl> weak_ptr_factory_; | 603 base::WeakPtrFactory<DiskMountManagerImpl> weak_ptr_factory_; |
606 | 604 |
607 DISALLOW_COPY_AND_ASSIGN(DiskMountManagerImpl); | 605 DISALLOW_COPY_AND_ASSIGN(DiskMountManagerImpl); |
608 }; | 606 }; |
609 | 607 |
610 } // namespace | 608 } // namespace |
611 | 609 |
612 DiskMountManager::Disk::Disk(const std::string& device_path, | 610 DiskMountManager::Disk::Disk(const std::string& device_path, |
613 const std::string& mount_path, | 611 const std::string& mount_path, |
614 const std::string& system_path, | 612 const std::string& system_path, |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 VLOG(1) << "DiskMountManager Shutdown completed"; | 753 VLOG(1) << "DiskMountManager Shutdown completed"; |
756 } | 754 } |
757 | 755 |
758 // static | 756 // static |
759 DiskMountManager* DiskMountManager::GetInstance() { | 757 DiskMountManager* DiskMountManager::GetInstance() { |
760 return g_disk_mount_manager; | 758 return g_disk_mount_manager; |
761 } | 759 } |
762 | 760 |
763 } // namespace disks | 761 } // namespace disks |
764 } // namespace chromeos | 762 } // namespace chromeos |
OLD | NEW |