From c1c6adb8dc3b1fc2fb034afc930ba4f7aa012932 Mon Sep 17 00:00:00 2001 From: Jelle van der Waa Date: Fri, 17 Nov 2023 18:21:10 +0100 Subject: [PATCH] modules/btrfs: add GetDefaultSubvolumeID libblockdev provides a method to get the default subvolume id since 2014, with no way to change it. This method does not require any administrative privileges but requires it for setting. --- .../data/org.freedesktop.UDisks2.btrfs.xml | 14 ++++++ modules/btrfs/udiskslinuxfilesystembtrfs.c | 46 +++++++++++++++++++ src/tests/dbus-tests/test_btrfs.py | 18 ++++++++ 3 files changed, 78 insertions(+) diff --git a/modules/btrfs/data/org.freedesktop.UDisks2.btrfs.xml b/modules/btrfs/data/org.freedesktop.UDisks2.btrfs.xml index e2b01e21cf..3858868635 100644 --- a/modules/btrfs/data/org.freedesktop.UDisks2.btrfs.xml +++ b/modules/btrfs/data/org.freedesktop.UDisks2.btrfs.xml @@ -219,6 +219,20 @@ + + + + + + diff --git a/modules/btrfs/udiskslinuxfilesystembtrfs.c b/modules/btrfs/udiskslinuxfilesystembtrfs.c index ba3e4f105c..82e404f553 100644 --- a/modules/btrfs/udiskslinuxfilesystembtrfs.c +++ b/modules/btrfs/udiskslinuxfilesystembtrfs.c @@ -660,6 +660,51 @@ handle_get_subvolumes (UDisksFilesystemBTRFS *fs_btrfs, return TRUE; } +static gboolean +handle_get_default_subvolume_id (UDisksFilesystemBTRFS *fs_btrfs, + GDBusMethodInvocation *invocation, + GVariant *arg_options) +{ + UDisksLinuxFilesystemBTRFS *l_fs_btrfs = UDISKS_LINUX_FILESYSTEM_BTRFS (fs_btrfs); + UDisksLinuxBlockObject *object = NULL; + GError *error = NULL; + gchar *mount_point = NULL; + guint64 default_id; + + object = udisks_daemon_util_dup_object (l_fs_btrfs, &error); + if (! object) + { + g_dbus_method_invocation_take_error (invocation, error); + goto out; + } + + /* Get the mount point for this volume. */ + mount_point = udisks_filesystem_btrfs_get_first_mount_point (fs_btrfs, &error); + if (! mount_point) + { + g_dbus_method_invocation_take_error (invocation, error); + goto out; + } + + default_id = bd_btrfs_get_default_subvolume_id (mount_point, &error); + if (! default_id && error) + { + g_dbus_method_invocation_take_error (invocation, error); + goto out; + } + + /* Complete DBus call. */ + udisks_filesystem_btrfs_complete_get_default_subvolume_id (fs_btrfs, invocation, default_id); + +out: + /* Release the resources */ + g_clear_object (&object); + g_free (mount_point); + + /* Indicate that we handled the method invocation */ + return TRUE; +} + static gboolean handle_create_snapshot (UDisksFilesystemBTRFS *fs_btrfs, GDBusMethodInvocation *invocation, @@ -849,6 +894,7 @@ udisks_linux_filesystem_btrfs_iface_init (UDisksFilesystemBTRFSIface *iface) iface->handle_create_subvolume = handle_create_subvolume; iface->handle_remove_subvolume = handle_remove_subvolume; iface->handle_get_subvolumes = handle_get_subvolumes; + iface->handle_get_default_subvolume_id = handle_get_default_subvolume_id; iface->handle_create_snapshot = handle_create_snapshot; iface->handle_repair = handle_repair; iface->handle_resize = handle_resize; diff --git a/src/tests/dbus-tests/test_btrfs.py b/src/tests/dbus-tests/test_btrfs.py index af991202a7..5e179c82fb 100644 --- a/src/tests/dbus-tests/test_btrfs.py +++ b/src/tests/dbus-tests/test_btrfs.py @@ -381,3 +381,21 @@ def test_subvolume_mount(self): dbus_mounts.assertLen(1) # just one mountpoint dbus_mnt = self.ay_to_str(dbus_mounts.value[0]) # mountpoints are arrays of bytes self.assertEqual(dbus_mnt, mnt_path) + + def test_get_default_subvolume_id(self): + dev = self._get_devices(1)[0] + self.addCleanup(self._clean_format, dev.obj) + + manager = self.get_object('/Manager') + manager.CreateVolume([dev.obj_path], + 'test_subvolume_id', 'single', 'single', + self.no_options, + dbus_interface=self.iface_prefix + '.Manager.BTRFS') + + fstype = self.get_property(dev.obj, '.Block', 'IdType') + fstype.assertEqual('btrfs') + + with self._temp_mount(dev.path): + default_id = dev.obj.GetDefaultSubvolumeID(self.no_options, + dbus_interface=self.iface_prefix + '.Filesystem.BTRFS') + self.assertEqual(default_id, 5)