1
0
mirror of https://gitlab.gnome.org/GNOME/gparted synced 2024-06-30 23:05:09 +00:00

Compare commits

...

13 Commits

Author SHA1 Message Date
Mike Fleetwood
946e482800 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-10 23:30:58 +01:00
Mike Fleetwood
c6f2ebc780 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-10 23:30:49 +01:00
Mike Fleetwood
d60ae82a25 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-10 23:22:35 +01:00
Mike Fleetwood
7a00482ab9 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-10 23:22:35 +01:00
Mike Fleetwood
53682c6aa1 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-10 23:22:35 +01:00
Mike Fleetwood
f38bebf6f2 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-10 23:20:38 +01:00
Mike Fleetwood
6e5f84c641 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-10 23:03:16 +01:00
Mike Fleetwood
6534bfa28d 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-10 22:51:31 +01:00
Mike Fleetwood
0da4f5999a 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-10 22:51:31 +01:00
Mike Fleetwood
b891498d0a 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-10 22:51:31 +01:00
Mike Fleetwood
5b47fb5c68 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-10 22:44:26 +01:00
Mike Fleetwood
4b30efd29d Add bcachefs detection (!123)
Uses blkid from util-linux >= 2.39 [1] for detection of bcachefs file
systems.

Use util-linux's FS images when testing GParted detection.
    # wget https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/plain/tests/ts/blkid/images-fs/bcachefs.img.xz
    # zxcat bcachefs.img.xz > /dev/sdb1
    # wget https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/plain/tests/ts/blkid/images-fs/bcachefs-2.img.xz
    # zxcat bcachefs-2.img.xz > /dev/sdb2
    # blkid /dev/sdb1 /dev/sdb2
    /dev/sdb1: UUID="46bd306f-80ad-4cd0-af4f-147e7d85f393" LABEL="Label" BLOCK_SIZE="4096" UUID_SUB="72a60ede-4cb6-4374-aa70-cb38a50af5ef" TYPE="bcachefs" PARTUUID="bd47302a-b33b-47a5-83a1-ba89f52f2a45"
    /dev/sdb2: UUID="4fa11b1e-75e6-4210-9167-34e1769c0fe1" LABEL="Label" BLOCK_SIZE="512" UUID_SUB="525fa857-174a-4d3f-be33-6fe60441de7c" LABEL_SUB="Device Label" TYPE="bcachefs" PARTUUID="6a46a084-5d3b-408a-bba7-351daaea1c66"

[1] Util-linux 2.39 Release Notes
    https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v2.39/v2.39-ReleaseNotes
    "blkid(8) and libblkid:

       * supports bcachefs
    "

