diff --git a/README.md b/README.md
index e5eb67dac..13d192a37 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,7 @@ Following storage technologies are supported by libblockdev
- partitions
- MSDOS, GPT
- filesystem operations
- - ext2, ext3, ext4, xfs, vfat, ntfs, exfat, btrfs, f2fs, nilfs2, udf
+ - ext2, ext3, ext4, xfs, vfat, ntfs, exfat, btrfs, f2fs, nilfs2, udf, bcachefs
- mounting
- LVM
- thin provisioning, LVM RAID, cache, LVM VDO
diff --git a/misc/install-test-dependencies.yml b/misc/install-test-dependencies.yml
index 14a04e4ff..475160d11 100644
--- a/misc/install-test-dependencies.yml
+++ b/misc/install-test-dependencies.yml
@@ -69,6 +69,10 @@
- xfsprogs
when: ansible_distribution == 'Fedora' and test_dependencies|bool
+ - name: Install bcachefs-tools test dependency (Fedora)
+ package: name=bcachefs-tools state=present
+ when: ansible_distribution == 'Fedora' and ansible_distribution_version == '40' and test_dependencies|bool
+
####### CentOS 8
- name: Install basic build tools (CentOS 8)
package: name={{item}} state=present
diff --git a/src/lib/plugin_apis/fs.api b/src/lib/plugin_apis/fs.api
index 1685c23e5..ad9716ff1 100644
--- a/src/lib/plugin_apis/fs.api
+++ b/src/lib/plugin_apis/fs.api
@@ -527,6 +527,7 @@ typedef enum {
BD_FS_TECH_EXFAT,
BD_FS_TECH_BTRFS,
BD_FS_TECH_UDF,
+ BD_FS_TECH_BCACHEFS,
} BDFSTech;
typedef enum {
@@ -811,6 +812,63 @@ GType bd_fs_udf_info_get_type () {
return type;
}
+/**
+ * BDFSBcachefsInfo:
+ * @uuid: uuid of the filesystem
+ * @size: size of the filesystem in bytes
+ * @free_space: free space on the filesystem in bytes
+ */
+typedef struct BDFSBcachefsInfo {
+ gchar *uuid;
+ guint64 size;
+ guint64 free_space;
+} BDFSBcachefsInfo;
+
+/**
+ * bd_fs_bcachefs_info_copy: (skip)
+ * @data: (nullable): %BDFSBcachefsInfo to copy
+ *
+ * Creates a new copy of @data.
+ */
+BDFSBcachefsInfo* bd_fs_bcachefs_info_copy (BDFSBcachefsInfo *data) {
+ if (data == NULL)
+ return NULL;
+
+ BDFSBcachefsInfo *ret = g_new0 (BDFSBcachefsInfo, 1);
+
+ ret->uuid = g_strdup (data->uuid);
+ ret->size = data->size;
+ ret->free_space = data->free_space;
+
+ return ret;
+}
+
+/**
+ * bd_fs_bcachefs_info_free: (skip)
+ * @data: (nullable): %BDFSBcachefsInfo to free
+ *
+ * Frees @data.
+ */
+void bd_fs_bcachefs_info_free (BDFSBcachefsInfo *data) {
+ if (data == NULL)
+ return;
+
+ g_free (data->uuid);
+ g_free (data);
+}
+
+GType bd_fs_bcachefs_info_get_type () {
+ static GType type = 0;
+
+ if (G_UNLIKELY(type == 0)) {
+ type = g_boxed_type_register_static("BDFSBcachefsInfo",
+ (GBoxedCopyFunc) bd_fs_bcachefs_info_copy,
+ (GBoxedFreeFunc) bd_fs_bcachefs_info_free);
+ }
+
+ return type;
+}
+
/**
* bd_fs_is_tech_avail:
* @tech: the queried tech
@@ -2634,6 +2692,35 @@ gboolean bd_fs_udf_check_uuid (const gchar *uuid, GError **error);
*/
BDFSUdfInfo* bd_fs_udf_get_info (const gchar *device, GError **error);
+/**
+ * bd_fs_bcachefs_mkfs:
+ * @device: the device to create a new bcachefs fs on
+ * @extra: (nullable) (array zero-terminated=1): extra options for the creation (right now
+ * passed to the 'mkfs.bcachefs' utility)
+ * @error: (out) (optional): place to store error (if any)
+ *
+ * Returns: whether a new bcachefs fs was successfully created on @device or not
+ *
+ * Tech category: %BD_FS_TECH_BCACHEFS-%BD_FS_TECH_MODE_MKFS
+ *
+ */
+gboolean bd_fs_bcachefs_mkfs (const gchar *device, const BDExtraArg **extra, GError **error);
+
+/**
+ * bd_fs_bcachefs_get_info:
+ * @mpoint: a mountpoint of the bcachefs filesystem to get information about
+ * @error: (out) (optional): place to store error (if any)
+ *
+ * Returns: (transfer full): information about the file system on @device or
+ * %NULL in case of error
+ *
+ * Note: This function WON'T WORK for multi device bcachefs filesystems,
+ * for more complicated setups use the bcachefs plugin instead.
+ *
+ * Tech category: %BD_FS_TECH_BCACHEFS-%BD_FS_TECH_MODE_QUERY
+ */
+BDFSBcachefsInfo* bd_fs_bcachefs_get_info (const gchar *mpoint, GError **error);
+
typedef enum {
BD_FS_SUPPORT_SET_LABEL = 1 << 1,
BD_FS_SUPPORT_SET_UUID = 1 << 2
diff --git a/src/plugins/fs.c b/src/plugins/fs.c
index 8fcf0bb06..40e61a13c 100644
--- a/src/plugins/fs.c
+++ b/src/plugins/fs.c
@@ -41,6 +41,7 @@ extern gboolean bd_fs_nilfs2_is_tech_avail (BDFSTech tech, guint64 mode, GError
extern gboolean bd_fs_exfat_is_tech_avail (BDFSTech tech, guint64 mode, GError **error);
extern gboolean bd_fs_btrfs_is_tech_avail (BDFSTech tech, guint64 mode, GError **error);
extern gboolean bd_fs_udf_is_tech_avail (BDFSTech tech, guint64 mode, GError **error);
+extern gboolean bd_fs_bcachefs_is_tech_avail (BDFSTech tech, guint64 mode, GError **error);
/**
* bd_fs_error_quark: (skip)
@@ -116,6 +117,8 @@ gboolean bd_fs_is_tech_avail (BDFSTech tech, guint64 mode, GError **error) {
return bd_fs_btrfs_is_tech_avail (tech, mode, error);
case BD_FS_TECH_UDF:
return bd_fs_udf_is_tech_avail (tech, mode, error);
+ case BD_FS_TECH_BCACHEFS:
+ return bd_fs_bcachefs_is_tech_avail (tech, mode, error);
/* coverity[dead_error_begin] */
default:
/* this should never be reached (see the comparison with LAST_FS
diff --git a/src/plugins/fs.h b/src/plugins/fs.h
index 3c38f5cb0..071efd0d1 100644
--- a/src/plugins/fs.h
+++ b/src/plugins/fs.h
@@ -23,7 +23,7 @@ typedef enum {
/* XXX: where the file systems start at the enum of technologies */
#define BD_FS_OFFSET 2
-#define BD_FS_LAST_FS 13
+#define BD_FS_LAST_FS 14
typedef enum {
BD_FS_TECH_GENERIC = 0,
BD_FS_TECH_MOUNT = 1,
@@ -38,6 +38,7 @@ typedef enum {
BD_FS_TECH_EXFAT = 10,
BD_FS_TECH_BTRFS = 11,
BD_FS_TECH_UDF = 12,
+ BD_FS_TECH_BCACHEFS = 13,
} BDFSTech;
/* XXX: number of the highest bit of all modes */
@@ -80,3 +81,4 @@ gboolean bd_fs_is_tech_avail (BDFSTech tech, guint64 mode, GError **error);
#include "fs/exfat.h"
#include "fs/btrfs.h"
#include "fs/udf.h"
+#include "fs/bcachefs.h"
diff --git a/src/plugins/fs/Makefile.am b/src/plugins/fs/Makefile.am
index 7d4849c0e..2998626ae 100644
--- a/src/plugins/fs/Makefile.am
+++ b/src/plugins/fs/Makefile.am
@@ -19,7 +19,8 @@ libbd_fs_la_SOURCES = ../check_deps.c ../check_deps.h \
nilfs.c nilfs.h \
exfat.c exfat.h \
btrfs.c btrfs.h \
- udf.c udf.h
+ udf.c udf.h \
+ bcachefs.c bcachefs.h
libincludefsdir = $(includedir)/blockdev/fs/
libincludefs_HEADERS = ext.h \
diff --git a/src/plugins/fs/bcachefs.c b/src/plugins/fs/bcachefs.c
new file mode 100644
index 000000000..ad8fcc1a2
--- /dev/null
+++ b/src/plugins/fs/bcachefs.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2023 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see .
+ *
+ * Author: Jelle van der Waa
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "bcachefs.h"
+#include "fs.h"
+#include "common.h"
+
+static volatile guint avail_deps = 0;
+static GMutex deps_check_lock;
+
+#define DEPS_MKFSBCACHEFS 0
+#define DEPS_MKFSBCACHEFS_MASK (1 << DEPS_MKFSBCACHEFS)
+#define DEPS_BCACHEFSCK 1
+#define DEPS_BCACHEFSCK_MASK (1 << DEPS_BCACHEFSCK)
+#define DEPS_BCACHEFS 2
+#define DEPS_BCACHEFS_MASK (1 << DEPS_BCACHEFS)
+
+#define DEPS_LAST 3
+
+static const UtilDep deps[DEPS_LAST] = {
+ {"mkfs.bcachefs", NULL, NULL, NULL},
+ {"fsck.bcachefs", NULL, NULL, NULL},
+ {"bcachefs", NULL, NULL, NULL},
+};
+
+static guint32 fs_mode_util[BD_FS_MODE_LAST+1] = {
+ DEPS_MKFSBCACHEFS_MASK, /* mkfs */
+ 0, /* wipe */
+ DEPS_BCACHEFSCK_MASK, /* check */
+ DEPS_BCACHEFSCK_MASK, /* repair */
+ DEPS_BCACHEFS_MASK, /* set-label */
+ DEPS_BCACHEFS_MASK, /* query */
+ DEPS_BCACHEFS_MASK, /* resize */
+};
+
+#define UNUSED __attribute__((unused))
+
+/**
+ * bd_fs_bcachefs_is_tech_avail:
+ * @tech: the queried tech
+ * @mode: a bit mask of queried modes of operation (#BDFSTechMode) for @tech
+ * @error: (out) (optional): place to store error (details about why the @tech-@mode combination is not available)
+ *
+ * Returns: whether the @tech-@mode combination is available -- supported by the
+ * plugin implementation and having all the runtime dependencies available
+ */
+gboolean __attribute__ ((visibility ("hidden")))
+bd_fs_bcachefs_is_tech_avail (BDFSTech tech UNUSED, guint64 mode, GError **error) {
+ guint32 required = 0;
+ guint i = 0;
+
+ for (i = 0; i <= BD_FS_MODE_LAST; i++)
+ if (mode & (1 << i))
+ required |= fs_mode_util[i];
+
+ return check_deps (&avail_deps, required, deps, DEPS_LAST, &deps_check_lock, error);
+}
+
+/**
+ * bd_fs_bcachefs_info_copy: (skip)
+ *
+ * Creates a new copy of @data.
+ */
+BDFSBcachefsInfo* bd_fs_bcachefs_info_copy (BDFSBcachefsInfo *data) {
+ if (data == NULL)
+ return NULL;
+
+ g_info("copying");
+ BDFSBcachefsInfo *ret = g_new0 (BDFSBcachefsInfo, 1);
+
+ ret->uuid = g_strdup (data->uuid);
+ ret->size = data->size;
+ ret->free_space = data->free_space;
+
+ return ret;
+}
+
+/**
+ * bd_fs_bcachefs_info_free: (skip)
+ *
+ * Frees @data.
+ */
+void bd_fs_bcachefs_info_free (BDFSBcachefsInfo *data) {
+ if (data == NULL)
+ return;
+ g_free (data->uuid);
+ g_free (data);
+}
+
+BDExtraArg __attribute__ ((visibility ("hidden")))
+**bd_fs_bcachefs_mkfs_options (BDFSMkfsOptions *options, const BDExtraArg **extra) {
+ GPtrArray *options_array = g_ptr_array_new ();
+ const BDExtraArg **extra_p = NULL;
+
+ if (options->label && g_strcmp0 (options->label, "") != 0)
+ g_ptr_array_add (options_array, bd_extra_arg_new ("-L", options->label));
+
+ if (options->uuid && g_strcmp0 (options->uuid, "") != 0)
+ g_ptr_array_add (options_array, bd_extra_arg_new ("-U", options->uuid));
+
+ if (options->force)
+ g_ptr_array_add (options_array, bd_extra_arg_new ("-f", ""));
+
+ if (extra) {
+ for (extra_p = extra; *extra_p; extra_p++)
+ g_ptr_array_add (options_array, bd_extra_arg_copy ((BDExtraArg *) *extra_p));
+ }
+
+ g_ptr_array_add (options_array, NULL);
+
+ return (BDExtraArg **) g_ptr_array_free (options_array, FALSE);
+}
+
+/**
+ * bd_fs_bcachefs_mkfs:
+ * @device: the device to create a new bcachefs fs on
+ * @extra: (nullable) (array zero-terminated=1): extra options for the creation (right now
+ * passed to the 'mkfs.bcachefs' utility)
+ * @error: (out) (optional): place to store error (if any)
+ *
+ * Returns: whether a new bcachefs fs was successfully created on @device or not
+ *
+ * Tech category: %BD_FS_TECH_BCACHEFS-%BD_FS_TECH_MODE_MKFS
+ *
+ */
+gboolean bd_fs_bcachefs_mkfs (const gchar *device, const BDExtraArg **extra, GError **error) {
+ const gchar *args[3] = {"mkfs.bcachefs", device, NULL};
+
+ if (!check_deps (&avail_deps, DEPS_MKFSBCACHEFS_MASK, deps, DEPS_LAST, &deps_check_lock, error))
+ return FALSE;
+
+ return bd_utils_exec_and_report_error (args, extra, error);
+}
+
+/**
+ * bd_fs_bcachefs_get_info:
+ * @mpoint: a mountpoint of the bcachefs filesystem to get information about
+ * @error: (out) (optional): place to store error (if any)
+ *
+ * Returns: (transfer full): information about the file system on @device or
+ * %NULL in case of error
+ *
+ * Note: This function WON'T WORK for multi device bcachefs filesystems,
+ * for more complicated setups use the btrfs plugin instead.
+ *
+ * Tech category: %BD_FS_TECH_BCACHEFS-%BD_FS_TECH_MODE_QUERY
+ */
+BDFSBcachefsInfo* bd_fs_bcachefs_get_info (const gchar *mpoint, GError **error) {
+ const gchar *args[5] = {"bcachefs", "fs", "usage", mpoint, NULL};
+ gboolean success = FALSE;
+ gchar *output = NULL;
+ gchar const * const pattern = "Filesystem:\\s+(?P\\S+)\\s+" \
+ "Size:\\s+(?P\\d+)\\s+" \
+ "Used:\\s+(?P\\d+)\\s+\\S+" ;
+ GRegex *regex = NULL;
+ GMatchInfo *match_info = NULL;
+ BDFSBcachefsInfo *ret = NULL;
+ gchar *item = NULL;
+ guint64 used = 0;
+
+ if (!check_deps (&avail_deps, DEPS_BCACHEFS_MASK, deps, DEPS_LAST, &deps_check_lock, error))
+ return NULL;
+
+ regex = g_regex_new (pattern, G_REGEX_EXTENDED, 0, error);
+ if (!regex) {
+ bd_utils_log_format (BD_UTILS_LOG_WARNING, "Failed to create new GRegex");
+ /* error is already populated */
+ return NULL;
+ }
+
+ success = bd_utils_exec_and_capture_output (args, NULL, &output, error);
+ if (!success) {
+ /* error is already populated */
+ return NULL;
+ }
+
+ success = g_regex_match (regex, output, 0, &match_info);
+ if (!success) {
+ g_regex_unref (regex);
+ g_match_info_free (match_info);
+ g_free (output);
+ return NULL;
+ }
+
+ ret = g_new (BDFSBcachefsInfo, 1);
+
+ ret->uuid = g_match_info_fetch_named (match_info, "uuid");
+ item = g_match_info_fetch_named (match_info, "size");
+ ret->size = g_ascii_strtoull (item, NULL, 0);
+ g_free (item);
+ item = g_match_info_fetch_named (match_info, "used");
+ used = g_ascii_strtoull (item, NULL, 0);
+ g_free (item);
+
+ g_match_info_free (match_info);
+ g_regex_unref (regex);
+ g_free (output);
+
+ // TODO error out if there are more then 1 devices
+ // TODO: detect label
+ ret->free_space = ret->size - used;
+
+ return ret;
+}
diff --git a/src/plugins/fs/bcachefs.h b/src/plugins/fs/bcachefs.h
new file mode 100644
index 000000000..0f80ed793
--- /dev/null
+++ b/src/plugins/fs/bcachefs.h
@@ -0,0 +1,19 @@
+#include
+#include
+
+#ifndef BD_FS_BCACHEFS
+#define BD_FS_BCACHEFS
+
+typedef struct BDFSBcachefsInfo {
+ gchar *uuid;
+ guint64 size;
+ guint64 free_space;
+} BDFSBcachefsInfo;
+
+BDFSBcachefsInfo* bd_fs_bcachefs_info_copy (BDFSBcachefsInfo *data);
+void bd_fs_bcachefs_info_free (BDFSBcachefsInfo *data);
+
+gboolean bd_fs_bcachefs_mkfs (const gchar *device, const BDExtraArg **extra, GError **error);
+BDFSBcachefsInfo* bd_fs_bcachefs_get_info (const gchar *device, GError **error);
+
+#endif /* BD_FS_BCACHEFS */
diff --git a/src/plugins/fs/generic.c b/src/plugins/fs/generic.c
index add470123..3b29a6dc8 100644
--- a/src/plugins/fs/generic.c
+++ b/src/plugins/fs/generic.c
@@ -153,6 +153,14 @@ static const BDFSFeatures fs_features[BD_FS_LAST_FS] = {
.features = BD_FS_FEATURE_OWNERS | BD_FS_FEATURE_PARTITION_TABLE,
.partition_id = "0x07",
.partition_type = "ebd0a0a2-b9e5-4433-87c0-68b6b72699c7" },
+ /* BCACHEFS */
+ { .resize = 0,
+ .mkfs = BD_FS_MKFS_LABEL | BD_FS_MKFS_UUID,
+ .fsck = BD_FS_FSCK_CHECK | BD_FS_FSCK_REPAIR,
+ .configure = 0,
+ .features = BD_FS_FEATURE_OWNERS | BD_FS_FEATURE_PARTITION_TABLE,
+ .partition_id = "0x83", // TODO: figure out
+ .partition_type = "0fc63daf-8483-4772-8e79-3d69d8477de4" }, // TODO: figure out
};
/**
@@ -291,6 +299,15 @@ const BDFSInfo fs_info[BD_FS_LAST_FS] = {
.label_util = "udflabel",
.info_util = "udfinfo",
.uuid_util = "udflabel" },
+ /* BCACHEFS */
+ { .type = "bcachefs",
+ .mkfs_util = "mkfs.bcachefs",
+ .check_util = "fsck.bcachefs",
+ .repair_util = "fsck.bcachefs",
+ .resize_util = "bcachefs",
+ .label_util = "bcachefs",
+ .info_util = "bcachefs",
+ .uuid_util = "bcachefs" },
};
/**
@@ -345,6 +362,8 @@ static BDFSTech fstype_to_tech (const gchar *fstype) {
return BD_FS_TECH_BTRFS;
} else if (g_strcmp0 (fstype, "udf") == 0) {
return BD_FS_TECH_UDF;
+ } else if (g_strcmp0 (fstype, "bcachefs") == 0) {
+ return BD_FS_TECH_BCACHEFS;
} else {
return BD_FS_TECH_GENERIC;
}
@@ -1897,6 +1916,7 @@ extern BDExtraArg** bd_fs_vfat_mkfs_options (BDFSMkfsOptions *options, const BDE
extern BDExtraArg** bd_fs_xfs_mkfs_options (BDFSMkfsOptions *options, const BDExtraArg **extra);
extern BDExtraArg** bd_fs_btrfs_mkfs_options (BDFSMkfsOptions *options, const BDExtraArg **extra);
extern BDExtraArg** bd_fs_udf_mkfs_options (BDFSMkfsOptions *options, const BDExtraArg **extra);
+extern BDExtraArg** bd_fs_bcachefs_mkfs_options (BDFSMkfsOptions *options, const BDExtraArg **extra);
/**
* bd_fs_mkfs:
@@ -1960,6 +1980,9 @@ gboolean bd_fs_mkfs (const gchar *device, const gchar *fstype, BDFSMkfsOptions *
} else if (g_strcmp0 (fstype, "udf") == 0) {
extra_args = bd_fs_udf_mkfs_options (options, extra);
ret = bd_fs_udf_mkfs (device, NULL, NULL, 0, (const BDExtraArg **) extra_args, error);
+ } else if (g_strcmp0 (fstype, "bcachefs") == 0) {
+ extra_args = bd_fs_bcachefs_mkfs_options (options, extra);
+ ret = bd_fs_bcachefs_mkfs (device, (const BDExtraArg **) extra_args, error);
} else {
g_set_error (error, BD_FS_ERROR, BD_FS_ERROR_NOT_SUPPORTED,
"Filesystem '%s' is not supported.", fstype);
diff --git a/tests/fs_tests/__init__.py b/tests/fs_tests/__init__.py
index b7474897e..7ee579cac 100644
--- a/tests/fs_tests/__init__.py
+++ b/tests/fs_tests/__init__.py
@@ -14,3 +14,4 @@
from .xfs_test import *
from .btrfs_test import *
from .udf_test import *
+from .bcachefs_test import *
diff --git a/tests/fs_tests/bcachefs_test.py b/tests/fs_tests/bcachefs_test.py
new file mode 100644
index 000000000..ae8598dad
--- /dev/null
+++ b/tests/fs_tests/bcachefs_test.py
@@ -0,0 +1,72 @@
+import os
+import re
+import subprocess
+import unittest
+import tempfile
+
+from .fs_test import FSTestCase, FSNoDevTestCase, mounted
+
+import overrides_hack
+import utils
+from utils import TestTags, tag_test
+
+from gi.repository import BlockDev, GLib
+
+
+def bcachefs_supported():
+ """Alternative try to modinfo bcachefs?"""
+
+ kernel_version = os.uname()[2]
+ version_split = kernel_version.rsplit('.')
+ major_ver, minor_ver = int(version_split[0]), int(version_split[1])
+ if major_ver > 6:
+ return True
+ elif major_ver == 6 and minor_ver >= 7:
+ return True
+
+ return False
+
+
+class BcachefsTestCase(FSTestCase):
+ def setUp(self):
+ if not self.bcachefs_avail:
+ self.skipTest("skipping bcachefs: not available")
+
+ if not bcachefs_supported():
+ self.skipTest("skipping Bcachefs: kernel version not supported")
+
+ self.mount_dir = tempfile.mkdtemp(prefix="libblockdev.", suffix="bcachefs_test")
+
+ super(BcachefsTestCase, self).setUp()
+
+
+class BcachefsNoDevTestCase(FSNoDevTestCase):
+ def setUp(self):
+ if not self.bcachefs_avail:
+ self.skipTest("skipping Bcachefs: not available")
+
+ if not bcachefs_supported():
+ self.skipTest("skipping Bcachefs: kernel version not supported")
+
+ super(BcachefsNoDevTestCase, self).setUp()
+
+
+class BcachefsTestMkfs(BcachefsTestCase):
+ def test_bcachefs_mkfs(self):
+ """Verify that it is possible to create a new bcachefs file system"""
+
+ with self.assertRaises(GLib.GError):
+ BlockDev.fs_bcachefs_mkfs("/non/existing/device", None)
+
+ succ = BlockDev.fs_bcachefs_mkfs(self.loop_dev, None)
+ self.assertTrue(succ)
+
+ # just try if we can mount the file system
+ with mounted(self.loop_dev, self.mount_dir):
+ pass
+
+ # check the fstype
+ fstype = BlockDev.fs_get_fstype(self.loop_dev)
+ self.assertEqual(fstype, "bcachefs")
+
+ BlockDev.fs_wipe(self.loop_dev, True)
diff --git a/tests/fs_tests/fs_test.py b/tests/fs_tests/fs_test.py
index 4cecb9e98..d5008b3c9 100644
--- a/tests/fs_tests/fs_test.py
+++ b/tests/fs_tests/fs_test.py
@@ -95,6 +95,12 @@ def setUpClass(cls):
except Exception :
cls.udf_avail = False
+ try:
+ cls.bcachefs_avail = BlockDev.fs_is_tech_avail(BlockDev.FSTech.BCACHEFS,
+ BlockDev.FSTechMode.MKFS |
+ BlockDev.FSTechMode.SET_LABEL)
+ except Exception :
+ cls.bcachefs_avail = False
class FSTestCase(FSNoDevTestCase):
diff --git a/tests/fs_tests/generic_test.py b/tests/fs_tests/generic_test.py
index fb8902297..8313789c8 100644
--- a/tests/fs_tests/generic_test.py
+++ b/tests/fs_tests/generic_test.py
@@ -1328,4 +1328,4 @@ def test_supported_filesystems(self):
filesystems = BlockDev.fs_supported_filesystems()
self.assertListEqual(filesystems,
["ext2", "ext3", "ext4", "xfs", "vfat", "ntfs",
- "f2fs", "nilfs2", "exfat", "btrfs", "udf"])
+ "f2fs", "nilfs2", "exfat", "btrfs", "udf", "bcachefs"])