Skip to content

Commit a93476a

Browse files
author
lianzhi chang
committed
Fix the problem that btrfs multi-partition cannot be unmounted
udisks state_check_mounted_fs() gets mounts before calling udisks state_check_mounted_fs_entry() in a loop. Signed-off-by: lianzhi chang <[email protected]>
1 parent 0af02e3 commit a93476a

File tree

3 files changed

+72
-5
lines changed

3 files changed

+72
-5
lines changed

src/udisksmountmonitor.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,33 @@ udisks_mount_monitor_ensure (UDisksMountMonitor *monitor)
709709
g_mutex_unlock (&monitor->mounts_mutex);
710710
}
711711

712+
/**
713+
* udisks_mount_monitor_get_mounts:
714+
* @monitor: A #UDisksMountMonitor.
715+
*
716+
* Gets all #UDisksMount objects.
717+
*
718+
* Returns: A #GList of #UDisksMount objects. The returned list must
719+
* be freed with g_list_free() after each element has been freed with
720+
* g_object_unref().
721+
*/
722+
GList *
723+
udisks_mount_monitor_get_mounts (UDisksMountMonitor *monitor)
724+
{
725+
GList *ret;
726+
727+
ret = NULL;
728+
729+
g_mutex_lock (&monitor->mounts_mutex);
730+
ret = g_list_copy_deep (monitor->mounts, (GCopyFunc) udisks_g_object_ref_copy, NULL);
731+
g_mutex_unlock (&monitor->mounts_mutex);
732+
733+
/* Sort the list to ensure that shortest mount paths appear first */
734+
ret = g_list_sort (ret, (GCompareFunc) udisks_mount_compare);
735+
736+
return ret;
737+
}
738+
712739
/**
713740
* udisks_mount_monitor_get_mounts_for_dev:
714741
* @monitor: A #UDisksMountMonitor.

src/udisksmountmonitor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ G_BEGIN_DECLS
3131

3232
GType udisks_mount_monitor_get_type (void) G_GNUC_CONST;
3333
UDisksMountMonitor *udisks_mount_monitor_new (void);
34+
GList *udisks_mount_monitor_get_mounts (UDisksMountMonitor *monitor);
3435
GList *udisks_mount_monitor_get_mounts_for_dev (UDisksMountMonitor *monitor,
3536
dev_t dev);
3637
gboolean udisks_mount_monitor_is_dev_in_use (UDisksMountMonitor *monitor,

src/udisksstate.c

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,42 @@ lookup_asv (GVariant *asv,
569569

570570
/* ---------------------------------------------------------------------------------------------------- */
571571

572+
/**
573+
* udisks_mount_monitor_get_mounts_for_dev:
574+
* @mounts: A #UDisksMount.
575+
* @dev: A #dev_t device number.
576+
*
577+
* Gets all #UDisksMount objects for @dev.
578+
*
579+
* Returns: A #GList of #UDisksMount objects. The returned list must
580+
* be freed with g_list_free() after each element has been freed with
581+
* g_object_unref().
582+
*/
583+
static GList *
584+
udisks_state_get_mounts_for_dev (GList *mounts,
585+
dev_t dev)
586+
{
587+
GList *ret;
588+
GList *l;
589+
590+
ret = NULL;
591+
592+
for (l = mounts; l != NULL; l = l->next)
593+
{
594+
UDisksMount *mount = UDISKS_MOUNT (l->data);
595+
596+
if (udisks_mount_get_dev (mount) == dev)
597+
{
598+
ret = g_list_prepend (ret, g_object_ref (mount));
599+
}
600+
}
601+
602+
/* Sort the list to ensure that shortest mount paths appear first */
603+
ret = g_list_sort (ret, (GCompareFunc) udisks_mount_compare);
604+
605+
return ret;
606+
}
607+
572608
/* returns TRUE if the entry should be kept */
573609
static gboolean
574610
udisks_state_check_mounted_fs_entry (UDisksState *state,
@@ -590,7 +626,6 @@ udisks_state_check_mounted_fs_entry (UDisksState *state,
590626
gboolean is_mounted;
591627
gboolean device_exists;
592628
gboolean device_to_be_cleaned;
593-
UDisksMountMonitor *monitor;
594629
GUdevClient *udev_client;
595630
GUdevDevice *udev_device;
596631
guint n;
@@ -608,8 +643,6 @@ udisks_state_check_mounted_fs_entry (UDisksState *state,
608643
details = NULL;
609644
locked = FALSE;
610645

611-
monitor = udisks_daemon_get_mount_monitor (state->daemon);
612-
613646
g_variant_get (value,
614647
"{&s@a{sv}}",
615648
&mount_point_str,
@@ -668,7 +701,7 @@ udisks_state_check_mounted_fs_entry (UDisksState *state,
668701
/* udisks_debug ("Validating mounted-fs entry for mount point %s", mount_point); */
669702

670703
/* Figure out if still mounted */
671-
mounts = udisks_mount_monitor_get_mounts_for_dev (monitor, block_device);
704+
mounts = udisks_state_get_mounts_for_dev (monitor_mounts, block_device);
672705
for (l = mounts; l != NULL; l = l->next)
673706
{
674707
UDisksMount *mount = UDISKS_MOUNT (l->data);
@@ -870,15 +903,21 @@ udisks_state_check_mounted_fs (UDisksState *state,
870903
{
871904
GVariantIter iter;
872905
GVariant *child;
906+
GList *mounts;
907+
UDisksMountMonitor *monitor;
908+
909+
monitor = udisks_daemon_get_mount_monitor (state->daemon);
910+
mounts = udisks_mount_monitor_get_mounts(monitor);
873911
g_variant_iter_init (&iter, value);
874912
while ((child = g_variant_iter_next_value (&iter)) != NULL)
875913
{
876-
if (udisks_state_check_mounted_fs_entry (state, child, devs_to_clean, match_block_device))
914+
if (udisks_state_check_mounted_fs_entry (state, child, devs_to_clean, match_block_device, mounts))
877915
g_variant_builder_add_value (&builder, child);
878916
else
879917
changed = TRUE;
880918
g_variant_unref (child);
881919
}
920+
g_list_free_full (mounts, g_object_unref);
882921
g_variant_unref (value);
883922
}
884923

0 commit comments

Comments
 (0)