Skip to content
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
1 change: 1 addition & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ libudisks_daemon_la_SOURCES =
udisksthreadedjob.h udisksthreadedjob.c \
udiskssimplejob.h udiskssimplejob.c \
udisksmount.h udisksmount.c \
udisksmountutil.h \
udisksmountmonitor.h udisksmountmonitor.c \
udisksdaemonutil.h udisksdaemonutil.c \
udiskslogging.h udiskslogging.c \
Expand Down
43 changes: 3 additions & 40 deletions src/udisksmountmonitor.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#include "udiskslogging.h"
#include "udisksmountmonitor.h"
#include "udisksmount.h"
#include "udisksmountutil.h"
#include "udisksprivate.h"
#include "udisksdaemonutil.h"

Expand Down Expand Up @@ -510,46 +511,8 @@ udisks_mount_monitor_parse_mountinfo (UDisksMountMonitor *monitor,
*/
if (major == 0)
{
const gchar *sep;
sep = strstr (lines[n], " - ");
if (sep != NULL)
{
gchar fstype[PATH_MAX + 1];
gchar mount_source[PATH_MAX + 1];
struct stat statbuf;

if (sscanf (sep + 3, PATH_MAX_FMT " " PATH_MAX_FMT, fstype, mount_source) != 2)
{
udisks_warning ("Error parsing things past - for '%s'", lines[n]);
continue;
}
fstype[sizeof fstype - 1] = '\0';
mount_source[sizeof mount_source - 1] = '\0';

if (g_strcmp0 (fstype, "btrfs") != 0)
continue;

if (!g_str_has_prefix (mount_source, "/dev/"))
continue;

if (stat (mount_source, &statbuf) != 0)
{
udisks_warning ("Error statting %s: %m", mount_source);
continue;
}

if (!S_ISBLK (statbuf.st_mode))
{
udisks_warning ("%s is not a block device", mount_source);
continue;
}

dev = statbuf.st_rdev;
}
else
{
continue;
}
if (!udisks_mount_util_get_btrfs_device_from_mountinfo (lines[n], &dev))
continue;
}
else
{
Expand Down
72 changes: 72 additions & 0 deletions src/udisksmountutil.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright (C) 2026 Wang Yu <wangyu@uniontech.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/

#ifndef __UDISKS_MOUNT_UTIL_H__
#define __UDISKS_MOUNT_UTIL_H__

#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>

#include <glib.h>

#define UDISKS_MOUNT_UTIL_XSTR(s) UDISKS_MOUNT_UTIL_STR(s)
#define UDISKS_MOUNT_UTIL_STR(s) #s
#define UDISKS_MOUNT_UTIL_PATH_MAX_FMT "%" UDISKS_MOUNT_UTIL_XSTR(PATH_MAX) "s"

static gboolean
udisks_mount_util_get_btrfs_device_from_mountinfo (const gchar *line,
dev_t *block_device)
{
const gchar *sep;
gchar fstype[PATH_MAX + 1];
gchar mount_source[PATH_MAX + 1];
struct stat statbuf;

sep = strstr (line, " - ");
if (sep == NULL)
return FALSE;

if (sscanf (sep + 3,
UDISKS_MOUNT_UTIL_PATH_MAX_FMT " " UDISKS_MOUNT_UTIL_PATH_MAX_FMT,
fstype,
mount_source) != 2)
return FALSE;

fstype[sizeof fstype - 1] = '\0';
mount_source[sizeof mount_source - 1] = '\0';

if (g_strcmp0 (fstype, "btrfs") != 0 ||
!g_str_has_prefix (mount_source, "/dev/") ||
stat (mount_source, &statbuf) != 0 ||
!S_ISBLK (statbuf.st_mode))
return FALSE;

*block_device = statbuf.st_rdev;
return TRUE;
}

#undef UDISKS_MOUNT_UTIL_PATH_MAX_FMT
#undef UDISKS_MOUNT_UTIL_STR
#undef UDISKS_MOUNT_UTIL_XSTR

#endif /* __UDISKS_MOUNT_UTIL_H__ */
1 change: 1 addition & 0 deletions tools/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ sbin_PROGRAMS = umount.udisks2

umount_udisks2_SOURCES = \
umount-udisks.c \
$(top_srcdir)/src/udisksmountutil.h \
$(NULL)

umount_udisks2_CFLAGS = \
Expand Down
53 changes: 52 additions & 1 deletion tools/umount-udisks.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,60 @@
#include <sys/sysmacros.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>

#include <udisks/udisks.h>

#include "src/udisksmountutil.h"

#define xstr(s) str(s)
#define str(s) #s
#define PATH_MAX_FMT "%" xstr(PATH_MAX) "s"
#define PATH_MAX_SKIP_FMT "%*" xstr(PATH_MAX) "s"

static gboolean
lookup_block_device_for_mount_point (const gchar *mount_point,
dev_t *block_device)
{
gchar *contents = NULL;
gchar **lines = NULL;
guint n;
gboolean ret = FALSE;

if (!g_file_get_contents ("/proc/self/mountinfo", &contents, NULL, NULL))
return FALSE;

lines = g_strsplit (contents, "\n", 0);
for (n = 0; lines[n] != NULL; n++)
{
gchar encoded_mount_point[PATH_MAX + 1];
gchar *decoded_mount_point;

if (strlen (lines[n]) == 0)
continue;

if (sscanf (lines[n],
"%*u %*u %*u:%*u " PATH_MAX_SKIP_FMT " " PATH_MAX_FMT,
encoded_mount_point) != 1)
continue;

encoded_mount_point[sizeof encoded_mount_point - 1] = '\0';
decoded_mount_point = g_strcompress (encoded_mount_point);

if (g_strcmp0 (decoded_mount_point, mount_point) == 0)
ret = udisks_mount_util_get_btrfs_device_from_mountinfo (lines[n], block_device);

g_free (decoded_mount_point);

if (ret)
break;
}

g_strfreev (lines);
g_free (contents);
return ret;
}

static UDisksObject *
lookup_object_for_block (UDisksClient *client,
dev_t block_device)
Expand Down Expand Up @@ -94,7 +145,7 @@ main (int argc, char *argv[])

if (S_ISBLK (statbuf.st_mode))
block_device = statbuf.st_rdev;
else
else if (!lookup_block_device_for_mount_point (argv[1], &block_device))
block_device = statbuf.st_dev;

error = NULL;
Expand Down