Skip to content

Commit

Permalink
Fix the problem that btrfs multi-partition cannot be unmounted
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
lianzhi chang committed May 20, 2022
1 parent 0af02e3 commit a93476a
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 5 deletions.
27 changes: 27 additions & 0 deletions src/udisksmountmonitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -709,6 +709,33 @@ udisks_mount_monitor_ensure (UDisksMountMonitor *monitor)
g_mutex_unlock (&monitor->mounts_mutex);
}

/**
* udisks_mount_monitor_get_mounts:
* @monitor: A #UDisksMountMonitor.
*
* Gets all #UDisksMount objects.
*
* Returns: A #GList of #UDisksMount objects. The returned list must
* be freed with g_list_free() after each element has been freed with
* g_object_unref().
*/
GList *
udisks_mount_monitor_get_mounts (UDisksMountMonitor *monitor)
{
GList *ret;

ret = NULL;

g_mutex_lock (&monitor->mounts_mutex);
ret = g_list_copy_deep (monitor->mounts, (GCopyFunc) udisks_g_object_ref_copy, NULL);
g_mutex_unlock (&monitor->mounts_mutex);

/* Sort the list to ensure that shortest mount paths appear first */
ret = g_list_sort (ret, (GCompareFunc) udisks_mount_compare);

return ret;
}

/**
* udisks_mount_monitor_get_mounts_for_dev:
* @monitor: A #UDisksMountMonitor.
Expand Down
1 change: 1 addition & 0 deletions src/udisksmountmonitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ G_BEGIN_DECLS

GType udisks_mount_monitor_get_type (void) G_GNUC_CONST;
UDisksMountMonitor *udisks_mount_monitor_new (void);
GList *udisks_mount_monitor_get_mounts (UDisksMountMonitor *monitor);
GList *udisks_mount_monitor_get_mounts_for_dev (UDisksMountMonitor *monitor,
dev_t dev);
gboolean udisks_mount_monitor_is_dev_in_use (UDisksMountMonitor *monitor,
Expand Down
49 changes: 44 additions & 5 deletions src/udisksstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,42 @@ lookup_asv (GVariant *asv,

/* ---------------------------------------------------------------------------------------------------- */

/**
* udisks_mount_monitor_get_mounts_for_dev:
* @mounts: A #UDisksMount.
* @dev: A #dev_t device number.
*
* Gets all #UDisksMount objects for @dev.
*
* Returns: A #GList of #UDisksMount objects. The returned list must
* be freed with g_list_free() after each element has been freed with
* g_object_unref().
*/
static GList *
udisks_state_get_mounts_for_dev (GList *mounts,
dev_t dev)
{
GList *ret;
GList *l;

ret = NULL;

for (l = mounts; l != NULL; l = l->next)
{
UDisksMount *mount = UDISKS_MOUNT (l->data);

if (udisks_mount_get_dev (mount) == dev)
{
ret = g_list_prepend (ret, g_object_ref (mount));
}
}

/* Sort the list to ensure that shortest mount paths appear first */
ret = g_list_sort (ret, (GCompareFunc) udisks_mount_compare);

return ret;
}

/* returns TRUE if the entry should be kept */
static gboolean
udisks_state_check_mounted_fs_entry (UDisksState *state,
Expand All @@ -590,7 +626,6 @@ udisks_state_check_mounted_fs_entry (UDisksState *state,
gboolean is_mounted;
gboolean device_exists;
gboolean device_to_be_cleaned;
UDisksMountMonitor *monitor;
GUdevClient *udev_client;
GUdevDevice *udev_device;
guint n;
Expand All @@ -608,8 +643,6 @@ udisks_state_check_mounted_fs_entry (UDisksState *state,
details = NULL;
locked = FALSE;

monitor = udisks_daemon_get_mount_monitor (state->daemon);

g_variant_get (value,
"{&s@a{sv}}",
&mount_point_str,
Expand Down Expand Up @@ -668,7 +701,7 @@ udisks_state_check_mounted_fs_entry (UDisksState *state,
/* udisks_debug ("Validating mounted-fs entry for mount point %s", mount_point); */

/* Figure out if still mounted */
mounts = udisks_mount_monitor_get_mounts_for_dev (monitor, block_device);
mounts = udisks_state_get_mounts_for_dev (monitor_mounts, block_device);
for (l = mounts; l != NULL; l = l->next)
{
UDisksMount *mount = UDISKS_MOUNT (l->data);
Expand Down Expand Up @@ -870,15 +903,21 @@ udisks_state_check_mounted_fs (UDisksState *state,
{
GVariantIter iter;
GVariant *child;
GList *mounts;
UDisksMountMonitor *monitor;

monitor = udisks_daemon_get_mount_monitor (state->daemon);
mounts = udisks_mount_monitor_get_mounts(monitor);
g_variant_iter_init (&iter, value);
while ((child = g_variant_iter_next_value (&iter)) != NULL)
{
if (udisks_state_check_mounted_fs_entry (state, child, devs_to_clean, match_block_device))
if (udisks_state_check_mounted_fs_entry (state, child, devs_to_clean, match_block_device, mounts))
g_variant_builder_add_value (&builder, child);
else
changed = TRUE;
g_variant_unref (child);
}
g_list_free_full (mounts, g_object_unref);
g_variant_unref (value);
}

Expand Down

0 comments on commit a93476a

Please sign in to comment.