Closes !123 - Add support for bcachefs, single device file systems only
2024-04-09 18:48:02 +01:00
Mike Fleetwood
24ff32fd63 Move ZFS to a darker shade of Orange (!123)
Bcachefs [1] has many of the same capabilities as Btrfs [2] and ZFS [3]:
COW (Copy-on-Write), multi-device, multi-volume, snapshotting and many
more.  Therefore when adding bcachefs use the same range of Orange
colours already used by Btrfs and ZFS [4].  As bcachefs is a native
Linux file system and ZFS is not, move ZFS to a darker shade of Orange
to allow bcachefs to be added in the middle:
    Btrfs    - Orange Medium (#E58749)
    bcachefs - Orange Dark   (#C26825)
    ZFS      - Orange Shadow (#984F18)

[1] bcachefs
    https://bcachefs.org/
[2] Welcome to BTRFS documentation! > Introduction
    https://btrfs.readthedocs.io/en/latest/Introduction.html
[3] ZFS
    https://en.wikipedia.org/wiki/ZFS
[4] 8a4f9ad205
    Adjust shades of aquamarine, cyan and orange

Closes !123 - Add support for bcachefs, single device file systems only
2024-04-09 18:46:20 +01:00
23 changed files with 301 additions and 72 deletions

1
README
View File

@ -265,6 +265,7 @@ devices and partitions. When available, it uses each file system's
specific commands. The following optional file system specific packages
provide this support:
bcachefs-tools
btrfs-progs / btrfs-tools
e2fsprogs
exfatprogs

View File

@ -18,9 +18,9 @@
data rescue from lost partitions.
</p>
<p>
GParted works with many file systems including: btrfs, exfat, ext2,
ext3, ext4, fat16, fat32, hfs, hfs+, linux-swap, lvm2 pv, minix,
nilfs2, ntfs, reiserfs, reiser4, udf, ufs, and xfs.
GParted works with many file systems including: bcachefs, btrfs,
exfat, ext2, ext3, ext4, fat16, fat32, hfs, hfs+, linux-swap,
lvm2 pv, minix, nilfs2, ntfs, reiserfs, reiser4, udf, ufs, and xfs.
</p>
</description>
<launchable type="desktop-id">gparted.desktop</launchable>

View File

@ -53,6 +53,7 @@ noinst_HEADERS = \
TreeView_Detail.h \
Utils.h \
Win_GParted.h \
bcachefs.h \
btrfs.h \
exfat.h \
ext2.h \

View File

@ -71,45 +71,46 @@ enum FSType
FS_EXTENDED = 6,
// Fully supported file system types
FS_BTRFS = 7,
FS_EXFAT = 8, /* Also known as fat64 */
FS_EXT2 = 9,
FS_EXT3 = 10,
FS_EXT4 = 11,
FS_F2FS = 12,
FS_FAT16 = 13,
FS_FAT32 = 14,
FS_HFS = 15,
FS_HFSPLUS = 16,
FS_JFS = 17,
FS_LINUX_SWAP = 18,
FS_LUKS = 19,
FS_LVM2_PV = 20,
FS_MINIX = 21,
FS_NILFS2 = 22,
FS_NTFS = 23,
FS_REISER4 = 24,
FS_REISERFS = 25,
FS_UDF = 26,
FS_XFS = 27,
FS_BCACHEFS = 7,
FS_BTRFS = 8,
FS_EXFAT = 9, /* Also known as fat64 */
FS_EXT2 = 10,
FS_EXT3 = 11,
FS_EXT4 = 12,
FS_F2FS = 13,
FS_FAT16 = 14,
FS_FAT32 = 15,
FS_HFS = 16,
FS_HFSPLUS = 17,
FS_JFS = 18,
FS_LINUX_SWAP = 19,
FS_LUKS = 20,
FS_LVM2_PV = 21,
FS_MINIX = 22,
FS_NILFS2 = 23,
FS_NTFS = 24,
FS_REISER4 = 25,
FS_REISERFS = 26,
FS_UDF = 27,
FS_XFS = 28,
// Other recognised file system types
FS_APFS = 28,
FS_ATARAID = 29,
FS_BCACHE = 30,
FS_BITLOCKER = 31,
FS_GRUB2_CORE_IMG = 32,
FS_ISO9660 = 33,
FS_JBD = 34,
FS_LINUX_SWRAID = 35,
FS_LINUX_SWSUSPEND = 36,
FS_REFS = 37,
FS_UFS = 38,
FS_ZFS = 39,
FS_APFS = 29,
FS_ATARAID = 30,
FS_BCACHE = 31,
FS_BITLOCKER = 32,
FS_GRUB2_CORE_IMG = 33,
FS_ISO9660 = 34,
FS_JBD = 35,
FS_LINUX_SWRAID = 36,
FS_LINUX_SWSUSPEND = 37,
FS_REFS = 38,
FS_UFS = 39,
FS_ZFS = 40,
// Partition space usage colours
FS_USED = 40,
FS_UNUSED = 41
FS_USED = 41,
FS_UNUSED = 42
} ;
enum SIZE_UNIT

46
include/bcachefs.h Normal file
View File

@ -0,0 +1,46 @@
/* Copyright (C) 2024 Mike Fleetwood
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef GPARTED_BCACHEFS_H
#define GPARTED_BCACHEFS_H
#include "FileSystem.h"
#include "OperationDetail.h"
#include "Partition.h"
namespace GParted
{
class bcachefs : public FileSystem
{
public:
FS get_filesystem_support();
void set_used_sectors(Partition& partition);
bool create(const Partition& new_partition, OperationDetail& operationdetail);
void read_label(Partition& partition);
void read_uuid(Partition& partition);
bool resize(const Partition& partition_new, OperationDetail& operationdetail, bool fill_partition);
bool check_repair(const Partition& partition, OperationDetail& operationdetail);
};
} //GParted
#endif /* GPARTED_BCACHEFS_H */

View File

@ -48,6 +48,7 @@ src/SWRaid_Info.cc
src/TreeView_Detail.cc
src/Utils.cc
src/Win_GParted.cc
src/bcachefs.cc
src/btrfs.cc
src/exfat.cc
src/ext2.cc

View File

@ -210,12 +210,11 @@ void DMRaid::get_devices( std::vector<Glib::ustring> & device_list )
Glib::ustring DMRaid::get_dmraid_name( const Glib::ustring & dev_path )
{
//Retrieve name of dmraid device
Glib::ustring dmraid_name = "" ;
Glib::ustring regexp = "" ;
Glib::ustring dmraid_name;
for ( unsigned int k=0; k < dmraid_devices .size(); k++ )
{
regexp = ".*(" + dmraid_devices[k] + ").*" ;
Glib::ustring regexp = ".*(" + dmraid_devices[k] + ").*";
if ( Utils::regexp_label( dev_path, regexp ) == dmraid_devices[k] )
dmraid_name = dmraid_devices[k] ;
}
@ -256,7 +255,7 @@ void DMRaid::get_dmraid_dir_entries( const Glib::ustring & dev_path, std::vector
Glib::ustring dmraid_name = get_dmraid_name( dev_path ) ;
//Loop through the entries in the directory
Glib::ustring filename = "" ;
Glib::ustring filename;
Glib::Dir dir( DEV_MAPPER_PATH );
while ( ( filename = dir .read_name() ) != "" )
{
@ -277,9 +276,9 @@ int DMRaid::get_partition_number( const Glib::ustring & partition_name )
Glib::ustring DMRaid::get_udev_dm_name( const Glib::ustring & dev_path )
{
//Retrieve DM_NAME of device using udev information
Glib::ustring output = "" ;
Glib::ustring error = "" ;
Glib::ustring dm_name = "" ;
Glib::ustring output;
Glib::ustring error;
Glib::ustring dm_name;
if (udevadm_found)
Utils::execute_command( "udevadm info --query=all --name=" + Glib::shell_quote( dev_path ),

View File

@ -228,7 +228,7 @@ void Dialog_Partition_Info::Display_Info()
Sector ptn_sectors = partition .get_sector_length() ;
Glib::ustring vgname = "" ; //Also used in partition status message
Glib::ustring vgname;
if (filesystem_ptn.fstype == FS_LVM2_PV)
vgname = LVM2_PV_Info::get_vg_name( filesystem_ptn.get_path() );

View File

@ -1235,7 +1235,6 @@ FSType GParted_Core::detect_filesystem(const PedDevice *lp_device, const PedPart
{
g_assert(lp_device != nullptr); // Bug: Not initialised by call to ped_device_get() or ped_device_get_next()
Glib::ustring fsname = "";
Glib::ustring path;
DMRaid dmraid;
@ -1257,7 +1256,7 @@ FSType GParted_Core::detect_filesystem(const PedDevice *lp_device, const PedPart
// (Q2) FS_Info (blkid) file system detection
// Blkid detects more signatures and generally has less limitations so use before
// libparted detection, but it doesn't report anything for extended partitions.
fsname = FS_Info::get_fs_type( path );
Glib::ustring fsname = FS_Info::get_fs_type(path);
// (Q3) Libparted file system detection
// Only used when blkid didn't report anything and only on partitions, not whole
@ -1270,6 +1269,8 @@ FSType GParted_Core::detect_filesystem(const PedDevice *lp_device, const PedPart
{
if ( fsname == "extended" )
return FS_EXTENDED;
else if (fsname == "bcachefs")
return FS_BCACHEFS;
else if ( fsname == "btrfs" )
return FS_BTRFS;
else if ( fsname == "exfat" )
@ -3787,6 +3788,7 @@ bool GParted_Core::erase_filesystem_signatures( const Partition & partition, Ope
// Not covered by the above are:
// * Btrfs super block mirror copies
// * One possible location of Promise FastTrack RAID super block
// * Bcachefs super block backup
//
// Btrfs super blocks are located at: 64 KiB, 64 MiB, 256 GiB and 1 PiB. The
// super block at 64 KiB will be erased by the zeroing from offset 0. The super
@ -3801,6 +3803,16 @@ bool GParted_Core::erase_filesystem_signatures( const Partition & partition, Ope
// location -3087 must be explicitly cleared.
// util-linux v2.38.1: libblkid/src/subperblocks/promise_raid.c:probe_pdcraid()
// https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git/tree/libblkid/src/superblocks/promise_raid.c?h=v2.38.1#n27
//
// Bcachefs super block backup is located at -1 MiB before the end of the device,
// rounded down to the file system's bucket size, where the bucket size is one of:
// 128 KiB, 256 KiB, 512 KiB or 1024 KiB.
// * 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
// * 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
// * 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
struct {
Byte_Value offset; // Negative offsets work backwards from the end of the partition
Byte_Value rounding; // Minimum desired rounding for offset
@ -3812,8 +3824,14 @@ bool GParted_Core::erase_filesystem_signatures( const Partition & partition, Ope
{ 256LL * GIBIBYTE, 1LL , 4LL * KIBIBYTE }, // Btrfs super block mirror copy
{ 1LL * PEBIBYTE, 1LL , 4LL * KIBIBYTE }, // Btrfs super block mirror copy
{ -3087LL * 512LL , 1LL , 512LL }, // Promise FastTrack RAID super block
{ -1LL * MEBIBYTE, 128LL * KIBIBYTE, 4LL * KIBIBYTE }, // Bcachefs backup super block
{ -1LL * MEBIBYTE, 256LL * KIBIBYTE, 4LL * KIBIBYTE }, // Bcachefs backup super block
{ -1LL * MEBIBYTE, 512LL * KIBIBYTE, 4LL * KIBIBYTE }, // Bcachefs backup super block
{ -1LL * MEBIBYTE, 1LL * MEBIBYTE, 4LL * KIBIBYTE }, // Bcachefs backup super block
{ -512LL * KIBIBYTE, 256LL * KIBIBYTE, 768LL * KIBIBYTE } // Super blocks at end
} ;
Byte_Value prev_byte_offset = -1;
Byte_Value prev_byte_len = -1;
for ( unsigned int i = 0 ; overall_success && i < sizeof( ranges ) / sizeof( ranges[0] ) ; i ++ )
{
//Rounding is performed in multiples of the sector size because writes are in whole sectors.
@ -3862,6 +3880,10 @@ bool GParted_Core::erase_filesystem_signatures( const Partition & partition, Ope
byte_len = partition .get_byte_length() - byte_offset ;
}
if (byte_offset == prev_byte_offset && byte_len == prev_byte_len)
// Byte range identical to previous. Skip.
continue;
OperationDetail & od = operationdetail .get_last_child() ;
Byte_Value written = 0LL ;
bool zero_success = false ;
@ -3887,6 +3909,10 @@ bool GParted_Core::erase_filesystem_signatures( const Partition & partition, Ope
written += amount ;
}
// Save byte range for detection of following identical range.
prev_byte_offset = byte_offset;
prev_byte_len = byte_len;
od.get_last_child().set_success_and_capture_errors( zero_success );
}
overall_success &= zero_success ;

View File

@ -63,6 +63,7 @@ gpartedbin_SOURCES = \
TreeView_Detail.cc \
Utils.cc \
Win_GParted.cc \
bcachefs.cc \
btrfs.cc \
exfat.cc \
ext2.cc \

View File

@ -18,6 +18,7 @@
#include "SupportedFileSystems.h"
#include "FileSystem.h"
#include "Utils.h"
#include "bcachefs.h"
#include "btrfs.h"
#include "exfat.h"
#include "ext2.h"
@ -59,6 +60,7 @@ SupportedFileSystems::SupportedFileSystems()
// supported_filesystem() -> false
m_fs_objects[FS_UNKNOWN] = nullptr;
m_fs_objects[FS_OTHER] = nullptr;
m_fs_objects[FS_BCACHEFS] = new bcachefs();
m_fs_objects[FS_BTRFS] = new btrfs();
m_fs_objects[FS_EXFAT] = new exfat();
m_fs_objects[FS_EXT2] = new ext2(FS_EXT2);

View File

@ -153,6 +153,7 @@ Glib::ustring Utils::get_color(FSType fstype)
case FS_CLEARED: return "#000000"; // Black
case FS_OTHER: return "#000000"; // Black (never displayed)
case FS_EXTENDED: return "#95E3E5"; // Cyan Hilight [*]
case FS_BCACHEFS: return "#C26825"; // Orange Dark [*]
case FS_BTRFS: return "#E58749"; // Orange Medium [*]
case FS_EXFAT: return "#267726"; // Accent Green Dark
case FS_EXT2: return "#7590AE"; // Blue Medium
@ -185,7 +186,7 @@ Glib::ustring Utils::get_color(FSType fstype)
case FS_LINUX_SWSUSPEND: return "#884631"; // Red Dark
case FS_REFS: return "#3EA281"; // Aquamarine Dark [*]
case FS_UFS: return "#AA8F2C"; // Accent Yellow Shadow [+]
case FS_ZFS: return "#C26825"; // Orange Dark [*]
case FS_ZFS: return "#984F18"; // Orange Shadow [*]
case FS_USED: return "#F8F8BA"; // Light Tan Yellow [*]
case FS_UNUSED: return "#FFFFFF"; // White
default: return "#000000"; // Black
@ -347,6 +348,7 @@ const Glib::ustring Utils::get_filesystem_string(FSType fstype)
*/
return _("cleared");
case FS_EXTENDED: return "extended";
case FS_BCACHEFS: return "bcachefs";
case FS_BTRFS: return "btrfs";
case FS_EXFAT: return "exfat";
case FS_EXT2: return "ext2";
@ -433,6 +435,7 @@ const Glib::ustring Utils::get_filesystem_software(FSType fstype)
{
switch (fstype)
{
case FS_BCACHEFS: return "bcachefs-tools";
case FS_BTRFS: return "btrfs-progs / btrfs-tools";
case FS_EXFAT: return "exfatprogs";
case FS_EXT2: return "e2fsprogs";
@ -532,14 +535,17 @@ bool Utils::kernel_version_at_least( int major_ver, int minor_ver, int patch_ver
Glib::ustring Utils::format_size( Sector sectors, Byte_Value sector_size )
{
std::stringstream ss ;
ss << std::setiosflags( std::ios::fixed ) << std::setprecision( 2 ) ;
ss << std::setiosflags(std::ios::fixed);
if ( (sectors * sector_size) < KIBIBYTE )
{
ss << std::setprecision(0);
ss << sector_to_unit( sectors, sector_size, UNIT_BYTE ) ;
return Glib::ustring::compose( _("%1 B"), ss .str() ) ;
}
else if ( (sectors * sector_size) < MEBIBYTE )
ss << std::setprecision(2);
if (sectors * sector_size < MEBIBYTE)
{
ss << sector_to_unit( sectors, sector_size, UNIT_KIB ) ;
return Glib::ustring::compose( _("%1 KiB"), ss .str() ) ;

View File

@ -3322,7 +3322,7 @@ void Win_GParted::activate_change_uuid()
Gtk::MESSAGE_WARNING,
Gtk::BUTTONS_OK,
true );
Glib::ustring tmp_msg = "" ;
Glib::ustring tmp_msg;
for ( i = 1 ; filesystem_object->get_custom_text( CTEXT_CHANGE_UUID_WARNING, i ) != "" ; i++ )
{
if ( i > 1 )
@ -3563,18 +3563,8 @@ bool Win_GParted::remove_non_empty_lvm2_pv_dialog( const OperationType optype )
Gtk::Label *label_members = Utils::mk_label("<b>" + Glib::ustring(members_label) + "</b>",
true, false, false, Gtk::ALIGN_START);
grid->attach(*label_members, 0, 1, 1, 1);
Glib::ustring members_str = "" ;
if ( ! members .empty() )
{
for ( unsigned int i = 0 ; i < members .size() ; i ++ )
{
if ( i > 0 )
members_str += "\n" ;
members_str += members[i] ;
}
}
Gtk::Label *value_members = Utils::mk_label(members_str, true, false, true, Gtk::ALIGN_START);
Gtk::Label *value_members = Utils::mk_label(Glib::build_path("\n", members),
true, false, true, Gtk::ALIGN_START);
grid->attach(*value_members, 1, 1, 1, 1);
value_members->get_accessible()->add_relationship(Atk::RELATION_LABELLED_BY,
label_members->get_accessible());

154
src/bcachefs.cc Normal file
View File

@ -0,0 +1,154 @@
/* Copyright (C) 2024 Mike Fleetwood
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "bcachefs.h"
#include "FileSystem.h"
#include "OperationDetail.h"
#include "Partition.h"
#include "Utils.h"
# include <glibmm/miscutils.h>
# include <glibmm/shell.h>
namespace GParted
{
FS bcachefs::get_filesystem_support()
{
FS fs(FS_BCACHEFS);
fs.busy = FS::GPARTED;
fs.move = FS::GPARTED;
fs.copy = FS::GPARTED;
fs.online_read = FS::GPARTED;
if (! Glib::find_program_in_path("bcachefs").empty())
{
fs.online_read = FS::EXTERNAL;
fs.create = FS::EXTERNAL;
fs.create_with_label = FS::EXTERNAL;
fs.read_label = FS::EXTERNAL;
fs.read_uuid = FS::EXTERNAL;
fs.grow = FS::EXTERNAL;
#ifdef ENABLE_ONLINE_RESIZE
if (Utils::kernel_version_at_least(3, 6, 0))
fs.online_grow = FS::EXTERNAL;
#endif
fs.check = FS::EXTERNAL;
}
fs_limits.min_size = 32 * MEBIBYTE;
return fs;
}
void bcachefs::set_used_sectors(Partition& partition)
{
// 'bcachefs fs usage' only reports usage for mounted file systems.
exit_status = Utils::execute_command("bcachefs fs usage " + Glib::shell_quote(partition.get_mountpoint()),
output, error, true);
if (exit_status != 0)
{
if (! output.empty())
partition.push_back_message(output);
if (! error.empty())
partition.push_back_message(error);
return;
}
// Device specific free space in bytes
long long dev_free_bytes = -1;
Glib::ustring::size_type index = output.find("free:");
if (index < output.length())
sscanf(output.substr(index).c_str(), "free: %lld", &dev_free_bytes);
// Device specific size in bytes
long long dev_capacity_bytes = -1;
index = output.find("capacity:");
if (index < output.length())
sscanf(output.substr(index).c_str(), "capacity: %lld", &dev_capacity_bytes);
if (dev_free_bytes > -1 && dev_capacity_bytes > -1)
{
Sector fs_size = dev_capacity_bytes / partition.sector_size;
Sector fs_free = dev_free_bytes / partition.sector_size;
partition.set_sector_usage(fs_size, fs_free);
// Block size is not available in 'bcachefs fs usage' output.
}
}
bool bcachefs::create(const Partition& new_partition, OperationDetail& operationdetail)
{
return ! execute_command("bcachefs format -L " + Glib::shell_quote(new_partition.get_filesystem_label()) +
" " + Glib::shell_quote(new_partition.get_path()),
operationdetail, EXEC_CHECK_STATUS);
}
void bcachefs::read_label(Partition& partition)
{
exit_status = Utils::execute_command("bcachefs show-super " + Glib::shell_quote(partition.get_path()),
output, error, true);
if (exit_status != 0)
{
if (! output.empty())
partition.push_back_message(output);
if (! error.empty())
partition.push_back_message(error);
return;
}
partition.set_filesystem_label(Utils::regexp_label(output, "^Label:[[:blank:]]*(.*)$"));
}
void bcachefs::read_uuid(Partition& partition)
{
exit_status = Utils::execute_command("bcachefs show-super " + Glib::shell_quote(partition.get_path()),
output, error, true);
if (exit_status != 0)
{
if (! output.empty())
partition.push_back_message(output);
if (! error.empty())
partition.push_back_message(error);
return;
}
partition.uuid = Utils::regexp_label(output, "^External UUID: *(" RFC4122_NONE_NIL_UUID_REGEXP ")");
}
bool bcachefs::resize(const Partition& partition_new, OperationDetail& operationdetail, bool fill_partition)
{
return ! execute_command("bcachefs device resize " + Glib::shell_quote(partition_new.get_path()),
operationdetail, EXEC_CHECK_STATUS);
}
bool bcachefs::check_repair(const Partition& partition, OperationDetail& operationdetail)
{
return ! execute_command("bcachefs fsck -f -y -v " + Glib::shell_quote(partition.get_path()),
operationdetail, EXEC_CHECK_STATUS);
}
} //GParted

View File

@ -128,7 +128,7 @@ bool f2fs::create( const Partition & new_partition, OperationDetail & operationd
bool f2fs::resize(const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition)
{
Glib::ustring size = "";
Glib::ustring size;
if (! fill_partition)
// resize.f2fs works in sector size units of whatever device the file
// system is currently stored on.

View File

@ -209,7 +209,7 @@ void fat16::read_label(Partition& partition)
bool fat16::write_label( const Partition & partition, OperationDetail & operationdetail )
{
Glib::ustring cmd = "" ;
Glib::ustring cmd;
if ( partition.get_filesystem_label().empty() )
cmd = "mlabel -c -i " + Glib::shell_quote(partition.get_path()) + " ::";
else

View File

@ -57,7 +57,7 @@ FS hfs::get_filesystem_support()
bool hfs::create( const Partition & new_partition, OperationDetail & operationdetail )
{
Glib::ustring cmd = "";
Glib::ustring cmd;
if( new_partition.get_filesystem_label().empty() )
cmd = "hformat " + Glib::shell_quote( new_partition.get_path() );
else

View File

@ -55,7 +55,7 @@ FS hfsplus::get_filesystem_support()
bool hfsplus::create( const Partition & new_partition, OperationDetail & operationdetail )
{
Glib::ustring cmd = "";
Glib::ustring cmd;
if( new_partition.get_filesystem_label().empty() )
cmd = "mkfs.hfsplus " + Glib::shell_quote( new_partition.get_path() );
else

View File

@ -151,7 +151,7 @@ bool luks::resize( const Partition & partition_new, OperationDetail & operationd
}
}
Glib::ustring size = "";
Glib::ustring size;
if ( ! fill_partition )
// Cryptsetup resize takes the size of the encryption mapping, not the
// size of the underlying block device. Both device-mapper and cryptsetup

View File

@ -105,7 +105,7 @@ bool lvm2_pv::create( const Partition & new_partition, OperationDetail & operati
bool lvm2_pv::resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition )
{
Glib::ustring size = "" ;
Glib::ustring size;
if ( ! fill_partition )
size = " --yes --setphysicalvolumesize " +
Utils::num_to_str(partition_new.get_byte_length() / KIBIBYTE) + "K ";

View File

@ -190,7 +190,7 @@ bool ntfs::create( const Partition & new_partition, OperationDetail & operationd
bool ntfs::resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition )
{
bool success;
Glib::ustring size = "" ;
Glib::ustring size;
if ( ! fill_partition )
size = " -s " + Utils::num_to_str(partition_new.get_byte_length());
Glib::ustring cmd = "ntfsresize --force --force" + size ;

View File

@ -176,7 +176,7 @@ bool reiserfs::create( const Partition & new_partition, OperationDetail & operat
bool reiserfs::resize( const Partition & partition_new, OperationDetail & operationdetail, bool fill_partition )
{
Glib::ustring size = "" ;
Glib::ustring size;
if ( ! fill_partition )
size = " -s " + Utils::num_to_str(partition_new.get_byte_length());
const Glib::ustring resize_cmd = "echo y | resize_reiserfs" + size +

View File

@ -50,6 +50,7 @@ gparted_core_OBJECTS = \
$(top_builddir)/src/SupportedFileSystems.$(OBJEXT) \
$(top_builddir)/src/SWRaid_Info.$(OBJEXT) \
$(top_builddir)/src/Utils.$(OBJEXT) \
$(top_builddir)/src/bcachefs.$(OBJEXT) \
$(top_builddir)/src/btrfs.$(OBJEXT) \
$(top_builddir)/src/exfat.$(OBJEXT) \
$(top_builddir)/src/ext2.$(OBJEXT) \