1
0
mirror of https://gitlab.gnome.org/GNOME/gparted synced 2024-07-02 15:58:47 +00:00

Compare commits

..

14 Commits

Author SHA1 Message Date
Mike Fleetwood
f45f560368 Merge branch 'bcachefs-single' into 'master'
Add support for bcachefs, single device file systems only

See merge request GNOME/gparted!123
2024-04-12 21:03:43 +00:00
Mike Fleetwood
3d36d7ed2b While space tidy-up of Utils::get_filesystem_maxlength()
Use smart tab alignment; indent with tabs and align with spaces.  Also
remove entries for lvm2 pv and minix which don't support labels, adding
a comment as to why.
2024-04-12 21:42:37 +01:00
Mike Fleetwood
3ebeadf050 Use Glib::build_path() to simplify remove_non_empty_lvm2_pv_dialog()
Simplify code in Win_GParted::remove_non_empty_lvm2_pv_dialog() by
replacing open coded concatenation of a vector of strings using a new
line separator with a call to Glib::build_path().
2024-04-12 08:02:41 +01:00
Mike Fleetwood
61ac1a416f Stop assigning a zero length string when constructing them
Most of the code doesn't assign a zero length string when constructing a
string object.  However there were a few places where it did.  This is
unnecessary because Glib::ustring [1] and std::string [2] objects are
constructed as the the empty string by default.

[1] Glib::ustring::ustring()
    https://developer-old.gnome.org/glibmm/stable/classGlib_1_1ustring.html#a71802782f4c2c408ef7ac69c6564b370
        "Glib::ustring::ustring()
        Default constructor, which creates an empty string.
        "
[2] std::string::string
    https://cplusplus.com/reference/string/string/string/
        "(1) empty string constructor (default constructor)
        Constructs an empty string, with a length of zero characters.
        "
2024-04-12 08:02:35 +01:00
Mike Fleetwood
cc65eef59a Drop the 2 decimal places when printing values in bytes
When printing a number of bytes using Utils::format_size() it always
formatted the value with 2 decimal digits and an IEC multiplier.  This
can be seen in the details of any operation which includes clearing old
file system signatures.  Fragment of operation details:
    Format /dev/sdb1 as cleared
    + calibrate /dev/sdb1
    + clear old file system signatures in /dev/sdb1
        write 512.00 KiB of zeros at byte offset 0
        write 4.00 KiB of zeros at byte offset 67108864
>>      write 512.00 B of zeros at byte offset 132537184
        write 4.00 KiB of zeros at byte offset 1072693248
        write 512.00 KiB of zeros at byte offset 133593440
        flush operating system cache of /dev/sdb1

It doesn't make sense to be reporting 100ths of a byte.  So when values
are below 1 KiB report numbers of bytes without any decimal digits.
2024-04-12 08:02:30 +01:00
Mike Fleetwood
a621623326 Query usage of multi-device bcachefs file systems correctly
Create an uneven used space multi-device bcachefs file system like this,
where sdb1 is about 1/2 used and sdb2 is almost empty:
    # bcachefs format /dev/sdb1
    # mount /dev/sdb1 /mnt/1
    # dd if=/dev/zero bs=1M count=512 of=/mnt/1/zeros.bin
    # bcachefs device add /mnt/1 /dev/sdb2

GParted reports both devices as having the same usage:
    Partition   File System   Mount Point   Size       Used         Unused       Flags
    /dev/sdb1   bcachefs      /mnt/1        1.00 GiB   526.00 MiB   498.00 MiB
    /dev/sdb2   bcachefs      /mnt/1        1.00 GiB   526.00 MiB   498.00 MiB

When in fact the used space is significantly different for each device:
    # bcachefs fs usage /mnt/1 | egrep ' \(device |free:|capacity:'
    (no label) (device 0):          sdb1              rw
      free:                    522190848            3984
      capacity:               1073741824            8192
    (no label) (device 1):          sdb2              rw
      free:                   1061945344            8102
      capacity:               1073741824            8192

