Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the problem that btrfs multi-partition cannot be unmounted #976

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
52 changes: 46 additions & 6 deletions src/udisksstate.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,12 +569,49 @@ lookup_asv (GVariant *asv,

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

/**
* udisks_state_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,
GVariant *value,
GArray *devs_to_clean,
dev_t match_block_device)
dev_t match_block_device,
GList *monitor_mounts)
{
const gchar *mount_point_str;
gchar mount_point[PATH_MAX] = { '\0', };
Expand All @@ -590,7 +627,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 +644,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 +702,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 +904,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