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
This commit is contained in:
Mike Fleetwood 2018-09-19 15:31:46 +01:00 committed by Curtis Gedak
parent f8512506ae
commit 39d3cd97c2
1 changed files with 1 additions and 1 deletions

View File

@ -169,7 +169,7 @@ void Mount_Info::add_mountpoint_entry( MountMapping & map,
{ {
// Map::operator[] default constructs MountEntry for new keys (nodes). // Map::operator[] default constructs MountEntry for new keys (nodes).
MountEntry & mountentry = map[BlockSpecial( node )]; MountEntry & mountentry = map[BlockSpecial( node )];
mountentry.readonly = readonly; mountentry.readonly = mountentry.readonly || readonly;
mountentry.mountpoints.push_back( mountpoint ); mountentry.mountpoints.push_back( mountpoint );
} }
} }