This is because bcachefs::set_used_sectors() is always searching for the
first "free:" and "capacity:" figures.  Fix by reading the figures for
the correct device.
2024-04-12 08:02:25 +01:00
Mike Fleetwood
3b5da02943 Add bcachefs checking (!123)
[Only the options being used by GParted are quoted here from the help
output.  More options are available.]
    $ bcachefs fsck --help
    bcachefs fsck - filesystem check and repair
    Usage: bcachefs fsck [OPTION]... <device>

    Options:
      -y               Assume "yes" to all questions
      -f               Force checking even if filesystem is marked clean
      -v               Be verbose

Closes !123 - Add support for bcachefs, single device file systems only
2024-04-12 08:02:20 +01:00
Mike Fleetwood
31df2f2b75 Add bcachefs growing (!123)
Shrinking a bcachefs file system is not supported.
    # truncate -s $((1*1024*1024*1024)) /tmp/disk.img
    # losetup --find --show /tmp/disk.img
    /dev/loop0
    # bcachefs format /dev/loop0
    ...
    # bcachefs device resize /dev/loop0 $((1*1024*1024*1024 - 512))
    Doing offline resize of /dev/loop0
    mounting version 1.4: member_seq
    initializing new filesystem
    going read-write
    initializing freespace
    Shrinking not supported yet
    # echo $?
    1

Growing a bcachefs file system is supported when unmounted.
    # truncate -s $((2*1024*1024*1024)) /tmp/disk.img
    # losetup --set-capacity /dev/loop0
    # bcachefs device resize /dev/loop0
    Doing offline resize of /dev/loop0
    mounting version 1.6: btree_subvolume_children
    recovering from unclean shutdown
    journal read done, replaying entries 1-1
    alloc_read... done
    stripes_read... done
    snapshots_read... done
    going read-write
    journal_replay... done
    resume_logged_ops... done
    delete_dead_inodes... done
    resizing /dev/loop0 to 16384 buckets
    # echo $?
    0
    # bcachefs show-super /dev/loop0 | egrep 'Device:|Size:'
    Device:                                     0
      Size:                                     2.00 GiB

Growing is also supported when mounted.
    # mount /dev/loop0 /mnt/0
    # truncate -s $((3*1024*1024*1024)) /tmp/disk.img
    # losetup --set-capacity /dev/loop0
    # bcachefs device resize /dev/loop0
    Doing online resize of /dev/loop0
    resizing /dev/loop0 to 24576 buckets
    # echo $?
    0
    # bcachefs show-super /dev/loop0 | egrep 'Device:|Size:'
    Device:                                     0
      Size:                                     3.00 GiB

Closes !123 - Add support for bcachefs, single device file systems only
2024-04-12 08:02:16 +01:00
Mike Fleetwood
f027809e73 Avoid erasing the same range multiple times (!123)
When the size of the partition being cleared is an exact multiple of
MiBs, likely given that GParted aligns partitions to whole MiBs by
default, then the same range will be zeroed 4 times in a row.  Example
operation details from clearing a partition look like this:

    Format /dev/sdb1 as cleared
    + calibrate /dev/sdb1
        path: /dev/sdb1 (partition)
        start: 2048
        end: 2099199
        size: 2097152 (1.00 GiB)
    + clear old file system signatures in /dev/sdb1
        write 512.00 KiB of zeros at byte offset 0
        write 4.00 KiB of zeros at byte offset 67108864
        write 512.00 B of zeros at byte offset 1072161280
>>      write 4.00 KiB of zeros at byte offset 1072693248
>>      write 4.00 KiB of zeros at byte offset 1072693248
>>      write 4.00 KiB of zeros at byte offset 1072693248
>>      write 4.00 KiB of zeros at byte offset 1072693248
        write 512.00 KiB of zeros at byte offset 1073217536
    + set partition type on /dev/sdb1

This is because the bcachefs backup super block is located at -1 MiB
from the end of the device, rounded down by the bcachefs bucket size.
The bucket size can be any of 128 KiB, 256 KiB, 512 KiB or 1 MiB,
depending on the size of the bcachefs file system.  So when the
partition size is an exact multiple of MiBs all 4 possible rounding
sizes result in the same offset.

