summaryrefslogtreecommitdiffstats
path: root/libparted/fs/ext2/interface.c
diff options
context:
space:
mode:
Diffstat (limited to 'libparted/fs/ext2/interface.c')
-rw-r--r--libparted/fs/ext2/interface.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/libparted/fs/ext2/interface.c b/libparted/fs/ext2/interface.c
new file mode 100644
index 0000000..7e0b197
--- /dev/null
+++ b/libparted/fs/ext2/interface.c
@@ -0,0 +1,163 @@
+/*
+ interface.c -- parted binding glue to libext2resize
+ Copyright (C) 1998-2000, 2007-2014, 2019-2023 Free Software Foundation,
+ Inc.
+
+ 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 3 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/>.
+*/
+
+/* VERSION: libext2resize 1.1.6 (by Lennert)
+ * merged 1.1.11 changes (by Andrew)
+ */
+
+#include <config.h>
+
+#include <parted/parted.h>
+#include "ext2.h"
+
+static PedFileSystemType _ext2_type;
+static PedFileSystemType _ext3_type;
+
+struct ext2_dev_handle* ext2_make_dev_handle_from_parted_geometry(PedGeometry* geom);
+
+static PedGeometry*
+_ext2_generic_probe (PedGeometry* geom, int expect_ext_ver)
+{
+ struct ext2_super_block *sb;
+ const int sectors = (4096 + geom->dev->sector_size - 1) /
+ geom->dev->sector_size;
+ uint8_t *buf = alloca (sectors * geom->dev->sector_size);
+ if (!ped_geometry_read(geom, buf, 0, sectors))
+ return NULL;
+ sb = (struct ext2_super_block *)(buf+1024);
+
+ if (EXT2_SUPER_MAGIC(*sb) == EXT2_SUPER_MAGIC_CONST) {
+ PedSector block_size = (EXT2_MIN_BLOCK_SIZE << (EXT2_SUPER_LOG_BLOCK_SIZE(*sb))) / geom->dev->sector_size;
+ PedSector block_count = EXT2_SUPER_BLOCKS_COUNT(*sb);
+ PedSector group_blocks = EXT2_SUPER_BLOCKS_PER_GROUP(*sb);
+ PedSector group_nr = EXT2_SUPER_BLOCK_GROUP_NR(*sb);
+ PedSector first_data_block = EXT2_SUPER_FIRST_DATA_BLOCK(*sb);
+ int version = EXT2_SUPER_REV_LEVEL(*sb);
+ int is_ext3 = 0;
+ int is_ext4 = 0;
+
+ is_ext3 = (EXT2_SUPER_FEATURE_COMPAT (*sb)
+ & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0;
+ if (is_ext3) {
+ is_ext4 = ((EXT2_SUPER_FEATURE_RO_COMPAT (*sb)
+ & EXT4_FEATURE_RO_COMPAT_HUGE_FILE)
+ || (EXT2_SUPER_FEATURE_RO_COMPAT (*sb)
+ & EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
+ || (EXT2_SUPER_FEATURE_RO_COMPAT (*sb)
+ & EXT4_FEATURE_RO_COMPAT_DIR_NLINK)
+ || (EXT2_SUPER_FEATURE_INCOMPAT (*sb)
+ & EXT4_FEATURE_INCOMPAT_EXTENTS)
+ || (EXT2_SUPER_FEATURE_INCOMPAT (*sb)
+ & EXT4_FEATURE_INCOMPAT_64BIT)
+ || (EXT2_SUPER_FEATURE_INCOMPAT (*sb)
+ & EXT4_FEATURE_INCOMPAT_FLEX_BG));
+ if (is_ext4)
+ is_ext3 = 0;
+ }
+ if (expect_ext_ver == 2 && (is_ext3 || is_ext4))
+ return NULL;
+ if (expect_ext_ver == 3 && !is_ext3)
+ return NULL;
+ else if (expect_ext_ver == 4 && !is_ext4)
+ return NULL;
+
+ if (version > 0 && group_nr > 0) {
+ PedSector start;
+ PedGeometry probe_geom;
+
+ start = geom->start
+ - group_blocks * group_nr
+ - first_data_block;
+
+ if (start < 0)
+ return NULL;
+ ped_geometry_init (&probe_geom, geom->dev,
+ start, block_count * block_size);
+ return _ext2_generic_probe (&probe_geom,
+ expect_ext_ver);
+ } else {
+ return ped_geometry_new (geom->dev, geom->start,
+ block_count * block_size);
+ }
+ }
+
+ return NULL;
+}
+
+static PedGeometry*
+_ext2_probe (PedGeometry* geom)
+{
+ return _ext2_generic_probe (geom, 2);
+}
+
+static PedGeometry*
+_ext3_probe (PedGeometry* geom)
+{
+ return _ext2_generic_probe (geom, 3);
+}
+
+static PedGeometry*
+_ext4_probe (PedGeometry* geom)
+{
+ return _ext2_generic_probe (geom, 4);
+}
+
+static PedFileSystemOps _ext2_ops = {
+ probe: _ext2_probe,
+};
+
+static PedFileSystemOps _ext3_ops = {
+ probe: _ext3_probe,
+};
+
+static PedFileSystemOps _ext4_ops = {
+ probe: _ext4_probe,
+};
+
+static PedFileSystemType _ext2_type = {
+ next: NULL,
+ ops: &_ext2_ops,
+ name: "ext2",
+};
+
+static PedFileSystemType _ext3_type = {
+ next: NULL,
+ ops: &_ext3_ops,
+ name: "ext3",
+};
+
+static PedFileSystemType _ext4_type = {
+ next: NULL,
+ ops: &_ext4_ops,
+ name: "ext4",
+};
+
+void ped_file_system_ext2_init ()
+{
+ ped_file_system_type_register (&_ext2_type);
+ ped_file_system_type_register (&_ext3_type);
+ ped_file_system_type_register (&_ext4_type);
+}
+
+void ped_file_system_ext2_done ()
+{
+ ped_file_system_type_unregister (&_ext2_type);
+ ped_file_system_type_unregister (&_ext3_type);
+ ped_file_system_type_unregister (&_ext4_type);
+}