[gparted/ro-mount] Disallow resizing btrfs if any of it's mount points are read-only (#10)



commit 1153b045559b72eaca21f1a2bbdc7a36d7064477
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Wed Sep 19 15:31:46 2018 +0100

    Disallow resizing btrfs if any of it's mount points are read-only (#10)
    
    No other file system allows this, but btrfs allows simultaneous mounting
    with different read-write permission.  Further, btrfs allows resizing
    via read-write mounts, but not via read-only mounts.
    
        # mkfs.btrfs /dev/sdb1
        btrfs-progs v4.15.1
        ...
        Filesystem size:    512.00MiB
        ...
        Number of devices:  1
        Devices:
           ID        SIZE  PATH
            1   512.00MiB  /dev/sdb1
    
        # mount -o ro /dev/sdb1 /mnt/1
        # mount -o rw /dev/sdb1 /mnt/2
        # grep sdb1 /proc/mounts
        /dev/sdb1 /mnt/1 btrfs ro,relatime,space_cache,subvolid=5,subvol=/ 0 0
        /dev/sdb1 /mnt/2 btrfs rw,relatime,space_cache,subvolid=5,subvol=/ 0 0
    
        # btrfs filesystem resize 1:500M /mnt/1
        Resize '/mnt/1' of '1:500M'
        ERROR: unable to resize '/mnt/1': Read-only file system
        # echo $?
        1
    
        # btrfs file system resize 1:500M /mnt/2
        Resize '/mnt/2' of '1:500M'
        # echo $?
        0
        # btrfs filesystem show /dev/sdb1
        Label: none  uuid: 74ccd37a-e665-4f25-b77e-a305b8a025e9
                Total devices 1 FS bytes used 128.00KiB
                devid    1 size 500.00MiB used 88.00MiB path /dev/sdb1
    
    Also with the above order of the read-only mount listed in /proc/mounts
    first and the read-write mount second, GParted again allows a resize
    operational to be tried, but if fails just like before:
    
        Grow /dev/sdb1 from 512.00 MiB to 1.0 GiB                  (ERROR)
        * calibrate /dev/sdb1                                      (SUCCESS)
        * grow partition from 512.00 MiB to 1.00 GiB               (SUCCESS)
        * grow filesystem to fill the partition                    (ERROR)
          * btrfs filesystem resize 1:max '/mnt/1'                 (ERROR)
              Resize '/mnt/1 to '1:max'
              ERROR: unable to resize '/mnt/1': Read-only file system
    
    What happened is that the Mount_Info module only stores single read-only
    flag against the mounted block device, not for each mount point, and as
    the first and second sdb1 lines from /proc/mounts were processed, the
    MountEntry became:
    
      1st)   mount_info[BS("/dev/sdb1")] -> {true , ["/mnt/1"]
      2nd)   mount_info[BS("/dev/sdb1")] -> {false, ["/mnt/1", "/mnt/2"]
    
    So GParted thought the file system was mounted read-write, but used the
    first mount point, /mnt/1, which was mounted read-only.
    
    This is a very unusual situation so unlikely to be encountered by users.
    Fix simply and safely by treating the mounted block device as mounted
    read-only if any of the mount points are mounted read-only, rather than
    just the last processed mount point.
    
    Closes #10 - Gparted fails to resize btrfs partition that is mounted
                 read-only

 src/Mount_Info.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
---
diff --git a/src/Mount_Info.cc b/src/Mount_Info.cc
index 0981c5e6..09936c57 100644
--- a/src/Mount_Info.cc
+++ b/src/Mount_Info.cc
@@ -169,7 +169,7 @@ void Mount_Info::add_mountpoint_entry( MountMapping & map,
        {
                // Map::operator[] default constructs MountEntry for new keys (nodes).
                MountEntry & mountentry = map[BlockSpecial( node )];
-               mountentry.readonly = readonly;
+               mountentry.readonly = mountentry.readonly || readonly;
                mountentry.mountpoints.push_back( mountpoint );
        }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]