Avoid writing the same range of zeros multiple times by skipping a range
if it is identical to the previous range.

Closes !123 - Add support for bcachefs, single device file systems only
2024-04-12 08:02:06 +01:00
Mike Fleetwood
76b27b9f7a Erase Bcachefs backup super block (!123)
GParted doesn't clear all bcachefs file system signatures.
    # truncate -s $((1*1024*1024*1024)) /tmp/disk.img
    # losetup --find --show /tmp/disk.img
    /dev/loop0
    # bcachefs format /tmp/disk.img
    # wipefs /dev/loop0
    DEVICE OFFSET     TYPE     UUID                                 LABEL
    loop0  0x1018     bcachefs 15304edb-6dc4-476c-989e-74eaea6660e8
    loop0  0x3ff00018 bcachefs 15304edb-6dc4-476c-989e-74eaea6660e8

Use GParted to format to cleared /dev/loop0.
    # wipefs /dev/loop0
    DEVICE OFFSET     TYPE     UUID                                 LABEL
    loop0  0x3ff00018 bcachefs 15304edb-6dc4-476c-989e-74eaea6660e8

The backup super block is located at -1 MiB before the end of the
device, rounded down to the file system's bucket size [1], where the
bucket size is one of: 128 KiB, 256 KiB, 512 KiB, 1024 KiB [2].
    location = device size - 1 MiB
             = hex(1*1024*1024*1024 - 1*1024*1024)
             = 0x3ff00000
Bcachefs magic is at byte offset 24 (0x18) into the super block [3].

The backup super block was not erased because GParted only writes zeros
from -512 KiB to the end of the device.  It is necessary to clear old
signatures before formatting with a new file system to avoid confusion
from detection of multiple incompatible signatures [4][5].  Fix this by
writing zeros over all possible locations of the bcachefs backup super
block.

[1] bcachefs-tools v1.6.4: c_src/libbcachefs.c:bch2_format()
    https://evilpiepirate.org/git/bcachefs-tools.git/tree/c_src/libbcachefs.c?h=v1.6.4#n313
    [This code locates the backup super block at device size - 1 MiB
    rounded down to the bucket size.]
    321     struct bch_sb_layout *l = &sb.sb->layout;
    322     u64 backup_sb = size_sectors - (1 << l->sb_max_size_bits);
    323
    324     backup_sb = rounddown(backup_sb, i->bucket_size >> 9);
[2] bcachefs-tools v1.6.4: c_src/libbcachefs.c:bch2_pick_bucket_size()
    https://evilpiepirate.org/git/bcachefs-tools.git/tree/c_src/libbcachefs.c?h=v1.6.4#n85
     85      /* Want a bucket size of at least 128k, if possible: */
     86      bucket_size = max(bucket_size, 128ULL << 10);
    ...
     94      /* max bucket size 1 mb */
     95      bucket_size = min(bucket_size * scale, 1ULL << 20);
[3] bcachefs-tools v1.6.4: libcachefs/bcachefs_format.h:struct bch_sb
    https://evilpiepirate.org/git/bcachefs-tools.git/tree/libbcachefs/bcachefs_format.h?h=v1.6.4#n907
