--- old/usr/src/lib/libparted/common/libparted/fs/ext2/ext2.c	2014-07-17 16:13:48.645765411 +0200
+++ /dev/null	2014-07-17 16:13:48.000000000 +0200
@@ -1,792 +0,0 @@
-/*
-    ext2.c -- generic ext2 stuff
-    Copyright (C) 1998, 1999, 2000, 2001, 2007 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;
-
-		ped_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;
-		ped_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;
-		}
-
-		ped_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:
-	ped_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);
-
-	ped_free(fs->gd);
-	ped_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."));
-		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;
-
-	ped_free(fs->gd);
-error_deinit_bcache:
-	ext2_bcache_deinit(fs);
-error_free_fs:
-	ped_free(fs);
-error:
-	return NULL;
-}
-
-#endif /* !DISCOVER_ONLY */
