#include <et/com_err.h>
#include "e2fsck.h"
+#ifdef ENABLE_SWAPFS
+
struct swap_block_struct {
- ino_t ino;
+ ext2_ino_t ino;
int isdir;
errcode_t errcode;
char *dir_buf;
* This function is responsible for byte-swapping all of the indirect,
* block pointers. It is also responsible for byte-swapping directories.
*/
-static void swap_inode_blocks(e2fsck_t ctx, ino_t ino, char *block_buf,
+static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
struct ext2_inode *inode)
{
errcode_t retval;
swap_block, &sb);
if (retval) {
com_err("swap_inode_blocks", retval,
- "while calling ext2fs_block_iterate");
+ _("while calling ext2fs_block_iterate"));
ctx->flags |= E2F_FLAG_ABORT;
return;
}
if (sb.errcode) {
com_err("swap_inode_blocks", sb.errcode,
- "while calling iterator function");
+ _("while calling iterator function"));
ctx->flags |= E2F_FLAG_ABORT;
return;
}
static void swap_inodes(e2fsck_t ctx)
{
ext2_filsys fs = ctx->fs;
- int i, group;
- ino_t ino = 1;
- char *buf, *block_buf;
+ dgrp_t group;
+ unsigned int i;
+ ext2_ino_t ino = 1;
+ char *buf = NULL, *block_buf = NULL;
errcode_t retval;
struct ext2_inode * inode;
e2fsck_use_inode_shortcuts(ctx, 1);
retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
- (void **) &buf);
+ &buf);
if (retval) {
com_err("swap_inodes", retval,
- "while allocating inode buffer");
+ _("while allocating inode buffer"));
ctx->flags |= E2F_FLAG_ABORT;
- return;
+ goto errout;
}
block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
"block interate buffer");
fs->inode_blocks_per_group, buf);
if (retval) {
com_err("swap_inodes", retval,
- "while reading inode table (group %d)",
+ _("while reading inode table (group %d)"),
group);
ctx->flags |= E2F_FLAG_ABORT;
- return;
+ goto errout;
}
inode = (struct ext2_inode *) buf;
for (i=0; i < fs->super->s_inodes_per_group;
swap_inode_blocks(ctx, ino, block_buf, inode);
if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
- return;
+ goto errout;
if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
ext2fs_swap_inode(fs, inode, inode, 1);
fs->inode_blocks_per_group, buf);
if (retval) {
com_err("swap_inodes", retval,
- "while writing inode table (group %d)",
+ _("while writing inode table (group %d)"),
group);
ctx->flags |= E2F_FLAG_ABORT;
- return;
+ goto errout;
}
}
- ext2fs_free_mem((void **) &buf);
- ext2fs_free_mem((void **) &block_buf);
+errout:
+ if (buf)
+ ext2fs_free_mem(&buf);
+ if (block_buf)
+ ext2fs_free_mem(&block_buf);
e2fsck_use_inode_shortcuts(ctx, 0);
+ ext2fs_flush_icache(fs);
}
+#if defined(__powerpc__) && defined(EXT2FS_ENABLE_SWAPFS)
+/*
+ * On the PowerPC, the big-endian variant of the ext2 filesystem
+ * has its bitmaps stored as 32-bit words with bit 0 as the LSB
+ * of each word. Thus a bitmap with only bit 0 set would be, as
+ * a string of bytes, 00 00 00 01 00 ...
+ * To cope with this, we byte-reverse each word of a bitmap if
+ * we have a big-endian filesystem, that is, if we are *not*
+ * byte-swapping other word-sized numbers.
+ */
+#define EXT2_BIG_ENDIAN_BITMAPS
+#endif
+
+#ifdef EXT2_BIG_ENDIAN_BITMAPS
+static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
+{
+ __u32 *p = (__u32 *) bmap->bitmap;
+ int n, nbytes = (bmap->end - bmap->start + 7) / 8;
+
+ for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
+ *p = ext2fs_swab32(*p);
+}
+#endif
+
+
void swap_filesys(e2fsck_t ctx)
{
ext2_filsys fs = ctx->fs;
#endif
if (!(ctx->options & E2F_OPT_PREEN))
- printf("Pass 0: Doing byte-swap of filesystem\n");
+ printf(_("Pass 0: Doing byte-swap of filesystem\n"));
#ifdef MTRACE
mtrace_print("Byte swap");
#endif
if (fs->super->s_mnt_count) {
- fprintf(stderr, "%s: the filesystem must be freshly "
+ fprintf(stderr, _("%s: the filesystem must be freshly "
"checked using fsck\n"
"and not mounted before trying to "
- "byte-swap it.\n", ctx->device_name);
+ "byte-swap it.\n"), ctx->device_name);
ctx->flags |= E2F_FLAG_ABORT;
return;
}
fs->flags |= EXT2_FLAG_SWAP_BYTES;
fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
EXT2_FLAG_SWAP_BYTES_WRITE);
+
+#ifdef EXT2_BIG_ENDIAN_BITMAPS
+ e2fsck_read_bitmaps(ctx);
+ ext2fs_swap_bitmap(fs->inode_map);
+ ext2fs_swap_bitmap(fs->block_map);
+ fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
+#endif
+ fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
ext2fs_flush(fs);
+ fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
#ifdef RESOURCE_TRACK
if (ctx->options & E2F_OPT_TIME2)
- print_resource_track("Byte swap", &rtrack);
+ print_resource_track(_("Byte swap"), &rtrack);
#endif
}
-
+#endif