[4] 743968ef68
    Add clearing of SWRaid metadata 0.90 and 1.0 super blocks (#756829)
[5] 3c75f3f5b1
    Use wipefs to clear old signatures before creating new file systems (#688882)

Closes !123 - Add support for bcachefs, single device file systems only
2024-04-12 08:02:00 +01:00
Mike Fleetwood
b8304a141a Add bcachefs label and UUID reading (!123)
Add reading of the bcachefs file system label, not the per device label,
and the external UUID.  These match what blkid reports.

Example without a label:
    # bcachefs format /dev/sdb1
    # bcachefs show-super /dev/sdb1 | egrep -i 'Label:|UUID:|Device:'
    External UUID:                              3316bc9a-d129-42b6-a80e-9649874bca73
    Internal UUID:                              656eebe5-10a9-4f12-94c8-aab2fdc54732
    Label:
    Device:                                     0
      Label:                                    (none)
      UUID:                                     cd436a8d-82eb-4993-a317-b39ea0d6bd2e
    # blkid /dev/sdb1
    /dev/sdb1: UUID="3316bc9a-d129-42b6-a80e-9649874bca73" BLOCK_SIZE="512" UUID_SUB="cd436a8d-82eb-4993-a317-b39ea0d6bd2e" TYPE="bcachefs" PARTUUID="7962e584-34c9-4088-8a00-a651af517089"

Example with a label:
    # bcachefs format --force -L 'test label' /dev/sdb1
    # bcachefs show-super /dev/sdb1 | egrep -i 'Label:|UUID:|Device:'
    External UUID:                              3d7bdabe-2616-4545-affc-1aba0f8fb4a7
    Internal UUID:                              9cc95d3e-7991-4f78-9dd0-850cb9749e34
    Label:                                      test label
    Device:                                     0
      Label:                                    (none)
      UUID:                                     784d1bd0-5769-4fbb-ad32-07894d381bba
    # blkid /dev/sdb1
    /dev/sdb1: UUID="3d7bdabe-2616-4545-affc-1aba0f8fb4a7" LABEL="test label" BLOCK_SIZE="512" UUID_SUB="784d1bd0-5769-4fbb-ad32-07894d381bba" TYPE="bcachefs" PARTUUID="7962e584-34c9-4088-8a00-a651af517089"

Closes !123 - Add support for bcachefs, single device file systems only
2024-04-12 08:01:55 +01:00
Mike Fleetwood
aabba99594 Increase minimum bcachefs size to 32 MiB (!123)
For bcachefs file systems 19 MiB and smaller, the available space is
reported as a very large value.  The calculation went negative in a
64-bit signed value but then was interpreted as an unsiged value.
Writing any significant amount of data to the file system hangs.
    # truncate -s $((19*1024*1024)) /tmp/test.img
    # losetup --find --show /tmp/test.img
    /dev/loop0
    # bcachefs format /dev/loop0
    # mkdir /mnt/0
    # mount /dev/loop0 /mnt/0
    # strace -e statfs df -k /mnt/0
    statfs("/mnt/0", {f_type=0xca451a4e, f_bsize=4096, f_blocks=2305843009213693856,
        f_bfree=2305843009213693600, f_bavail=35474507834056483, f_files=18446744073709529090,
        f_ffree=18446744073709529088, f_fsid={val=[0xddb6645d, 0x8560584]}, f_namelen=512,
        f_frsize=4096, f_flags=ST_VALID|ST_RELATIME}) = 0
    Filesystem               1K-blocks  Used          Available Use% Mounted on
    /dev/loop0     9223372036854775424  1024 141898031336225932   1% /mnt/0

For a 20 MiB bcachefs the available space is 0 so the file system
overhead is 100%.
    # umount /mnt/0
    # truncate -s $((20*1024*1024)) /tmp/disk.img
    # losetup --set-capacity /dev/loop0
    # bcachefs format --force /dev/loop0
    # mount /dev/loop0 /mnt/0
    # strace -e statfs df -k /mnt/0
    statfs("/mnt/0", {f_type=0xca451a4e, f_bsize=512, f_blocks=1280, f_bfree=0, f_bavail=0,
        f_files=2, f_ffree=0, f_fsid={val=[0x6b3e4926, 0x33f99a32]}, f_namelen=512, f_frsize=512,
        f_flags=ST_VALID|ST_RELATIME}) = 0
    Filesystem     1K-blocks  Used Available Use% Mounted on
    /dev/loop0           640   640         0 100% /mnt/0

For a 32 MiB bcachefs the file system overhead is a more reasonable 9%
so use this as the minimum bcachefs file system size.
    ...
    # truncate -s $((32*1024*1024)) /tmp/disk.img
    ...
    # strace -e statfs df -k /mnt/0
    statfs("/mnt/0", {f_type=0xca451a4e, f_bsize=512, f_blocks=24832, f_bfree=22784,
        f_bavail=22433, f_files=182274, f_ffree=182272, f_fsid={val=[0xfdddedd3, 0xe90be3cb]},
        f_namelen=512, f_frsize=512, f_flags=ST_VALID|ST_RELATIME}) = 0
    Filesystem     1K-blocks  Used Available Use% Mounted on
    /dev/loop0         12416  1024     11217   9% /mnt/0

Closes !123 - Add support for bcachefs, single device file systems only
2024-04-12 08:01:50 +01:00
Mike Fleetwood
ccdf14ddb4 Add reading of bcachefs usage when mounted (!123)
Currently bcachefs-tools only provides a method to report the file
system usage while it is mounted.  We won't make GParted mount a
bcachefs to read it's usage as we want to keep GParted's scanning as a
read-only activity.  Therefore GParted can't report the usage of an
unmounted bcachefs.

    # bcachefs format /dev/sdb1
    # bcachefs fs usage /dev/sdb1
    error opening /dev/sdb1: not a bcachefs filesystem
    # echo $?
    1
    # bcachefs fs usage --help
    bcachefs fs usage - display detailed filesystem usage
    Usage: bcachefs fs usage [OPTION]... <mountpoint>
    ...
    # mount /dev/sdb1 /mnt/1
    # bcachefs fs usage /mnt/1
    Filesystem: a61a8302-9a79-4c24-a9e6-486e7fcc78f5
    Size:                      987842560
    Used:                       12713984
    Online reserved:                   0

    Data type       Required/total  Durability    Devices
    btree:          1/1             1             [sdb1]               1048576

    (no label) (device 0):          sdb1              rw
                                    data         buckets    fragmented
      free:                   1061027840            8095
      sb:                        3149824              25        126976
      journal:                   8388608              64
      btree:                     1048576               8
      user:                            0               0
      cached:                          0               0
      parity:                          0               0
      stripe:                          0               0
      need_gc_gens:                    0               0
      need_discard:                    0               0
      capacity:               1073741824            8192
    # echo $?
    0

Closes !123 - Add support for bcachefs, single device file systems only
2024-04-12 08:01:45 +01:00
Mike Fleetwood
7ca99a1577 Add bcachefs creation (!123)
Set the minimum file system size to 16 MiB as creating a bcachefs that
size succeeds:
    $ truncate -s $((16*1024*1024)) /tmp/disk.img
    $ bcachefs format /tmp/disk.img
    ...
    initializing new filesystem
    going read-write
    initializing freespace
    $ echo $?
    0

Where as creating a smaller file system fails for most sizes below that:
    $ rm /tmp/disk.img
    $ truncate -s $((15*1024*1024)) /tmp/disk.img
    $ bcachefs format /tmp/disk.img
    ...
    mounting version 1.6: btree_subvolume_children
    initializing new filesystem
    going read-write
    bch2_trans_mark_dev_sb(): error ENOSPC_disk_reservation
    bch2_fs_initialize(): error marking superblocks ENOSPC_disk_reservation
    bch2_fs_initialize(): error ENOSPC_disk_reservation
    bch2_fs_start(): error starting filesystem ENOSPC_disk_reservation
    error opening /tmp/disk.img: ENOSPC_disk_reservation
    $ echo $?
    1

Closes !123 - Add support for bcachefs, single device file systems only
2024-04-12 07:54:10 +01:00

View File

@ -256,53 +256,54 @@ int Utils::get_max_partition_name_length( Glib::ustring & tabletype )
int Utils::get_filesystem_label_maxlength(FSType fstype)
{
// Only file systems which can have labels, either set when created or changed
// afterwards, need a maximum length defining.
switch (fstype)
{
//All file systems commented out are not supported for labelling
// by either the new partition or label partition operations.
case FS_BTRFS : return 255 ;
case FS_EXFAT : return 11;
case FS_EXT2 : return 16 ;
case FS_EXT3 : return 16 ;
case FS_EXT4 : return 16 ;
case FS_BCACHEFS: return 32;
case FS_BTRFS: return 255;
case FS_EXFAT: return 11;
case FS_EXT2: return 16;
case FS_EXT3: return 16;
case FS_EXT4: return 16;
// mkfs.f2fs supports labels up to 512 characters, however only blkid is
// used to read the label and that only displays the first 127 characters.
case FS_F2FS : return 127;
case FS_FAT16 : return 11 ;
case FS_FAT32 : return 11 ;
//mkfs.hfsplus can create hfs and hfs+ file systems with labels up to 255
// characters. However there is no specific tool to read the labels and
// blkid, the only tool currently available, only display the first 27
// and 63 character respectively.
// Reference:
// util-linux-2.20.1/libblkid/src/superblocks/hfs.c:struct hfs_mdb
case FS_HFS : return 27 ;
case FS_HFSPLUS : return 63 ;
//mkfs.jfs and jfs_tune can create and update labels to 16 characters but
// only displays the first 11 characters. This is because version 1 jfs
// file systems only have an 11 character field for the label but version
// 2 jfs has extra fields containing a 16 character label. mkfs.jfs
// writes the extra fields containing the 16 character label, but then
// sets it to version 1 jfs. It does this to be backwardly compatible
// with jfs before 1.0.18, released May 2002. Blkid does display the
// full 16 character label by just ignoring the file system version.
// As using jfs_tune to get the label stick with an 11 character limit.
// References:
// jfsutils-1.1.15/tune/tune.c:main()
// jfsutils-1.1.15/mkfs/mkfs.c:create_aggregate()
// http://jfs.cvs.sourceforge.net/viewvc/jfs/jfsutils/NEWS?revision=HEAD
case FS_JFS : return 11 ;
case FS_LINUX_SWAP : return 15 ;
//case FS_LVM2_PV : return ;
case FS_MINIX : return 0; // MINIX doesn't support labelling.
case FS_NILFS2 : return 80 ;
case FS_NTFS : return 128 ;
case FS_REISER4 : return 16 ;
case FS_REISERFS : return 16 ;
case FS_UDF : return 126; // and only 63 if label contains character above U+FF
case FS_XFS : return 12 ;
case FS_F2FS: return 127;
case FS_FAT16: return 11;
case FS_FAT32: return 11;
default : return 30 ;
// mkfs.hfsplus can create hfs and hfs+ file systems with labels up to 255
// characters. However there is no specific tool to read the labels and
// blkid, the only tool currently available, only display the first 27 and
// 63 character respectively.
// Reference:
// util-linux-2.20.1/libblkid/src/superblocks/hfs.c:struct hfs_mdb
case FS_HFS: return 27;
case FS_HFSPLUS: return 63;
// mkfs.jfs and jfs_tune can create and update labels to 16 characters but
// only displays the first 11 characters. This is because version 1 jfs
// file systems only have an 11 character field for the label but version
// 2 jfs has extra fields containing a 16 character label. mkfs.jfs
// writes the extra fields containing the 16 character label, but then
// sets it to version 1 jfs. It does this to be backwardly compatible
// with jfs before 1.0.18, released May 2002. Blkid does display the full
// 16 character label by just ignoring the file system version. As using
// jfs_tune to read the label stick with an 11 character limit.
// References:
// jfsutils-1.1.15/tune/tune.c:main()
// jfsutils-1.1.15/mkfs/mkfs.c:create_aggregate()
// http://jfs.cvs.sourceforge.net/viewvc/jfs/jfsutils/NEWS?revision=HEAD
case FS_JFS: return 11;
case FS_LINUX_SWAP: return 15;
case FS_NILFS2: return 80;
case FS_NTFS: return 128;
case FS_REISER4: return 16;
case FS_REISERFS: return 16;
case FS_UDF: return 126; // and only 63 if label contains character above U+FF
case FS_XFS: return 12;
default: return 30;
}
}
@ -408,6 +409,7 @@ const Glib::ustring Utils::get_filesystem_kernel_name( FSType fstype )
{
switch ( fstype )
{
case FS_BCACHEFS : return "bcachefs";
case FS_BTRFS : return "btrfs";
case FS_EXFAT : return "exfat";
case FS_EXT2 : return "ext2";