summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Meyering <meyering@redhat.com>2011-05-16 12:11:23 +0200
committerJim Meyering <meyering@redhat.com>2011-05-27 17:07:45 +0200
commit884a76f6ea4f6a2009337ab0f7b3caee6cbd6efe (patch)
tree18cf692bc8d6e5f17ebb5aa64f7058e0e4ee1af8
parent58413d67ecb80740a07c3582d31883884cbb1966 (diff)
downloadparted-884a76f6ea4f6a2009337ab0f7b3caee6cbd6efe.tar.gz
ext2: remove all-but-probe FS-related code
-rw-r--r--configure.ac1
-rw-r--r--libparted/fs/ext2/Makefile.am16
-rw-r--r--libparted/fs/ext2/ext2.c795
-rw-r--r--libparted/fs/ext2/ext2.h166
-rw-r--r--libparted/fs/ext2/ext2_block_relocator.c921
-rw-r--r--libparted/fs/ext2/ext2_buffer.c445
-rw-r--r--libparted/fs/ext2/ext2_inode_relocator.c598
-rw-r--r--libparted/fs/ext2/ext2_meta.c145
-rw-r--r--libparted/fs/ext2/ext2_mkfs.c633
-rw-r--r--libparted/fs/ext2/ext2_resize.c730
-rw-r--r--libparted/fs/ext2/interface.c191
-rw-r--r--libparted/fs/ext2/parted_io.c137
-rw-r--r--libparted/fs/ext2/parted_io.h26
-rw-r--r--libparted/fs/ext2/tune.c39
-rw-r--r--libparted/fs/ext2/tune.h29
15 files changed, 5 insertions, 4867 deletions
diff --git a/configure.ac b/configure.ac
index 2aa257a..76ac8a8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -519,6 +519,7 @@ If you can't find one try:
)
AC_CHECK_HEADERS([getopt.h])
+AC_CHECK_HEADERS([linux/ext2_fs.h])
dnl required for libparted/llseek.c (TODO: make linux-x86 only)
if test "$OS" = linux; then
diff --git a/libparted/fs/ext2/Makefile.am b/libparted/fs/ext2/Makefile.am
index 8ee3821..0acd080 100644
--- a/libparted/fs/ext2/Makefile.am
+++ b/libparted/fs/ext2/Makefile.am
@@ -1,20 +1,10 @@
+AM_CFLAGS = $(WARN_CFLAGS) $(WERROR_CFLAGS)
partedincludedir = -I$(top_srcdir)/include
noinst_LTLIBRARIES = libext2.la
-libext2_la_SOURCES = ext2.c \
- ext2.h \
+libext2_la_SOURCES = ext2.h \
ext2_fs.h \
- ext2_block_relocator.c \
- ext2_buffer.c \
- ext2_inode_relocator.c \
- ext2_meta.c \
- ext2_mkfs.c \
- ext2_resize.c \
- interface.c \
- parted_io.c \
- parted_io.h \
- tune.c \
- tune.h
+ interface.c
INCLUDES = $(partedincludedir) $(INTLINCS)
diff --git a/libparted/fs/ext2/ext2.c b/libparted/fs/ext2/ext2.c
deleted file mode 100644
index c3dbe4d..0000000
--- a/libparted/fs/ext2/ext2.c
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- ext2.c -- generic ext2 stuff
- Copyright (C) 1998-2001, 2007, 2009-2011 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/>.
-*/
-
-#include <config.h>
-
-#ifndef DISCOVER_ONLY
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <uuid/uuid.h>
-#include "ext2.h"
-
-/* ext2 stuff ****************************************************************/
-
-unsigned char _bitmap[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
-
-int ext2_copy_block(struct ext2_fs *fs, blk_t from, blk_t to)
-{
- unsigned char* buf = ped_malloc (fs->blocksize);
-
- if (!ext2_bcache_flush(fs, from)) return 0;
- if (!ext2_bcache_flush(fs, to)) return 0;
-
- if (!ext2_read_blocks(fs, buf, from, 1)) return 0;
- if (!ext2_write_blocks(fs, buf, to, 1)) return 0;
-
- return 1;
-}
-
-int ext2_get_block_state(struct ext2_fs *fs, blk_t block)
-{
- struct ext2_buffer_head *bh;
- int group;
- int offset;
- int state;
-
- block -= EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb);
- group = block / EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
- offset = block % EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
-
- bh = ext2_bread(fs, EXT2_GROUP_BLOCK_BITMAP(fs->gd[group]));
- state = bh->data[offset>>3] & _bitmap[offset&7];
- ext2_brelse(bh, 0);
-
- return state;
-}
-
-blk_t ext2_find_free_block(struct ext2_fs *fs)
-{
- int i;
-
- for (i=0;i<fs->numgroups;i++)
- if (EXT2_GROUP_FREE_BLOCKS_COUNT(fs->gd[i]))
- {
- blk_t j;
- blk_t offset;
-
- offset = i * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb)
- + EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb);
- for (j=fs->adminblocks;
- j<EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
- j++)
- if (ext2_is_data_block(fs, offset + j) &&
- !ext2_get_block_state(fs, offset + j))
- return offset + j;
-
- ped_exception_throw (PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Inconsistent group descriptors!"));
- }
-
- ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
- _("File system full!"));
- return 0;
-}
-
-ino_t ext2_find_free_inode(struct ext2_fs *fs)
-{
- int i;
-
- for (i=0;i<fs->numgroups;i++)
- if (EXT2_GROUP_FREE_INODES_COUNT(fs->gd[i]))
- {
- ino_t j;
- ino_t offset;
-
- offset = i * EXT2_SUPER_INODES_PER_GROUP(fs->sb) + 1;
- for (j=0;j<EXT2_SUPER_INODES_PER_GROUP(fs->sb);j++)
- if (!ext2_get_inode_state(fs, offset + j))
- return offset + j;
-
- ped_exception_throw (PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("Inconsistent group descriptors!"));
- }
-
- ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
- _("File system full!"));
- return 0;
-}
-
-int ext2_move_blocks(struct ext2_fs *fs, blk_t src, blk_t num, blk_t dest)
-{
- unsigned char *buf;
- blk_t i;
-
- ped_exception_fetch_all();
- if ((buf = ped_malloc(num << fs->logsize)) != NULL)
- {
- ped_exception_leave_all();
-
- if (!ext2_bcache_flush_range(fs, src, num)) return 0;
- if (!ext2_bcache_flush_range(fs, dest, num)) return 0;
-
- if (!ext2_read_blocks(fs, buf, src, num)) return 0;
- if (!ext2_write_blocks(fs, buf, dest, num)) return 0;
-
- free(buf);
- return 1;
- }
- ped_exception_catch();
- ped_exception_leave_all();
-
- if (src > dest)
- {
- for (i=0;i<num;i++)
- if (!ext2_copy_block(fs, src+i, dest+i))
- return 0;
- }
- else
- {
- for (i=num;i>0;i--)
- if (!ext2_copy_block(fs, src+i, dest+i))
- return 0;
- }
- return 1;
-}
-
-int ext2_read_blocks(struct ext2_fs *fs, void *ptr, blk_t block, blk_t num)
-{
- return fs->devhandle->ops->read(fs->devhandle->cookie, ptr, block, num);
-}
-
-int ext2_set_block_state(struct ext2_fs *fs, blk_t block, int state, int updatemetadata)
-{
- struct ext2_buffer_head *bh;
- int group;
- int offset;
-
- block -= EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb);
- group = block / EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
- offset = block % EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
-
- bh = ext2_bread(fs, EXT2_GROUP_BLOCK_BITMAP(fs->gd[group]));
- bh->dirty = 1;
- if (state)
- bh->data[offset>>3] |= _bitmap[offset&7];
- else
- bh->data[offset>>3] &= ~_bitmap[offset&7];
- ext2_brelse(bh, 0);
-
- if (updatemetadata)
- {
- int diff;
-
- diff = state ? -1 : 1;
-
- fs->gd[group].bg_free_blocks_count = PED_CPU_TO_LE16
- (EXT2_GROUP_FREE_BLOCKS_COUNT(fs->gd[group]) + diff);
- fs->sb.s_free_blocks_count = PED_CPU_TO_LE32
- (EXT2_SUPER_FREE_BLOCKS_COUNT(fs->sb) + diff);
- fs->metadirty |= EXT2_META_SB | EXT2_META_GD;
- }
- return 1;
-}
-
-int ext2_write_blocks(struct ext2_fs *fs, void *ptr, blk_t block, blk_t num)
-{
- return fs->devhandle->ops->write(fs->devhandle->cookie, ptr, block, num);
-}
-
-int ext2_zero_blocks(struct ext2_fs *fs, blk_t block, blk_t num)
-{
- unsigned char *buf;
- blk_t i;
-
- ped_exception_fetch_all();
- buf = ped_malloc (num << fs->logsize);
- if (buf)
- {
- ped_exception_leave_all();
-
- memset(buf, 0, num << fs->logsize);
- if (!ext2_bcache_flush_range(fs, block, num))
- goto error_free_buf;
- if (!ext2_write_blocks(fs, buf, block, num))
- goto error_free_buf;
- free(buf);
- return 1;
- }
- ped_exception_catch();
-
- buf = ped_malloc (fs->blocksize);
- if (buf)
- {
- ped_exception_leave_all();
-
- memset(buf, 0, fs->blocksize);
-
- for (i=0;i<num;i++)
- {
- if (!ext2_bcache_flush(fs, block+i))
- goto error_free_buf;
- if (!ext2_write_blocks(fs, buf, block+i, 1))
- goto error_free_buf;
- }
-
- free(buf);
- return 1;
- }
- ped_exception_catch();
- ped_exception_leave_all();
-
- for (i=0;i<num;i++)
- {
- struct ext2_buffer_head *bh;
-
- bh = ext2_bcreate(fs, block+i);
- if (!bh)
- goto error;
- bh->dirty = 1;
- if (!ext2_brelse(bh, 1))
- goto error;
- }
- return 1;
-
-error_free_buf:
- free(buf);
-error:
- return 0;
-}
-
-off_t ext2_get_inode_offset(struct ext2_fs *fs, ino_t inode, blk_t *block)
-{
- int group;
- int offset;
-
- inode--;
-
- group = inode / EXT2_SUPER_INODES_PER_GROUP(fs->sb);
- offset = (inode % EXT2_SUPER_INODES_PER_GROUP(fs->sb))
- * sizeof(struct ext2_inode);
-
- *block = EXT2_GROUP_INODE_TABLE(fs->gd[group])
- + (offset >> fs->logsize);
-
- return offset & (fs->blocksize - 1);
-}
-
-int ext2_get_inode_state(struct ext2_fs *fs, ino_t inode)
-{
- struct ext2_buffer_head *bh;
- int group;
- int offset;
- int ret;
-
- inode--;
- group = inode / EXT2_SUPER_INODES_PER_GROUP(fs->sb);
- offset = inode % EXT2_SUPER_INODES_PER_GROUP(fs->sb);
-
- bh = ext2_bread(fs, EXT2_GROUP_INODE_BITMAP(fs->gd[group]));
- ret = bh->data[offset>>3] & _bitmap[offset&7];
- ext2_brelse(bh, 0);
-
- return ret;
-}
-
-int ext2_read_inode(struct ext2_fs *fs, ino_t inode, struct ext2_inode *data)
-{
- struct ext2_buffer_head *bh;
- blk_t blk;
- off_t off;
-
- off = ext2_get_inode_offset(fs, inode, &blk);
-
- bh = ext2_bread(fs, blk);
- if (!bh)
- return 0;
-
- memcpy(data, bh->data + off, sizeof(struct ext2_inode));
- ext2_brelse(bh, 0);
- return 1;
-}
-
-int ext2_set_inode_state(struct ext2_fs *fs, ino_t inode, int state, int updatemetadata)
-{
- struct ext2_buffer_head *bh;
- int group;
- int offset;
-
- inode--;
- group = inode / EXT2_SUPER_INODES_PER_GROUP(fs->sb);
- offset = inode % EXT2_SUPER_INODES_PER_GROUP(fs->sb);
-
- bh = ext2_bread(fs, EXT2_GROUP_INODE_BITMAP(fs->gd[group]));
- if (!bh)
- return 0;
- bh->dirty = 1;
- if (state)
- bh->data[offset>>3] |= _bitmap[offset&7];
- else
- bh->data[offset>>3] &= ~_bitmap[offset&7];
- ext2_brelse(bh, 0);
-
- if (updatemetadata)
- {
- int diff;
-
- diff = state ? -1 : 1;
-
- fs->gd[group].bg_free_inodes_count = PED_CPU_TO_LE16
- (EXT2_GROUP_FREE_INODES_COUNT(fs->gd[group]) + diff);
- fs->sb.s_free_inodes_count = PED_CPU_TO_LE32
- (EXT2_SUPER_FREE_INODES_COUNT(fs->sb) + diff);
- fs->metadirty = EXT2_META_SB | EXT2_META_GD;
- }
- return 1;
-}
-
-static void
-_inode_update_size(struct ext2_fs *fs, struct ext2_inode *inode, int delta)
-{
- int i512perblock = 1 << (fs->logsize - 9);
- uint64_t size;
-
- /* i_blocks is in 512 byte blocks */
- inode->i_blocks = PED_CPU_TO_LE32(EXT2_INODE_BLOCKS(*inode)
- + delta * i512perblock);
- size = EXT2_INODE_SIZE(*inode) + delta * fs->blocksize;
- inode->i_size = PED_CPU_TO_LE32(size % (1LL << 32));
- inode->i_size_high = PED_CPU_TO_LE32(size / (1LL << 32));
- inode->i_mtime = PED_CPU_TO_LE32(time(NULL));
-}
-
-int ext2_do_inode(struct ext2_fs *fs, struct ext2_inode *inode, blk_t block,
- int action)
-{
- struct ext2_buffer_head *bh;
- uint32_t *udata;
- blk_t count = 0;
- int i;
- int u32perblock = fs->blocksize >> 2;
- int i512perblock = 1 << (fs->logsize - 9);
-
- if (block == 0 || EXT2_INODE_MODE(*inode) == 0)
- return -1;
-
- if (fs->opt_debug)
- switch (action)
- {
- case EXT2_ACTION_ADD:
- fprintf(stderr,"adding 0x%04x to inode\n",
- block);
- break;
- case EXT2_ACTION_DELETE:
- fprintf(stderr,"deleting 0x%04x from inode\n",
- block);
- break;
- case EXT2_ACTION_FIND:
- fprintf(stderr,"finding 0x%04x in inode\n",
- block);
- break;
- }
-
- /* Direct blocks for first 12 blocks */
- for (i = 0; i < EXT2_NDIR_BLOCKS; i++)
- {
- if (action == EXT2_ACTION_ADD && !EXT2_INODE_BLOCK(*inode, i))
- {
- inode->i_block[i] = PED_CPU_TO_LE32(block);
- _inode_update_size (fs, inode, 1);
- ext2_set_block_state(fs, block, 1, 1);
- return i;
- }
- if (EXT2_INODE_BLOCK(*inode, i) == block)
- {
- if (action == EXT2_ACTION_DELETE)
- {
- inode->i_block[i] = 0;
- _inode_update_size (fs, inode, -1);
- ext2_set_block_state(fs, block, 0, 1);
- }
- return i;
- }
- if (EXT2_INODE_BLOCK(*inode, i))
- count += i512perblock;
- }
-
- count += EXT2_INODE_BLOCK(*inode, EXT2_IND_BLOCK) ? i512perblock : 0;
- count += EXT2_INODE_BLOCK(*inode, EXT2_DIND_BLOCK) ? i512perblock : 0;
- count += EXT2_INODE_BLOCK(*inode, EXT2_TIND_BLOCK) ? i512perblock : 0;
-
- if (!EXT2_INODE_BLOCK(*inode, EXT2_IND_BLOCK) ||
- (count >= EXT2_INODE_BLOCKS(*inode) && action != EXT2_ACTION_ADD))
- return -1;
-
- bh = ext2_bread(fs, EXT2_INODE_BLOCK(*inode, EXT2_IND_BLOCK));
- udata = (uint32_t *)bh->data;
-
- /* Indirect blocks for next 256/512/1024 blocks (for 1k/2k/4k blocks) */
- for (i = 0; i < u32perblock; i++) {
- if (action == EXT2_ACTION_ADD && !udata[i]) {
- bh->dirty = 1;
- udata[i] = PED_CPU_TO_LE32(block);
- _inode_update_size (fs, inode, 1);
- ext2_set_block_state(fs, block, 1, 1);
- ext2_brelse(bh, 0);
- return EXT2_NDIR_BLOCKS + i;
- }
- if (PED_LE32_TO_CPU(udata[i]) == block) {
- if (action == EXT2_ACTION_DELETE) {
- bh->dirty = 1;
- udata[i] = 0;
- _inode_update_size (fs, inode, -1);
- ext2_set_block_state(fs, block, 0, 1);
- }
- ext2_brelse(bh, 0);
- return EXT2_NDIR_BLOCKS + i;
- }
- if (udata[i])
- {
- count += i512perblock;
- if (count >= EXT2_INODE_BLOCKS(*inode) &&
- action != EXT2_ACTION_ADD)
- return -1;
- }
- }
-
- ext2_brelse(bh, 0);
-
- if (!EXT2_INODE_BLOCK(*inode, EXT2_DIND_BLOCK) ||
- (count >= EXT2_INODE_BLOCKS(*inode) && action != EXT2_ACTION_ADD))
- return -1;
- bh = ext2_bread(fs, EXT2_INODE_BLOCK(*inode, EXT2_DIND_BLOCK));
- udata = (uint32_t *)bh->data;
-
- /* Double indirect blocks for next 2^16/2^18/2^20 1k/2k/4k blocks */
- for (i = 0; i < u32perblock; i++) {
- struct ext2_buffer_head *bh2;
- uint32_t *udata2;
- int j;
-
- if (!udata[i]) {
- ext2_brelse(bh, 0);
- return -1;
- }
- bh2 = ext2_bread(fs, PED_LE32_TO_CPU(udata[i]));
- udata2 = (uint32_t *)bh2->data;
- count += i512perblock;
-
- for (j = 0; j < u32perblock; j++) {
- if (action == EXT2_ACTION_ADD && !udata2[j]) {
- bh2->dirty = 1;
- udata2[j] = PED_CPU_TO_LE32(block);
- _inode_update_size (fs, inode, 1);
- ext2_set_block_state(fs, block, 1, 1);
- ext2_brelse(bh, 0);
- ext2_brelse(bh2, 0);
- return EXT2_NDIR_BLOCKS + i * u32perblock + j;
- }
- if (PED_LE32_TO_CPU(udata2[j]) == block) {
- if (action == EXT2_ACTION_DELETE) {
- bh2->dirty = 1;
- udata2[j] = 0;
- _inode_update_size (fs, inode, -1);
- ext2_set_block_state(fs, block, 0, 1);
- }
- ext2_brelse(bh, 0);
- ext2_brelse(bh2, 0);
- return EXT2_NDIR_BLOCKS + i * u32perblock + j;
- }
- if (udata2[j])
- {
- count += i512perblock;
- if (count >= EXT2_INODE_BLOCKS(*inode) &&
- action != EXT2_ACTION_ADD)
- return -1;
- }
- }
- ext2_brelse(bh2, 0);
- }
- ext2_brelse(bh, 0);
-
- /* FIXME: we should check for triple-indirect blocks here, but it
- * would be nice to have a better routine to traverse blocks, and
- * file systems that need triple-indirect blocks for the resize
- * inode are too big to worry about yet.
- */
-
- return -1;
-}
-
-int ext2_write_inode(struct ext2_fs *fs, ino_t inode, const struct ext2_inode *data)
-{
- struct ext2_buffer_head *bh;
- blk_t blk;
- off_t off;
-
- off = ext2_get_inode_offset(fs, inode, &blk);
-
- bh = ext2_bread(fs, blk);
- if (!bh)
- return 0;
- bh->dirty = 1;
- memcpy(bh->data + off, data, sizeof(struct ext2_inode));
- ext2_brelse(bh, 0);
-
- return 1;
-}
-
-int ext2_zero_inode(struct ext2_fs *fs, ino_t inode)
-{
- struct ext2_inode buf;
-
- memset(&buf, 0, sizeof(struct ext2_inode));
- return ext2_write_inode(fs, inode, &buf);
-}
-
-
-
-
-
-/* check whether y is root of x
- * (formula grabbed from linux ext2 kernel source) */
-static int is_root(int x, int y)
-{
- if (!x)
- return 1;
-
- while (1)
- {
- if (x == 1)
- return 1;
-
- if (x % y)
- return 0;
-
- x /= y;
- }
-}
-
-/* check whether group contains a superblock copy on file systems
- * where not all groups have one (sparse superblock feature) */
-int ext2_is_group_sparse(struct ext2_fs *fs, int group)
-{
- if (!fs->sparse)
- return 1;
-
- if (is_root(group, 3) || is_root(group, 5) || is_root(group, 7))
- return 1;
-
- return 0;
-}
-
-void ext2_close(struct ext2_fs *fs)
-{
- ext2_commit_metadata(fs, EXT2_META_PRIMARY | EXT2_META_BACKUP);
- ext2_sync(fs);
-
- ext2_bcache_deinit(fs);
-
- fs->devhandle->ops->close(fs->devhandle->cookie);
-
- free(fs->gd);
- free(fs);
-}
-
-int ext2_commit_metadata(struct ext2_fs *fs, int copies)
-{
- int i;
- int num;
- int wmeta = fs->metadirty & copies;
- unsigned char* sb = ped_malloc(fs->blocksize);
- struct ext2_super_block *sb_for_io;
- int sb_block;
-
- /* See if there is even anything to write... */
- if (wmeta == EXT2_META_CLEAN)
- return 1;
-
- fs->sb.s_r_blocks_count = PED_CPU_TO_LE32 (
- fs->r_frac * (loff_t)EXT2_SUPER_BLOCKS_COUNT(fs->sb)
- / 100);
-
- if (!ext2_read_blocks (fs, sb, 0, 1))
- return 0;
-
- if (EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb)) {
- memcpy(sb, &fs->sb, 1024);
- sb_for_io = (struct ext2_super_block *) sb;
- } else {
- memcpy(sb+1024, &fs->sb, 1024);
- sb_for_io = (struct ext2_super_block *) (sb + 1024);
- }
-
- num = copies & EXT2_META_BACKUP ? fs->numgroups : 1;
-
- for (i = 0, sb_block = EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb); i < num;
- i++, sb_block += EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb))
- {
-
- if (!ext2_is_group_sparse(fs, i))
- continue;
-
- if (fs->dynamic_version)
- sb_for_io->s_block_group_nr = PED_CPU_TO_LE16 (i);
-
- if ((i == 0 && wmeta & EXT2_META_PRIMARY_SB) ||
- (i != 0 && wmeta & EXT2_META_SB))
- {
- if (!ext2_bcache_flush_range(fs, sb_block, 1))
- return 0;
- if (!ext2_write_blocks(fs, sb, sb_block, 1))
- return 0;
- }
- if ((i == 0 && wmeta & EXT2_META_PRIMARY_GD) ||
- (i != 0 && wmeta & EXT2_META_GD))
- {
- if (!ext2_bcache_flush_range(fs, sb_block + 1,
- fs->gdblocks))
- return 0;
- if (!ext2_write_blocks(fs, fs->gd, sb_block + 1,
- fs->gdblocks))
- return 0;
- }
- }
-
- sb_for_io->s_block_group_nr = 0;
-
- /* Clear the flags of the components we just finished writing. */
- fs->metadirty &= ~copies;
-
- return 1;
-}
-
-int ext2_sync(struct ext2_fs *fs)
-{
- if (!ext2_commit_metadata(fs, EXT2_META_PRIMARY)) return 0;
- if (!ext2_bcache_sync(fs)) return 0;
- if (!fs->devhandle->ops->sync(fs->devhandle->cookie)) return 0;
- return 1;
-}
-
-struct ext2_fs *ext2_open(struct ext2_dev_handle *handle, int state)
-{
- struct ext2_fs *fs;
-
- if ((fs = (struct ext2_fs *) ped_malloc(sizeof(struct ext2_fs)))
- == NULL)
- goto error;
-
- handle->ops->set_blocksize(handle->cookie, 10);
-
- if (!handle->ops->read(handle->cookie, &fs->sb, 1, 1)
- || EXT2_SUPER_MAGIC(fs->sb) != EXT2_SUPER_MAGIC_CONST)
- {
- ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
- _("Invalid superblock. Are you sure this is an ext2 "
- "file system?"));
- goto error_free_fs;
- }
-
-
- fs->opt_debug = 1;
- fs->opt_safe = 1;
- fs->opt_verbose = 0;
-
- if (EXT2_SUPER_STATE(fs->sb) & EXT2_ERROR_FS & ~(state & EXT2_ERROR_FS))
- {
- if (ped_exception_throw (
- PED_EXCEPTION_WARNING, PED_EXCEPTION_IGNORE_CANCEL,
- _("File system has errors! You should run e2fsck."))
- == PED_EXCEPTION_CANCEL)
- goto error_free_fs;
- }
-
- if (!((EXT2_SUPER_STATE(fs->sb) | state) & EXT2_VALID_FS)
- || (EXT2_SUPER_FEATURE_INCOMPAT(fs->sb)
- & EXT3_FEATURE_INCOMPAT_RECOVER))
- {
- if (ped_exception_throw (
- PED_EXCEPTION_ERROR, PED_EXCEPTION_IGNORE_CANCEL,
- _("File system was not cleanly unmounted! "
- "You should run e2fsck. Modifying an unclean "
- "file system could cause severe corruption."))
- != PED_EXCEPTION_IGNORE)
- goto error_free_fs;
- }
-
- fs->dynamic_version = EXT2_SUPER_REV_LEVEL (fs->sb) > 0;
-
- if ((EXT2_SUPER_FEATURE_COMPAT(fs->sb)
- & ~(EXT3_FEATURE_COMPAT_HAS_JOURNAL |
- EXT2_FEATURE_COMPAT_HAS_DIR_INDEX)) ||
- (EXT2_SUPER_FEATURE_INCOMPAT(fs->sb)
- & ~(EXT2_FEATURE_INCOMPAT_FILETYPE |
- EXT3_FEATURE_INCOMPAT_RECOVER)) ||
- (EXT2_SUPER_FEATURE_RO_COMPAT(fs->sb)
- & ~(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER |
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE)))
- {
- ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
- _("File system has an incompatible feature enabled. "
- "Compatible features are has_journal, dir_index, "
- "filetype, sparse_super and large_file. "
- "Use tune2fs or debugfs to remove features."));
- goto error_free_fs;
- }
-
- fs->devhandle = handle;
- fs->logsize = EXT2_SUPER_LOG_BLOCK_SIZE(fs->sb) + 10;
- handle->ops->set_blocksize(handle->cookie, fs->logsize);
-
- if (!ext2_bcache_init(fs))
- {
- ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
- _("Error allocating buffer cache."));
- goto error_free_fs;
- }
-
- fs->blocksize = 1 << fs->logsize;
-
- fs->numgroups = ped_div_round_up (EXT2_SUPER_BLOCKS_COUNT(fs->sb)
- - EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb),
- EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb));
- fs->gdblocks = ped_div_round_up (fs->numgroups
- * sizeof(struct ext2_group_desc),
- fs->blocksize);
- fs->inodeblocks = ped_div_round_up (EXT2_SUPER_INODES_PER_GROUP(fs->sb)
- * sizeof(struct ext2_inode),
- fs->blocksize);
- fs->r_frac = ped_div_round_up (100 * (loff_t)EXT2_SUPER_R_BLOCKS_COUNT(fs->sb),
- EXT2_SUPER_BLOCKS_COUNT(fs->sb));
- fs->adminblocks = 3 + fs->gdblocks + fs->inodeblocks;
-
- fs->sparse = 0;
- if (EXT2_SUPER_FEATURE_RO_COMPAT(fs->sb)
- & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
- fs->sparse = 1;
-
- fs->has_journal = 0 < (EXT2_SUPER_FEATURE_COMPAT(fs->sb)
- & EXT3_FEATURE_COMPAT_HAS_JOURNAL);
- fs->has_internal_journal
- = fs->has_journal
- && uuid_is_null(EXT2_SUPER_JOURNAL_UUID(fs->sb))
- && EXT2_SUPER_JOURNAL_INUM(fs->sb);
-
- fs->gd = ped_malloc (fs->numgroups * sizeof (struct ext2_group_desc)
- + fs->blocksize);
- if (!fs->gd)
- goto error_deinit_bcache;
-
- ext2_read_blocks(fs, fs->gd, EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb) + 1,
- fs->gdblocks);
-
- fs->metadirty = 0;
- return fs;
-
- free(fs->gd);
-error_deinit_bcache:
- ext2_bcache_deinit(fs);
-error_free_fs:
- free(fs);
-error:
- return NULL;
-}
-
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/ext2/ext2.h b/libparted/fs/ext2/ext2.h
index eb647b4..11a17f2 100644
--- a/libparted/fs/ext2/ext2.h
+++ b/libparted/fs/ext2/ext2.h
@@ -22,7 +22,6 @@
#include <parted/parted.h>
#include <parted/debug.h>
#include <sys/types.h>
-#include "tune.h"
#include <inttypes.h>
@@ -33,70 +32,14 @@
# define _(String) (String)
#endif /* ENABLE_NLS */
-
-/* Ehrm.... sorry, pedanticists! :-) */
-#ifndef offsetof
-# define offsetof(type, field) ((size_t)(&(((type *)0)->field)))
-#endif
-
-#ifdef __BEOS__
- typedef off_t loff_t;
-#endif
-
typedef u_int32_t blk_t;
-#ifdef HAVE_LINUX_EXT2_FS_H
-#define _LINUX_TYPES_H
-#define i_version i_generation
+#ifdef HAVE_LINUX_EXT2_FS_H__FAILS_TO_COMPILE
#include <linux/ext2_fs.h>
#else
#include "ext2_fs.h"
#endif
-extern unsigned char _bitmap[8];
-
-struct ext2_buffer_cache
-{
- struct ext2_buffer_head *cache;
- struct ext2_buffer_head *heads;
- struct ext2_buffer_head **hash;
- struct ext2_fs *fs;
-
- int size;
- int numalloc;
- unsigned char *buffermem;
-};
-
-struct ext2_buffer_head
-{
- struct ext2_buffer_head *next;
- struct ext2_buffer_head *prev;
- unsigned char *data;
- blk_t block;
-
- int usecount;
- int dirty;
-
- struct ext2_buffer_cache *bc;
- int alloc;
-};
-
-struct ext2_dev_ops
-{
- int (*close)(void *cookie);
- blk_t (*get_size)(void *cookie);
- int (*read)(void *cookie, void *ptr, blk_t block, blk_t num);
- int (*set_blocksize)(void *cookie, int logsize);
- int (*sync)(void *cookie);
- int (*write)(void *cookie, void *ptr, blk_t block, blk_t num);
-};
-
-struct ext2_dev_handle
-{
- struct ext2_dev_ops *ops;
- void *cookie;
-};
-
struct ext2_fs
{
struct ext2_dev_handle *devhandle;
@@ -132,111 +75,4 @@ struct ext2_fs
void *journal;
};
-
-#define EXT2_ACTION_ADD 1
-#define EXT2_ACTION_DELETE 2
-#define EXT2_ACTION_FIND 3
-
-#define EXT2_META_CLEAN 0
-#define EXT2_META_PRIMARY_SB 1
-#define EXT2_META_BACKUP_SB 2
-#define EXT2_META_PRIMARY_GD 4
-#define EXT2_META_BACKUP_GD 8
-
-#define EXT2_META_PRIMARY (EXT2_META_PRIMARY_SB | EXT2_META_PRIMARY_GD)
-#define EXT2_META_BACKUP (EXT2_META_BACKUP_SB | EXT2_META_BACKUP_GD)
-#define EXT2_META_SB (EXT2_META_PRIMARY_SB | EXT2_META_BACKUP_SB)
-#define EXT2_META_GD (EXT2_META_PRIMARY_GD | EXT2_META_BACKUP_GD)
-
-/* generic stuff */
-int ext2_copy_block (struct ext2_fs *fs, blk_t from, blk_t to);
-void ext2_close (struct ext2_fs *fs);
-int ext2_commit_metadata (struct ext2_fs *fs, int copies);
-off_t ext2_get_inode_offset (struct ext2_fs *fs, ino_t inode, blk_t *block);
-blk_t ext2_find_free_block (struct ext2_fs *fs);
-ino_t ext2_find_free_inode (struct ext2_fs *fs);
-int ext2_get_inode_state (struct ext2_fs *fs, ino_t inode);
-int ext2_is_group_sparse (struct ext2_fs *fs, int group);
-int ext2_move_blocks (struct ext2_fs *fs, blk_t src, blk_t num, blk_t dest);
-struct ext2_fs *ext2_open (struct ext2_dev_handle *handle, int state);
-int ext2_read_blocks (struct ext2_fs *fs, void *ptr, blk_t block, blk_t numblocks);
-int ext2_read_inode (struct ext2_fs *fs, ino_t inode, struct ext2_inode *inodep);
-int ext2_set_inode_state (struct ext2_fs *fs, ino_t inode, int state, int updatemetadata);
-int ext2_do_inode (struct ext2_fs *fs, struct ext2_inode *inode, blk_t block, int action);
-int ext2_sync (struct ext2_fs *fs);
-int ext2_write_blocks (struct ext2_fs *fs, void *ptr, blk_t block, blk_t numblocks);
-int ext2_write_inode (struct ext2_fs *fs, ino_t inode, const struct ext2_inode *inodep);
-int ext2_zero_blocks (struct ext2_fs *fs, blk_t block, blk_t num);
-int ext2_zero_inode (struct ext2_fs *fs, ino_t inode);
-
-/* block related */
-void ext2_bgbitmap_cache_deinit (struct ext2_fs *fs);
-int ext2_bgbitmap_cache_flush (struct ext2_fs *fs);
-int ext2_bgbitmap_cache_init (struct ext2_fs *fs);
-int ext2_get_block_state (struct ext2_fs *, blk_t block);
-int ext2_set_block_state (struct ext2_fs *, blk_t block, int state, int updatemetadata);
-
-/* block relocator */
-int ext2_block_relocate (struct ext2_fs *fs, blk_t newsize);
-
-/* buffer */
-void ext2_bcache_deinit (struct ext2_fs *fs);
-void ext2_bcache_dump (struct ext2_fs *fs);
-int ext2_bcache_flush (struct ext2_fs *fs, blk_t block);
-int ext2_bcache_flush_range (struct ext2_fs *fs, blk_t first, blk_t last);
-int ext2_bcache_init (struct ext2_fs *fs);
-int ext2_bcache_sync (struct ext2_fs *fs);
-struct ext2_buffer_head *ext2_bcreate (struct ext2_fs *fs, blk_t block);
-struct ext2_buffer_head *ext2_bread (struct ext2_fs *fs, blk_t block);
-int ext2_brelse (struct ext2_buffer_head *bh, int forget);
-
-/* inode relocator */
-int ext2_inode_relocate (struct ext2_fs *fs, int newgroups);
-
-/* journalling */
-void ext2_journal_deinit (struct ext2_fs *fs);
-int ext2_journal_init (struct ext2_fs *fs);
-
-/* metadata mover */
-int ext2_metadata_push (struct ext2_fs *fs, blk_t newsize);
-
-/* fs creation */
-struct ext2_fs *ext2_mkfs (struct ext2_dev_handle *handle, blk_t numblocks, int log_block_size, blk_t blocks_per_group, int inodes_per_group, int sparse_sb, int reserved_block_percentage, PedTimer* timer);
-
-/* resize */
-int ext2_resize_fs (struct ext2_fs *fs, blk_t newsize, PedTimer* timer);
-
-/* unix I/O */
-struct ext2_dev_handle *ext2_make_dev_handle_from_file(char *dev);
-
-
-
-
-static __inline__ int ext2_is_data_block(struct ext2_fs *fs, blk_t block)
-{
- blk_t blk;
- int group;
-
- PED_ASSERT (block >= EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb));
- PED_ASSERT (block < EXT2_SUPER_BLOCKS_COUNT(fs->sb));
-
- blk = block - EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb);
-
- group = blk / EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
- blk %= EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
-
- if (ext2_is_group_sparse(fs, group) && blk <= fs->gdblocks)
- return 0;
-
- if (block == EXT2_GROUP_BLOCK_BITMAP(fs->gd[group]) ||
- block == EXT2_GROUP_INODE_BITMAP(fs->gd[group]))
- return 0;
-
- if (block >= EXT2_GROUP_INODE_TABLE(fs->gd[group]) &&
- block < EXT2_GROUP_INODE_TABLE(fs->gd[group]) + fs->inodeblocks)
- return 0;
-
- return 1;
-}
-
#endif
diff --git a/libparted/fs/ext2/ext2_block_relocator.c b/libparted/fs/ext2/ext2_block_relocator.c
deleted file mode 100644
index d44d4f3..0000000
--- a/libparted/fs/ext2/ext2_block_relocator.c
+++ /dev/null
@@ -1,921 +0,0 @@
-/*
- ext2_block_relocator.c -- ext2 block relocator
- Copyright (C) 1998-2000, 2007, 2009-2011 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/>.
-*/
-
-#include <config.h>
-
-#ifndef DISCOVER_ONLY
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "ext2.h"
-
-
-/* This struct describes a single block that will be relocated. The
- * block's original location is "num", and its new location is "dest".
- * The block is presumebly referred to by some other block in the file
- * system, which is recorded as "refblock". (Only one reference to
- * the block is allowed by the block relocator.) "refoffset" describes
- * the location within the refblock in which the block is referenced.
- * "isindirect" is 0 for direct, 1 for single-indirect, 2 for
- * double-indirect, etc.
- *
- * The algorithms in the file fill the entries of this struct in this order:
- * num, refblock/refoffset/isindirectblock, dest.
- */
-struct ext2_block_entry
-{
- blk_t num;
- blk_t dest;
- blk_t refblock;
- unsigned refoffset:16;
- unsigned isindirectblock:16;
-};
-
-/* This struct contains all data structures relevant to the block relocator.
- * - newallocoffset is the distance between the start of a block group,
- * and the first data block in the group. This can change when a
- * filesystem is resized, because the size of the group descriptors is
- * proportional to the size of the filesystem.
- *
- * - allocentries is the size of the "block" array. It is a tuneable
- * parameter that determines how many blocks can be moved in each
- * pass.
- *
- * - usedentries says how many entries of the "block" array have been
- * used. That is, how many blocks have been scheduled so far to
- * be moved.
- *
- * - resolvedentries is the number of blocks whose referencing block
- * has been found and recorded in block[.]->refblock, etc.
- *
- * - block is an array that records which blocks need to be moved, and
- * where they will be moved to, etc. At some point in the algorithm, this
- * array gets sorted (grep for qsort!) by indirectness.
- *
- * - start: each entry in this array corresponds to a level of
- * indirectness (0-3). Each level has two items: dst and num. "num"
- * is the number of blocks inside "block" of that level of indirectness.
- * After doscan() is finished, and the level of indirectness of each
- * block is known, "block" is sorted (see above). The "dst" pointer
- * is a pointer inside "block" that indicates the start of the portion
- * of the array containg blocks of that level of indirectness.
- */
-struct ext2_block_relocator_state
-{
- blk_t newallocoffset;
- blk_t allocentries;
- blk_t usedentries;
- blk_t resolvedentries;
- struct ext2_block_entry *block;
-
- struct {
- struct ext2_block_entry *dst;
- int num;
- } start[4];
-};
-
-
-
-static int compare_block_entries(const void *x0, const void *x1)
-{
- const struct ext2_block_entry *b0;
- const struct ext2_block_entry *b1;
-
- b0 = (const struct ext2_block_entry *)x0;
- b1 = (const struct ext2_block_entry *)x1;
-
- if (b0->num < b1->num)
- return -1;
-
- if (b0->num > b1->num)
- return 1;
-
- return 0;
-}
-
-static int compare_block_entries_ind(const void *x0, const void *x1)
-{
- const struct ext2_block_entry *b0;
- const struct ext2_block_entry *b1;
-
- b0 = (const struct ext2_block_entry *)x0;
- b1 = (const struct ext2_block_entry *)x1;
-
- if (b0->isindirectblock > b1->isindirectblock)
- return -1;
-
- if (b0->isindirectblock < b1->isindirectblock)
- return 1;
-
- return 0;
-}
-
-static int compare_block_entries_ref(const void *x0, const void *x1)
-{
- const struct ext2_block_entry *b0;
- const struct ext2_block_entry *b1;
-
- b0 = (const struct ext2_block_entry *)x0;
- b1 = (const struct ext2_block_entry *)x1;
-
- if (b0->refblock < b1->refblock)
- return -1;
-
- if (b0->refblock > b1->refblock)
- return 1;
-
- return 0;
-}
-
-struct ext2_block_entry *findit(struct ext2_block_relocator_state *state, blk_t block)
-{
- int min;
- int max;
- struct ext2_block_entry *retv;
- int t;
- blk_t tval;
-
- max = state->usedentries - 1;
- min = 0;
- retv = NULL;
-
- repeat:
- if (min > max)
- goto out;
-
- t = (min + max) >> 1;
- tval = state->block[t].num;
-
- if (tval > block)
- max = t - 1;
-
- if (tval < block)
- min = t + 1;
-
- if (tval != block)
- goto repeat;
-
- retv = &state->block[t];
-
- out:
- return retv;
-}
-
-/* This function adds records a reference to a block ("blk"), if that
- * block is scheduled to be moved.
- */
-static int doblock(struct ext2_fs *fs,
- struct ext2_block_relocator_state *state,
- blk_t blk,
- blk_t refblock,
- off_t refoffset,
- int indirect)
-{
- struct ext2_block_entry *ent;
-
- if ((ent = findit(state, blk)) == NULL)
- return 1;
-
- if (ent->refblock)
- {
- ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
- _("Cross-linked blocks found! Better go run e2fsck "
- "first!"));
- return 0;
- }
-
- ent->refblock = refblock;
- ent->refoffset = refoffset;
- ent->isindirectblock = indirect;
-
- state->resolvedentries++;
- state->start[indirect].num++;
-
- return 1;
-}
-
-static int doindblock(struct ext2_fs *fs,
- struct ext2_block_relocator_state *state,
- blk_t blk,
- blk_t refblock,
- off_t refoffset)
-{
- struct ext2_buffer_head *bh;
- int i;
- uint32_t *uptr;
-
- if (!doblock(fs, state, blk, refblock, refoffset, 1))
- return 0;
-
- bh = ext2_bread(fs, blk);
- if (!bh)
- return 0;
- uptr = (uint32_t *)bh->data;
-
- for (i=0;i<(fs->blocksize >> 2);i++)
- if (uptr[i])
- if (!doblock(fs, state, PED_LE32_TO_CPU(uptr[i]), blk,
- i<<2, 0))
- return 0;
-
- if (!ext2_brelse(bh, 0))
- return 0;
-
- return 1;
-}
-
-static int dodindblock(struct ext2_fs *fs,
- struct ext2_block_relocator_state *state,
- blk_t blk,
- blk_t refblock,
- off_t refoffset)
-{
- struct ext2_buffer_head *bh;
- int i;
- uint32_t *uptr;
-
- if (!doblock(fs, state, blk, refblock, refoffset, 2))
- return 0;
-
- bh = ext2_bread(fs, blk);
- if (!bh)
- return 0;
- uptr = (uint32_t *)bh->data;
-
- for (i=0;i<(fs->blocksize >> 2);i++)
- if (uptr[i])
- if (!doindblock(fs, state, PED_LE32_TO_CPU(uptr[i]),
- blk, i<<2))
- return 0;
-
- if (!ext2_brelse(bh, 0))
- return 0;
-
- return 1;
-}
-
-static int dotindblock(struct ext2_fs *fs,
- struct ext2_block_relocator_state *state,
- blk_t blk,
- blk_t refblock,
- off_t refoffset)
-{
- struct ext2_buffer_head *bh;
- int i;
- uint32_t *uptr;
-
- if (!doblock(fs, state, blk, refblock, refoffset, 3))
- return 0;
-
- bh = ext2_bread(fs, blk);
- if (!bh)
- return 0;
- uptr = (uint32_t *)bh->data;
-
- for (i=0;i<(fs->blocksize >> 2);i++)
- if (uptr[i])
- if (!dodindblock(fs, state, PED_LE32_TO_CPU(uptr[i]),
- blk, i<<2))
- return 0;
-
- if (!ext2_brelse(bh, 0))
- return 0;
-
- return 1;
-}
-
-
-/* This function records any block references from an inode to blocks that are
- * scheduled to be moved.
- */
-static int doinode(struct ext2_fs *fs, struct ext2_block_relocator_state *state, int inode)
-{
- struct ext2_inode buf;
-
- if (!ext2_read_inode(fs, inode, &buf))
- return 0;
-
- if (EXT2_INODE_BLOCKS(buf))
- {
- blk_t blk;
- int i;
- off_t inodeoffset;
- blk_t inodeblock;
-
- inodeoffset = ext2_get_inode_offset(fs, inode, &inodeblock);
-
- /* do Hurd block, if there is one... */
- if (EXT2_SUPER_CREATOR_OS(fs->sb) == EXT2_OS_HURD
- && EXT2_INODE_TRANSLATOR(buf)) {
- if (!doblock(fs,
- state,
- EXT2_INODE_TRANSLATOR(buf),
- inodeblock,
- inodeoffset + offsetof(struct ext2_inode,
- osd1.hurd1.h_i_translator),
- 0))
- return 0;
- }
-
- for (i=0;i<EXT2_NDIR_BLOCKS;i++)
- if ((blk = EXT2_INODE_BLOCK(buf, i)) != 0)
- if (!doblock(fs,
- state,
- blk,
- inodeblock,
- inodeoffset + offsetof(struct ext2_inode, i_block[i]),
- 0))
- return 0;
-
- if ((blk = EXT2_INODE_BLOCK(buf, EXT2_IND_BLOCK)) != 0)
- if (!doindblock(fs,
- state,
- blk,
- inodeblock,
- inodeoffset + offsetof(struct ext2_inode, i_block[EXT2_IND_BLOCK])))
- return 0;
-
- if ((blk = EXT2_INODE_BLOCK(buf, EXT2_DIND_BLOCK)) != 0)
- if (!dodindblock(fs,
- state,
- blk,
- inodeblock,
- inodeoffset + offsetof(struct ext2_inode, i_block[EXT2_DIND_BLOCK])))
- return 0;
-
- if ((blk = EXT2_INODE_BLOCK(buf, EXT2_TIND_BLOCK)) != 0)
- if (!dotindblock(fs,
- state,
- blk,
- inodeblock,
- inodeoffset + offsetof(struct ext2_inode, i_block[EXT2_TIND_BLOCK])))
- return 0;
-
- }
-
- return 1;
-}
-
-/* This function scans the entire filesystem, to find all references to blocks
- * that are scheduled to be moved.
- */
-static int doscan(struct ext2_fs *fs, struct ext2_block_relocator_state *state)
-{
- int i;
-
- state->start[0].num = 0;
- state->start[1].num = 0;
- state->start[2].num = 0;
- state->start[3].num = 0;
-
- for (i=0;i<fs->numgroups;i++)
- {
- struct ext2_buffer_head *bh;
- unsigned int j;
- int offset;
-
- if (fs->opt_verbose)
- {
- fprintf(stderr, " scanning group %i.... ", i);
- fflush(stderr);
- }
-
- bh = ext2_bread(fs, EXT2_GROUP_INODE_BITMAP(fs->gd[i]));
- if (!bh)
- return 0;
- offset = i * EXT2_SUPER_INODES_PER_GROUP(fs->sb) + 1;
-
- for (j=0;j<EXT2_SUPER_INODES_PER_GROUP(fs->sb);j++)
- if (bh->data[j>>3] & _bitmap[j&7])
- {
- if (!doinode(fs, state, offset + j))
- {
- ext2_brelse(bh, 0);
- return 0;
- }
-
- if (state->resolvedentries == state->usedentries)
- break;
- }
-
- ext2_brelse(bh, 0);
-
- if (fs->opt_verbose)
- {
- fprintf(stderr, "%i/%i blocks resolved\r",
- state->resolvedentries,
- state->usedentries);
- fflush(stderr);
- }
-
- if (state->resolvedentries == state->usedentries)
- break;
- }
-
- if (fs->opt_verbose)
- fputc('\n', stderr);
-
- state->start[3].dst = state->block;
- state->start[2].dst = state->start[3].dst + state->start[3].num;
- state->start[1].dst = state->start[2].dst + state->start[2].num;
- state->start[0].dst = state->start[1].dst + state->start[1].num;
-
- return 1;
-}
-
-
-
-
-
-static int ext2_block_relocator_copy(struct ext2_fs *fs, struct ext2_block_relocator_state *state)
-{
- unsigned char *buf;
-
- ped_exception_fetch_all();
- buf = (unsigned char *) ped_malloc(MAXCONT << fs->logsize);
- if (buf)
- {
- int num;
- int numleft;
- struct ext2_block_entry *ptr;
-
- ped_exception_leave_all();
-
- numleft = state->usedentries;
- ptr = state->block;
- while (numleft)
- {
- num = PED_MIN(numleft, MAXCONT);
- while (num != 1)
- {
- if (ptr[0].num + num-1 == ptr[num-1].num &&
- ptr[0].dest + num-1 == ptr[num-1].dest)
- break;
-
- num >>= 1;
- }
-
- if (!ext2_bcache_flush_range(fs, ptr[0].num, num))
- goto error_free_buf;
- if (!ext2_bcache_flush_range(fs, ptr[0].dest, num))
- goto error_free_buf;
-
- if (!ext2_read_blocks(fs, buf, ptr[0].num, num))
- goto error_free_buf;
- if (!ext2_write_blocks(fs, buf, ptr[0].dest, num))
- goto error_free_buf;
-
- ptr += num;
- numleft -= num;
-
- if (fs->opt_verbose)
- {
- fprintf(stderr, "copied %i/%i blocks\r",
- state->usedentries - numleft,
- state->usedentries);
- fflush(stderr);
- }
- }
-
- free(buf);
-
- if (fs->opt_safe)
- ext2_sync(fs);
-
- if (fs->opt_verbose)
- fputc('\n', stderr);
- }
- else
- {
- blk_t i;
-
- ped_exception_catch();
- ped_exception_leave_all();
-
- for (i=0;i<state->usedentries;i++)
- {
- struct ext2_block_entry *block;
-
- block = &state->block[i];
- if (!ext2_copy_block(fs, block->num, block->dest))
- goto error;
- }
- }
-
- return 1;
-
-error_free_buf:
- free(buf);
-error:
- return 0;
-}
-
-static int ext2_block_relocator_ref(struct ext2_fs *fs, struct ext2_block_relocator_state *state, struct ext2_block_entry *block)
-{
- struct ext2_buffer_head *bh;
- static int numerrors = 0;
-
- if (!(block->refblock || block->refoffset))
- {
- ped_exception_throw (PED_EXCEPTION_BUG, PED_EXCEPTION_CANCEL,
- _("Block %i has no reference? Weird."),
- block->num);
- return 0;
- }
-
- bh = ext2_bread(fs, block->refblock);
- if (!bh)
- return 0;
-
- if (fs->opt_debug)
- {
- if (PED_LE32_TO_CPU(*((uint32_t *)(bh->data + block->refoffset)))
- != block->num) {
- fprintf(stderr,
- "block %i ref error! (->%i {%i, %i})\n",
- block->num,
- block->dest,
- block->refblock,
- block->refoffset);
- ext2_brelse(bh, 0);
-
- if (numerrors++ < 4)
- return 1;
-
- fputs("all is not well!\n", stderr);
- return 0;
- }
- }
-
- *((uint32_t *)(bh->data + block->refoffset))
- = PED_LE32_TO_CPU(block->dest);
- bh->dirty = 1;
- ext2_brelse(bh, 0);
-
- ext2_set_block_state(fs, block->dest, 1, 1);
- ext2_set_block_state(fs, block->num, 0, 1);
-
- if (block->isindirectblock)
- {
- struct ext2_block_entry *dst;
- int i;
- int num;
-
- dst = state->start[block->isindirectblock-1].dst;
- num = state->start[block->isindirectblock-1].num;
-
- for (i=0;i<num;i++)
- if (dst[i].refblock == block->num)
- dst[i].refblock = block->dest;
- }
-
- return 1;
-}
-
-/* This function allocates new locations for blocks that are scheduled to move
- * (inside state->blocks).
- *
- * FIXME: doesn't seem to handle sparse block groups. That is, there might be
- * some free space that could be exploited in resizing that currently isn't...
- *
- * FIXME: should throw an exception if it fails to allocate blocks.
- */
-static int ext2_block_relocator_grab_blocks(struct ext2_fs *fs, struct ext2_block_relocator_state *state)
-{
- int i;
- blk_t ptr;
-
- ptr = 0;
-
- for (i=0;i<fs->numgroups;i++)
- if (EXT2_GROUP_FREE_BLOCKS_COUNT(fs->gd[i]))
- {
- struct ext2_buffer_head *bh;
- unsigned int j;
- int offset;
-
- bh = ext2_bread(fs, EXT2_GROUP_BLOCK_BITMAP(fs->gd[i]));
- offset = i * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb)
- + EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb);
-
- for (j=state->newallocoffset;
- j<EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
- j++)
- if (!(bh->data[j>>3] & _bitmap[j&7]))
- {
- state->block[ptr++].dest = offset + j;
-
- if (ptr == state->usedentries)
- {
- ext2_brelse(bh, 0);
- return 1;
- }
- }
-
- ext2_brelse(bh, 0);
- }
-
- return 0;
-}
-
-static int ext2_block_relocator_flush(struct ext2_fs *fs, struct ext2_block_relocator_state *state)
-{
- int i;
-
- if (!state->usedentries)
- return 1;
-
- if (fs->opt_verbose)
- fputs("ext2_block_relocator_flush\n", stderr);
-
- if (fs->opt_debug)
- {
- again:
-
- for (i=0; (unsigned int) i < state->usedentries-1; i++)
- if (state->block[i].num >= state->block[i+1].num)
- {
- fputs("ext2_block_relocator_flush: "
- "blocks not in order!\n", stderr);
-
- qsort(state->block,
- state->usedentries,
- sizeof(struct ext2_block_entry),
- compare_block_entries);
- goto again;
- }
- }
-
- if (!doscan(fs, state))
- return 0;
-
- if (!ext2_block_relocator_grab_blocks(fs, state))
- return 0;
-
- if (!ext2_block_relocator_copy(fs, state))
- return 0;
-
- qsort(state->block,
- state->usedentries,
- sizeof(struct ext2_block_entry),
- compare_block_entries_ind);
-
- for (i=3;i>=0;i--)
- {
- struct ext2_block_entry *dst;
- int j;
- int num;
-
- dst = state->start[i].dst;
- num = state->start[i].num;
-
- if (!num)
- continue;
-
- if (fs->opt_verbose)
- {
- /* FIXXXME gross hack */
- fprintf(stderr, "relocating %s blocks",
- ((const char *const [4])
- {"direct",
- "singly indirect",
- "doubly indirect",
- "triply indirect"})[i]);
- fflush(stderr);
- }
-
- qsort(dst,
- num,
- sizeof(struct ext2_block_entry),
- compare_block_entries_ref);
-
- for (j=0;j<num;j++)
- if (!ext2_block_relocator_ref(fs, state, &dst[j]))
- return 0;
-
- if (fs->opt_safe) {
- if (!ext2_sync(fs))
- return 0;
- }
-
- if (fs->opt_verbose)
- fputc('\n', stderr);
- }
-
- state->usedentries = 0;
- state->resolvedentries = 0;
-
- return 1;
-}
-
-static int ext2_block_relocator_mark(struct ext2_fs *fs, struct ext2_block_relocator_state *state, blk_t block)
-{
- int i;
-
- if (fs->opt_debug)
- {
- if (!ext2_get_block_state(fs, block) ||
- !ext2_is_data_block(fs, block))
- {
- ped_exception_throw (PED_EXCEPTION_WARNING,
- PED_EXCEPTION_IGNORE,
- _("Block %i shouldn't have been marked "
- "(%d, %d)!"), block,
- ext2_get_block_state(fs, block),
- ext2_is_data_block(fs, block));
- }
- }
-
- if (state->usedentries == state->allocentries - 1)
- if (!ext2_block_relocator_flush(fs, state))
- return 0;
-
- i = state->usedentries;
- state->block[i].num = block;
- state->block[i].dest = 0;
- state->block[i].refblock = 0;
- state->block[i].refoffset = 0;
-
- state->usedentries++;
- return 1;
-}
-
-static int ext2_block_relocate_grow(struct ext2_fs *fs, struct ext2_block_relocator_state *state, blk_t newsize)
-{
- blk_t newgdblocks;
- blk_t newitoffset;
- int i;
-
- newgdblocks = ped_div_round_up (newsize
- - EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb),
- EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb));
- newgdblocks = ped_div_round_up (newgdblocks
- * sizeof(struct ext2_group_desc),
- fs->blocksize);
- if (newgdblocks == fs->gdblocks)
- return 1;
-
- newitoffset = newgdblocks + 3;
- state->newallocoffset = newitoffset + fs->inodeblocks;
-
- for (i=0;i<fs->numgroups;i++)
- {
- struct ext2_buffer_head *bh;
- blk_t diff;
- blk_t j;
- blk_t start;
- int sparse;
-
- bh = ext2_bread(fs, EXT2_GROUP_BLOCK_BITMAP(fs->gd[i]));
- start = (i * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb))
- + EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb);
- sparse = ext2_is_group_sparse(fs, i);
-
- if (EXT2_GROUP_INODE_TABLE(fs->gd[i]) < start + newitoffset
- || (sparse && ((EXT2_GROUP_BLOCK_BITMAP(fs->gd[i])
- < start + newitoffset - 2)
- || (EXT2_GROUP_INODE_BITMAP(fs->gd[i])
- < start + newitoffset - 1))))
- {
- diff = newitoffset - (EXT2_GROUP_INODE_TABLE(fs->gd[i])
- - start);
-
- for (j=0;j<diff;j++)
- {
- blk_t block;
- blk_t k;
-
- k = EXT2_GROUP_INODE_TABLE(fs->gd[i])
- + fs->inodeblocks + j;
- block = k % EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
- if (bh->data[block>>3] & _bitmap[block&7]) {
- k += EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb);
- if (!ext2_block_relocator_mark(fs,
- state, k))
- {
- ext2_brelse(bh, 0);
- return 0;
- }
- }
- }
- }
-
- ext2_brelse(bh, 0);
- }
-
- if (!ext2_block_relocator_flush(fs, state))
- return 0;
-
- return 1;
-}
-
-static int ext2_block_relocate_shrink(struct ext2_fs *fs, struct ext2_block_relocator_state *state, blk_t newsize)
-{
- int i;
-
- state->newallocoffset = fs->itoffset + fs->inodeblocks;
-
- for (i=0;i<fs->numgroups;i++)
- {
- struct ext2_buffer_head *bh;
- blk_t groupsize;
- blk_t j;
- blk_t offset;
- int sparse;
- blk_t start;
- int type;
-
- offset = i * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb)
- + EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb);
- sparse = ext2_is_group_sparse(fs, i);
-
- if (newsize >= offset + EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb))
- continue; /* group will survive */
-
- bh = ext2_bread(fs, EXT2_GROUP_BLOCK_BITMAP(fs->gd[i]));
-
- if (newsize <= offset)
- type = 2; /* group is fully chopped off */
- else
- type = 1; /* group is partly chopped off */
-
- if (!sparse && type == 2)
- {
- for (j=EXT2_GROUP_INODE_BITMAP(fs->gd[i])+1;
- j<EXT2_GROUP_INODE_TABLE(fs->gd[i]);
- j++)
- {
- blk_t k;
-
- k = j - offset;
- if (bh->data[k>>3] & _bitmap[k&7])
- if (!ext2_block_relocator_mark(fs, state, j))
- {
- ext2_brelse(bh, 0);
- return 0;
- }
- }
- }
-
- start = newsize;
- if (type == 2)
- start = EXT2_GROUP_INODE_TABLE(fs->gd[i])
- + fs->inodeblocks;
-
- start -= offset;
-
- groupsize = EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
- if (offset + groupsize > EXT2_SUPER_BLOCKS_COUNT(fs->sb))
- groupsize = EXT2_SUPER_BLOCKS_COUNT(fs->sb) - offset;
-
- for (j=start;j<groupsize;j++)
- if (bh->data[j>>3] & _bitmap[j&7])
- if (!ext2_block_relocator_mark(fs, state,
- offset + j))
- {
- ext2_brelse(bh, 0);
- return 0;
- }
-
- ext2_brelse(bh, 0);
- }
-
- return ext2_block_relocator_flush(fs, state);
-}
-
-int ext2_block_relocate(struct ext2_fs *fs, blk_t newsize)
-{
- struct ext2_block_relocator_state state;
-
- if (fs->opt_verbose)
- fputs("relocating blocks....\n", stderr);
-
- state.newallocoffset = 0;
- state.allocentries = (ext2_relocator_pool_size << 10) /
- sizeof(struct ext2_block_entry);
- state.usedentries = 0;
- state.resolvedentries = 0;
- state.block = (struct ext2_block_entry *)fs->relocator_pool;
-
- if (newsize < EXT2_SUPER_BLOCKS_COUNT(fs->sb))
- return ext2_block_relocate_shrink(fs, &state, newsize);
-
- return ext2_block_relocate_grow(fs, &state, newsize);
-}
-
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/ext2/ext2_buffer.c b/libparted/fs/ext2/ext2_buffer.c
deleted file mode 100644
index f5578e6..0000000
--- a/libparted/fs/ext2/ext2_buffer.c
+++ /dev/null
@@ -1,445 +0,0 @@
-/*
- ext2_buffer.c -- ext2 buffer cache
- Copyright (C) 1998-2000, 2007, 2009-2011 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/>.
-*/
-
-#include <config.h>
-
-#ifndef DISCOVER_ONLY
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "ext2.h"
-
-/* pseudo-header */
-
-static __inline__ int ext2_block_hash(blk_t block)
-{
- unsigned long x;
-
- x = block ^ (block >> 8) ^ (block >> 16) ^ (block >> 24);
- return x & ((1 << ext2_hash_bits) - 1);
-}
-
-static struct ext2_buffer_head *ext2_bh_alloc (struct ext2_buffer_cache *, blk_t);
-static void ext2_bh_dealloc (struct ext2_buffer_head *);
-static struct ext2_buffer_head *ext2_bh_find (struct ext2_buffer_cache *, blk_t);
-static int ext2_bh_do_read (struct ext2_buffer_head *);
-static int ext2_bh_do_write(struct ext2_buffer_head *);
-static void ext2_bh_hash (struct ext2_buffer_head *);
-static void ext2_bh_unhash (struct ext2_buffer_head *);
-
-
-
-static int try_to_flush(struct ext2_buffer_cache *bc)
-{
- int i;
-
- for (i=0;i<bc->size;i++)
- {
- struct ext2_buffer_head *bh;
-
- bh = &bc->heads[i];
-
- if (bh->alloc && !bh->usecount && !bh->dirty)
- {
- ext2_bh_dealloc(bh);
- return 1;
- }
- }
-
- for (i=0;i<bc->size;i++)
- {
- struct ext2_buffer_head *bh;
-
- bh = &bc->heads[i];
-
- if (bh->alloc && !bh->usecount && bh->dirty)
- {
- ext2_bh_do_write(bh);
- ext2_bh_dealloc(bh);
- return 1;
- }
- }
-
- if (ped_exception_throw (PED_EXCEPTION_ERROR,
- PED_EXCEPTION_IGNORE_CANCEL,
- _("Couldn't flush buffer cache!"))
- != PED_EXCEPTION_IGNORE)
- return 0;
- return 1;
-}
-
-
-
-
-
-static struct ext2_buffer_head *ext2_bh_alloc(struct ext2_buffer_cache *bc, blk_t block)
-{
- struct ext2_buffer_head *bh;
- int i;
-
- bh = NULL;
-
- tryagain:
- for (i=0;i<bc->size;i++)
- {
- bh = &bc->heads[i];
-
- if (!bh->alloc)
- break;
- }
-
- if (i == bc->size)
- {
- try_to_flush(bc);
- goto tryagain;
- }
-
- bh = &bc->heads[i];
-
- bh->next = NULL;
- bh->prev = NULL;
- bh->block = block;
- bh->usecount = 0;
- bh->dirty = 0;
- bh->alloc = 1;
- bc->numalloc++;
-
- ext2_bh_hash(bh);
-
- return bh;
-}
-
-static void ext2_bh_dealloc(struct ext2_buffer_head *bh)
-{
- if (bh->dirty)
- ped_exception_throw (PED_EXCEPTION_BUG, PED_EXCEPTION_IGNORE,
- "deallocing() a dirty buffer! %i\n", bh->block);
-
- ext2_bh_unhash(bh);
- bh->alloc = 0;
- bh->bc->numalloc--;
-}
-
-static struct ext2_buffer_head *ext2_bh_find(struct ext2_buffer_cache *bc, blk_t block)
-{
- struct ext2_buffer_head *a;
- struct ext2_buffer_head *b;
- int hash;
-
- hash = ext2_block_hash(block);
- a = bc->hash[hash];
-
- if (a != NULL)
- {
- b = a;
- do
- {
- if (a->block == block)
- return a;
-
- a = a->next;
- } while (a != b);
- }
-
- return NULL;
-}
-
-static int ext2_bh_do_read(struct ext2_buffer_head *bh)
-{
- return ext2_read_blocks(bh->bc->fs, bh->data, bh->block, 1);
-}
-
-static int ext2_bh_do_write(struct ext2_buffer_head *bh)
-{
- if (!bh->alloc) {
- ped_exception_throw (PED_EXCEPTION_BUG, PED_EXCEPTION_CANCEL,
- "Attempt to write unallocated buffer.");
- return 0;
- }
-
- ext2_write_blocks(bh->bc->fs, bh->data, bh->block, 1);
- bh->dirty = 0;
- return 1;
-}
-
-static void ext2_bh_hash(struct ext2_buffer_head *bh)
-{
- int hash;
-
- hash = ext2_block_hash(bh->block);
- if (bh->bc->hash[hash] != NULL)
- {
- bh->next = bh->bc->hash[hash];
- bh->prev = bh->next->prev;
- bh->next->prev = bh;
- bh->prev->next = bh;
- return;
- }
-
- bh->bc->hash[hash] = bh;
- bh->next = bh->prev = bh;
-}
-
-static void ext2_bh_unhash(struct ext2_buffer_head *bh)
-{
- int hash;
-
- hash = ext2_block_hash(bh->block);
-
- bh->prev->next = bh->next;
- bh->next->prev = bh->prev;
-
- if (bh->bc->hash[hash] == bh)
- {
- if (bh->next != bh)
- bh->bc->hash[hash] = bh->next;
- else
- bh->bc->hash[hash] = NULL;
- }
-
- bh->next = NULL;
- bh->prev = NULL;
-}
-
-
-
-
-
-
-
-static int breadimmhits = 0;
-static int breadindhits = 0;
-static int breadmisses = 0;
-
-void ext2_bcache_deinit(struct ext2_fs *fs)
-{
- ext2_bcache_sync(fs);
- free(fs->bc->buffermem);
- free(fs->bc->hash);
- free(fs->bc->heads);
- free(fs->bc);
-
- if (fs->opt_verbose)
- fprintf(stderr,
- "direct hits: %i, indirect hits: %i, misses: %i\n",
- breadimmhits,
- breadindhits,
- breadmisses);
-}
-
-void ext2_bcache_dump(struct ext2_fs *fs)
-{
- int i;
-
- fputs ("buffer cache dump:\n", stderr);
-
- for (i=0;i<(1<<ext2_hash_bits);i++)
- if (fs->bc->hash[i] != NULL)
- {
- struct ext2_buffer_head *a;
- struct ext2_buffer_head *b;
-
- fprintf(stderr, "%i: ", i);
-
- a = b = fs->bc->hash[i];
- do
- {
- fprintf(stderr, "%i ", a->block);
- a = a->next;
- } while (a != b);
-
- fputc ('\n', stderr);
- }
-}
-
-int ext2_bcache_flush(struct ext2_fs *fs, blk_t block)
-{
- struct ext2_buffer_head *bh;
-
- if ((bh = ext2_bh_find(fs->bc, block)) == NULL)
- return 1;
-
- if (bh->usecount) {
- ped_exception_throw (PED_EXCEPTION_BUG, PED_EXCEPTION_CANCEL,
- "Attempt to flush a buffer that's in use! [%i,%i]",
- bh->block, bh->usecount);
- return 0;
- }
-
- if (bh->dirty) {
- if (!ext2_bh_do_write(bh))
- return 0;
- }
-
- ext2_bh_dealloc(bh);
- return 1;
-}
-
-int ext2_bcache_flush_range(struct ext2_fs *fs, blk_t block, blk_t num)
-{
- blk_t end = block + num;
-
- for (; block < end; block++) {
- if (!ext2_bcache_flush(fs, block))
- return 0;
- }
- return 1;
-}
-
-int ext2_bcache_init(struct ext2_fs *fs)
-{
- struct ext2_buffer_cache *bc;
- int i;
- int size;
-
- size = ext2_buffer_cache_pool_size >> (fs->logsize - 10);
-
- if ((bc = (struct ext2_buffer_cache *) ped_malloc(sizeof(struct ext2_buffer_cache))) == NULL)
- return 0;
-
- if ((bc->heads = (struct ext2_buffer_head *) ped_malloc(size * sizeof(struct ext2_buffer_head))) == NULL)
- return 0;
-
- if ((bc->hash = (struct ext2_buffer_head **) ped_malloc(sizeof(struct ext2_buffer_head *) << ext2_hash_bits)) == NULL)
- {
- free(bc->heads);
- free(bc);
- return 0;
- }
-
- if ((bc->buffermem = (unsigned char *) ped_malloc(ext2_buffer_cache_pool_size << 10)) == NULL)
- {
- free(bc->hash);
- free(bc->heads);
- free(bc);
- return 0;
- }
-
- bc->cache = &bc->heads[0];
- bc->fs = fs;
- bc->size = size;
- bc->numalloc = 0;
-
- for (i=0;i<size;i++)
- {
- bc->heads[i].data = bc->buffermem + (i << fs->logsize);
- bc->heads[i].bc = bc;
- bc->heads[i].alloc = 0;
- }
-
- for (i=0;i<(1<<ext2_hash_bits);i++)
- bc->hash[i] = NULL;
-
- fs->bc = bc;
-
- return 1;
-}
-
-int ext2_bcache_sync(struct ext2_fs *fs)
-{
- int i;
-
- for (i=0;i<fs->bc->size;i++)
- {
- struct ext2_buffer_head *bh;
-
- bh = &fs->bc->heads[i];
-
- if (bh->alloc && bh->dirty) {
- if (!ext2_bh_do_write(bh))
- return 0;
- }
- }
- return 1;
-}
-
-
-
-
-
-
-
-
-struct ext2_buffer_head *ext2_bcreate(struct ext2_fs *fs, blk_t block)
-{
- struct ext2_buffer_head *bh;
-
- if ((bh = ext2_bh_find(fs->bc, block)) != NULL)
- {
- bh->usecount++;
- }
- else
- {
- bh = ext2_bh_alloc(fs->bc, block);
- bh->usecount = 1;
- }
-
- memset(bh->data, 0, fs->blocksize);
- bh->dirty = 1;
-
- return bh;
-}
-
-struct ext2_buffer_head *ext2_bread(struct ext2_fs *fs, blk_t block)
-{
- struct ext2_buffer_head *bh;
-
- if ((bh = fs->bc->cache)->block == block)
- {
- breadimmhits++;
- bh->usecount++;
- return bh;
- }
-
- if ((bh = ext2_bh_find(fs->bc, block)) != NULL)
- {
- fs->bc->cache = bh;
- breadindhits++;
- bh->usecount++;
- return bh;
- }
-
- breadmisses++;
-
- bh = ext2_bh_alloc(fs->bc, block);
- fs->bc->cache = bh;
- bh->usecount = 1;
- if (!ext2_bh_do_read(bh)) {
- ext2_bh_dealloc(bh);
- return NULL;
- }
-
- return bh;
-}
-
-int ext2_brelse(struct ext2_buffer_head *bh, int forget)
-{
- if (bh->usecount-- == 1 && forget)
- {
- if (bh->dirty) {
- if (!ext2_bh_do_write(bh))
- return 0;
- }
-
- ext2_bh_dealloc(bh);
- }
- return 1;
-}
-
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/ext2/ext2_inode_relocator.c b/libparted/fs/ext2/ext2_inode_relocator.c
deleted file mode 100644
index 56b4b5c..0000000
--- a/libparted/fs/ext2/ext2_inode_relocator.c
+++ /dev/null
@@ -1,598 +0,0 @@
-/*
- ext2_inode_relocator.c -- ext2 inode relocator
- Copyright (C) 1998-2000, 2007, 2009-2011 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/>.
-*/
-
-#include <config.h>
-
-#ifndef DISCOVER_ONLY
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h> /* for S_ISDIR */
-#include "ext2.h"
-
-
-
-
-
-
-struct ext2_reference
-{
- blk_t block;
- off_t offset;
-};
-
-struct ext2_inode_entry
-{
- ino_t num;
- ino_t dest;
- unsigned numreferences:16;
- unsigned isdir:1;
- struct ext2_reference *ref;
-};
-
-struct ext2_inode_relocator_state
-{
- int usedentries;
- int resolvedentries;
- struct ext2_inode_entry *inode;
- struct ext2_reference *last;
-};
-
-
-
-
-
-static struct ext2_inode_entry *findit(struct ext2_inode_relocator_state *state, ino_t inode)
-{
- int min;
- int max;
- struct ext2_inode_entry *retv;
- int t;
- blk_t tval;
-
- max = state->usedentries - 1;
- min = 0;
- retv = NULL;
-
- repeat:
- if (min > max)
- goto out;
-
- t = (min + max) >> 1;
- tval = state->inode[t].num;
-
- t--;
- if (tval > inode)
- max = t;
-
- t += 2;
- if (tval < inode)
- min = t;
-
- t--;
-
- if (tval != inode)
- goto repeat;
-
- retv = &state->inode[t];
-
- out:
- return retv;
-}
-
-static int addref(struct ext2_fs *fs, struct ext2_inode_relocator_state *state, ino_t inode, blk_t block, off_t offset)
-{
- struct ext2_inode_entry *ent;
- int i;
-
- if ((ent = findit(state, inode)) == NULL)
- return 1;
-
- for (i=0;i<ent->numreferences;i++)
- if (!ent->ref[i].block)
- break;
-
- if (i == ent->numreferences)
- {
- ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
- _("Found an inode with a incorrect link count. "
- "Better go run e2fsck first!"));
- return 0;
- }
-
- if (i == ent->numreferences - 1)
- state->resolvedentries++;
-
- ent->ref[i].block = block;
- ent->ref[i].offset = offset;
-
- return 1;
-}
-
-static int doblock(struct ext2_fs *fs, struct ext2_inode_relocator_state *state, blk_t blockno)
-{
- struct ext2_buffer_head *bh;
- off_t offset;
-
- bh = ext2_bread(fs, blockno);
- if (!bh)
- return 0;
-
- offset = 0;
- do
- {
- struct ext2_dir_entry_2 *ptr;
-
- ptr = (struct ext2_dir_entry_2 *)(bh->data + offset);
-
- if (ptr->name_len)
- if (!addref(fs, state, EXT2_DIRENT_INODE(*ptr), blockno,
- offset))
- return 0;
-
- PED_ASSERT (ptr->rec_len > 0);
- offset += EXT2_DIRENT_REC_LEN (*ptr);
- } while (offset < fs->blocksize);
-
- ext2_brelse(bh, 0);
- return 1;
-}
-
-static int doindblock(struct ext2_fs *fs, struct ext2_inode_relocator_state *state, blk_t blockno)
-{
- struct ext2_buffer_head *bh;
- blk_t blk;
- int i;
-
- bh = ext2_bread(fs, blockno);
-
- for (i=0;i<(fs->blocksize>>2);i++)
- if ((blk = PED_LE32_TO_CPU(((uint32_t *)bh->data)[i])) != 0)
- if (!doblock(fs, state, blk))
- return 0;
-
- ext2_brelse(bh, 0);
- return 1;
-}
-
-static int dodindblock(struct ext2_fs *fs, struct ext2_inode_relocator_state *state, blk_t blockno)
-{
- struct ext2_buffer_head *bh;
- blk_t blk;
- int i;
-
- bh = ext2_bread(fs, blockno);
- if (!bh)
- return 0;
-
- for (i=0;i<(fs->blocksize>>2);i++)
- if ((blk = PED_LE32_TO_CPU(((uint32_t *)bh->data)[i])) != 0)
- if (!doindblock(fs, state, blk))
- return 0;
-
- ext2_brelse(bh, 0);
- return 1;
-}
-
-static int dotindblock(struct ext2_fs *fs, struct ext2_inode_relocator_state *state, blk_t blockno)
-{
- struct ext2_buffer_head *bh;
- blk_t blk;
- int i;
-
- bh = ext2_bread(fs, blockno);
- if (!bh)
- return 0;
-
- for (i=0;i<(fs->blocksize>>2);i++)
- if ((blk = PED_LE32_TO_CPU(((uint32_t *)bh->data)[i])) != 0)
- if (!dodindblock(fs, state, blk))
- return 0;
-
- ext2_brelse(bh, 0);
- return 1;
-}
-
-static int doinode(struct ext2_fs *fs, struct ext2_inode_relocator_state *state, ino_t inode)
-{
- struct ext2_inode buf;
- int i;
-
- if (!ext2_read_inode(fs, inode, &buf))
- return 0;
- if (S_ISDIR(EXT2_INODE_MODE(buf)))
- {
- blk_t blk;
-
- for (i=0;i<EXT2_NDIR_BLOCKS;i++)
- if ((blk = EXT2_INODE_BLOCK(buf, i)) != 0)
- if (!doblock(fs, state, blk))
- return 0;
-
- if ((blk = EXT2_INODE_BLOCK(buf, EXT2_IND_BLOCK)) != 0)
- if (!doindblock(fs, state, blk))
- return 0;
-
- if ((blk = EXT2_INODE_BLOCK(buf, EXT2_DIND_BLOCK)) != 0)
- if (!dodindblock(fs, state, blk))
- return 0;
-
- if ((blk = EXT2_INODE_BLOCK(buf, EXT2_TIND_BLOCK)) != 0)
- if (!dotindblock(fs, state, blk))
- return 0;
- }
-
- return 1;
-}
-
-static int doscangroup(struct ext2_fs *fs, struct ext2_inode_relocator_state *state, int group)
-{
- struct ext2_buffer_head *bh;
- unsigned int i;
- int offset;
-
- if (fs->opt_verbose)
- fprintf(stderr, " scanning group %i.... ", group);
-
- bh = ext2_bread(fs, EXT2_GROUP_INODE_BITMAP(fs->gd[group]));
- offset = group * EXT2_SUPER_INODES_PER_GROUP(fs->sb) + 1;
-
- for (i=0;i<EXT2_SUPER_INODES_PER_GROUP(fs->sb);i++)
- if (bh->data[i>>3] & _bitmap[i&7])
- {
- if (!doinode(fs, state, offset + i))
- {
- ext2_brelse(bh, 0);
- return 0;
- }
-
- if (state->resolvedentries == state->usedentries)
- break;
- }
-
- ext2_brelse(bh, 0);
-
- if (fs->opt_verbose)
- fprintf(stderr,
- "%i/%i inodes resolved\r",
- state->resolvedentries,
- state->usedentries);
-
- return 1;
-}
-
-/* basically: this builds a dependency graph of the inodes in the entire file
- * system. inodes are only referenced by the directory tree (or the magic
- * ones implicitly, like the bad blocks inode), so we just walk the directory
- * tree adding references.
- */
-static int doscan(struct ext2_fs *fs, struct ext2_inode_relocator_state *state)
-{
- int i;
-
- /* while the journal will usually be inode 8 (and therefore will never
- * need to be moved), we don't have any guarantee (grrr). So, we
- * need to be prepared to move it... (and update the reference in the
- * super block)
- */
- if (fs->has_internal_journal)
- addref(fs, state, EXT2_SUPER_JOURNAL_INUM(fs->sb),
- 1, offsetof(struct ext2_super_block, s_journal_inum));
-
- if (!doscangroup(fs, state, 0))
- return 0;
-
- if (state->resolvedentries != state->usedentries)
- for (i=fs->numgroups-1;i>0;i--)
- {
- if (!doscangroup(fs, state, i))
- return 0;
-
- if (state->resolvedentries == state->usedentries)
- break;
- }
-
- if (fs->opt_verbose)
- fputc ('\n', stderr);
-
- return 1;
-}
-
-
-
-
-
-
-
-static int ext2_inode_relocator_copy(struct ext2_fs *fs, struct ext2_inode_relocator_state *state)
-{
- int i;
-
- for (i=0;i<state->usedentries;i++)
- {
- struct ext2_inode buf;
- struct ext2_inode_entry *entry;
-
- entry = &state->inode[i];
-
- if (fs->opt_debug)
- if (!ext2_get_inode_state(fs, entry->num) ||
- ext2_get_inode_state(fs, entry->dest))
- fputs ("inodebitmaperror\n", stderr);
-
- if (!ext2_read_inode(fs, entry->num, &buf))
- return 0;
- if (!ext2_write_inode(fs, entry->dest, &buf))
- return 0;
-
- entry->isdir = S_ISDIR(EXT2_INODE_MODE(buf))?1:0;
- }
-
- if (fs->opt_safe)
- if (!ext2_sync(fs))
- return 0;
- return 1;
-}
-
-static int ext2_inode_relocator_finish(struct ext2_fs *fs, struct ext2_inode_relocator_state *state)
-{
- int i;
-
- for (i=0;i<state->usedentries;i++)
- {
- struct ext2_inode_entry *entry;
-
- entry = &state->inode[i];
- ext2_set_inode_state(fs, entry->dest, 1, 1);
- ext2_set_inode_state(fs, entry->num, 0, 1);
- ext2_zero_inode(fs, entry->num);
- }
-
- if (fs->opt_safe)
- if (!ext2_sync(fs))
- return 0;
- return 1;
-}
-
-static int ext2_inode_relocator_ref(struct ext2_fs *fs, struct ext2_inode_relocator_state *state)
-{
- int i;
- static int numerrors = 0;
-
- for (i=0;i<state->usedentries;i++)
- {
- struct ext2_inode_entry *entry;
- int j;
- uint32_t t;
-
- entry = &state->inode[i];
- t = entry->dest;
-
- for (j=0;j<entry->numreferences;j++)
- {
- struct ext2_buffer_head *bh;
-
- bh = ext2_bread(fs, entry->ref[j].block);
- if (!bh)
- return 0;
-
- if (fs->opt_debug)
- {
- if (PED_LE32_TO_CPU((*((uint32_t *)(bh->data + entry->ref[j].offset)))) != entry->num)
- {
- fprintf(stderr,
- "inode %li ref error! (->%li, [%i]={%i, %i})\n",
- (long) entry->num,
- (long) entry->dest,
- j,
- entry->ref[j].block,
- (int) entry->ref[j].offset);
- ext2_brelse(bh, 0);
-
- if (numerrors++ < 4)
- continue;
-
- fputs ("all is not well!\n", stderr);
- return 0;
- }
- }
-
- *((uint32_t *)(bh->data + entry->ref[j].offset))
- = PED_CPU_TO_LE32(t);
- bh->dirty = 1;
-
- ext2_brelse(bh, 0);
- }
-
- if (entry->isdir)
- {
- int oldgroup;
- int newgroup;
-
- oldgroup = (entry->num - 1)
- / EXT2_SUPER_INODES_PER_GROUP(fs->sb);
- newgroup = (entry->dest - 1)
- / EXT2_SUPER_INODES_PER_GROUP(fs->sb);
-
- fs->gd[oldgroup].bg_used_dirs_count = PED_CPU_TO_LE16 (
- EXT2_GROUP_USED_DIRS_COUNT(fs->gd[oldgroup])
- - 1);
- fs->gd[newgroup].bg_used_dirs_count = PED_CPU_TO_LE16 (
- EXT2_GROUP_USED_DIRS_COUNT(fs->gd[newgroup])
- + 1);
-
- fs->metadirty = EXT2_META_GD;
- }
- }
-
- if (fs->opt_safe)
- if (!ext2_sync(fs))
- return 0;
-
- return 1;
-}
-
-static int ext2_inode_relocator_grab_inodes(struct ext2_fs *fs, struct ext2_inode_relocator_state *state)
-{
- int i;
- int ptr;
-
- ptr = 0;
-
- for (i=0;i<fs->numgroups;i++)
- if (EXT2_GROUP_FREE_INODES_COUNT(fs->gd[i]))
- {
- struct ext2_buffer_head *bh;
- unsigned int j;
- int offset;
-
- bh = ext2_bread(fs, EXT2_GROUP_INODE_BITMAP(fs->gd[i]));
- if (!bh)
- return 0;
- offset = i * EXT2_SUPER_INODES_PER_GROUP(fs->sb) + 1;
-
- j = i ? 0 : 13;
- for (;j<EXT2_SUPER_INODES_PER_GROUP(fs->sb);j++)
- if (!(bh->data[j>>3] & _bitmap[j&7]))
- {
- state->inode[ptr++].dest = offset + j;
-
- if (ptr == state->usedentries)
- {
- ext2_brelse(bh, 0);
- return 1;
- }
- }
-
- ext2_brelse(bh, 0);
- }
-
- ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
- _("Not enough free inodes!"));
- return 0;
-}
-
-static int ext2_inode_relocator_flush(struct ext2_fs *fs, struct ext2_inode_relocator_state *state)
-{
- if (!state->usedentries)
- return 1;
-
- if (!doscan(fs, state))
- return 0;
-
- if (!ext2_inode_relocator_grab_inodes(fs, state))
- return 0;
-
- if (!ext2_inode_relocator_copy(fs, state))
- return 0;
-
- if (!ext2_inode_relocator_ref(fs, state))
- return 0;
-
- if (!ext2_inode_relocator_finish(fs, state))
- return 0;
-
- state->usedentries = 0;
- state->resolvedentries = 0;
- state->last = (struct ext2_reference *)fs->relocator_pool_end;
-
- if (fs->opt_safe)
- if (!ext2_sync(fs))
- return 0;
-
- return 1;
-}
-
-static int ext2_inode_relocator_mark(struct ext2_fs *fs, struct ext2_inode_relocator_state *state, ino_t inode)
-{
- struct ext2_inode buf;
- struct ext2_inode_entry *ent;
- int i;
-
- if (!ext2_read_inode(fs, inode, &buf))
- return 0;
-
- {
- register void *adv;
- register void *rec;
-
- adv = state->inode + state->usedentries + 1;
- rec = state->last - EXT2_INODE_LINKS_COUNT(buf);
-
- if (adv >= rec)
- ext2_inode_relocator_flush(fs, state);
- }
-
- state->last -= EXT2_INODE_LINKS_COUNT(buf);
-
- ent = &state->inode[state->usedentries];
- ent->num = inode;
- ent->dest = 0;
- ent->numreferences = EXT2_INODE_LINKS_COUNT(buf);
- ent->ref = state->last;
-
- for (i=0;i<ent->numreferences;i++)
- {
- ent->ref[i].block = 0;
- ent->ref[i].offset = 0;
- }
-
- state->usedentries++;
-
- return 1;
-}
-
-
-int ext2_inode_relocate(struct ext2_fs *fs, int newgroups)
-{
- int i;
- struct ext2_inode_relocator_state state;
-
- if (fs->opt_verbose)
- fputs ("ext2_inode_relocate\n", stderr);
-
- state.usedentries = 0;
- state.resolvedentries = 0;
- state.inode = (struct ext2_inode_entry *)fs->relocator_pool;
- state.last = (struct ext2_reference *)fs->relocator_pool_end;
-
- for (i=newgroups;i<fs->numgroups;i++)
- {
- struct ext2_buffer_head *bh;
- unsigned int j;
- int offset;
-
- bh = ext2_bread(fs, EXT2_GROUP_INODE_BITMAP(fs->gd[i]));
- if (!bh)
- return 0;
- offset = i * EXT2_SUPER_INODES_PER_GROUP(fs->sb) + 1;
-
- for (j=0;j<EXT2_SUPER_INODES_PER_GROUP(fs->sb);j++)
- if (bh->data[j>>3] & _bitmap[j&7])
- ext2_inode_relocator_mark(fs, &state,
- offset + j);
-
- ext2_brelse(bh, 0);
- }
-
- if (!ext2_inode_relocator_flush(fs, &state))
- return 0;
-
- return 1;
-}
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/ext2/ext2_meta.c b/libparted/fs/ext2/ext2_meta.c
deleted file mode 100644
index bd51790..0000000
--- a/libparted/fs/ext2/ext2_meta.c
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- ext2_meta.c -- ext2 metadata mover
- Copyright (C) 1998-2000, 2007, 2009-2011 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/>.
-*/
-
-#include <config.h>
-
-#ifndef DISCOVER_ONLY
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "ext2.h"
-
-int ext2_metadata_push(struct ext2_fs *fs, blk_t newsize)
-{
- int i;
- int newgdblocks;
- blk_t newitoffset;
-
- newgdblocks = ped_div_round_up (newsize
- - EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb),
- EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb));
- newgdblocks = ped_div_round_up (newgdblocks
- * sizeof(struct ext2_group_desc),
- fs->blocksize);
- newitoffset = newgdblocks + 3;
-
- if (newitoffset <= fs->itoffset)
- return 1;
-
- for (i=0;i<fs->numgroups;i++)
- {
- blk_t diff;
- blk_t j;
- blk_t fromblock;
- blk_t start;
-
- start = (i * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb))
- + EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb);
-
- if (EXT2_GROUP_INODE_TABLE(fs->gd[i]) >= start + newitoffset
- && EXT2_GROUP_BLOCK_BITMAP(fs->gd[i]) >= start + newitoffset - 2
- && EXT2_GROUP_INODE_BITMAP(fs->gd[i]) >= start + newitoffset - 1)
- continue;
-
- diff = newitoffset - (EXT2_GROUP_INODE_TABLE(fs->gd[i]) - start);
-
- /* inode table */
- fromblock = EXT2_GROUP_INODE_TABLE(fs->gd[i]) + fs->inodeblocks;
-
- if (fs->opt_debug)
- {
- for (j=0;j<diff;j++)
- if (!ext2_get_block_state(fs, fromblock+j))
- {
- fprintf(stderr,
- "error: block relocator "
- "should have relocated "
- "%i\n",
- fromblock);
-
- return 0;
- }
- }
-
- for (j=0;j<diff;j++)
- if (!ext2_set_block_state(fs, fromblock+j, 1, 0))
- return 0;
-
- if (!ext2_move_blocks(fs,
- EXT2_GROUP_INODE_TABLE(fs->gd[i]),
- fs->inodeblocks,
- EXT2_GROUP_INODE_TABLE(fs->gd[i]) + diff))
- return 0;
- fs->gd[i].bg_inode_table = PED_CPU_TO_LE32 (
- EXT2_GROUP_INODE_TABLE(fs->gd[i]) + diff);
- fs->metadirty |= EXT2_META_GD;
-
- if (fs->opt_safe)
- if (!ext2_sync(fs))
- return 0;
-
- /* block bitmap and inode bitmap */
- fromblock = EXT2_GROUP_INODE_TABLE(fs->gd[i]);
- if (ext2_is_group_sparse(fs, i))
- {
- if (!ext2_copy_block(fs,
- EXT2_GROUP_INODE_BITMAP(fs->gd[i]),
- EXT2_GROUP_INODE_BITMAP(fs->gd[i]) + diff))
- return 0;
- fs->gd[i].bg_inode_bitmap = PED_CPU_TO_LE32 (
- EXT2_GROUP_INODE_BITMAP(fs->gd[i]) + diff);
- fs->metadirty |= EXT2_META_GD;
-
- if (fs->opt_safe)
- if (!ext2_sync(fs))
- return 0;
-
- if (!ext2_copy_block(fs,
- EXT2_GROUP_BLOCK_BITMAP(fs->gd[i]),
- EXT2_GROUP_BLOCK_BITMAP(fs->gd[i])+diff))
- return 0;
- fs->gd[i].bg_block_bitmap = PED_CPU_TO_LE32 (
- EXT2_GROUP_BLOCK_BITMAP(fs->gd[i]) + diff);
- fs->metadirty |= EXT2_META_GD;
-
- if (fs->opt_safe)
- if (!ext2_sync(fs))
- return 0;
-
- fromblock = EXT2_GROUP_BLOCK_BITMAP(fs->gd[i]);
- }
-
- ext2_zero_blocks(fs, fromblock-diff, diff);
- for (j=0;j<diff;j++)
- if (!ext2_set_block_state(fs, fromblock+j-diff, 0, 0))
- return 0;
-
- if (fs->opt_verbose)
- fprintf(stderr,
- "ext2_metadata_push: group %i/%i\r",
- i+1, fs->numgroups);
- }
-
- fs->itoffset = newitoffset;
-
- if (fs->opt_verbose)
- fputc ('\n', stderr);
-
- return 1;
-}
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/ext2/ext2_mkfs.c b/libparted/fs/ext2/ext2_mkfs.c
deleted file mode 100644
index c4964b7..0000000
--- a/libparted/fs/ext2/ext2_mkfs.c
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
- ext2_mkfs.c -- ext2 fs creator
- Copyright (C) 1999-2001, 2007-2011 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/>.
-*/
-
-#include <config.h>
-
-#ifndef DISCOVER_ONLY
-
-#define USE_EXT2_IS_DATA_BLOCK
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <unistd.h>
-#include <uuid/uuid.h>
-#include "ext2.h"
-
-/* formula grabbed from linux ext2 kernel source
- *
- * returns 1 iff:
- * x == y^N, N is some natural number
- * OR x == 0
- */
-static __inline__ int is_root(int x, int y)
-{
- if (!x) return 1;
-
- while (1)
- {
- if (x == 1) return 1;
-
- if (x % y) return 0;
-
- x /= y;
- }
-}
-
-static __inline__ int is_group_sparse(int sparsesbfs, int group)
-{
- if (!sparsesbfs)
- return 1;
-
- if (is_root(group, 3) || is_root(group, 5) || is_root(group, 7))
- return 1;
-
- return 0;
-}
-
-/* has implicit parameter 'sb' !! */
-#define is_sparse(group) is_group_sparse(EXT2_SUPER_FEATURE_RO_COMPAT(*sb) \
- & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER, (group))
-
-static int ext2_mkfs_write_main(struct ext2_dev_handle *handle,
- struct ext2_super_block *sb,
- struct ext2_group_desc *gd)
-{
- int freeit;
- int i;
- int numgroups;
- int gdblocks;
- unsigned char *sbbuf;
- struct ext2_super_block *sb_for_io;
-
- freeit = 0;
- sbbuf = (unsigned char *)sb;
- sb_for_io = sb;
- if (EXT2_SUPER_LOG_BLOCK_SIZE(*sb))
- {
- sbbuf = ped_malloc(1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb));
- if (!(handle->ops->read)(handle->cookie, sbbuf, 0, 1))
- return 0;
- memcpy (sbbuf+1024, sb, 1024);
- freeit = 1;
- sb_for_io = (struct ext2_super_block*) (sbbuf + 1024);
- }
-
- numgroups = ped_div_round_up (EXT2_SUPER_BLOCKS_COUNT(*sb)
- - EXT2_SUPER_FIRST_DATA_BLOCK(*sb),
- EXT2_SUPER_BLOCKS_PER_GROUP(*sb));
- gdblocks = ped_div_round_up (numgroups * sizeof(struct ext2_group_desc),
- 1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb));
-
- for (i=0;i<numgroups;i++)
- {
- if (is_sparse(i))
- {
- int offset;
-
- offset = EXT2_SUPER_FIRST_DATA_BLOCK(*sb)
- + i * EXT2_SUPER_BLOCKS_PER_GROUP(*sb);
-
- sb_for_io->s_block_group_nr = PED_CPU_TO_LE16 (i);
-
- if (!handle->ops->write(handle->cookie, sbbuf,
- offset, 1))
- return 0;
- if (!handle->ops->write(handle->cookie, gd, offset+1,
- gdblocks))
- return 0;
- }
- }
-
- sb_for_io->s_block_group_nr = 0;
-
- if (freeit)
- free(sbbuf);
- return 1;
-}
-
-static int ext2_mkfs_write_meta(struct ext2_dev_handle *handle,
- struct ext2_super_block *sb,
- struct ext2_group_desc *gd,
- PedTimer* timer)
-{
- int blocksize;
- int gdtsize;
- int i;
- int itsize;
- int numgroups;
- unsigned char *bb;
- unsigned char *ib;
- unsigned char *zero;
-
- blocksize = 1 << (EXT2_SUPER_LOG_BLOCK_SIZE(*sb) + 13);
-
- numgroups = ped_div_round_up (EXT2_SUPER_BLOCKS_COUNT(*sb)
- - EXT2_SUPER_FIRST_DATA_BLOCK(*sb),
- EXT2_SUPER_BLOCKS_PER_GROUP(*sb));
- itsize = ped_div_round_up (sizeof(struct ext2_inode)
- * EXT2_SUPER_INODES_PER_GROUP(*sb),
- (1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb)));
- gdtsize = ped_div_round_up (sizeof(struct ext2_group_desc) * numgroups,
- (1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb)));
-
- bb = ped_malloc(1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb));
- if (!bb) goto error;
- ib = ped_malloc(1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb));
- if (!ib) goto error_free_bb;
- zero = ped_malloc((1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb)) * itsize);
- if (!zero) goto error_free_zero;
-
- memset(zero, 0, (1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb)) * itsize);
-
- ped_timer_reset (timer);
- ped_timer_set_state_name (timer, _("writing per-group metadata"));
-
- for (i=0;i<numgroups;i++)
- {
- int admin;
- blk_t bbblock;
- int groupsize;
- int groupoffset;
- blk_t ibblock;
- int j;
-
- ped_timer_update (timer, 1.0 * i / numgroups);
-
- groupoffset = i*EXT2_SUPER_BLOCKS_PER_GROUP(*sb)
- + EXT2_SUPER_FIRST_DATA_BLOCK(*sb);
- groupsize = PED_MIN(EXT2_SUPER_BLOCKS_COUNT(*sb) - groupoffset,
- EXT2_SUPER_BLOCKS_PER_GROUP(*sb));
-
- admin = itsize + 2;
- bbblock = groupoffset;
- ibblock = groupoffset + 1;
- if (is_sparse(i))
- {
- admin += gdtsize + 1;
- bbblock = groupoffset + gdtsize + 1;
- ibblock = groupoffset + gdtsize + 2;
- }
-
- {
- memset(bb, 0, 1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb));
- if (is_sparse(i))
- for (j=0;j<gdtsize+1;j++)
- bb[j>>3] |= _bitmap[j&7];
-
- j = bbblock - groupoffset;
- bb[j>>3] |= _bitmap[j&7];
-
- j = ibblock - groupoffset;
- bb[j>>3] |= _bitmap[j&7];
-
- for (j=0;j<itsize;j++)
- {
- int k = j + gdtsize + 3;
-
- bb[k>>3] |= _bitmap[k&7];
- }
-
- for (j=groupsize;j<blocksize;j++)
- bb[j>>3] |= _bitmap[j&7];
-
- if (!handle->ops->write(handle->cookie, bb, bbblock, 1))
- goto error_free_zero;
- }
-
- {
- memset(ib, 0, 1024 << EXT2_SUPER_LOG_BLOCK_SIZE(*sb));
-
- for (j=EXT2_SUPER_INODES_PER_GROUP(*sb);j<blocksize;j++)
- bb[j>>3] |= _bitmap[j&7];
-
- if (!handle->ops->write(handle->cookie, ib, ibblock, 1))
- goto error_free_zero;
- }
-
- if (!handle->ops->write(handle->cookie, zero,
- groupoffset + gdtsize + 3, itsize))
- goto error_free_zero;
-
- gd[i].bg_block_bitmap = PED_CPU_TO_LE32(bbblock);
- gd[i].bg_inode_bitmap = PED_CPU_TO_LE32(ibblock);
- gd[i].bg_inode_table = PED_CPU_TO_LE32(groupoffset + gdtsize
- + 3);
- gd[i].bg_free_blocks_count = PED_CPU_TO_LE16(groupsize - admin);
- gd[i].bg_free_inodes_count = PED_CPU_TO_LE16(
- EXT2_SUPER_INODES_PER_GROUP(*sb));
- gd[i].bg_used_dirs_count = 0;
- gd[i].bg_used_dirs_count = 0;
- gd[i].bg_pad = 0;
- gd[i].bg_reserved[0] = 0;
- gd[i].bg_reserved[1] = 0;
- gd[i].bg_reserved[2] = 0;
-
- sb->s_free_blocks_count = PED_CPU_TO_LE32 (
- EXT2_SUPER_FREE_BLOCKS_COUNT(*sb)
- + EXT2_GROUP_FREE_BLOCKS_COUNT(gd[i]));
- }
-
- ped_timer_update (timer, 1.0);
-
- free(zero);
- free(ib);
- free(bb);
- return 1;
-
-error_free_zero:
- free(zero);
- free(ib);
-error_free_bb:
- free(bb);
-error:
- return 0;
-}
-
-/* returns the offset into the buffer of the start of the next dir entry */
-static int _set_dirent(void* buf, int offset, int block_size, int is_last,
- uint32_t inode, const char* name, int file_type)
-{
- struct ext2_dir_entry_2 *dirent = (void*) (((char*)buf) + offset);
- int name_len = strlen(name);
- int rec_len;
-
- if (is_last)
- rec_len = block_size - offset;
- else
- rec_len = ped_round_up_to(name_len + 1 + 8, 4);
-
- memset (dirent, 0, rec_len);
-
- dirent->inode = PED_CPU_TO_LE32(inode);
- dirent->name_len = name_len;
- dirent->rec_len = PED_CPU_TO_LE16(rec_len);
- dirent->file_type = file_type;
- strcpy(dirent->name, name);
-
- return offset + rec_len;
-}
-
-static int ext2_mkfs_create_lost_and_found_inode(struct ext2_fs *fs)
-{
- struct ext2_buffer_head *bh;
- blk_t blocks[12];
- uint32_t* data = ped_malloc ((fs->blocksize / 4) * sizeof(uint32_t));
- int i;
- struct ext2_inode inode;
- int offset;
-
- for (i=0;i<12;i++)
- {
- if (!(blocks[i] = ext2_find_free_block(fs)))
- return 0;
-
- if (!ext2_set_block_state(fs, blocks[i], 1, 1))
- return 0;
- }
-
- /* create the directory entries, preallocating lots of blocks */
- /* first block contains . and .. */
- bh = ext2_bcreate(fs, blocks[0]);
- if (!bh)
- return 0;
- memset(bh->data, 0, fs->blocksize);
- offset = _set_dirent(bh->data, 0, fs->blocksize, 0,
- 11, ".", EXT2_FT_DIR);
- offset = _set_dirent(bh->data, offset, fs->blocksize, 1,
- EXT2_ROOT_INO, "..", EXT2_FT_DIR);
- (void) offset;
- bh->dirty = 1;
- ext2_brelse(bh, 1);
-
- /* subsequent blocks are empty */
- memset(data, 0, fs->blocksize);
- data[0] = 0;
- data[1] = PED_CPU_TO_LE32(fs->blocksize);
- for (i=1;i<12;i++)
- {
- bh = ext2_bcreate(fs, blocks[i]);
- memcpy(bh->data, data, fs->blocksize);
- bh->dirty = 1;
- ext2_brelse(bh, 1);
- }
-
- /* create inode */
- memset(&inode, 0, sizeof(struct ext2_inode));
- inode.i_mode = PED_CPU_TO_LE16(S_IFDIR | 0755);
- inode.i_uid = 0;
- inode.i_size = PED_CPU_TO_LE32(12 * fs->blocksize);
- inode.i_atime = PED_CPU_TO_LE32(time(NULL));
- inode.i_ctime = PED_CPU_TO_LE32(time(NULL));
- inode.i_mtime = PED_CPU_TO_LE32(time(NULL));
- inode.i_dtime = 0;
- inode.i_gid = 0;
- inode.i_links_count = PED_CPU_TO_LE16(2);
- inode.i_blocks = PED_CPU_TO_LE32((12 * fs->blocksize) >> 9);
- inode.i_flags = 0;
- for (i=0;i<12;i++)
- inode.i_block[i] = PED_CPU_TO_LE32(blocks[i]);
-
- if (!ext2_write_inode(fs, 11, &inode))
- return 0;
- fs->gd[0].bg_used_dirs_count = PED_CPU_TO_LE16(
- EXT2_GROUP_USED_DIRS_COUNT(fs->gd[0]) + 1);
- fs->metadirty |= EXT2_META_GD;
-
- return 1;
-}
-
-static int ext2_mkfs_create_root_inode(struct ext2_fs *fs)
-{
- struct ext2_buffer_head *bh;
- blk_t block;
- struct ext2_inode inode;
- int offset;
-
- if (!(block = ext2_find_free_block(fs)))
- return 0;
- if (!ext2_set_block_state(fs, block, 1, 1))
- return 0;
-
- /* create directory entries */
- bh = ext2_bcreate(fs, block);
- memset(bh->data, 0, fs->blocksize);
- offset = _set_dirent(bh->data, 0, fs->blocksize, 0,
- EXT2_ROOT_INO, ".", EXT2_FT_DIR);
- offset = _set_dirent(bh->data, offset, fs->blocksize, 0,
- EXT2_ROOT_INO, "..", EXT2_FT_DIR);
- offset = _set_dirent(bh->data, offset, fs->blocksize, 1,
- 11, "lost+found", EXT2_FT_DIR);
- bh->dirty = 1;
- if (!ext2_brelse(bh, 1))
- return 0;
-
- /* create inode */
- memset(&inode, 0, sizeof(struct ext2_inode));
- inode.i_mode = PED_CPU_TO_LE16(S_IFDIR | 0755);
- inode.i_uid = 0;
- inode.i_size = PED_CPU_TO_LE32(fs->blocksize);
- inode.i_atime = PED_CPU_TO_LE32(time(NULL));
- inode.i_ctime = PED_CPU_TO_LE32(time(NULL));
- inode.i_mtime = PED_CPU_TO_LE32(time(NULL));
- inode.i_dtime = 0;
- inode.i_gid = 0;
- inode.i_links_count = PED_CPU_TO_LE16(3);
- inode.i_blocks = PED_CPU_TO_LE32(fs->blocksize >> 9);
- inode.i_flags = 0;
- inode.i_block[0] = PED_CPU_TO_LE32(block);
-
- if (!ext2_write_inode(fs, 2, &inode))
- return 0;
- fs->gd[0].bg_used_dirs_count = PED_CPU_TO_LE16 (
- EXT2_GROUP_USED_DIRS_COUNT(fs->gd[0]) + 1);
- fs->metadirty |= EXT2_META_GD;
-
- return 1;
-}
-
-static int ext2_reserve_inodes(struct ext2_fs *fs)
-{
- int i;
-
- for (i=1;i<12;i++)
- if (!ext2_set_inode_state(fs, i, 1, 1))
- return 0;
- return 1;
-}
-
-static int ext2_mkfs_init_sb (struct ext2_super_block *sb, blk_t numblocks,
- int numgroups, int first_block,
- int log_block_size, blk_t blocks_per_group,
- int inodes_per_group, int sparse_sb,
- int reserved_block_percentage)
-{
- /* catch a bug in gcc 2.95.2 */
- PED_ASSERT(numgroups != 0);
-
- memset(sb, 0, 1024);
-
- sb->s_inodes_count = PED_CPU_TO_LE32(numgroups * inodes_per_group);
- sb->s_blocks_count = PED_CPU_TO_LE32(numblocks);
- sb->s_r_blocks_count = PED_CPU_TO_LE32(((uint64_t)numblocks
- * reserved_block_percentage) / 100);
-
- /* hack: this get's inc'd as we go through each group in
- * ext2_mkfs_write_meta()
- */
- sb->s_free_blocks_count = 0;
- sb->s_free_inodes_count = PED_CPU_TO_LE32 (numgroups
- * inodes_per_group);
- sb->s_first_data_block = PED_CPU_TO_LE32(first_block);
- sb->s_log_block_size = PED_CPU_TO_LE32(log_block_size - 10);
- sb->s_log_frag_size = sb->s_log_block_size;
- sb->s_blocks_per_group = PED_CPU_TO_LE32(blocks_per_group);
- sb->s_frags_per_group = PED_CPU_TO_LE32(blocks_per_group);
- sb->s_inodes_per_group = PED_CPU_TO_LE32(inodes_per_group);
- sb->s_mtime = 0;
- sb->s_wtime = 0;
- sb->s_mnt_count = 0;
- sb->s_max_mnt_count = PED_CPU_TO_LE16(30);
- sb->s_magic = PED_CPU_TO_LE16(0xEF53);
- sb->s_state = PED_CPU_TO_LE16(EXT2_VALID_FS);
- sb->s_errors = PED_CPU_TO_LE16(EXT2_ERRORS_DEFAULT);
- sb->s_minor_rev_level = 0;
- sb->s_lastcheck = 0;
- sb->s_checkinterval = 0;
- sb->s_creator_os = 0;
- sb->s_rev_level = PED_CPU_TO_LE32(1);
- sb->s_def_resuid = 0;
- sb->s_def_resgid = 0;
- sb->s_first_ino = PED_CPU_TO_LE32(11);
- sb->s_inode_size = PED_CPU_TO_LE16(128);
- sb->s_block_group_nr = 0;
- sb->s_feature_compat = 0;
- sb->s_feature_incompat = 0;
- sb->s_feature_ro_compat = 0;
- if (sparse_sb)
- sb->s_feature_ro_compat
- |= PED_CPU_TO_LE32(EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER);
-
-/* FIXME: let the user decide? _set_dirent() assumes FILETYPE */
- sb->s_feature_incompat
- |= PED_CPU_TO_LE32(EXT2_FEATURE_INCOMPAT_FILETYPE);
-
- uuid_generate(sb->s_uuid);
- memset(sb->s_volume_name, 0, 16);
- memset(sb->s_last_mounted, 0, 64);
- sb->s_algorithm_usage_bitmap = 0;
- sb->s_prealloc_blocks = 0;
- sb->s_prealloc_dir_blocks = 0;
- sb->s_padding1 = 0;
-
- return 1;
-}
-
-/* Given these five inputs, compute the three outputs. */
-static void
-compute_block_counts (blk_t numblocks, int numgroups, int log_block_size,
- int sparse_sb, blk_t blocks_per_group,
- int *last_group_blocks,
- int *last_group_admin,
- int *inodes_per_group)
-{
- int first_block = (log_block_size == 10) ? 1 : 0;
- size_t block_size = 1 << log_block_size;
-
- *last_group_blocks = ((numblocks - first_block) % blocks_per_group);
- if (!*last_group_blocks)
- *last_group_blocks = blocks_per_group;
- *inodes_per_group = ped_round_up_to (numblocks / numgroups / 2,
- (block_size
- / sizeof(struct ext2_inode)));
- *last_group_admin = (2 + *inodes_per_group * sizeof(struct ext2_inode)
- / block_size);
- if (is_group_sparse(sparse_sb, numgroups - 1)) {
- *last_group_admin +=
- (ped_div_round_up (numgroups * sizeof(struct ext2_group_desc),
- block_size));
- }
-}
-
-struct ext2_fs *ext2_mkfs(struct ext2_dev_handle *handle,
- blk_t numblocks,
- int log_block_size,
- blk_t blocks_per_group,
- int inodes_per_group,
- int sparse_sb,
- int reserved_block_percentage,
- PedTimer* timer)
-{
- struct ext2_fs *fs;
- struct ext2_super_block sb;
- struct ext2_group_desc *gd;
- int numgroups;
- int first_block;
- int last_group_blocks;
- int last_group_admin;
-
- /* if the FS is > 512Mb, use 4k blocks, otherwise 1k blocks */
- if (log_block_size == 0) {
- handle->ops->set_blocksize(handle->cookie, 12);
- if (handle->ops->get_size(handle->cookie) > (512 * 1024))
- log_block_size = 12;
- else
- log_block_size = 10;
- }
-
- /* FIXME: block size must be > MAX(logicalbs, physicalbs)
- * to avoid modify-on-write.
- * -- Leslie
- */
-
-
- handle->ops->set_blocksize(handle->cookie, log_block_size);
-
- if (numblocks == 0)
- numblocks = handle->ops->get_size(handle->cookie);
- if (numblocks == 0)
- goto diagnose_fs_too_small;
-
- if (blocks_per_group == (unsigned int) 0)
- blocks_per_group = 8 << log_block_size;
-
- first_block = (log_block_size == 10) ? 1 : 0;
-
- numgroups = ped_div_round_up (numblocks
- - first_block, blocks_per_group);
-
- if (sparse_sb == -1)
- sparse_sb = 1;
-
- /* FIXME: 5% not appropriate for modern drive sizes */
- if (reserved_block_percentage == -1)
- reserved_block_percentage = 5;
-
- compute_block_counts (numblocks, numgroups, log_block_size, sparse_sb,
- blocks_per_group, &last_group_blocks,
- &last_group_admin, &inodes_per_group);
-
- int fs_too_small = 0;
- if (last_group_admin + 1 >= last_group_blocks)
- {
- numgroups--;
- if (numgroups == 0)
- fs_too_small = 1;
- else
- {
- numblocks -= last_group_blocks;
- compute_block_counts (numblocks, numgroups, log_block_size,
- sparse_sb, blocks_per_group,
- &last_group_blocks, &last_group_admin,
- &inodes_per_group);
- }
- }
-
- if (numgroups == 1
- && (last_group_blocks - last_group_admin < 8
- || inodes_per_group < 16
- /* This final term ensures that we detect
- mkpartfs primary ext2 10KB 27650B as invalid. */
- || (inodes_per_group == 16
- && last_group_blocks - last_group_admin < 14)))
- fs_too_small = 1;
-
- if (fs_too_small) {
- diagnose_fs_too_small:
- ped_exception_throw (
- PED_EXCEPTION_ERROR,
- PED_EXCEPTION_CANCEL,
- _("File system too small for ext2."));
- goto error;
- }
-
- gd = ped_malloc(numgroups * sizeof(struct ext2_group_desc)
- + (1 << log_block_size));
- if (!gd)
- goto error;
-
- if (!ext2_mkfs_init_sb(&sb, numblocks, numgroups, first_block,
- log_block_size, blocks_per_group,
- inodes_per_group, sparse_sb,
- reserved_block_percentage))
- goto error_free_gd;
- if (!ext2_mkfs_write_meta(handle, &sb, gd, timer))
- goto error_free_gd;
- if (!ext2_mkfs_write_main(handle, &sb, gd))
- goto error_free_gd;
-
- fs = ext2_open(handle, 0);
- if (!fs) goto error_close_fs;
- if (!ext2_reserve_inodes(fs)) goto error_close_fs;
- if (!ext2_mkfs_create_root_inode(fs)) goto error_close_fs;
- if (!ext2_mkfs_create_lost_and_found_inode(fs))
- goto error_close_fs;
- if (!ext2_sync(fs)) goto error_close_fs;
- free(gd);
- return fs;
-
-error_close_fs:
- ext2_close(fs);
-error_free_gd:
- free (gd);
-error:
- return NULL;
-}
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/ext2/ext2_resize.c b/libparted/fs/ext2/ext2_resize.c
deleted file mode 100644
index 3ce20fd..0000000
--- a/libparted/fs/ext2/ext2_resize.c
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- ext2_resize.c -- ext2 resizer
- Copyright (C) 1998-2000, 2007, 2009-2011 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/>.
-*/
-
-#include <config.h>
-
-#ifndef DISCOVER_ONLY
-
-#include <stdio.h>
-#include <stdlib.h>
-#include "ext2.h"
-
-static int ext2_add_group(struct ext2_fs *fs, blk_t groupsize)
-{
- blk_t admin;
- int group;
- blk_t groupstart;
- blk_t newgdblocks;
- int sparse;
-
- if (fs->opt_verbose)
- fputs ("ext2_add_group\n", stderr);
-
- if (!ped_realloc ((void*) &fs->gd,
- (fs->numgroups+1) * sizeof(struct ext2_group_desc)
- + fs->blocksize))
- return 0;
-
- if (fs->opt_debug)
- {
- if (EXT2_SUPER_BLOCKS_COUNT(fs->sb) !=
- EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb)
- + fs->numgroups * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb))
- {
- fputs ("ext2_add_group: last (existing) group "
- "isn't complete!\n", stderr);
-
- return 0;
- }
- }
-
- group = fs->numgroups;
- sparse = ext2_is_group_sparse(fs, group);
- groupstart = EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb)
- + group * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
-
- admin = fs->adminblocks;
- if (!sparse)
- admin -= fs->gdblocks + 1;
-
- if (fs->opt_debug)
- {
- if (groupsize < fs->adminblocks ||
- groupsize > EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb))
- {
- fprintf(stderr,
- "ext2_add_group: groups of %i blocks are "
- "impossible!\n", groupsize);
-
- return 0;
- }
- }
-
- newgdblocks = ped_div_round_up((fs->numgroups + 1)
- * sizeof(struct ext2_group_desc),
- fs->blocksize);
- if (newgdblocks != fs->gdblocks)
- {
- int i;
-
- for (i=0;i<fs->numgroups;i++)
- if (ext2_is_group_sparse(fs, i))
- {
- blk_t start;
-
- start = EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb)
- + i * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
- ext2_set_block_state(fs,
- start + fs->gdblocks + 1, 1, 1);
- }
-
- fs->gdblocks++;
- fs->adminblocks++;
- if (sparse)
- admin++;
- }
-
- fs->numgroups++;
-
- fs->sb.s_inodes_count = PED_CPU_TO_LE32(
- EXT2_SUPER_INODES_COUNT(fs->sb)
- + EXT2_SUPER_INODES_PER_GROUP(fs->sb));
- fs->sb.s_blocks_count = PED_CPU_TO_LE32(
- EXT2_SUPER_BLOCKS_COUNT(fs->sb) + groupsize);
- fs->sb.s_free_blocks_count = PED_CPU_TO_LE32(
- EXT2_SUPER_FREE_BLOCKS_COUNT(fs->sb) + groupsize - admin);
- fs->sb.s_free_inodes_count = PED_CPU_TO_LE32(
- EXT2_SUPER_FREE_INODES_COUNT(fs->sb)
- + EXT2_SUPER_INODES_PER_GROUP(fs->sb));
- fs->metadirty |= EXT2_META_SB;
-
- {
- blk_t off;
- blk_t sparseoff;
-
- off = groupstart;
- sparseoff = off + fs->itoffset - 2;
-
- if (sparse)
- {
- fs->gd[group].bg_block_bitmap
- = PED_CPU_TO_LE32(sparseoff);
- fs->gd[group].bg_inode_bitmap
- = PED_CPU_TO_LE32(sparseoff + 1);
- }
- else
- {
- fs->gd[group].bg_block_bitmap
- = PED_CPU_TO_LE32(off);
- fs->gd[group].bg_inode_bitmap
- = PED_CPU_TO_LE32(off + 1);
- }
-
- /* Hey, I don't know _why_ either */
- fs->gd[group].bg_inode_table = PED_CPU_TO_LE32(sparseoff + 2);
- }
-
- fs->gd[group].bg_free_blocks_count = PED_CPU_TO_LE16(groupsize - admin);
- fs->gd[group].bg_free_inodes_count = PED_CPU_TO_LE16(
- EXT2_SUPER_INODES_PER_GROUP(fs->sb));
- fs->gd[group].bg_used_dirs_count = 0;
- fs->metadirty |= EXT2_META_SB | EXT2_META_GD;
-
- {
- struct ext2_buffer_head *bh;
- blk_t i;
-
- bh = ext2_bcreate(fs, EXT2_GROUP_BLOCK_BITMAP(fs->gd[group]));
- if (!bh)
- return 0;
-
- if (sparse)
- {
- bh->data[0] |= _bitmap[0];
- for (i=1;i<=fs->gdblocks;i++)
- bh->data[i>>3] |= _bitmap[i&7];
- }
-
- i = EXT2_GROUP_BLOCK_BITMAP(fs->gd[group]) - groupstart;
- bh->data[i>>3] |= _bitmap[i&7];
-
- i = EXT2_GROUP_INODE_BITMAP(fs->gd[group]) - groupstart;
- bh->data[i>>3] |= _bitmap[i&7];
-
- for (i=0;i<fs->inodeblocks;i++)
- {
- blk_t j;
-
- j = EXT2_GROUP_INODE_TABLE(fs->gd[group])
- - groupstart + i;
- bh->data[j>>3] |= _bitmap[j&7];
- }
-
- for (i=groupsize;i<EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);i++)
- bh->data[i>>3] |= _bitmap[i&7];
-
- ext2_brelse(bh, 0); /* this is a block bitmap */
- }
-
- if (!ext2_zero_blocks(fs, EXT2_GROUP_INODE_BITMAP(fs->gd[group]), 1))
- return 0;
- if (!ext2_zero_blocks(fs, EXT2_GROUP_INODE_TABLE(fs->gd[group]),
- fs->inodeblocks))
- return 0;
-
- if (fs->opt_safe)
- if (!ext2_sync(fs))
- return 0;
-
- return 1;
-}
-
-static int ext2_del_group(struct ext2_fs *fs)
-{
- blk_t admin;
- int group;
- blk_t groupsize;
- blk_t newgdblocks;
- int sparse;
-
- if (fs->opt_verbose)
- fputs ("ext2_del_group\n", stderr);
-
- group = fs->numgroups - 1;
- sparse = ext2_is_group_sparse(fs, group);
-
- admin = fs->adminblocks;
- if (!sparse)
- admin -= fs->gdblocks + 1;
-
- groupsize = EXT2_SUPER_BLOCKS_COUNT(fs->sb)
- - EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb)
- - group * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
-
- if (EXT2_SUPER_FREE_BLOCKS_COUNT(fs->sb) < groupsize - admin)
- {
- ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
- _("File system is too full to remove a group!"));
-
- return 0;
- }
-
- if (EXT2_SUPER_FREE_INODES_COUNT(fs->sb)
- < EXT2_SUPER_INODES_PER_GROUP(fs->sb))
- {
- ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
- _("File system has too many allocated inodes to "
- "remove a group!"));
- return 0;
- }
-
- if (fs->opt_debug)
- {
- if (EXT2_GROUP_FREE_INODES_COUNT(fs->gd[group]) !=
- EXT2_SUPER_INODES_PER_GROUP(fs->sb))
- {
- fputs ("ext2_del_group: this should not "
- "happen anymore!\n", stderr);
-
- return 0;
- }
- }
-
- newgdblocks = ped_div_round_up((fs->numgroups - 1) *
- sizeof(struct ext2_group_desc), fs->blocksize);
-
- if (newgdblocks != fs->gdblocks)
- {
- int i;
-
- for (i=0;i<fs->numgroups;i++)
- if (ext2_is_group_sparse(fs, i))
- {
- blk_t start;
-
- start = EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb) +
- i * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
- ext2_set_block_state(fs,
- start + fs->gdblocks,
- 0, 1);
- }
-
- fs->gdblocks--;
- fs->adminblocks--;
- if (sparse)
- admin--;
- }
-
- if (fs->opt_debug)
- {
- if (EXT2_GROUP_FREE_BLOCKS_COUNT(fs->gd[group])
- != groupsize - admin)
- {
- blk_t i;
- blk_t num;
- blk_t offset;
-
- offset = EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb) +
- group * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
- num = EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
-
- for (i=0;i<num;i++)
- if (ext2_is_data_block(fs, offset+i) &&
- ext2_get_block_state(fs, offset+i))
- {
- fprintf(stderr,
- "error: block relocator "
- "should have relocated "
- "%i\n",
- offset+i);
-
- return 0;
- }
- }
- }
-
- fs->numgroups--;
-
- fs->sb.s_inodes_count = PED_CPU_TO_LE32(
- EXT2_SUPER_INODES_COUNT(fs->sb)
- - EXT2_SUPER_INODES_PER_GROUP(fs->sb));
- fs->sb.s_blocks_count = PED_CPU_TO_LE32(
- EXT2_SUPER_BLOCKS_COUNT(fs->sb) - groupsize);
- fs->sb.s_free_blocks_count = PED_CPU_TO_LE32(
- EXT2_SUPER_FREE_BLOCKS_COUNT(fs->sb) - (groupsize - admin));
- fs->sb.s_free_inodes_count = PED_CPU_TO_LE32(
- EXT2_SUPER_FREE_INODES_COUNT(fs->sb)
- - EXT2_SUPER_INODES_PER_GROUP(fs->sb));
- fs->metadirty |= EXT2_META_SB;
-
- if (fs->opt_safe)
- ext2_sync(fs);
-
- ped_realloc ((void*) &fs->gd,
- fs->numgroups * sizeof(struct ext2_group_desc)
- + fs->blocksize);
-
- return 1;
-}
-
-static int ext2_grow_group(struct ext2_fs *fs, blk_t newsize)
-{
- int group;
- blk_t groupoff;
- blk_t gblocks;
- blk_t i;
-
- if (fs->opt_verbose)
- fputs ("ext2_grow_group\n", stderr);
-
- group = fs->numgroups - 1;
- groupoff = group * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb)
- + EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb);
- gblocks = EXT2_SUPER_BLOCKS_COUNT(fs->sb) - groupoff;
-
- if (fs->opt_debug)
- {
- if (newsize < gblocks)
- {
- fputs ("ext2_grow_group: called to shrink group!\n",
- stderr);
-
- return 0;
- }
-
- if (gblocks == newsize)
- {
- fputs ("ext2_grow_group: nothing to do!\n", stderr);
- return 0;
- }
- }
-
- for (i=gblocks;i<newsize;i++)
- ext2_set_block_state(fs, groupoff + i, 0, 1);
-
- fs->sb.s_blocks_count = PED_CPU_TO_LE32(
- EXT2_SUPER_BLOCKS_COUNT(fs->sb) + newsize - gblocks);
- fs->metadirty |= EXT2_META_SB;
-
- if (fs->opt_safe)
- ext2_sync(fs);
-
- return 1;
-}
-
-static int ext2_shrink_group(struct ext2_fs *fs, blk_t newsize)
-{
- blk_t admin;
- int group;
- blk_t groupoff;
- blk_t gblocks;
- blk_t i;
-
- if (fs->opt_verbose)
- fputs ("ext2_shrink_group\n", stderr);
-
- group = fs->numgroups - 1;
-
- admin = fs->adminblocks;
- if (!ext2_is_group_sparse(fs, group))
- admin -= fs->gdblocks + 1;
-
- groupoff = group * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb)
- + EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb);
- gblocks = EXT2_SUPER_BLOCKS_COUNT(fs->sb) - groupoff;
-
- if (fs->opt_debug)
- {
- if (newsize < admin)
- {
- fprintf(stderr,
- "ext2_shrink_group: cant shrink a group "
- "to %i blocks\n", newsize);
-
- return 0;
- }
-
- if (newsize > gblocks)
- {
- fputs ("ext2_shrink_group: called to grow group!\n",
- stderr);
-
- return 0;
- }
-
- if (gblocks == newsize)
- {
- fputs ("ext2_shrink_group: nothing to do!\n",
- stderr);
-
- return 0;
- }
- }
-
- for (i=newsize;i<gblocks;i++)
- {
- if (fs->opt_debug && ext2_get_block_state(fs, groupoff + i))
- {
- fprintf(stderr,
- "error: block relocator should have relocated "
- "%i\n",
- groupoff + i);
-
- return 0;
- }
-
- ext2_set_block_state(fs, groupoff + i, 1, 0);
- }
-
- i = gblocks - newsize;
- fs->sb.s_blocks_count = PED_CPU_TO_LE32(
- EXT2_SUPER_BLOCKS_COUNT(fs->sb) - i);
- fs->sb.s_free_blocks_count = PED_CPU_TO_LE32(
- EXT2_SUPER_FREE_BLOCKS_COUNT(fs->sb) - i);
- fs->gd[group].bg_free_blocks_count = PED_CPU_TO_LE16(
- EXT2_GROUP_FREE_BLOCKS_COUNT(fs->gd[group]) - i);
-
- fs->metadirty |= EXT2_META_SB | EXT2_META_GD;
-
- if (fs->opt_safe)
- ext2_sync(fs);
-
- return 1;
-}
-
-
-
-
-
-
-static int ext2_grow_fs(struct ext2_fs *fs, blk_t newsize, PedTimer* timer)
-{
- blk_t diff;
- blk_t sizelast;
- blk_t origsize = EXT2_SUPER_BLOCKS_COUNT(fs->sb);
-
- if (fs->opt_verbose)
- fputs ("ext2_grow_fs\n", stderr);
-
- if (!ext2_block_relocate(fs, newsize))
- return 0;
-
- if (!ext2_metadata_push(fs, newsize))
- return 0;
-
- diff = newsize - EXT2_SUPER_BLOCKS_COUNT(fs->sb);
- sizelast = EXT2_SUPER_BLOCKS_COUNT(fs->sb)
- - EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb)
- - (fs->numgroups-1) * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
-
- if (sizelast != EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb))
- {
- blk_t growto;
-
- growto = sizelast + diff;
- if (growto > EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb))
- growto = EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
-
- if (!ext2_grow_group(fs, growto))
- return 0;
-
- diff -= growto - sizelast;
- }
-
- ped_timer_reset (timer);
- ped_timer_set_state_name (timer, _("adding groups"));
-
- while (diff)
- {
- ped_timer_update (timer,
- 1.0 - 1.0 * diff / (newsize - origsize));
-
- sizelast = PED_MIN(diff, EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb));
- if (!ext2_add_group(fs, sizelast))
- return 0;
-
- diff -= sizelast;
- }
-
- ped_timer_update (timer, 1.0);
-
- return 1;
-}
-
-static int ext2_shrink_fs(struct ext2_fs *fs, blk_t newsize,
- PedTimer* timer)
-{
- blk_t origsize = EXT2_SUPER_BLOCKS_COUNT (fs->sb);
- blk_t diff;
- int newgroups;
- blk_t sizelast;
-
- if (fs->opt_verbose)
- fputs ("ext2_shrink_fs\n", stderr);
-
- newgroups = ped_div_round_up (newsize
- - EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb),
- EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb));
- if (EXT2_SUPER_BLOCKS_COUNT(fs->sb)
- - EXT2_SUPER_FREE_BLOCKS_COUNT(fs->sb) > newsize)
- {
- ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
- _("Your file system is too full to resize it to %i "
- "blocks. Sorry."), newsize);
- return 0;
- }
-
- if (EXT2_SUPER_INODES_COUNT(fs->sb)
- - EXT2_SUPER_FREE_INODES_COUNT(fs->sb)
- > newgroups * EXT2_SUPER_INODES_PER_GROUP(fs->sb))
- {
- ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
- _("Your file system has too many occupied inodes to "
- "resize it to %i blocks. Sorry."), newsize);
- return 0;
- }
-
- if (!ext2_inode_relocate(fs, newgroups))
- return 0;
-
- if (!ext2_block_relocate(fs, newsize))
- return 0;
-
- diff = EXT2_SUPER_BLOCKS_COUNT(fs->sb) - newsize;
-
- ped_timer_reset (timer);
- ped_timer_set_state_name (timer, _("shrinking"));
-
- while (diff > 0)
- {
- ped_timer_update (timer,
- 1.0 - 1.0 * diff / (origsize - newsize));
-
- sizelast = EXT2_SUPER_BLOCKS_COUNT(fs->sb)
- - EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb) -
- (fs->numgroups - 1)
- * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
-
- if (diff < sizelast)
- {
- if (!ext2_shrink_group(fs, sizelast - diff))
- return 0;
-
- diff = 0;
- }
- else
- {
- if (!ext2_del_group(fs))
- return 0;
-
- diff -= sizelast;
- }
- }
-
- ped_timer_update (timer, 1.0);
-
- return 1;
-}
-
-int ext2_determine_itoffset(struct ext2_fs *fs)
-{
- int i;
-
- fs->itoffset = EXT2_GROUP_INODE_TABLE(fs->gd[0])
- - EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb);
-
- /*PED_DEBUG (0x20, "itoffset is %d", fs->itoffset);
-
- PED_DEBUG (0x20, "walking %d groups", fs->numgroups);*/
-
- for (i=0;i<fs->numgroups;i++)
- {
- blk_t start;
- blk_t bb;
- blk_t ib;
- blk_t it;
-
- start = EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb)
- + (i * EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb));
- it = start + fs->itoffset;
-
- /*PED_DEBUG (0x21, "start = %d, it = %d", start, it);*/
-
- if (ext2_is_group_sparse(fs, i))
- {
- /*PED_DEBUG (0x21, "%d has a superblock copy", i);*/
- bb = it - 2;
- ib = it - 1;
- }
- else
- {
- /*PED_DEBUG (0x21, "%d doesn't have a superblock copy",
- i);*/
- bb = start;
- ib = start + 1;
- }
-
- if (EXT2_GROUP_BLOCK_BITMAP(fs->gd[i]) != bb ||
- EXT2_GROUP_INODE_BITMAP(fs->gd[i]) != ib ||
- EXT2_GROUP_INODE_TABLE(fs->gd[i]) != it)
- {
- /* ped_exception_throw (PED_EXCEPTION_NO_FEATURE,
- PED_EXCEPTION_CANCEL,
- _("This ext2 file system has a rather strange layout! "
- "Parted can't resize this (yet)."));*/
-
- /* PED_DEBUG (0x21, "calculated block bitmap to be %d, "
- "but fs says %d.", bb,
- EXT2_GROUP_BLOCK_BITMAP(fs->gd[i]));
- PED_DEBUG (0x21, "calculated inode bitmap to be %d, "
- "but fs says %d.", ib,
- EXT2_GROUP_INODE_BITMAP(fs->gd[i]));
- PED_DEBUG (0x21, "calculated inode table to be %d, "
- "but fs says %d.", it,
- EXT2_GROUP_INODE_TABLE(fs->gd[i]));*/
-
- return 0;
- }
- }
-
- return 1;
-}
-
-int ext2_resize_fs(struct ext2_fs *fs, blk_t newsize, PedTimer* timer)
-{
- blk_t residue;
- int status;
-
- if (EXT2_SUPER_STATE(fs->sb) & EXT2_ERROR_FS)
- {
- ped_exception_throw (
- PED_EXCEPTION_WARNING, PED_EXCEPTION_CANCEL,
- _("File system has errors! You should run e2fsck."));
- return 0;
- }
-
- if (!(EXT2_SUPER_STATE(fs->sb) & EXT2_VALID_FS))
- {
- ped_exception_throw (
- PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
- _("File system was not cleanly unmounted! "
- "You should run e2fsck."));
- return 0;
- }
-
- if (EXT2_SUPER_FEATURE_COMPAT(fs->sb)
- & EXT2_FEATURE_COMPAT_HAS_DIR_INDEX) {
- if (ped_exception_throw (
- PED_EXCEPTION_WARNING, PED_EXCEPTION_IGNORE_CANCEL,
- _("The file system has the 'dir_index' feature "
- "enabled. Parted can only resize the file system "
- "if it disables this feature. You can enable it "
- "later by running 'tune2fs -O dir_index DEVICE' "
- "and then 'e2fsck -fD DEVICE'."))
- != PED_EXCEPTION_IGNORE)
- return 0;
- fs->sb.s_feature_compat
- = PED_CPU_TO_LE32(EXT2_SUPER_FEATURE_COMPAT(fs->sb)
- & ~EXT2_FEATURE_COMPAT_HAS_DIR_INDEX);
- fs->metadirty |= EXT2_META_SB;
- }
-
- if (!ext2_determine_itoffset(fs) && ped_exception_throw (
- PED_EXCEPTION_WARNING,
- PED_EXCEPTION_OK_CANCEL,
- _("A resize operation on this file system will "
- "use EXPERIMENTAL code\n"
- "that MAY CORRUPT it (although no one has "
- "reported any such damage yet).\n"
- "You should at least backup your data first, "
- "and run 'e2fsck -f' afterwards."))
- == PED_EXCEPTION_CANCEL)
- {
- return 0;
- }
-
- if (fs->opt_verbose)
- fputs ("ext2_resize_fs\n", stderr);
-
- residue = (newsize - EXT2_SUPER_FIRST_DATA_BLOCK(fs->sb))
- % EXT2_SUPER_BLOCKS_PER_GROUP(fs->sb);
- if (residue && residue <= fs->adminblocks)
- newsize -= residue;
-
- if (newsize == EXT2_SUPER_BLOCKS_COUNT(fs->sb))
- return 1;
-
- fs->relocator_pool
- = (unsigned char *)ped_malloc(ext2_relocator_pool_size << 10);
- if (!fs->relocator_pool)
- return 0;
- fs->relocator_pool_end
- = fs->relocator_pool + (ext2_relocator_pool_size << 10);
-
- if (newsize < EXT2_SUPER_BLOCKS_COUNT(fs->sb))
- status = ext2_shrink_fs(fs, newsize, timer);
- else
- status = ext2_grow_fs(fs, newsize, timer);
-
- free(fs->relocator_pool);
- fs->relocator_pool = NULL;
- fs->relocator_pool_end = NULL;
-
- return status;
-}
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/ext2/interface.c b/libparted/fs/ext2/interface.c
index 09257ad..c8dd31e 100644
--- a/libparted/fs/ext2/interface.c
+++ b/libparted/fs/ext2/interface.c
@@ -24,7 +24,6 @@
#include <parted/parted.h>
#include "ext2.h"
-#include "parted_io.h"
static PedFileSystemType _ext2_type;
static PedFileSystemType _ext3_type;
@@ -120,196 +119,6 @@ _ext4_probe (PedGeometry* geom)
return _ext2_generic_probe (geom, 4);
}
-#ifndef DISCOVER_ONLY
-static int
-_ext2_clobber (PedGeometry* geom)
-{
- void *sb_v;
- int ok = 0;
-
- if (ped_geometry_read_alloc(geom, &sb_v, 2, 2)) {
- struct ext2_super_block *sb = sb_v;
- /* Clobber only if there's a matching magic number. */
- if (EXT2_SUPER_MAGIC(*sb) != EXT2_SUPER_MAGIC_CONST) {
- ok = 1;
- } else {
- sb->s_magic = 0;
- ok = ped_geometry_write(geom, sb, 2, 2);
- }
- free (sb);
- }
- return ok;
-}
-
-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:
- 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:
- 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);
-
- 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);
-
- 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,
};
diff --git a/libparted/fs/ext2/parted_io.c b/libparted/fs/ext2/parted_io.c
deleted file mode 100644
index edb43bf..0000000
--- a/libparted/fs/ext2/parted_io.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- parted_io.c -- parted I/O code interface for libext2resize
- Copyright (C) 1998-2000, 2007, 2009-2011 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/>.
-*/
-
-#include <config.h>
-
-#ifndef DISCOVER_ONLY
-
-#include <parted/parted.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include "ext2.h"
-
-/* pseudo-header.... */
-
-loff_t llseek(unsigned int fd, loff_t offset, unsigned int whence);
-
-struct my_cookie
-{
- int logsize;
- PedGeometry* geom;
-};
-
-/* ...then this must be pseudo-code :-) */
-
-static int do_close (void *cookie);
-static int do_sync (void *cookie);
-static blk_t do_get_size (void *cookie);
-static int do_read (void *cookie, void *ptr, blk_t block, blk_t numblocks);
-static int do_set_blocksize(void *cookie, int logsize);
-static int do_write (void *cookie, void *ptr, blk_t block, blk_t numblocks);
-
-struct ext2_dev_ops ops =
-{
- close: do_close,
- get_size: do_get_size,
- read: do_read,
- set_blocksize: do_set_blocksize,
- sync: do_sync,
- write: do_write
-};
-
-
-
-static int do_close(void *cookie)
-{
- struct my_cookie *monster = cookie;
-
- return ped_geometry_sync(monster->geom);
-}
-
-static int do_sync(void *cookie)
-{
- struct my_cookie *monster = cookie;
-
- return ped_geometry_sync(monster->geom);
-}
-
-static blk_t do_get_size(void *cookie)
-{
- struct my_cookie *monster = cookie;
-
- return monster->geom->length >> (monster->logsize - 9);
-}
-
-static int do_read(void *cookie, void *ptr, blk_t block, blk_t num)
-{
- struct my_cookie *monster = cookie;
-
- return ped_geometry_read(monster->geom, ptr,
- (PedSector) block << (monster->logsize - 9),
- (PedSector) num << (monster->logsize - 9));
-}
-
-static int do_set_blocksize(void *cookie, int logsize)
-{
- struct my_cookie *monster = cookie;
-
- monster->logsize = logsize;
- return 1;
-}
-
-static int do_write(void *cookie, void *ptr, blk_t block, blk_t num)
-{
- struct my_cookie *monster = cookie;
-
- return ped_geometry_write(monster->geom, ptr,
- (PedSector) block << (monster->logsize - 9),
- (PedSector) num << (monster->logsize - 9));
-}
-
-
-struct ext2_dev_handle *ext2_make_dev_handle_from_parted_geometry(PedGeometry* geom)
-{
- struct ext2_dev_handle *dh;
- struct my_cookie *monster;
-
- if ((dh = ped_malloc(sizeof(struct ext2_dev_handle))) == NULL)
- goto error;
-
- if ((monster = ped_malloc(sizeof(struct my_cookie))) == NULL)
- goto error_free_dh;
-
- dh->ops = &ops;
- dh->cookie = monster;
- monster->logsize = 9;
- monster->geom = geom;
-
- return dh;
-
-error_free_dh:
- free(dh);
-error:
- return NULL;
-}
-
-void ext2_destroy_dev_handle(struct ext2_dev_handle *handle)
-{
- ped_geometry_destroy(((struct my_cookie *)handle->cookie)->geom);
- free(handle->cookie);
- free(handle);
-}
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/ext2/parted_io.h b/libparted/fs/ext2/parted_io.h
deleted file mode 100644
index d51ecdd..0000000
--- a/libparted/fs/ext2/parted_io.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- parted_io.h
- Copyright (C) 1998-2000, 2007, 2009-2011 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/>.
-*/
-
-#ifndef _PARTED_IO_H
-#define _PARTED_IO_H
-
-#include "ext2.h"
-
-void ext2_destroy_dev_handle(struct ext2_dev_handle *handle);
-
-#endif
diff --git a/libparted/fs/ext2/tune.c b/libparted/fs/ext2/tune.c
deleted file mode 100644
index de8efd7..0000000
--- a/libparted/fs/ext2/tune.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- tune.c -- tuneable stuff
- Copyright (C) 1998-2000, 2007, 2009-2011 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/>.
-*/
-
-#include <config.h>
-
-#ifndef DISCOVER_ONLY
-
-/*
- * maybe i'll make this all command-line configurable one day
- */
-
-/* The size of the buffer cache in kilobytes. Note that this is only
- the actual buffer memory. On top of this amount additional memory
- will be allocated for buffer cache bookkeeping. */
-int ext2_buffer_cache_pool_size = 512;
-
-/* The size of the buffer cache hash table (log2 of # of buckets). */
-int ext2_hash_bits = 8;
-
-/* The block/inode relocator pool size in kilobytes. Make this as big
- as you can. The smaller this is, the more disk I/O is required for
- doing relocations. */
-int ext2_relocator_pool_size = 4096;
-#endif /* !DISCOVER_ONLY */
diff --git a/libparted/fs/ext2/tune.h b/libparted/fs/ext2/tune.h
deleted file mode 100644
index 37218a8..0000000
--- a/libparted/fs/ext2/tune.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- tune.h -- ext2 tunables header
- Copyright (C) 1998-2000, 2007, 2009-2011 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/>.
-*/
-
-#ifndef _TUNE_H
-#define _TUNE_H
-
-#define MAXCONT 256
-
-extern int ext2_buffer_cache_pool_size;
-extern int ext2_hash_bits;
-extern int ext2_max_groups;
-extern int ext2_relocator_pool_size;
-
-#endif