--- old/usr/src/lib/libparted/common/libparted/fs/ext2/ext2_inode_relocator.c	2014-07-17 16:13:48.949313827 +0200
+++ /dev/null	2014-07-17 16:13:48.000000000 +0200
@@ -1,599 +0,0 @@
-/*
-    ext2_inode_relocator.c -- ext2 inode relocator
-    Copyright (C) 1998-2000, 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 <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, return 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 */
-
