Accepting request 1117492 from home:tsaupe:branches:Base:System:udisks2-boo1216055

fix mount failure on ntfs formatted usb disks (bsc#1216055)

OBS-URL: https://build.opensuse.org/request/show/1117492
OBS-URL: https://build.opensuse.org/package/show/Base:System/udisks2?expand=0&rev=103
This commit is contained in:
Bjørn Lie 2023-10-12 17:11:58 +00:00 committed by Git OBS Bridge
parent e01612e541
commit 288938bc91
7 changed files with 419 additions and 0 deletions

View File

@ -0,0 +1,35 @@
From fee9a3a50c3d4f687ed0c310096b1cd0e21f8923 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Tue, 22 Aug 2023 14:33:07 +0200
Subject: [PATCH] doc: Clarify the Filesystem.Size property presence
We've done many tweaks and introduced limits to some
filesystem types, let's document that.
---
data/org.freedesktop.UDisks2.xml | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/data/org.freedesktop.UDisks2.xml b/data/org.freedesktop.UDisks2.xml
index bfa6e660..53194c70 100644
--- a/data/org.freedesktop.UDisks2.xml
+++ b/data/org.freedesktop.UDisks2.xml
@@ -2715,11 +2715,12 @@
</method>
<!-- Size: The size of the filesystem. This is the amount of
- bytes used on the block device. If this is smaller than
- org.freedesktop.Udisks2.Block.Size, then the filesystem can
- be made larger with Resize.
+ bytes used on the block device representing an outer filesystem
+ boundary. If this is smaller than org.freedesktop.Udisks2.Block.Size,
+ then the filesystem can be made larger with Resize.
- If the size is unknown, the property is zero.
+ If the size is unknown, the property is zero. Currently limited
+ to xfs and ext filesystems only.
Please note that reading value of this property typically causes
some I/O to read the filesystem superblock. Unlike the rest
--
2.42.0

View File

@ -0,0 +1,111 @@
From c73288f465107567d91be2658a68c61e5f3f5a16 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Tue, 22 Aug 2023 14:19:05 +0200
Subject: [PATCH] tests: Add offline and online filesystem grow tests
---
src/tests/dbus-tests/test_80_filesystem.py | 81 +++++++++++++++++++++-
1 file changed, 80 insertions(+), 1 deletion(-)
diff --git a/src/tests/dbus-tests/test_80_filesystem.py b/src/tests/dbus-tests/test_80_filesystem.py
index 59946720..87d63922 100644
--- a/src/tests/dbus-tests/test_80_filesystem.py
+++ b/src/tests/dbus-tests/test_80_filesystem.py
@@ -314,7 +314,7 @@ class UdisksFSTestCase(udiskstestcase.UdisksTestCase):
rpr, _ = manager.CanRepair(self._fs_signature)
except:
rpr = chk = rep = False
- if not (rpr and chk and rep) or mode & (1 << 1) == 0:
+ if not (rpr and chk and rep) or mode & BlockDev.FSResizeFlags.OFFLINE_SHRINK == 0:
self.skipTest('Cannot check, offline-shrink and repair %s filesystem' % self._fs_signature)
disk = self.get_object('/block_devices/' + os.path.basename(self.vdevs[0]))
@@ -344,6 +344,85 @@ class UdisksFSTestCase(udiskstestcase.UdisksTestCase):
self.assertTrue(block_fs.Check(self.no_options, dbus_interface=self.iface_prefix + '.Filesystem'))
self.get_property(block_fs, '.Filesystem', 'Size').assertAlmostEqual(size // 2, delta=1024**2)
+ def _test_grow(self, online):
+ TMP_SIZE_1 = 500 * 1024**2
+ TMP_SIZE_2 = 2 * TMP_SIZE_1
+
+ self._check_can_create()
+
+ if not self._can_mount:
+ self.skipTest('Cannot mount %s filesystem' % self._fs_signature)
+
+ if not self._can_query_size:
+ self.skipTest('Cannot determine size of %s filesystem' % self._fs_signature)
+
+ manager = self.get_interface(self.get_object('/Manager'), '.Manager')
+ try:
+ res, mode, _ = manager.CanResize(self._fs_signature)
+ except:
+ res = False
+ mode = 0
+ if not res:
+ self.skipTest('Cannot resize %s filesystem' % self._fs_signature)
+ if online and mode & BlockDev.FSResizeFlags.ONLINE_GROW == 0:
+ self.skipTest('Cannot online-grow %s filesystem' % self._fs_signature)
+ if not online and mode & BlockDev.FSResizeFlags.OFFLINE_GROW == 0:
+ self.skipTest('Cannot offline-grow %s filesystem' % self._fs_signature)
+
+ with tempfile.NamedTemporaryFile(prefix="udisks_test", delete=True, mode='w+b') as temp:
+ temp.truncate(TMP_SIZE_1)
+ loop_dev_obj_path = manager.LoopSetup(temp.fileno(), self.no_options)
+ loop_dev_obj = self.get_object(loop_dev_obj_path)
+ _, loop_dev = loop_dev_obj_path.rsplit("/", 1)
+ self.addCleanup(self.run_command, 'losetup --detach /dev/%s' % loop_dev)
+
+ # check the initial size
+ bsize = self.get_property(loop_dev_obj, '.Block', 'Size')
+ bsize.assertEqual(TMP_SIZE_1)
+
+ # create filesystem
+ loop_dev_obj.Format(self._fs_signature, self.no_options, dbus_interface=self.iface_prefix + '.Block')
+ fssize = self.get_property(loop_dev_obj, '.Filesystem', 'Size')
+ fssize.assertAlmostEqual(TMP_SIZE_1, delta=1024**2)
+
+ # not mounted
+ mounts = self.get_property(loop_dev_obj, '.Filesystem', 'MountPoints')
+ mounts.assertLen(0)
+
+ # mount it
+ if online:
+ d = dbus.Dictionary(signature='sv')
+ if self._fs_name:
+ d['fstype'] = self._fs_name
+ mnt_path = loop_dev_obj.Mount(d, dbus_interface=self.iface_prefix + '.Filesystem')
+ self.addCleanup(self.try_unmount, mnt_path)
+ self.addCleanup(self.try_unmount, '/dev/%s' % loop_dev)
+
+ # resize the loop device
+ temp.truncate(TMP_SIZE_2)
+ self.run_command('losetup -c /dev/%s' % loop_dev)
+ time.sleep(2)
+ bsize = self.get_property(loop_dev_obj, '.Block', 'Size')
+ bsize.assertEqual(TMP_SIZE_2)
+ fssize = self.get_property(loop_dev_obj, '.Filesystem', 'Size')
+ fssize.assertAlmostEqual(TMP_SIZE_1, delta=1024**2)
+
+ # perform the grow
+ loop_dev_obj.Resize(dbus.UInt64(TMP_SIZE_2), self.no_options, dbus_interface=self.iface_prefix + '.Filesystem')
+ fssize = self.get_property(loop_dev_obj, '.Filesystem', 'Size')
+ fssize.assertAlmostEqual(TMP_SIZE_2, delta=1024**2)
+
+ # unmount
+ if online:
+ loop_dev_obj.Unmount(self.no_options, dbus_interface=self.iface_prefix + '.Filesystem')
+ self.assertFalse(os.path.ismount(mnt_path))
+
+ def test_online_grow(self):
+ self._test_grow(True)
+
+ def test_offline_grow(self):
+ self._test_grow(True)
+
def test_size(self):
self._check_can_create()
--
2.42.0

View File

@ -0,0 +1,38 @@
From bb45fda15f2a5c2063d76db4d2a6dcafaffa9ad1 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Tue, 22 Aug 2023 14:31:50 +0200
Subject: [PATCH] tests: Mark UDF fstab filesystem tests as unstable
Protective part table involved, duplicate identifiers leading
to random match each time. Until we have a proper fix, just
mark them as unstable.
---
src/tests/dbus-tests/test_80_filesystem.py | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/src/tests/dbus-tests/test_80_filesystem.py b/src/tests/dbus-tests/test_80_filesystem.py
index 87d63922..18c8011d 100644
--- a/src/tests/dbus-tests/test_80_filesystem.py
+++ b/src/tests/dbus-tests/test_80_filesystem.py
@@ -1758,6 +1758,18 @@ class UDFTestCase(UdisksFSTestCase):
def _gen_uuid(self):
return str.format("%016x" % random.randint(0, 0xffffffffffffffff))
+ @udiskstestcase.tag_test(udiskstestcase.TestTags.UNSTABLE)
+ def test_mount_fstab_complex_label(self):
+ super(UDFTestCase, self).test_mount_fstab_complex_label()
+
+ @udiskstestcase.tag_test(udiskstestcase.TestTags.UNSTABLE)
+ def test_mount_fstab_complex_label2(self):
+ super(UDFTestCase, self).test_mount_fstab_complex_label2()
+
+ @udiskstestcase.tag_test(udiskstestcase.TestTags.UNSTABLE)
+ def test_mount_fstab_complex_label_bad(self):
+ super(UDFTestCase, self).test_mount_fstab_complex_label_bad()
+
class FailsystemTestCase(UdisksFSTestCase):
# test that not supported operations fail 'nicely'
--
2.42.0

View File

@ -0,0 +1,65 @@
From bb54e1898e6c3569ca8d32dc1c9ca5e39e86875a Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Fri, 4 Aug 2023 17:53:18 +0200
Subject: [PATCH] udiskslinuxfilesystem: Force native tools for mounted XFS fs
size retrieval
Just another quirk discovered by Cockpit tests. Looks like
the superblock gets written on-disk at some later point while
the mounted filesystem structures keep the new geometry in-memory.
This is an obvious limitation of blkid that only reads data
from the block device.
---
src/udiskslinuxfilesystem.c | 22 +++++++++++++++-------
1 file changed, 15 insertions(+), 7 deletions(-)
diff --git a/src/udiskslinuxfilesystem.c b/src/udiskslinuxfilesystem.c
index 9bfda895..9f4880ad 100644
--- a/src/udiskslinuxfilesystem.c
+++ b/src/udiskslinuxfilesystem.c
@@ -352,6 +352,7 @@ udisks_linux_filesystem_update (UDisksLinuxFilesystem *filesystem,
GPtrArray *p;
GList *mounts;
GList *l;
+ gboolean mounted;
mount_monitor = udisks_daemon_get_mount_monitor (udisks_linux_block_object_get_daemon (object));
device = udisks_linux_block_object_get_device (object);
@@ -370,6 +371,7 @@ udisks_linux_filesystem_update (UDisksLinuxFilesystem *filesystem,
g_ptr_array_add (p, NULL);
udisks_filesystem_set_mount_points (UDISKS_FILESYSTEM (filesystem),
(const gchar *const *) p->pdata);
+ mounted = p->len > 0;
g_ptr_array_free (p, TRUE);
g_list_free_full (mounts, g_object_unref);
@@ -389,13 +391,19 @@ udisks_linux_filesystem_update (UDisksLinuxFilesystem *filesystem,
g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (filesystem));
- /* The ID_FS_SIZE property only contains data part of the total filesystem
- * size while 'ID_FS_LASTBLOCK * ID_FS_BLOCKSIZE' typically marks the size
- * boundary of the filesystem. This is the approach of libblockdev fs size
- * reporting.
- */
- filesystem->cached_fs_size = g_udev_device_get_property_as_uint64 (device->udev_device, "ID_FS_LASTBLOCK") *
- g_udev_device_get_property_as_uint64 (device->udev_device, "ID_FS_BLOCKSIZE");
+ if (mounted && g_strcmp0 (filesystem->cached_fs_type, "xfs") == 0)
+ /* Force native filesystem tools for mounted XFS as superblock might
+ * not have been written right after the grow.
+ */
+ filesystem->cached_fs_size = 0;
+ else
+ /* The ID_FS_SIZE property only contains data part of the total filesystem
+ * size and comes with no guarantees while 'ID_FS_LASTBLOCK * ID_FS_BLOCKSIZE'
+ * typically marks the boundary of the filesystem.
+ */
+ filesystem->cached_fs_size = g_udev_device_get_property_as_uint64 (device->udev_device, "ID_FS_LASTBLOCK") *
+ g_udev_device_get_property_as_uint64 (device->udev_device, "ID_FS_BLOCKSIZE");
+
/* The Size property is hacked to be retrieved on-demand, only need to
* notify subscribers that it has changed.
*/
--
2.42.0

View File

@ -0,0 +1,154 @@
From 4a06a6ee126751af3a7ab9fc33721a904adb6850 Mon Sep 17 00:00:00 2001
From: Tomas Bzatek <tbzatek@redhat.com>
Date: Fri, 4 Aug 2023 17:48:41 +0200
Subject: [PATCH] udiskslinuxfilesystem: Refactor internal whitelists
(cherry picked from commit eb7e79e0b7e5f284809965b21c96b6451662c544)
---
src/udiskslinuxfilesystem.c | 100 +++++++++++++++++++++---------------
1 file changed, 58 insertions(+), 42 deletions(-)
diff --git a/src/udiskslinuxfilesystem.c b/src/udiskslinuxfilesystem.c
index f2e5eb60..9bfda895 100644
--- a/src/udiskslinuxfilesystem.c
+++ b/src/udiskslinuxfilesystem.c
@@ -109,6 +109,45 @@ G_DEFINE_TYPE_WITH_CODE (UDisksLinuxFilesystem, udisks_linux_filesystem, UDISKS_
#define MOUNT_BASE_PERSISTENT FALSE
#endif
+/* required for kernel module autoloading */
+static const gchar *well_known_filesystems[] =
+{
+ "bcache",
+ "bcachefs",
+ "btrfs",
+ "erofs",
+ "exfat",
+ "ext2",
+ "ext3",
+ "ext4",
+ "f2fs",
+ "hfs",
+ "hfsplus",
+ "iso9660",
+ "jfs",
+ "msdos",
+ "nilfs",
+ "nilfs2",
+ "ntfs",
+ "ntfs3",
+ "udf",
+ "reiserfs",
+ "reiser4",
+ "reiser5",
+ "umsdos",
+ "vfat",
+ "xfs",
+};
+
+/* filesystems known to report their outer boundaries */
+static const gchar *fs_lastblock_list[] =
+{
+ "ext2",
+ "ext3",
+ "ext4",
+ "xfs",
+};
+
/* ---------------------------------------------------------------------------------------------------- */
static void
@@ -199,6 +238,17 @@ udisks_linux_filesystem_new (void)
/* ---------------------------------------------------------------------------------------------------- */
+static gboolean
+in_fs_lastblock_list (const gchar *fstype)
+{
+ guint n;
+
+ for (n = 0; n < G_N_ELEMENTS (fs_lastblock_list); n++)
+ if (g_strcmp0 (fs_lastblock_list[n], fstype) == 0)
+ return TRUE;
+ return FALSE;
+}
+
/* WARNING: called with GDBusObjectManager lock held, avoid any object lookup */
static guint64
get_filesystem_size (UDisksLinuxFilesystem *filesystem)
@@ -211,6 +261,10 @@ get_filesystem_size (UDisksLinuxFilesystem *filesystem)
if (!filesystem->cached_device_file || !filesystem->cached_fs_type)
return 0;
+ /* manually getting size is supported only for Ext and XFS */
+ if (!in_fs_lastblock_list (filesystem->cached_fs_type))
+ return 0;
+
/* if the drive is ATA and is sleeping, skip filesystem size check to prevent
* drive waking up - nothing has changed anyway since it's been sleeping...
*/
@@ -352,37 +406,6 @@ udisks_linux_filesystem_update (UDisksLinuxFilesystem *filesystem,
/* ---------------------------------------------------------------------------------------------------- */
-/* required for kernel module autoloading */
-static const gchar *well_known_filesystems[] =
-{
- "bcache",
- "bcachefs",
- "btrfs",
- "erofs",
- "exfat",
- "ext2",
- "ext3",
- "ext4",
- "f2fs",
- "hfs",
- "hfsplus",
- "iso9660",
- "jfs",
- "msdos",
- "nilfs",
- "nilfs2",
- "ntfs",
- "ntfs3",
- "udf",
- "reiserfs",
- "reiser4",
- "reiser5",
- "umsdos",
- "vfat",
- "xfs",
- NULL,
-};
-
static gboolean
is_in_filesystem_file (const gchar *filesystems_file,
const gchar *fstype)
@@ -432,19 +455,12 @@ is_in_filesystem_file (const gchar *filesystems_file,
static gboolean
is_well_known_filesystem (const gchar *fstype)
{
- gboolean ret = FALSE;
guint n;
- for (n = 0; well_known_filesystems[n] != NULL; n++)
- {
- if (g_strcmp0 (well_known_filesystems[n], fstype) == 0)
- {
- ret = TRUE;
- goto out;
- }
- }
- out:
- return ret;
+ for (n = 0; n < G_N_ELEMENTS (well_known_filesystems); n++)
+ if (g_strcmp0 (well_known_filesystems[n], fstype) == 0)
+ return TRUE;
+ return FALSE;
}
/* this is not a very efficient implementation but it's very rarely
--
2.42.0

View File

@ -1,3 +1,14 @@
-------------------------------------------------------------------
Wed Oct 11 15:37:37 UTC 2023 - Thomas Blume <thomas.blume@suse.com>
- fix mount failure on ntfs formatted usb disks (bsc#1216055)
* add:
0001-doc-Clarify-the-Filesystem.Size-property-presence.patch
0001-tests-Mark-UDF-fstab-filesystem-tests-as-unstable.patch
0001-udiskslinuxfilesystem-Refactor-internal-whitelists.patch
0001-tests-Add-offline-and-online-filesystem-grow-tests.patch
0001-udiskslinuxfilesystem-Force-native-tools-for-mounted.patch
-------------------------------------------------------------------
Tue Aug 29 20:28:56 UTC 2023 - Luciano Santos <luc14n0@opensuse.org>

View File

@ -34,6 +34,11 @@ Source0: %{url}/releases/download/udisks-%{version}/udisks-%{version}.tar
# an exception will be silently removed with the next version update.
Patch0: harden_udisks2.service.patch
Patch1: 0001-doc-Clarify-the-Filesystem.Size-property-presence.patch
Patch2: 0001-tests-Mark-UDF-fstab-filesystem-tests-as-unstable.patch
Patch3: 0001-udiskslinuxfilesystem-Refactor-internal-whitelists.patch
Patch4: 0001-tests-Add-offline-and-online-filesystem-grow-tests.patch
Patch5: 0001-udiskslinuxfilesystem-Force-native-tools-for-mounted.patch
BuildRequires: chrpath
BuildRequires: docbook-xsl-stylesheets