summaryrefslogtreecommitdiff
path: root/libparted/fs/ext2/interface.c
diff options
context:
space:
mode:
authorAnant Narayanan <anant@kix.in>2006-09-14 15:18:45 +0000
committerAnant Narayanan <anant@kix.in>2006-09-14 15:18:45 +0000
commit232dbda915dfcfec99e5983b7f53d57d4498a6aa (patch)
tree4d54060e75f7f2df07de6e83004551b610ac9865 /libparted/fs/ext2/interface.c
downloadparted-232dbda915dfcfec99e5983b7f53d57d4498a6aa.tar.gz
Fix ChangeLog
git-svn-id: svn://svn.debian.org/svn/parted/upstream/trunk@820 2d424fd7-7fe2-0310-af74-8bc65edeb173
Diffstat (limited to 'libparted/fs/ext2/interface.c')
-rw-r--r--libparted/fs/ext2/interface.c355
1 files changed, 355 insertions, 0 deletions
diff --git a/libparted/fs/ext2/interface.c b/libparted/fs/ext2/interface.c
new file mode 100644
index 0000000..7b48f4c
--- /dev/null
+++ b/libparted/fs/ext2/interface.c
@@ -0,0 +1,355 @@
+/*
+ interface.c -- parted binding glue to libext2resize
+ Copyright (C) 1998-2000 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 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, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+/* VERSION: libext2resize 1.1.6 (by Lennert)
+ * merged 1.1.11 changes (by Andrew)
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <parted/parted.h>
+#include "ext2.h"
+#include "parted_io.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_ext3)
+{
+ struct ext2_super_block sb;
+
+ if (!ped_geometry_read(geom, &sb, 2, 2))
+ return NULL;
+
+ if (EXT2_SUPER_MAGIC(sb) == EXT2_SUPER_MAGIC_CONST) {
+ PedSector block_size = 1 << (EXT2_SUPER_LOG_BLOCK_SIZE(sb) + 1);
+ 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 = (EXT2_SUPER_FEATURE_COMPAT(sb)
+ & EXT3_FEATURE_COMPAT_HAS_JOURNAL) != 0;
+
+ if (expect_ext3 != is_ext3)
+ 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_ext3);
+ } 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, 0);
+}
+
+static PedGeometry*
+_ext3_probe (PedGeometry* geom)
+{
+ return _ext2_generic_probe (geom, 1);
+}
+
+#ifndef DISCOVER_ONLY
+static int
+_ext2_clobber (PedGeometry* geom)
+{
+ struct ext2_super_block sb;
+
+ if (!ped_geometry_read(geom, &sb, 2, 2))
+ return 0;
+ if (EXT2_SUPER_MAGIC(sb) != EXT2_SUPER_MAGIC_CONST)
+ return 1;
+
+ sb.s_magic = 0;
+ return ped_geometry_write(geom, &sb, 2, 2);
+}
+
+static PedFileSystem*
+_ext2_open (PedGeometry* geom)
+{
+ PedFileSystem* fs;
+ struct ext2_fs* fs_info;
+ struct ext2_dev_handle* handle;
+
+ fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem));
+ if (!fs) goto error;
+
+ fs->type = &_ext2_type;
+ fs->geom = ped_geometry_duplicate (geom);
+ fs->checked = 1;
+
+ handle = ext2_make_dev_handle_from_parted_geometry(fs->geom);
+ if (!handle) goto error_free_fs;
+
+ fs_info = (struct ext2_fs*) ext2_open(handle, 0);
+ if (!fs_info) goto error_free_handle;
+
+ fs->type_specific = (void*) fs_info;
+ fs_info->opt_verbose = 0;
+
+ return fs;
+
+error_free_handle:
+ ext2_destroy_dev_handle(handle);
+error_free_fs:
+ ped_free(fs);
+error:
+ return NULL;
+}
+
+static PedFileSystem*
+_ext2_create (PedGeometry* geom, PedTimer* timer)
+{
+ PedFileSystem* fs;
+ struct ext2_fs* fs_info;
+ struct ext2_dev_handle* handle;
+
+ fs = (PedFileSystem*) ped_malloc (sizeof (PedFileSystem));
+ if (!fs) goto error;
+
+ fs->type = &_ext2_type;
+ fs->geom = ped_geometry_duplicate (geom);
+
+ handle = ext2_make_dev_handle_from_parted_geometry(fs->geom);
+ if (!handle) goto error_free_fs;
+
+ fs_info = ext2_mkfs (handle, 0, 0, 0, 0, -1, -1, timer);
+ if (!fs_info) goto error_free_handle;
+
+ fs->type_specific = (void*) fs_info;
+ fs_info->opt_verbose = 0;
+
+ return fs;
+
+error_free_handle:
+ ext2_destroy_dev_handle(handle);
+error_free_fs:
+ ped_free(fs);
+error:
+ return NULL;
+}
+
+static int
+_ext2_close (PedFileSystem *fs)
+{
+ struct ext2_dev_handle* handle;
+
+ handle = ((struct ext2_fs*)fs->type_specific)->devhandle;
+ ext2_close(fs->type_specific);
+ ext2_destroy_dev_handle(handle);
+
+ ped_free(fs);
+ return 1;
+}
+
+static int
+_ext2_check (PedFileSystem *fs, PedTimer* timer)
+{
+ ped_exception_throw (PED_EXCEPTION_INFORMATION, PED_EXCEPTION_OK,
+ _("The ext2 file system passed a basic check. For a more "
+ "comprehensive check, use the e2fsck program."));
+ return 1;
+}
+
+static int
+_ext2_resize (PedFileSystem* fs, PedGeometry* geom, PedTimer* timer)
+{
+ struct ext2_fs* f;
+ PedSector old_length = fs->geom->length;
+
+ PED_ASSERT (fs->geom->dev == geom->dev, return 0);
+
+ if (fs->geom->start != geom->start)
+ {
+ ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
+ PED_EXCEPTION_CANCEL,
+ _("Sorry, can't move the start of ext2 partitions yet!"));
+ return 0;
+ }
+
+ geom->dev->boot_dirty = 1;
+
+ f = (struct ext2_fs *) fs->type_specific;
+
+/* ensure that the geometry contains the new and old geometry */
+ if (old_length > geom->length) {
+ if (!ext2_resize_fs(f, geom->length >> (f->logsize - 9),
+ timer))
+ goto error;
+
+ fs->geom->length = geom->length;
+ fs->geom->end = fs->geom->start + geom->length - 1;
+ } else {
+ fs->geom->length = geom->length;
+ fs->geom->end = fs->geom->start + geom->length - 1;
+
+ if (!ext2_resize_fs(f, geom->length >> (f->logsize - 9),
+ timer))
+ goto error;
+ }
+ return 1;
+
+error:
+ return 0;
+}
+
+static PedConstraint*
+_ext2_get_create_constraint (const PedDevice* dev)
+{
+ PedGeometry full_dev;
+
+ if (!ped_geometry_init (&full_dev, dev, 0, dev->length - 1))
+ return NULL;
+
+ return ped_constraint_new (
+ ped_alignment_any, ped_alignment_any,
+ &full_dev, &full_dev,
+ 64, dev->length);
+}
+
+static PedConstraint*
+_ext2_get_resize_constraint (const PedFileSystem* fs)
+{
+ struct ext2_fs* f = (struct ext2_fs *) fs->type_specific;
+ PedDevice* dev = fs->geom->dev;
+ PedAlignment start_align;
+ PedGeometry start_sector;
+ PedGeometry full_dev;
+ PedSector min_size;
+
+ if (!ped_alignment_init (&start_align, fs->geom->start, 0))
+ return NULL;
+ if (!ped_geometry_init (&full_dev, dev, 0, dev->length - 1))
+ return NULL;
+ if (!ped_geometry_init (&start_sector, dev, fs->geom->start, 1))
+ return NULL;
+ min_size = (EXT2_SUPER_BLOCKS_COUNT(f->sb)
+ - EXT2_SUPER_FREE_BLOCKS_COUNT(f->sb))
+ * (f->blocksize / dev->sector_size);
+
+ return ped_constraint_new (&start_align, ped_alignment_any,
+ &start_sector, &full_dev, min_size,
+ dev->length);
+}
+#endif /* !DISCOVER_ONLY */
+
+static PedFileSystemOps _ext2_ops = {
+ probe: _ext2_probe,
+#ifndef DISCOVER_ONLY
+ clobber: _ext2_clobber,
+ open: _ext2_open,
+ create: _ext2_create,
+ close: _ext2_close,
+ check: _ext2_check,
+ resize: _ext2_resize,
+ copy: NULL,
+ get_create_constraint: _ext2_get_create_constraint,
+ get_copy_constraint: NULL,
+ get_resize_constraint: _ext2_get_resize_constraint
+#else /* !DISCOVER_ONLY */
+ clobber: NULL,
+ open: NULL,
+ create: NULL,
+ close: NULL,
+ check: NULL,
+ resize: NULL,
+ copy: NULL,
+ get_create_constraint: NULL,
+ get_copy_constraint: NULL,
+ get_resize_constraint: NULL
+#endif /* !DISCOVER_ONLY */
+};
+
+static PedFileSystemOps _ext3_ops = {
+ probe: _ext3_probe,
+#ifndef DISCOVER_ONLY
+ clobber: _ext2_clobber,
+ open: _ext2_open,
+ create: NULL,
+ close: _ext2_close,
+ check: _ext2_check,
+ resize: _ext2_resize,
+ copy: NULL,
+ get_create_constraint: _ext2_get_create_constraint,
+ get_copy_constraint: NULL,
+ get_resize_constraint: _ext2_get_resize_constraint
+#else /* !DISCOVER_ONLY */
+ clobber: NULL,
+ open: NULL,
+ create: NULL,
+ close: NULL,
+ check: NULL,
+ resize: NULL,
+ copy: NULL,
+ get_create_constraint: NULL,
+ get_copy_constraint: NULL,
+ get_resize_constraint: NULL
+#endif /* !DISCOVER_ONLY */
+};
+
+#define EXT23_BLOCK_SIZES ((int[6]){512, 1024, 2048, 4096, 8192, 0})
+
+static PedFileSystemType _ext2_type = {
+ next: NULL,
+ ops: &_ext2_ops,
+ name: "ext2",
+ block_sizes: EXT23_BLOCK_SIZES
+};
+
+static PedFileSystemType _ext3_type = {
+ next: NULL,
+ ops: &_ext3_ops,
+ name: "ext3",
+ block_sizes: EXT23_BLOCK_SIZES
+};
+
+void ped_file_system_ext2_init ()
+{
+ ped_file_system_type_register (&_ext2_type);
+ ped_file_system_type_register (&_ext3_type);
+}
+
+void ped_file_system_ext2_done ()
+{
+ ped_file_system_type_unregister (&_ext2_type);
+ ped_file_system_type_unregister (&_ext3_type);
+}