diff options
author | Jim Meyering <meyering@redhat.com> | 2011-05-16 12:11:23 +0200 |
---|---|---|
committer | Jim Meyering <meyering@redhat.com> | 2011-05-27 17:07:45 +0200 |
commit | 884a76f6ea4f6a2009337ab0f7b3caee6cbd6efe (patch) | |
tree | 18cf692bc8d6e5f17ebb5aa64f7058e0e4ee1af8 | |
parent | 58413d67ecb80740a07c3582d31883884cbb1966 (diff) | |
download | parted-884a76f6ea4f6a2009337ab0f7b3caee6cbd6efe.tar.gz |
ext2: remove all-but-probe FS-related code
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | libparted/fs/ext2/Makefile.am | 16 | ||||
-rw-r--r-- | libparted/fs/ext2/ext2.c | 795 | ||||
-rw-r--r-- | libparted/fs/ext2/ext2.h | 166 | ||||
-rw-r--r-- | libparted/fs/ext2/ext2_block_relocator.c | 921 | ||||
-rw-r--r-- | libparted/fs/ext2/ext2_buffer.c | 445 | ||||
-rw-r--r-- | libparted/fs/ext2/ext2_inode_relocator.c | 598 | ||||
-rw-r--r-- | libparted/fs/ext2/ext2_meta.c | 145 | ||||
-rw-r--r-- | libparted/fs/ext2/ext2_mkfs.c | 633 | ||||
-rw-r--r-- | libparted/fs/ext2/ext2_resize.c | 730 | ||||
-rw-r--r-- | libparted/fs/ext2/interface.c | 191 | ||||
-rw-r--r-- | libparted/fs/ext2/parted_io.c | 137 | ||||
-rw-r--r-- | libparted/fs/ext2/parted_io.h | 26 | ||||
-rw-r--r-- | libparted/fs/ext2/tune.c | 39 | ||||
-rw-r--r-- | libparted/fs/ext2/tune.h | 29 |
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 |