diff options
author | Anant Narayanan <anant@kix.in> | 2006-09-14 15:18:45 +0000 |
---|---|---|
committer | Anant Narayanan <anant@kix.in> | 2006-09-14 15:18:45 +0000 |
commit | 232dbda915dfcfec99e5983b7f53d57d4498a6aa (patch) | |
tree | 4d54060e75f7f2df07de6e83004551b610ac9865 /libparted/fs/ext2/interface.c | |
download | parted-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.c | 355 |
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); +} |