ext2_inode_relocator.c revision 7e7bd3dccbfe8f79e25e5c1554b5bc3a9aaca321
/*
ext2_inode_relocator.c -- ext2 inode relocator
Copyright (C) 1998-2000, 2007 Free Software Foundation, Inc.
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"
struct ext2_reference
{
};
struct ext2_inode_entry
{
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;
};
{
int min;
int max;
struct ext2_inode_entry *retv;
int t;
min = 0;
goto out;
t--;
max = t;
t += 2;
min = t;
t--;
goto repeat;
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;
return 1;
for (i=0;i<ent->numreferences;i++)
break;
if (i == ent->numreferences)
{
_("Found an inode with a incorrect link count. "
"Better go run e2fsck first!"));
return 0;
}
state->resolvedentries++;
return 1;
}
{
struct ext2_buffer_head *bh;
if (!bh)
return 0;
offset = 0;
do
{
struct ext2_dir_entry_2 *ptr;
offset))
return 0;
ext2_brelse(bh, 0);
return 1;
}
{
struct ext2_buffer_head *bh;
int i;
return 0;
ext2_brelse(bh, 0);
return 1;
}
{
struct ext2_buffer_head *bh;
int i;
if (!bh)
return 0;
return 0;
ext2_brelse(bh, 0);
return 1;
}
{
struct ext2_buffer_head *bh;
int i;
if (!bh)
return 0;
return 0;
ext2_brelse(bh, 0);
return 1;
}
{
struct ext2_inode buf;
int i;
return 0;
{
for (i=0;i<EXT2_NDIR_BLOCKS;i++)
return 0;
return 0;
return 0;
return 0;
}
return 1;
}
{
struct ext2_buffer_head *bh;
unsigned int i;
int offset;
if (fs->opt_verbose)
{
{
ext2_brelse(bh, 0);
return 0;
}
break;
}
ext2_brelse(bh, 0);
if (fs->opt_verbose)
"%i/%i inodes resolved\r",
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.
*/
{
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)
return 0;
{
return 0;
break;
}
if (fs->opt_verbose)
return 1;
}
{
int i;
for (i=0;i<state->usedentries;i++)
{
struct ext2_inode buf;
struct ext2_inode_entry *entry;
return 0;
return 0;
}
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;
}
return 0;
return 1;
}
{
int i;
static int numerrors = 0;
for (i=0;i<state->usedentries;i++)
{
struct ext2_inode_entry *entry;
int j;
uint32_t t;
for (j=0;j<entry->numreferences;j++)
{
struct ext2_buffer_head *bh;
if (!bh)
return 0;
{
{
"inode %li ref error! (->%li, [%i]={%i, %i})\n",
j,
ext2_brelse(bh, 0);
if (numerrors++ < 4)
continue;
return 0;
}
}
= PED_CPU_TO_LE32(t);
ext2_brelse(bh, 0);
}
{
int oldgroup;
int newgroup;
- 1);
+ 1);
}
}
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;
{
struct ext2_buffer_head *bh;
unsigned int j;
int offset;
if (!bh)
return 0;
j = i ? 0 : 13;
{
{
ext2_brelse(bh, 0);
return 1;
}
}
ext2_brelse(bh, 0);
}
_("Not enough free inodes!"));
return 0;
}
{
if (!state->usedentries)
return 1;
return 0;
return 0;
return 0;
return 0;
return 0;
state->usedentries = 0;
state->resolvedentries = 0;
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;
return 0;
{
register void *adv;
register void *rec;
}
for (i=0;i<ent->numreferences;i++)
{
}
state->usedentries++;
return 1;
}
{
int i;
struct ext2_inode_relocator_state state;
if (fs->opt_verbose)
state.usedentries = 0;
state.resolvedentries = 0;
{
struct ext2_buffer_head *bh;
unsigned int j;
int offset;
if (!bh)
return 0;
offset + j);
ext2_brelse(bh, 0);
}
return 0;
return 1;
}
#endif /* !DISCOVER_ONLY */