[Pkg-lustre-svn-commit] updated: [eca8263] Removed somed .orig files and don't fail when the patches and series file is not around
Patrick Winnertz
winnie at debian.org
Thu Apr 19 12:54:41 UTC 2012
The following commit has been merged in the master branch:
commit eca826343b20eb3f3f6296692e67f6e14c294a9c
Author: Patrick Winnertz <winnie at debian.org>
Date: Fri Mar 9 12:32:42 2012 +0100
Removed somed .orig files and don't fail when the patches and series
file is not around
Signed-off-by: Patrick Winnertz <winnie at debian.org>
diff --git a/debian/rules b/debian/rules
index 14f090d..25e0fff 100755
--- a/debian/rules
+++ b/debian/rules
@@ -80,7 +80,7 @@ clean:
[ ! -f Makefile ] || $(MAKE) distclean
rm -f config.sub config.guess
quilt --quiltrc /dev/null pop -a || true
- rm -f patches series
+ -rm -f patches series
rm -rf .pc
rm -f e2fsck/lfsck.8 public_config.h e2fsck/e2fsck.conf.5
rm -f asm_types.h e2fsck/prof_err.c e2fsck/prof_err.h
diff --git a/debugfs/debugfs.c.orig b/debugfs/debugfs.c.orig
deleted file mode 100644
index 6782880..0000000
--- a/debugfs/debugfs.c.orig
+++ /dev/null
@@ -1,2326 +0,0 @@
-/*
- * debugfs.c --- a program which allows you to attach an ext2fs
- * filesystem and play with it.
- *
- * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
- * under the terms of the GNU Public License.
- *
- * Modifications by Robert Sanders <gt8134b at prism.gatech.edu>
- */
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <time.h>
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#else
-extern int optind;
-extern char *optarg;
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "et/com_err.h"
-#include "ss/ss.h"
-#include "debugfs.h"
-#include "uuid/uuid.h"
-#include "e2p/e2p.h"
-
-#include <ext2fs/ext2_ext_attr.h>
-
-#include "../version.h"
-#include "jfs_user.h"
-
-extern ss_request_table debug_cmds;
-ss_request_table *extra_cmds;
-const char *debug_prog_name;
-
-ext2_filsys current_fs = NULL;
-ext2_ino_t root, cwd;
-
-static void open_filesystem(char *device, int open_flags, blk64_t superblock,
- blk64_t blocksize, int catastrophic,
- char *data_filename)
-{
- int retval;
- io_channel data_io = 0;
-
- if (superblock != 0 && blocksize == 0) {
- com_err(device, 0, "if you specify the superblock, you must also specify the block size");
- current_fs = NULL;
- return;
- }
-
- if (data_filename) {
- if ((open_flags & EXT2_FLAG_IMAGE_FILE) == 0) {
- com_err(device, 0,
- "The -d option is only valid when reading an e2image file");
- current_fs = NULL;
- return;
- }
- retval = unix_io_manager->open(data_filename, 0, &data_io);
- if (retval) {
- com_err(data_filename, 0, "while opening data source");
- current_fs = NULL;
- return;
- }
- }
-
- if (catastrophic && (open_flags & EXT2_FLAG_RW)) {
- com_err(device, 0,
- "opening read-only because of catastrophic mode");
- open_flags &= ~EXT2_FLAG_RW;
- }
- if (catastrophic)
- open_flags |= EXT2_FLAG_SKIP_MMP;
-
- retval = ext2fs_open(device, open_flags, superblock, blocksize,
- unix_io_manager, ¤t_fs);
- if (retval) {
- com_err(device, retval, "while opening filesystem");
- current_fs = NULL;
- return;
- }
-
- if (catastrophic)
- com_err(device, 0, "catastrophic mode - not reading inode or group bitmaps");
- else {
- retval = ext2fs_read_inode_bitmap(current_fs);
- if (retval) {
- com_err(device, retval, "while reading inode bitmap");
- goto errout;
- }
- retval = ext2fs_read_block_bitmap(current_fs);
- if (retval) {
- com_err(device, retval, "while reading block bitmap");
- goto errout;
- }
- }
-
- if (data_io) {
- retval = ext2fs_set_data_io(current_fs, data_io);
- if (retval) {
- com_err(device, retval,
- "while setting data source");
- goto errout;
- }
- }
-
- root = cwd = EXT2_ROOT_INO;
- return;
-
-errout:
- retval = ext2fs_close(current_fs);
- if (retval)
- com_err(device, retval, "while trying to close filesystem");
- current_fs = NULL;
-}
-
-void do_open_filesys(int argc, char **argv)
-{
- int c, err;
- int catastrophic = 0;
- blk64_t superblock = 0;
- blk64_t blocksize = 0;
- int open_flags = EXT2_FLAG_SOFTSUPP_FEATURES | EXT2_FLAG_64BITS;
- char *data_filename = 0;
-
- reset_getopt();
- while ((c = getopt (argc, argv, "iwfecb:s:d:D")) != EOF) {
- switch (c) {
- case 'i':
- open_flags |= EXT2_FLAG_IMAGE_FILE;
- break;
- case 'w':
- open_flags |= EXT2_FLAG_RW;
- break;
- case 'f':
- open_flags |= EXT2_FLAG_FORCE;
- break;
- case 'e':
- open_flags |= EXT2_FLAG_EXCLUSIVE;
- break;
- case 'c':
- catastrophic = 1;
- break;
- case 'd':
- data_filename = optarg;
- break;
- case 'D':
- open_flags |= EXT2_FLAG_DIRECT_IO;
- break;
- case 'b':
- blocksize = parse_ulong(optarg, argv[0],
- "block size", &err);
- if (err)
- return;
- break;
- case 's':
- superblock = parse_ulong(optarg, argv[0],
- "superblock number", &err);
- if (err)
- return;
- break;
- default:
- goto print_usage;
- }
- }
- if (optind != argc-1) {
- goto print_usage;
- }
- if (check_fs_not_open(argv[0]))
- return;
- open_filesystem(argv[optind], open_flags,
- superblock, blocksize, catastrophic,
- data_filename);
- return;
-
-print_usage:
- fprintf(stderr, "%s: Usage: open [-s superblock] [-b blocksize] "
- "[-c] [-w] <device>\n", argv[0]);
-}
-
-void do_lcd(int argc, char **argv)
-{
- if (argc != 2) {
- com_err(argv[0], 0, "Usage: %s %s", argv[0], "<native dir>");
- return;
- }
-
- if (chdir(argv[1]) == -1) {
- com_err(argv[0], errno,
- "while trying to change native directory to %s",
- argv[1]);
- return;
- }
-}
-
-static void close_filesystem(NOARGS)
-{
- int retval;
-
- if (current_fs->flags & EXT2_FLAG_IB_DIRTY) {
- retval = ext2fs_write_inode_bitmap(current_fs);
- if (retval)
- com_err("ext2fs_write_inode_bitmap", retval, 0);
- }
- if (current_fs->flags & EXT2_FLAG_BB_DIRTY) {
- retval = ext2fs_write_block_bitmap(current_fs);
- if (retval)
- com_err("ext2fs_write_block_bitmap", retval, 0);
- }
- retval = ext2fs_close(current_fs);
- if (retval)
- com_err("ext2fs_close", retval, 0);
- current_fs = NULL;
- return;
-}
-
-void do_close_filesys(int argc, char **argv)
-{
- int c;
-
- if (check_fs_open(argv[0]))
- return;
-
- reset_getopt();
- while ((c = getopt (argc, argv, "a")) != EOF) {
- switch (c) {
- case 'a':
- current_fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
- break;
- default:
- goto print_usage;
- }
- }
-
- if (argc > optind) {
- print_usage:
- com_err(0, 0, "Usage: close_filesys [-a]");
- return;
- }
-
- close_filesystem();
-}
-
-void do_init_filesys(int argc, char **argv)
-{
- struct ext2_super_block param;
- errcode_t retval;
- int err;
-
- if (common_args_process(argc, argv, 3, 3, "initialize",
- "<device> <blocksize>", CHECK_FS_NOTOPEN))
- return;
-
- memset(¶m, 0, sizeof(struct ext2_super_block));
- ext2fs_blocks_count_set(¶m, parse_ulong(argv[2], argv[0],
- "blocks count", &err));
- if (err)
- return;
- retval = ext2fs_initialize(argv[1], 0, ¶m,
- unix_io_manager, ¤t_fs);
- if (retval) {
- com_err(argv[1], retval, "while initializing filesystem");
- current_fs = NULL;
- return;
- }
- root = cwd = EXT2_ROOT_INO;
- return;
-}
-
-static void print_features(struct ext2_super_block * s, FILE *f)
-{
- int i, j, printed=0;
- __u32 *mask = &s->s_feature_compat, m;
-
- fputs("Filesystem features:", f);
- for (i=0; i <3; i++,mask++) {
- for (j=0,m=1; j < 32; j++, m<<=1) {
- if (*mask & m) {
- fprintf(f, " %s", e2p_feature2string(i, m));
- printed++;
- }
- }
- }
- if (printed == 0)
- fputs("(none)", f);
- fputs("\n", f);
-}
-
-static void print_bg_opts(ext2_filsys fs, dgrp_t group, int mask,
- const char *str, int *first, FILE *f)
-{
- if (ext2fs_bg_flags_test(fs, group, mask)) {
- if (*first) {
- fputs(" [", f);
- *first = 0;
- } else
- fputs(", ", f);
- fputs(str, f);
- }
-}
-
-void do_show_super_stats(int argc, char *argv[])
-{
- dgrp_t i;
- FILE *out;
- int c, header_only = 0;
- int numdirs = 0, first, gdt_csum;
-
- reset_getopt();
- while ((c = getopt (argc, argv, "h")) != EOF) {
- switch (c) {
- case 'h':
- header_only++;
- break;
- default:
- goto print_usage;
- }
- }
- if (optind != argc) {
- goto print_usage;
- }
- if (check_fs_open(argv[0]))
- return;
- out = open_pager();
-
- list_super2(current_fs->super, out);
- for (i=0; i < current_fs->group_desc_count; i++)
- numdirs += ext2fs_bg_used_dirs_count(current_fs, i);
- fprintf(out, "Directories: %d\n", numdirs);
-
- if (header_only) {
- close_pager(out);
- return;
- }
-
- gdt_csum = EXT2_HAS_RO_COMPAT_FEATURE(current_fs->super,
- EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
- for (i = 0; i < current_fs->group_desc_count; i++) {
- fprintf(out, " Group %2d: block bitmap at %llu, "
- "inode bitmap at %llu, "
- "inode table at %llu\n"
- " %u free %s, "
- "%u free %s, "
- "%u used %s%s",
- i, ext2fs_block_bitmap_loc(current_fs, i),
- ext2fs_inode_bitmap_loc(current_fs, i),
- ext2fs_inode_table_loc(current_fs, i),
- ext2fs_bg_free_blocks_count(current_fs, i),
- ext2fs_bg_free_blocks_count(current_fs, i) != 1 ?
- "blocks" : "block",
- ext2fs_bg_free_inodes_count(current_fs, i),
- ext2fs_bg_free_inodes_count(current_fs, i) != 1 ?
- "inodes" : "inode",
- ext2fs_bg_used_dirs_count(current_fs, i),
- ext2fs_bg_used_dirs_count(current_fs, i) != 1 ? "directories"
- : "directory", gdt_csum ? ", " : "\n");
- if (gdt_csum)
- fprintf(out, "%u unused %s\n",
- ext2fs_bg_itable_unused(current_fs, i),
- ext2fs_bg_itable_unused(current_fs, i) != 1 ?
- "inodes" : "inode");
- first = 1;
- print_bg_opts(current_fs, i, EXT2_BG_INODE_UNINIT, "Inode not init",
- &first, out);
- print_bg_opts(current_fs, i, EXT2_BG_BLOCK_UNINIT, "Block not init",
- &first, out);
- if (gdt_csum) {
- fprintf(out, "%sChecksum 0x%04x",
- first ? " [":", ", ext2fs_bg_checksum(current_fs, i));
- first = 0;
- }
- if (!first)
- fputs("]\n", out);
- }
- close_pager(out);
- return;
-print_usage:
- fprintf(stderr, "%s: Usage: show_super [-h]\n", argv[0]);
-}
-
-void do_dirty_filesys(int argc EXT2FS_ATTR((unused)),
- char **argv EXT2FS_ATTR((unused)))
-{
- if (check_fs_open(argv[0]))
- return;
- if (check_fs_read_write(argv[0]))
- return;
-
- if (argv[1] && !strcmp(argv[1], "-clean"))
- current_fs->super->s_state |= EXT2_VALID_FS;
- else
- current_fs->super->s_state &= ~EXT2_VALID_FS;
- ext2fs_mark_super_dirty(current_fs);
-}
-
-struct list_blocks_struct {
- FILE *f;
- e2_blkcnt_t total;
- blk64_t first_block, last_block;
- e2_blkcnt_t first_bcnt, last_bcnt;
- e2_blkcnt_t first;
-};
-
-static void finish_range(struct list_blocks_struct *lb)
-{
- if (lb->first_block == 0)
- return;
- if (lb->first)
- lb->first = 0;
- else
- fprintf(lb->f, ", ");
- if (lb->first_block == lb->last_block)
- fprintf(lb->f, "(%lld):%llu",
- (long long)lb->first_bcnt, lb->first_block);
- else
- fprintf(lb->f, "(%lld-%lld):%llu-%llu",
- (long long)lb->first_bcnt, (long long)lb->last_bcnt,
- lb->first_block, lb->last_block);
- lb->first_block = 0;
-}
-
-static int list_blocks_proc(ext2_filsys fs EXT2FS_ATTR((unused)),
- blk64_t *blocknr, e2_blkcnt_t blockcnt,
- blk64_t ref_block EXT2FS_ATTR((unused)),
- int ref_offset EXT2FS_ATTR((unused)),
- void *private)
-{
- struct list_blocks_struct *lb = (struct list_blocks_struct *) private;
-
- lb->total++;
- if (blockcnt >= 0) {
- /*
- * See if we can add on to the existing range (if it exists)
- */
- if (lb->first_block &&
- (lb->last_block+1 == *blocknr) &&
- (lb->last_bcnt+1 == blockcnt)) {
- lb->last_block = *blocknr;
- lb->last_bcnt = blockcnt;
- return 0;
- }
- /*
- * Start a new range.
- */
- finish_range(lb);
- lb->first_block = lb->last_block = *blocknr;
- lb->first_bcnt = lb->last_bcnt = blockcnt;
- return 0;
- }
- /*
- * Not a normal block. Always force a new range.
- */
- finish_range(lb);
- if (lb->first)
- lb->first = 0;
- else
- fprintf(lb->f, ", ");
- if (blockcnt == -1)
- fprintf(lb->f, "(IND):%llu", (unsigned long long) *blocknr);
- else if (blockcnt == -2)
- fprintf(lb->f, "(DIND):%llu", (unsigned long long) *blocknr);
- else if (blockcnt == -3)
- fprintf(lb->f, "(TIND):%llu", (unsigned long long) *blocknr);
- return 0;
-}
-
-static void dump_xattr_string(FILE *out, const char *str, int len)
-{
- int printable = 0;
- int i;
-
- /* check: is string "printable enough?" */
- for (i = 0; i < len; i++)
- if (isprint(str[i]))
- printable++;
-
- if (printable <= len*7/8)
- printable = 0;
-
- for (i = 0; i < len; i++)
- if (printable)
- fprintf(out, isprint(str[i]) ? "%c" : "\\%03o",
- (unsigned char)str[i]);
- else
- fprintf(out, "%02x ", (unsigned char)str[i]);
-}
-
-static void internal_dump_inode_extra(FILE *out,
- const char *prefix EXT2FS_ATTR((unused)),
- ext2_ino_t inode_num EXT2FS_ATTR((unused)),
- struct ext2_inode_large *inode)
-{
- struct ext2_ext_attr_entry *entry;
- __u32 *magic;
- char *start, *end;
- int inode_xattr;
- unsigned int storage_size;
-
- fprintf(out, "Size of extra inode fields: %u\n", inode->i_extra_isize);
- if (inode->i_extra_isize > EXT2_INODE_SIZE(current_fs->super) -
- EXT2_GOOD_OLD_INODE_SIZE) {
- fprintf(stderr, "invalid inode->i_extra_isize (%u)\n",
- inode->i_extra_isize);
- return;
- }
- storage_size = EXT2_INODE_SIZE(current_fs->super) -
- EXT2_GOOD_OLD_INODE_SIZE -
- inode->i_extra_isize;
- magic = (__u32 *)((char *)inode + EXT2_GOOD_OLD_INODE_SIZE +
- inode->i_extra_isize);
- if (*magic == EXT2_EXT_ATTR_MAGIC) {
- fprintf(out, "Extended attributes stored in inode body: \n");
- end = (char *) inode + EXT2_INODE_SIZE(current_fs->super);
- start = (char *) magic + sizeof(__u32);
- entry = (struct ext2_ext_attr_entry *) start;
- while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
- struct ext2_ext_attr_entry *next =
- EXT2_EXT_ATTR_NEXT(entry);
- inode_xattr =
- EXT2_HAS_INCOMPAT_FEATURE(current_fs->super,
- EXT4_FEATURE_INCOMPAT_EA_INODE) &&
- entry->e_value_offs == 0 &&
- entry->e_value_inum != 0;
- if ((entry->e_value_size > storage_size &&
- !inode_xattr) || (char *)next >= end) {
- fprintf(out, "invalid EA entry in inode\n");
- return;
- }
- fprintf(out, " ");
-
- dump_xattr_string(out, EXT2_EXT_ATTR_NAME(entry),
- entry->e_name_len);
- fprintf(out, " = \"");
- if (inode_xattr)
- fprintf(out, "inode <%u>",
- entry->e_value_inum);
- else
- dump_xattr_string(out,
- start + entry->e_value_offs,
- entry->e_value_size);
- fprintf(out, "\" (%u)\n", entry->e_value_size);
- entry = next;
- }
- }
-}
-
-static void dump_blocks(FILE *f, const char *prefix, ext2_ino_t inode)
-{
- struct list_blocks_struct lb;
-
- fprintf(f, "%sBLOCKS:\n%s", prefix, prefix);
- lb.total = 0;
- lb.first_block = 0;
- lb.f = f;
- lb.first = 1;
- ext2fs_block_iterate3(current_fs, inode, BLOCK_FLAG_READ_ONLY, NULL,
- list_blocks_proc, (void *)&lb);
- finish_range(&lb);
- if (lb.total)
- fprintf(f, "\n%sTOTAL: %lld\n", prefix, (long long)lb.total);
- fprintf(f,"\n");
-}
-
-static int int_log10(unsigned long long arg)
-{
- int l = 0;
-
- arg = arg / 10;
- while (arg) {
- l++;
- arg = arg / 10;
- }
- return l;
-}
-
-#define DUMP_LEAF_EXTENTS 0x01
-#define DUMP_NODE_EXTENTS 0x02
-#define DUMP_EXTENT_TABLE 0x04
-
-static void dump_extents(FILE *f, const char *prefix, ext2_ino_t ino,
- int flags, int logical_width, int physical_width)
-{
- ext2_extent_handle_t handle;
- struct ext2fs_extent extent;
- struct ext2_extent_info info;
- int op = EXT2_EXTENT_ROOT;
- unsigned int printed = 0;
- errcode_t errcode;
-
- errcode = ext2fs_extent_open(current_fs, ino, &handle);
- if (errcode)
- return;
-
- if (flags & DUMP_EXTENT_TABLE)
- fprintf(f, "Level Entries %*s %*s Length Flags\n",
- (logical_width*2)+3, "Logical",
- (physical_width*2)+3, "Physical");
- else
- fprintf(f, "%sEXTENTS:\n%s", prefix, prefix);
-
- while (1) {
- errcode = ext2fs_extent_get(handle, op, &extent);
-
- if (errcode)
- break;
-
- op = EXT2_EXTENT_NEXT;
-
- if (extent.e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT)
- continue;
-
- if (extent.e_flags & EXT2_EXTENT_FLAGS_LEAF) {
- if ((flags & DUMP_LEAF_EXTENTS) == 0)
- continue;
- } else {
- if ((flags & DUMP_NODE_EXTENTS) == 0)
- continue;
- }
-
- errcode = ext2fs_extent_get_info(handle, &info);
- if (errcode)
- continue;
-
- if (!(extent.e_flags & EXT2_EXTENT_FLAGS_LEAF)) {
- if (extent.e_flags & EXT2_EXTENT_FLAGS_SECOND_VISIT)
- continue;
-
- if (flags & DUMP_EXTENT_TABLE) {
- fprintf(f, "%2d/%2d %3d/%3d %*llu - %*llu "
- "%*llu%*s %6u\n",
- info.curr_level, info.max_depth,
- info.curr_entry, info.num_entries,
- logical_width,
- extent.e_lblk,
- logical_width,
- extent.e_lblk + (extent.e_len - 1),
- physical_width,
- extent.e_pblk,
- physical_width+3, "", extent.e_len);
- continue;
- }
-
- fprintf(f, "%s(ETB%d):%lld",
- printed ? ", " : "", info.curr_level,
- extent.e_pblk);
- printed = 1;
- continue;
- }
-
- if (flags & DUMP_EXTENT_TABLE) {
- fprintf(f, "%2d/%2d %3d/%3d %*llu - %*llu "
- "%*llu - %*llu %6u %s\n",
- info.curr_level, info.max_depth,
- info.curr_entry, info.num_entries,
- logical_width,
- extent.e_lblk,
- logical_width,
- extent.e_lblk + (extent.e_len - 1),
- physical_width,
- extent.e_pblk,
- physical_width,
- extent.e_pblk + (extent.e_len - 1),
- extent.e_len,
- extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT ?
- "Uninit" : "");
- continue;
- }
-
- if (extent.e_len == 0)
- continue;
- else if (extent.e_len == 1)
- fprintf(f,
- "%s(%lld%s):%lld",
- printed ? ", " : "",
- extent.e_lblk,
- extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT ?
- "[u]" : "",
- extent.e_pblk);
- else
- fprintf(f,
- "%s(%lld-%lld%s):%lld-%lld",
- printed ? ", " : "",
- extent.e_lblk,
- extent.e_lblk + (extent.e_len - 1),
- extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT ?
- "[u]" : "",
- extent.e_pblk,
- extent.e_pblk + (extent.e_len - 1));
- printed = 1;
- }
- if (printed)
- fprintf(f, "\n");
-}
-
-void internal_dump_inode(FILE *out, const char *prefix,
- ext2_ino_t inode_num, struct ext2_inode *inode,
- int do_dump_blocks)
-{
- const char *i_type;
- char frag, fsize;
- int os = current_fs->super->s_creator_os;
- struct ext2_inode_large *large_inode;
- int is_large_inode = 0;
-
- if (EXT2_INODE_SIZE(current_fs->super) > EXT2_GOOD_OLD_INODE_SIZE)
- is_large_inode = 1;
- large_inode = (struct ext2_inode_large *) inode;
-
- if (LINUX_S_ISDIR(inode->i_mode)) i_type = "directory";
- else if (LINUX_S_ISREG(inode->i_mode)) i_type = "regular";
- else if (LINUX_S_ISLNK(inode->i_mode)) i_type = "symlink";
- else if (LINUX_S_ISBLK(inode->i_mode)) i_type = "block special";
- else if (LINUX_S_ISCHR(inode->i_mode)) i_type = "character special";
- else if (LINUX_S_ISFIFO(inode->i_mode)) i_type = "FIFO";
- else if (LINUX_S_ISSOCK(inode->i_mode)) i_type = "socket";
- else i_type = "bad type";
- fprintf(out, "%sInode: %u Type: %s ", prefix, inode_num, i_type);
- fprintf(out, "%sMode: %04o Flags: 0x%x\n",
- prefix, inode->i_mode & 0777, inode->i_flags);
- if (is_large_inode && large_inode->i_extra_isize >= 24) {
- fprintf(out, "%sGeneration: %u Version: 0x%08x:%08x\n",
- prefix, inode->i_generation, large_inode->i_version_hi,
- inode->osd1.linux1.l_i_version);
- } else {
- fprintf(out, "%sGeneration: %u Version: 0x%08x\n", prefix,
- inode->i_generation, inode->osd1.linux1.l_i_version);
- }
- fprintf(out, "%sUser: %5d Group: %5d Size: ",
- prefix, inode_uid(*inode), inode_gid(*inode));
- if (LINUX_S_ISREG(inode->i_mode))
- fprintf(out, "%llu\n", EXT2_I_SIZE(inode));
- else
- fprintf(out, "%d\n", inode->i_size);
- if (os == EXT2_OS_HURD)
- fprintf(out,
- "%sFile ACL: %d Directory ACL: %d Translator: %d\n",
- prefix,
- inode->i_file_acl, LINUX_S_ISDIR(inode->i_mode) ? inode->i_dir_acl : 0,
- inode->osd1.hurd1.h_i_translator);
- else
- fprintf(out, "%sFile ACL: %llu Directory ACL: %d\n",
- prefix,
- inode->i_file_acl | ((long long)
- (inode->osd2.linux2.l_i_file_acl_high) << 32),
- LINUX_S_ISDIR(inode->i_mode) ? inode->i_dir_acl : 0);
- if (os == EXT2_OS_LINUX)
- fprintf(out, "%sLinks: %d Blockcount: %llu\n",
- prefix, inode->i_links_count,
- (((unsigned long long)
- inode->osd2.linux2.l_i_blocks_hi << 32)) +
- inode->i_blocks);
- else
- fprintf(out, "%sLinks: %d Blockcount: %u\n",
- prefix, inode->i_links_count, inode->i_blocks);
- switch (os) {
- case EXT2_OS_HURD:
- frag = inode->osd2.hurd2.h_i_frag;
- fsize = inode->osd2.hurd2.h_i_fsize;
- break;
- default:
- frag = fsize = 0;
- }
- fprintf(out, "%sFragment: Address: %d Number: %d Size: %d\n",
- prefix, inode->i_faddr, frag, fsize);
- if (is_large_inode && large_inode->i_extra_isize >= 24) {
- fprintf(out, "%s ctime: 0x%08x:%08x -- %s", prefix,
- inode->i_ctime, large_inode->i_ctime_extra,
- time_to_string(inode->i_ctime));
- fprintf(out, "%s atime: 0x%08x:%08x -- %s", prefix,
- inode->i_atime, large_inode->i_atime_extra,
- time_to_string(inode->i_atime));
- fprintf(out, "%s mtime: 0x%08x:%08x -- %s", prefix,
- inode->i_mtime, large_inode->i_mtime_extra,
- time_to_string(inode->i_mtime));
- fprintf(out, "%scrtime: 0x%08x:%08x -- %s", prefix,
- large_inode->i_crtime, large_inode->i_crtime_extra,
- time_to_string(large_inode->i_crtime));
- } else {
- fprintf(out, "%sctime: 0x%08x -- %s", prefix, inode->i_ctime,
- time_to_string(inode->i_ctime));
- fprintf(out, "%satime: 0x%08x -- %s", prefix, inode->i_atime,
- time_to_string(inode->i_atime));
- fprintf(out, "%smtime: 0x%08x -- %s", prefix, inode->i_mtime,
- time_to_string(inode->i_mtime));
- }
- if (inode->i_dtime)
- fprintf(out, "%sdtime: 0x%08x -- %s", prefix, inode->i_dtime,
- time_to_string(inode->i_dtime));
- if (EXT2_INODE_SIZE(current_fs->super) > EXT2_GOOD_OLD_INODE_SIZE)
- internal_dump_inode_extra(out, prefix, inode_num,
- (struct ext2_inode_large *) inode);
- if (LINUX_S_ISLNK(inode->i_mode) && ext2fs_inode_data_blocks(current_fs,inode) == 0)
- fprintf(out, "%sFast_link_dest: %.*s\n", prefix,
- (int) inode->i_size, (char *)inode->i_block);
- else if (LINUX_S_ISBLK(inode->i_mode) || LINUX_S_ISCHR(inode->i_mode)) {
- int major, minor;
- const char *devnote;
-
- if (inode->i_block[0]) {
- major = (inode->i_block[0] >> 8) & 255;
- minor = inode->i_block[0] & 255;
- devnote = "";
- } else {
- major = (inode->i_block[1] & 0xfff00) >> 8;
- minor = ((inode->i_block[1] & 0xff) |
- ((inode->i_block[1] >> 12) & 0xfff00));
- devnote = "(New-style) ";
- }
- fprintf(out, "%sDevice major/minor number: %02d:%02d (hex %02x:%02x)\n",
- devnote, major, minor, major, minor);
- } else if (do_dump_blocks) {
- if (inode->i_flags & EXT4_EXTENTS_FL)
- dump_extents(out, prefix, inode_num,
- DUMP_LEAF_EXTENTS|DUMP_NODE_EXTENTS, 0, 0);
- else
- dump_blocks(out, prefix, inode_num);
- }
-}
-
-static void dump_inode(ext2_ino_t inode_num, struct ext2_inode *inode)
-{
- FILE *out;
-
- out = open_pager();
- internal_dump_inode(out, "", inode_num, inode, 1);
- close_pager(out);
-}
-
-void do_stat(int argc, char *argv[])
-{
- ext2_ino_t inode;
- struct ext2_inode * inode_buf;
-
- if (check_fs_open(argv[0]))
- return;
-
- inode_buf = (struct ext2_inode *)
- malloc(EXT2_INODE_SIZE(current_fs->super));
- if (!inode_buf) {
- fprintf(stderr, "do_stat: can't allocate buffer\n");
- return;
- }
-
- if (common_inode_args_process(argc, argv, &inode, 0)) {
- free(inode_buf);
- return;
- }
-
- if (debugfs_read_inode_full(inode, inode_buf, argv[0],
- EXT2_INODE_SIZE(current_fs->super))) {
- free(inode_buf);
- return;
- }
-
- dump_inode(inode, inode_buf);
- free(inode_buf);
- return;
-}
-
-void do_dump_extents(int argc, char **argv)
-{
- struct ext2_inode inode;
- ext2_ino_t ino;
- FILE *out;
- int c, flags = 0;
- int logical_width;
- int physical_width;
-
- reset_getopt();
- while ((c = getopt(argc, argv, "nl")) != EOF) {
- switch (c) {
- case 'n':
- flags |= DUMP_NODE_EXTENTS;
- break;
- case 'l':
- flags |= DUMP_LEAF_EXTENTS;
- break;
- }
- }
-
- if (argc != optind + 1) {
- com_err(0, 0, "Usage: dump_extents [-n] [-l] file");
- return;
- }
-
- if (flags == 0)
- flags = DUMP_NODE_EXTENTS | DUMP_LEAF_EXTENTS;
- flags |= DUMP_EXTENT_TABLE;
-
- if (check_fs_open(argv[0]))
- return;
-
- ino = string_to_inode(argv[optind]);
- if (ino == 0)
- return;
-
- if (debugfs_read_inode(ino, &inode, argv[0]))
- return;
-
- if ((inode.i_flags & EXT4_EXTENTS_FL) == 0) {
- fprintf(stderr, "%s: does not uses extent block maps\n",
- argv[optind]);
- return;
- }
-
- logical_width = int_log10((EXT2_I_SIZE(&inode)+current_fs->blocksize-1)/
- current_fs->blocksize) + 1;
- if (logical_width < 5)
- logical_width = 5;
- physical_width = int_log10(ext2fs_blocks_count(current_fs->super)) + 1;
- if (physical_width < 5)
- physical_width = 5;
-
- out = open_pager();
- dump_extents(out, "", ino, flags, logical_width, physical_width);
- close_pager(out);
- return;
-}
-
-void do_chroot(int argc, char *argv[])
-{
- ext2_ino_t inode;
- int retval;
-
- if (common_inode_args_process(argc, argv, &inode, 0))
- return;
-
- retval = ext2fs_check_directory(current_fs, inode);
- if (retval) {
- com_err(argv[1], retval, 0);
- return;
- }
- root = inode;
-}
-
-void do_clri(int argc, char *argv[])
-{
- ext2_ino_t inode;
- struct ext2_inode inode_buf;
-
- if (common_inode_args_process(argc, argv, &inode, CHECK_FS_RW))
- return;
-
- if (debugfs_read_inode(inode, &inode_buf, argv[0]))
- return;
- memset(&inode_buf, 0, sizeof(inode_buf));
- if (debugfs_write_inode(inode, &inode_buf, argv[0]))
- return;
-}
-
-void do_freei(int argc, char *argv[])
-{
- ext2_ino_t inode;
-
- if (common_inode_args_process(argc, argv, &inode,
- CHECK_FS_RW | CHECK_FS_BITMAPS))
- return;
-
- if (!ext2fs_test_inode_bitmap2(current_fs->inode_map,inode))
- com_err(argv[0], 0, "Warning: inode already clear");
- ext2fs_unmark_inode_bitmap2(current_fs->inode_map,inode);
- ext2fs_mark_ib_dirty(current_fs);
-}
-
-void do_seti(int argc, char *argv[])
-{
- ext2_ino_t inode;
-
- if (common_inode_args_process(argc, argv, &inode,
- CHECK_FS_RW | CHECK_FS_BITMAPS))
- return;
-
- if (ext2fs_test_inode_bitmap2(current_fs->inode_map,inode))
- com_err(argv[0], 0, "Warning: inode already set");
- ext2fs_mark_inode_bitmap2(current_fs->inode_map,inode);
- ext2fs_mark_ib_dirty(current_fs);
-}
-
-void do_testi(int argc, char *argv[])
-{
- ext2_ino_t inode;
-
- if (common_inode_args_process(argc, argv, &inode, CHECK_FS_BITMAPS))
- return;
-
- if (ext2fs_test_inode_bitmap2(current_fs->inode_map,inode))
- printf("Inode %u is marked in use\n", inode);
- else
- printf("Inode %u is not in use\n", inode);
-}
-
-void do_freeb(int argc, char *argv[])
-{
- blk64_t block;
- blk64_t count = 1;
-
- if (common_block_args_process(argc, argv, &block, &count))
- return;
- if (check_fs_read_write(argv[0]))
- return;
- while (count-- > 0) {
- if (!ext2fs_test_block_bitmap2(current_fs->block_map,block))
- com_err(argv[0], 0, "Warning: block %llu already clear",
- block);
- ext2fs_unmark_block_bitmap2(current_fs->block_map,block);
- block++;
- }
- ext2fs_mark_bb_dirty(current_fs);
-}
-
-void do_setb(int argc, char *argv[])
-{
- blk64_t block;
- blk64_t count = 1;
-
- if (common_block_args_process(argc, argv, &block, &count))
- return;
- if (check_fs_read_write(argv[0]))
- return;
- while (count-- > 0) {
- if (ext2fs_test_block_bitmap2(current_fs->block_map,block))
- com_err(argv[0], 0, "Warning: block %llu already set",
- block);
- ext2fs_mark_block_bitmap2(current_fs->block_map,block);
- block++;
- }
- ext2fs_mark_bb_dirty(current_fs);
-}
-
-void do_testb(int argc, char *argv[])
-{
- blk64_t block;
- blk64_t count = 1;
-
- if (common_block_args_process(argc, argv, &block, &count))
- return;
- while (count-- > 0) {
- if (ext2fs_test_block_bitmap2(current_fs->block_map,block))
- printf("Block %llu marked in use\n", block);
- else
- printf("Block %llu not in use\n", block);
- block++;
- }
-}
-
-static void modify_u8(char *com, const char *prompt,
- const char *format, __u8 *val)
-{
- char buf[200];
- unsigned long v;
- char *tmp;
-
- sprintf(buf, format, *val);
- printf("%30s [%s] ", prompt, buf);
- if (!fgets(buf, sizeof(buf), stdin))
- return;
- if (buf[strlen (buf) - 1] == '\n')
- buf[strlen (buf) - 1] = '\0';
- if (!buf[0])
- return;
- v = strtoul(buf, &tmp, 0);
- if (*tmp)
- com_err(com, 0, "Bad value - %s", buf);
- else
- *val = v;
-}
-
-static void modify_u16(char *com, const char *prompt,
- const char *format, __u16 *val)
-{
- char buf[200];
- unsigned long v;
- char *tmp;
-
- sprintf(buf, format, *val);
- printf("%30s [%s] ", prompt, buf);
- if (!fgets(buf, sizeof(buf), stdin))
- return;
- if (buf[strlen (buf) - 1] == '\n')
- buf[strlen (buf) - 1] = '\0';
- if (!buf[0])
- return;
- v = strtoul(buf, &tmp, 0);
- if (*tmp)
- com_err(com, 0, "Bad value - %s", buf);
- else
- *val = v;
-}
-
-static void modify_u32(char *com, const char *prompt,
- const char *format, __u32 *val)
-{
- char buf[200];
- unsigned long v;
- char *tmp;
-
- sprintf(buf, format, *val);
- printf("%30s [%s] ", prompt, buf);
- if (!fgets(buf, sizeof(buf), stdin))
- return;
- if (buf[strlen (buf) - 1] == '\n')
- buf[strlen (buf) - 1] = '\0';
- if (!buf[0])
- return;
- v = strtoul(buf, &tmp, 0);
- if (*tmp)
- com_err(com, 0, "Bad value - %s", buf);
- else
- *val = v;
-}
-
-
-void do_modify_inode(int argc, char *argv[])
-{
- struct ext2_inode inode;
- ext2_ino_t inode_num;
- int i;
- unsigned char *frag, *fsize;
- char buf[80];
- int os;
- const char *hex_format = "0x%x";
- const char *octal_format = "0%o";
- const char *decimal_format = "%d";
- const char *unsignedlong_format = "%lu";
-
- if (common_inode_args_process(argc, argv, &inode_num, CHECK_FS_RW))
- return;
-
- os = current_fs->super->s_creator_os;
-
- if (debugfs_read_inode(inode_num, &inode, argv[1]))
- return;
-
- modify_u16(argv[0], "Mode", octal_format, &inode.i_mode);
- modify_u16(argv[0], "User ID", decimal_format, &inode.i_uid);
- modify_u16(argv[0], "Group ID", decimal_format, &inode.i_gid);
- modify_u32(argv[0], "Size", unsignedlong_format, &inode.i_size);
- modify_u32(argv[0], "Creation time", decimal_format, &inode.i_ctime);
- modify_u32(argv[0], "Modification time", decimal_format, &inode.i_mtime);
- modify_u32(argv[0], "Access time", decimal_format, &inode.i_atime);
- modify_u32(argv[0], "Deletion time", decimal_format, &inode.i_dtime);
- modify_u16(argv[0], "Link count", decimal_format, &inode.i_links_count);
- if (os == EXT2_OS_LINUX)
- modify_u16(argv[0], "Block count high", unsignedlong_format,
- &inode.osd2.linux2.l_i_blocks_hi);
- modify_u32(argv[0], "Block count", unsignedlong_format, &inode.i_blocks);
- modify_u32(argv[0], "File flags", hex_format, &inode.i_flags);
- modify_u32(argv[0], "Generation", hex_format, &inode.i_generation);
-#if 0
- modify_u32(argv[0], "Reserved1", decimal_format, &inode.i_reserved1);
-#endif
- modify_u32(argv[0], "File acl", decimal_format, &inode.i_file_acl);
- if (LINUX_S_ISDIR(inode.i_mode))
- modify_u32(argv[0], "Directory acl", decimal_format, &inode.i_dir_acl);
- else
- modify_u32(argv[0], "High 32bits of size", decimal_format, &inode.i_size_high);
-
- if (os == EXT2_OS_HURD)
- modify_u32(argv[0], "Translator Block",
- decimal_format, &inode.osd1.hurd1.h_i_translator);
-
- modify_u32(argv[0], "Fragment address", decimal_format, &inode.i_faddr);
- switch (os) {
- case EXT2_OS_HURD:
- frag = &inode.osd2.hurd2.h_i_frag;
- fsize = &inode.osd2.hurd2.h_i_fsize;
- break;
- default:
- frag = fsize = 0;
- }
- if (frag)
- modify_u8(argv[0], "Fragment number", decimal_format, frag);
- if (fsize)
- modify_u8(argv[0], "Fragment size", decimal_format, fsize);
-
- for (i=0; i < EXT2_NDIR_BLOCKS; i++) {
- sprintf(buf, "Direct Block #%d", i);
- modify_u32(argv[0], buf, decimal_format, &inode.i_block[i]);
- }
- modify_u32(argv[0], "Indirect Block", decimal_format,
- &inode.i_block[EXT2_IND_BLOCK]);
- modify_u32(argv[0], "Double Indirect Block", decimal_format,
- &inode.i_block[EXT2_DIND_BLOCK]);
- modify_u32(argv[0], "Triple Indirect Block", decimal_format,
- &inode.i_block[EXT2_TIND_BLOCK]);
- if (debugfs_write_inode(inode_num, &inode, argv[1]))
- return;
-}
-
-void do_change_working_dir(int argc, char *argv[])
-{
- ext2_ino_t inode;
- int retval;
-
- if (common_inode_args_process(argc, argv, &inode, 0))
- return;
-
- retval = ext2fs_check_directory(current_fs, inode);
- if (retval) {
- com_err(argv[1], retval, 0);
- return;
- }
- cwd = inode;
- return;
-}
-
-void do_print_working_directory(int argc, char *argv[])
-{
- int retval;
- char *pathname = NULL;
-
- if (common_args_process(argc, argv, 1, 1,
- "print_working_directory", "", 0))
- return;
-
- retval = ext2fs_get_pathname(current_fs, cwd, 0, &pathname);
- if (retval) {
- com_err(argv[0], retval,
- "while trying to get pathname of cwd");
- }
- printf("[pwd] INODE: %6u PATH: %s\n",
- cwd, pathname ? pathname : "NULL");
- if (pathname) {
- free(pathname);
- pathname = NULL;
- }
- retval = ext2fs_get_pathname(current_fs, root, 0, &pathname);
- if (retval) {
- com_err(argv[0], retval,
- "while trying to get pathname of root");
- }
- printf("[root] INODE: %6u PATH: %s\n",
- root, pathname ? pathname : "NULL");
- if (pathname) {
- free(pathname);
- pathname = NULL;
- }
- return;
-}
-
-/*
- * Given a mode, return the ext2 file type
- */
-static int ext2_file_type(unsigned int mode)
-{
- if (LINUX_S_ISREG(mode))
- return EXT2_FT_REG_FILE;
-
- if (LINUX_S_ISDIR(mode))
- return EXT2_FT_DIR;
-
- if (LINUX_S_ISCHR(mode))
- return EXT2_FT_CHRDEV;
-
- if (LINUX_S_ISBLK(mode))
- return EXT2_FT_BLKDEV;
-
- if (LINUX_S_ISLNK(mode))
- return EXT2_FT_SYMLINK;
-
- if (LINUX_S_ISFIFO(mode))
- return EXT2_FT_FIFO;
-
- if (LINUX_S_ISSOCK(mode))
- return EXT2_FT_SOCK;
-
- return 0;
-}
-
-static void make_link(char *sourcename, char *destname)
-{
- ext2_ino_t ino;
- struct ext2_inode inode;
- int retval;
- ext2_ino_t dir;
- char *dest, *cp, *base_name;
-
- /*
- * Get the source inode
- */
- ino = string_to_inode(sourcename);
- if (!ino)
- return;
- base_name = strrchr(sourcename, '/');
- if (base_name)
- base_name++;
- else
- base_name = sourcename;
- /*
- * Figure out the destination. First see if it exists and is
- * a directory.
- */
- if (! (retval=ext2fs_namei(current_fs, root, cwd, destname, &dir)))
- dest = base_name;
- else {
- /*
- * OK, it doesn't exist. See if it is
- * '<dir>/basename' or 'basename'
- */
- cp = strrchr(destname, '/');
- if (cp) {
- *cp = 0;
- dir = string_to_inode(destname);
- if (!dir)
- return;
- dest = cp+1;
- } else {
- dir = cwd;
- dest = destname;
- }
- }
-
- if (debugfs_read_inode(ino, &inode, sourcename))
- return;
-
- retval = ext2fs_link(current_fs, dir, dest, ino,
- ext2_file_type(inode.i_mode));
- if (retval)
- com_err("make_link", retval, 0);
- return;
-}
-
-
-void do_link(int argc, char *argv[])
-{
- if (common_args_process(argc, argv, 3, 3, "link",
- "<source file> <dest_name>", CHECK_FS_RW))
- return;
-
- make_link(argv[1], argv[2]);
-}
-
-static int mark_blocks_proc(ext2_filsys fs, blk64_t *blocknr,
- e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
- blk64_t ref_block EXT2FS_ATTR((unused)),
- int ref_offset EXT2FS_ATTR((unused)),
- void *private EXT2FS_ATTR((unused)))
-{
- blk64_t block;
-
- block = *blocknr;
- ext2fs_block_alloc_stats2(fs, block, +1);
- return 0;
-}
-
-void do_undel(int argc, char *argv[])
-{
- ext2_ino_t ino;
- struct ext2_inode inode;
-
- if (common_args_process(argc, argv, 2, 3, "undelete",
- "<inode_num> [dest_name]",
- CHECK_FS_RW | CHECK_FS_BITMAPS))
- return;
-
- ino = string_to_inode(argv[1]);
- if (!ino)
- return;
-
- if (debugfs_read_inode(ino, &inode, argv[1]))
- return;
-
- if (ext2fs_test_inode_bitmap2(current_fs->inode_map, ino)) {
- com_err(argv[1], 0, "Inode is not marked as deleted");
- return;
- }
-
- /*
- * XXX this function doesn't handle changing the links count on the
- * parent directory when undeleting a directory.
- */
- inode.i_links_count = LINUX_S_ISDIR(inode.i_mode) ? 2 : 1;
- inode.i_dtime = 0;
-
- if (debugfs_write_inode(ino, &inode, argv[0]))
- return;
-
- ext2fs_block_iterate3(current_fs, ino, BLOCK_FLAG_READ_ONLY, NULL,
- mark_blocks_proc, NULL);
-
- ext2fs_inode_alloc_stats2(current_fs, ino, +1, 0);
-
- if (argc > 2)
- make_link(argv[1], argv[2]);
-}
-
-static void unlink_file_by_name(char *filename)
-{
- int retval;
- ext2_ino_t dir;
- char *base_name;
-
- base_name = strrchr(filename, '/');
- if (base_name) {
- *base_name++ = '\0';
- dir = string_to_inode(filename);
- if (!dir)
- return;
- } else {
- dir = cwd;
- base_name = filename;
- }
- retval = ext2fs_unlink(current_fs, dir, base_name, 0, 0);
- if (retval)
- com_err("unlink_file_by_name", retval, 0);
- return;
-}
-
-void do_unlink(int argc, char *argv[])
-{
- if (common_args_process(argc, argv, 2, 2, "link",
- "<pathname>", CHECK_FS_RW))
- return;
-
- unlink_file_by_name(argv[1]);
-}
-
-void do_find_free_block(int argc, char *argv[])
-{
- blk64_t free_blk, goal, first_free = 0;
- int count;
- errcode_t retval;
- char *tmp;
-
- if ((argc > 3) || (argc==2 && *argv[1] == '?')) {
- com_err(argv[0], 0, "Usage: find_free_block [count [goal]]");
- return;
- }
- if (check_fs_open(argv[0]))
- return;
-
- if (argc > 1) {
- count = strtol(argv[1],&tmp,0);
- if (*tmp) {
- com_err(argv[0], 0, "Bad count - %s", argv[1]);
- return;
- }
- } else
- count = 1;
-
- if (argc > 2) {
- goal = strtol(argv[2], &tmp, 0);
- if (*tmp) {
- com_err(argv[0], 0, "Bad goal - %s", argv[1]);
- return;
- }
- }
- else
- goal = current_fs->super->s_first_data_block;
-
- printf("Free blocks found: ");
- free_blk = goal - 1;
- while (count-- > 0) {
- retval = ext2fs_new_block2(current_fs, free_blk + 1, 0,
- &free_blk);
- if (first_free) {
- if (first_free == free_blk)
- break;
- } else
- first_free = free_blk;
- if (retval) {
- com_err("ext2fs_new_block", retval, 0);
- return;
- } else
- printf("%llu ", free_blk);
- }
- printf("\n");
-}
-
-void do_find_free_inode(int argc, char *argv[])
-{
- ext2_ino_t free_inode, dir;
- int mode;
- int retval;
- char *tmp;
-
- if (argc > 3 || (argc>1 && *argv[1] == '?')) {
- com_err(argv[0], 0, "Usage: find_free_inode [dir] [mode]");
- return;
- }
- if (check_fs_open(argv[0]))
- return;
-
- if (argc > 1) {
- dir = strtol(argv[1], &tmp, 0);
- if (*tmp) {
- com_err(argv[0], 0, "Bad dir - %s", argv[1]);
- return;
- }
- }
- else
- dir = root;
- if (argc > 2) {
- mode = strtol(argv[2], &tmp, 0);
- if (*tmp) {
- com_err(argv[0], 0, "Bad mode - %s", argv[2]);
- return;
- }
- } else
- mode = 010755;
-
- retval = ext2fs_new_inode(current_fs, dir, mode, 0, &free_inode);
- if (retval)
- com_err("ext2fs_new_inode", retval, 0);
- else
- printf("Free inode found: %u\n", free_inode);
-}
-
-static errcode_t copy_file(int fd, ext2_ino_t newfile)
-{
- ext2_file_t e2_file;
- errcode_t retval;
- int got;
- unsigned int written;
- char buf[8192];
- char *ptr;
-
- retval = ext2fs_file_open(current_fs, newfile,
- EXT2_FILE_WRITE, &e2_file);
- if (retval)
- return retval;
-
- while (1) {
- got = read(fd, buf, sizeof(buf));
- if (got == 0)
- break;
- if (got < 0) {
- retval = errno;
- goto fail;
- }
- ptr = buf;
- while (got > 0) {
- retval = ext2fs_file_write(e2_file, ptr,
- got, &written);
- if (retval)
- goto fail;
-
- got -= written;
- ptr += written;
- }
- }
- retval = ext2fs_file_close(e2_file);
- return retval;
-
-fail:
- (void) ext2fs_file_close(e2_file);
- return retval;
-}
-
-
-void do_write(int argc, char *argv[])
-{
- int fd;
- struct stat statbuf;
- ext2_ino_t newfile;
- errcode_t retval;
- struct ext2_inode inode;
-
- if (common_args_process(argc, argv, 3, 3, "write",
- "<native file> <new file>", CHECK_FS_RW))
- return;
-
- fd = open(argv[1], O_RDONLY);
- if (fd < 0) {
- com_err(argv[1], errno, 0);
- return;
- }
- if (fstat(fd, &statbuf) < 0) {
- com_err(argv[1], errno, 0);
- close(fd);
- return;
- }
-
- retval = ext2fs_namei(current_fs, root, cwd, argv[2], &newfile);
- if (retval == 0) {
- com_err(argv[0], 0, "The file '%s' already exists\n", argv[2]);
- close(fd);
- return;
- }
-
- retval = ext2fs_new_inode(current_fs, cwd, 010755, 0, &newfile);
- if (retval) {
- com_err(argv[0], retval, 0);
- close(fd);
- return;
- }
- printf("Allocated inode: %u\n", newfile);
- retval = ext2fs_link(current_fs, cwd, argv[2], newfile,
- EXT2_FT_REG_FILE);
- if (retval == EXT2_ET_DIR_NO_SPACE) {
- retval = ext2fs_expand_dir(current_fs, cwd);
- if (retval) {
- com_err(argv[0], retval, "while expanding directory");
- close(fd);
- return;
- }
- retval = ext2fs_link(current_fs, cwd, argv[2], newfile,
- EXT2_FT_REG_FILE);
- }
- if (retval) {
- com_err(argv[2], retval, 0);
- close(fd);
- return;
- }
- if (ext2fs_test_inode_bitmap2(current_fs->inode_map,newfile))
- com_err(argv[0], 0, "Warning: inode already set");
- ext2fs_inode_alloc_stats2(current_fs, newfile, +1, 0);
- memset(&inode, 0, sizeof(inode));
- inode.i_mode = (statbuf.st_mode & ~LINUX_S_IFMT) | LINUX_S_IFREG;
- inode.i_atime = inode.i_ctime = inode.i_mtime =
- current_fs->now ? current_fs->now : time(0);
- inode.i_links_count = 1;
- inode.i_size = statbuf.st_size;
- if (current_fs->super->s_feature_incompat &
- EXT3_FEATURE_INCOMPAT_EXTENTS)
- inode.i_flags |= EXT4_EXTENTS_FL;
- if (debugfs_write_new_inode(newfile, &inode, argv[0])) {
- close(fd);
- return;
- }
- if (LINUX_S_ISREG(inode.i_mode)) {
- retval = copy_file(fd, newfile);
- if (retval)
- com_err("copy_file", retval, 0);
- }
- close(fd);
-}
-
-void do_mknod(int argc, char *argv[])
-{
- unsigned long mode, major, minor;
- ext2_ino_t newfile;
- errcode_t retval;
- struct ext2_inode inode;
- int filetype, nr;
-
- if (check_fs_open(argv[0]))
- return;
- if (argc < 3 || argv[2][1]) {
- usage:
- com_err(argv[0], 0, "Usage: mknod <name> [p| [c|b] <major> <minor>]");
- return;
- }
- mode = minor = major = 0;
- switch (argv[2][0]) {
- case 'p':
- mode = LINUX_S_IFIFO;
- filetype = EXT2_FT_FIFO;
- nr = 3;
- break;
- case 'c':
- mode = LINUX_S_IFCHR;
- filetype = EXT2_FT_CHRDEV;
- nr = 5;
- break;
- case 'b':
- mode = LINUX_S_IFBLK;
- filetype = EXT2_FT_BLKDEV;
- nr = 5;
- break;
- default:
- filetype = 0;
- nr = 0;
- }
- if (nr == 5) {
- major = strtoul(argv[3], argv+3, 0);
- minor = strtoul(argv[4], argv+4, 0);
- if (major > 65535 || minor > 65535 || argv[3][0] || argv[4][0])
- nr = 0;
- }
- if (argc != nr)
- goto usage;
- if (check_fs_read_write(argv[0]))
- return;
- retval = ext2fs_new_inode(current_fs, cwd, 010755, 0, &newfile);
- if (retval) {
- com_err(argv[0], retval, 0);
- return;
- }
- printf("Allocated inode: %u\n", newfile);
- retval = ext2fs_link(current_fs, cwd, argv[1], newfile, filetype);
- if (retval == EXT2_ET_DIR_NO_SPACE) {
- retval = ext2fs_expand_dir(current_fs, cwd);
- if (retval) {
- com_err(argv[0], retval, "while expanding directory");
- return;
- }
- retval = ext2fs_link(current_fs, cwd, argv[1], newfile,
- filetype);
- }
- if (retval) {
- com_err(argv[1], retval, 0);
- return;
- }
- if (ext2fs_test_inode_bitmap2(current_fs->inode_map,newfile))
- com_err(argv[0], 0, "Warning: inode already set");
- ext2fs_mark_inode_bitmap2(current_fs->inode_map, newfile);
- ext2fs_mark_ib_dirty(current_fs);
- memset(&inode, 0, sizeof(inode));
- inode.i_mode = mode;
- inode.i_atime = inode.i_ctime = inode.i_mtime =
- current_fs->now ? current_fs->now : time(0);
- if ((major < 256) && (minor < 256)) {
- inode.i_block[0] = major*256+minor;
- inode.i_block[1] = 0;
- } else {
- inode.i_block[0] = 0;
- inode.i_block[1] = (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
- }
- inode.i_links_count = 1;
- if (debugfs_write_new_inode(newfile, &inode, argv[0]))
- return;
-}
-
-void do_mkdir(int argc, char *argv[])
-{
- char *cp;
- ext2_ino_t parent;
- char *name;
- errcode_t retval;
-
- if (common_args_process(argc, argv, 2, 2, "mkdir",
- "<filename>", CHECK_FS_RW))
- return;
-
- cp = strrchr(argv[1], '/');
- if (cp) {
- *cp = 0;
- parent = string_to_inode(argv[1]);
- if (!parent) {
- com_err(argv[1], ENOENT, 0);
- return;
- }
- name = cp+1;
- } else {
- parent = cwd;
- name = argv[1];
- }
-
-try_again:
- retval = ext2fs_mkdir(current_fs, parent, 0, name);
- if (retval == EXT2_ET_DIR_NO_SPACE) {
- retval = ext2fs_expand_dir(current_fs, parent);
- if (retval) {
- com_err(argv[0], retval, "while expanding directory");
- return;
- }
- goto try_again;
- }
- if (retval) {
- com_err("ext2fs_mkdir", retval, 0);
- return;
- }
-
-}
-
-static int release_blocks_proc(ext2_filsys fs, blk64_t *blocknr,
- e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
- blk64_t ref_block EXT2FS_ATTR((unused)),
- int ref_offset EXT2FS_ATTR((unused)),
- void *private EXT2FS_ATTR((unused)))
-{
- blk64_t block;
-
- block = *blocknr;
- ext2fs_block_alloc_stats2(fs, block, -1);
- return 0;
-}
-
-static void kill_file_by_inode(ext2_ino_t inode)
-{
- struct ext2_inode inode_buf;
-
- if (debugfs_read_inode(inode, &inode_buf, 0))
- return;
- inode_buf.i_dtime = current_fs->now ? current_fs->now : time(0);
- if (debugfs_write_inode(inode, &inode_buf, 0))
- return;
- if (!ext2fs_inode_has_valid_blocks(&inode_buf))
- return;
-
- ext2fs_block_iterate3(current_fs, inode, BLOCK_FLAG_READ_ONLY, NULL,
- release_blocks_proc, NULL);
- printf("\n");
- ext2fs_inode_alloc_stats2(current_fs, inode, -1,
- LINUX_S_ISDIR(inode_buf.i_mode));
-}
-
-
-void do_kill_file(int argc, char *argv[])
-{
- ext2_ino_t inode_num;
-
- if (common_inode_args_process(argc, argv, &inode_num, CHECK_FS_RW))
- return;
-
- kill_file_by_inode(inode_num);
-}
-
-void do_rm(int argc, char *argv[])
-{
- int retval;
- ext2_ino_t inode_num;
- struct ext2_inode inode;
-
- if (common_args_process(argc, argv, 2, 2, "rm",
- "<filename>", CHECK_FS_RW))
- return;
-
- retval = ext2fs_namei(current_fs, root, cwd, argv[1], &inode_num);
- if (retval) {
- com_err(argv[0], retval, "while trying to resolve filename");
- return;
- }
-
- if (debugfs_read_inode(inode_num, &inode, argv[0]))
- return;
-
- if (LINUX_S_ISDIR(inode.i_mode)) {
- com_err(argv[0], 0, "file is a directory");
- return;
- }
-
- --inode.i_links_count;
- if (debugfs_write_inode(inode_num, &inode, argv[0]))
- return;
-
- unlink_file_by_name(argv[1]);
- if (inode.i_links_count == 0)
- kill_file_by_inode(inode_num);
-}
-
-struct rd_struct {
- ext2_ino_t parent;
- int empty;
-};
-
-static int rmdir_proc(ext2_ino_t dir EXT2FS_ATTR((unused)),
- int entry EXT2FS_ATTR((unused)),
- struct ext2_dir_entry *dirent,
- int offset EXT2FS_ATTR((unused)),
- int blocksize EXT2FS_ATTR((unused)),
- char *buf EXT2FS_ATTR((unused)),
- void *private)
-{
- struct rd_struct *rds = (struct rd_struct *) private;
-
- if (dirent->inode == 0)
- return 0;
- if (((dirent->name_len&0xFF) == 1) && (dirent->name[0] == '.'))
- return 0;
- if (((dirent->name_len&0xFF) == 2) && (dirent->name[0] == '.') &&
- (dirent->name[1] == '.')) {
- rds->parent = dirent->inode;
- return 0;
- }
- rds->empty = 0;
- return 0;
-}
-
-void do_rmdir(int argc, char *argv[])
-{
- int retval;
- ext2_ino_t inode_num;
- struct ext2_inode inode;
- struct rd_struct rds;
-
- if (common_args_process(argc, argv, 2, 2, "rmdir",
- "<filename>", CHECK_FS_RW))
- return;
-
- retval = ext2fs_namei(current_fs, root, cwd, argv[1], &inode_num);
- if (retval) {
- com_err(argv[0], retval, "while trying to resolve filename");
- return;
- }
-
- if (debugfs_read_inode(inode_num, &inode, argv[0]))
- return;
-
- if (!LINUX_S_ISDIR(inode.i_mode)) {
- com_err(argv[0], 0, "file is not a directory");
- return;
- }
-
- rds.parent = 0;
- rds.empty = 1;
-
- retval = ext2fs_dir_iterate2(current_fs, inode_num, 0,
- 0, rmdir_proc, &rds);
- if (retval) {
- com_err(argv[0], retval, "while iterating over directory");
- return;
- }
- if (rds.empty == 0) {
- com_err(argv[0], 0, "directory not empty");
- return;
- }
-
- inode.i_links_count = 0;
- if (debugfs_write_inode(inode_num, &inode, argv[0]))
- return;
-
- unlink_file_by_name(argv[1]);
- kill_file_by_inode(inode_num);
-
- if (rds.parent) {
- if (debugfs_read_inode(rds.parent, &inode, argv[0]))
- return;
- if (inode.i_links_count > 1)
- inode.i_links_count--;
- if (debugfs_write_inode(rds.parent, &inode, argv[0]))
- return;
- }
-}
-
-void do_show_debugfs_params(int argc EXT2FS_ATTR((unused)),
- char *argv[] EXT2FS_ATTR((unused)))
-{
- FILE *out = stdout;
-
- if (current_fs)
- fprintf(out, "Open mode: read-%s\n",
- current_fs->flags & EXT2_FLAG_RW ? "write" : "only");
- fprintf(out, "Filesystem in use: %s\n",
- current_fs ? current_fs->device_name : "--none--");
-}
-
-void do_expand_dir(int argc, char *argv[])
-{
- ext2_ino_t inode;
- int retval;
-
- if (common_inode_args_process(argc, argv, &inode, CHECK_FS_RW))
- return;
-
- retval = ext2fs_expand_dir(current_fs, inode);
- if (retval)
- com_err("ext2fs_expand_dir", retval, 0);
- return;
-}
-
-void do_features(int argc, char *argv[])
-{
- int i;
-
- if (check_fs_open(argv[0]))
- return;
-
- if ((argc != 1) && check_fs_read_write(argv[0]))
- return;
- for (i=1; i < argc; i++) {
- if (e2p_edit_feature(argv[i],
- ¤t_fs->super->s_feature_compat, 0))
- com_err(argv[0], 0, "Unknown feature: %s\n",
- argv[i]);
- else
- ext2fs_mark_super_dirty(current_fs);
- }
- print_features(current_fs->super, stdout);
-}
-
-void do_bmap(int argc, char *argv[])
-{
- ext2_ino_t ino;
- blk64_t blk, pblk;
- int err;
- errcode_t errcode;
-
- if (common_args_process(argc, argv, 3, 3, argv[0],
- "<file> logical_blk", 0))
- return;
-
- ino = string_to_inode(argv[1]);
- if (!ino)
- return;
- blk = parse_ulong(argv[2], argv[0], "logical_block", &err);
-
- errcode = ext2fs_bmap2(current_fs, ino, 0, 0, 0, blk, 0, &pblk);
- if (errcode) {
- com_err("argv[0]", errcode,
- "while mapping logical block %llu\n", blk);
- return;
- }
- printf("%llu\n", pblk);
-}
-
-void do_imap(int argc, char *argv[])
-{
- ext2_ino_t ino;
- unsigned long group, block, block_nr, offset;
-
- if (common_args_process(argc, argv, 2, 2, argv[0],
- "<file>", 0))
- return;
- ino = string_to_inode(argv[1]);
- if (!ino)
- return;
-
- group = (ino - 1) / EXT2_INODES_PER_GROUP(current_fs->super);
- offset = ((ino - 1) % EXT2_INODES_PER_GROUP(current_fs->super)) *
- EXT2_INODE_SIZE(current_fs->super);
- block = offset >> EXT2_BLOCK_SIZE_BITS(current_fs->super);
- if (!ext2fs_inode_table_loc(current_fs, (unsigned)group)) {
- com_err(argv[0], 0, "Inode table for group %lu is missing\n",
- group);
- return;
- }
- block_nr = ext2fs_inode_table_loc(current_fs, (unsigned)group) +
- block;
- offset &= (EXT2_BLOCK_SIZE(current_fs->super) - 1);
-
- printf("Inode %d is part of block group %lu\n"
- "\tlocated at block %lu, offset 0x%04lx\n", ino, group,
- block_nr, offset);
-
-}
-
-void do_set_current_time(int argc, char *argv[])
-{
- time_t now;
-
- if (common_args_process(argc, argv, 2, 2, argv[0],
- "<time>", 0))
- return;
-
- now = string_to_time(argv[1]);
- if (now == ((time_t) -1)) {
- com_err(argv[0], 0, "Couldn't parse argument as a time: %s\n",
- argv[1]);
- return;
-
- } else {
- printf("Setting current time to %s\n", time_to_string(now));
- current_fs->now = now;
- }
-}
-
-static int find_supp_feature(__u32 *supp, int feature_type, char *name)
-{
- int compat, bit, ret;
- unsigned int feature_mask;
-
- if (name) {
- if (feature_type == E2P_FS_FEATURE)
- ret = e2p_string2feature(name, &compat, &feature_mask);
- else
- ret = e2p_jrnl_string2feature(name, &compat,
- &feature_mask);
- if (ret)
- return ret;
-
- if (!(supp[compat] & feature_mask))
- return 1;
- } else {
- for (compat = 0; compat < 3; compat++) {
- for (bit = 0, feature_mask = 1; bit < 32;
- bit++, feature_mask <<= 1) {
- if (supp[compat] & feature_mask) {
- if (feature_type == E2P_FS_FEATURE)
- fprintf(stdout, " %s",
- e2p_feature2string(compat,
- feature_mask));
- else
- fprintf(stdout, " %s",
- e2p_jrnl_feature2string(compat,
- feature_mask));
- }
- }
- }
- fprintf(stdout, "\n");
- }
-
- return 0;
-}
-
-void do_supported_features(int argc, char *argv[])
-{
- int ret;
- __u32 supp[3] = { EXT2_LIB_FEATURE_COMPAT_SUPP,
- EXT2_LIB_FEATURE_INCOMPAT_SUPP,
- EXT2_LIB_FEATURE_RO_COMPAT_SUPP };
- __u32 jrnl_supp[3] = { JFS_KNOWN_COMPAT_FEATURES,
- JFS_KNOWN_INCOMPAT_FEATURES,
- JFS_KNOWN_ROCOMPAT_FEATURES };
-
- if (argc > 1) {
- ret = find_supp_feature(supp, E2P_FS_FEATURE, argv[1]);
- if (ret) {
- ret = find_supp_feature(jrnl_supp, E2P_JOURNAL_FEATURE,
- argv[1]);
- }
- if (ret)
- com_err(argv[0], 0, "Unknown feature: %s\n", argv[1]);
- else
- fprintf(stdout, "Supported feature: %s\n", argv[1]);
- } else {
- fprintf(stdout, "Supported features:");
- ret = find_supp_feature(supp, E2P_FS_FEATURE, NULL);
- ret = find_supp_feature(jrnl_supp, E2P_JOURNAL_FEATURE, NULL);
- }
-}
-
-void do_punch(int argc, char *argv[])
-{
- ext2_ino_t ino;
- blk64_t start, end;
- int err;
- errcode_t errcode;
-
- if (common_args_process(argc, argv, 3, 4, argv[0],
- "<file> start_blk [end_blk]",
- CHECK_FS_RW | CHECK_FS_BITMAPS))
- return;
-
- ino = string_to_inode(argv[1]);
- if (!ino)
- return;
- start = parse_ulong(argv[2], argv[0], "logical_block", &err);
- if (argc == 4)
- end = parse_ulong(argv[3], argv[0], "logical_block", &err);
- else
- end = ~0;
-
- errcode = ext2fs_punch(current_fs, ino, 0, 0, start, end);
-
- if (errcode) {
- com_err(argv[0], errcode,
- "while truncating inode %u from %llu to %llu\n", ino,
- (unsigned long long) start, (unsigned long long) end);
- return;
- }
-}
-
-void do_dump_mmp(int argc, char *argv[])
-{
- struct mmp_struct *mmp_s;
- errcode_t retval = 0;
-
- if (current_fs->mmp_buf == NULL) {
- retval = ext2fs_get_mem(current_fs->blocksize,
- ¤t_fs->mmp_buf);
- if (retval) {
- com_err(argv[0], 0, "Could not allocate memory.\n");
- return;
- }
- }
-
- mmp_s = current_fs->mmp_buf;
-
- retval = ext2fs_mmp_read(current_fs, current_fs->super->s_mmp_block,
- current_fs->mmp_buf);
- if (retval) {
- com_err(argv[0], retval, "Error reading MMP block.\n");
- return;
- }
-
- fprintf(stdout, "MMP Block: %llu\n", current_fs->super->s_mmp_block);
- fprintf(stdout, "MMP Update Interval: %d\n",
- current_fs->super->s_mmp_update_interval);
- fprintf(stdout, "MMP Check Interval: %d\n", mmp_s->mmp_check_interval);
- fprintf(stdout, "MMP Sequence: %u\n", mmp_s->mmp_seq);
- fprintf(stdout, "Last Update Time: %llu\n", mmp_s->mmp_time);
- fprintf(stdout, "Node: %s\n", mmp_s->mmp_nodename);
- fprintf(stdout, "Device: %s\n", mmp_s->mmp_bdevname);
-}
-
-static int source_file(const char *cmd_file, int sci_idx)
-{
- FILE *f;
- char buf[256];
- char *cp;
- int exit_status = 0;
- int retval;
-
- if (strcmp(cmd_file, "-") == 0)
- f = stdin;
- else {
- f = fopen(cmd_file, "r");
- if (!f) {
- perror(cmd_file);
- exit(1);
- }
- }
- fflush(stdout);
- fflush(stderr);
- setbuf(stdout, NULL);
- setbuf(stderr, NULL);
- while (!feof(f)) {
- if (fgets(buf, sizeof(buf), f) == NULL)
- break;
- cp = strchr(buf, '\n');
- if (cp)
- *cp = 0;
- cp = strchr(buf, '\r');
- if (cp)
- *cp = 0;
- printf("debugfs: %s\n", buf);
- retval = ss_execute_line(sci_idx, buf);
- if (retval) {
- ss_perror(sci_idx, retval, buf);
- exit_status++;
- }
- }
- if (f != stdin)
- fclose(f);
- return exit_status;
-}
-
-int main(int argc, char **argv)
-{
- int retval;
- int sci_idx;
- const char *usage = "Usage: %s [-b blocksize] [-s superblock] [-f cmd_file] [-R request] [-V] [[-w] [-c] device]";
- int c;
- int open_flags = EXT2_FLAG_SOFTSUPP_FEATURES | EXT2_FLAG_64BITS;
- char *request = 0;
- int exit_status = 0;
- char *cmd_file = 0;
- blk64_t superblock = 0;
- blk64_t blocksize = 0;
- int catastrophic = 0;
- char *data_filename = 0;
-
- if (debug_prog_name == 0)
- debug_prog_name = "debugfs";
-
- add_error_table(&et_ext2_error_table);
- fprintf (stderr, "%s %s (%s)\n", debug_prog_name,
- E2FSPROGS_VERSION, E2FSPROGS_DATE);
-
- while ((c = getopt (argc, argv, "iwcR:f:b:s:Vd:D")) != EOF) {
- switch (c) {
- case 'R':
- request = optarg;
- break;
- case 'f':
- cmd_file = optarg;
- break;
- case 'd':
- data_filename = optarg;
- break;
- case 'i':
- open_flags |= EXT2_FLAG_IMAGE_FILE;
- break;
- case 'w':
- open_flags |= EXT2_FLAG_RW;
- break;
- case 'D':
- open_flags |= EXT2_FLAG_DIRECT_IO;
- break;
- case 'b':
- blocksize = parse_ulong(optarg, argv[0],
- "block size", 0);
- break;
- case 's':
- superblock = parse_ulong(optarg, argv[0],
- "superblock number", 0);
- break;
- case 'c':
- catastrophic = 1;
- break;
- case 'V':
- /* Print version number and exit */
- fprintf(stderr, "\tUsing %s\n",
- error_message(EXT2_ET_BASE));
- exit(0);
- default:
- com_err(argv[0], 0, usage, debug_prog_name);
- return 1;
- }
- }
- if (optind < argc)
- open_filesystem(argv[optind], open_flags,
- superblock, blocksize, catastrophic,
- data_filename);
-
- sci_idx = ss_create_invocation(debug_prog_name, "0.0", (char *) NULL,
- &debug_cmds, &retval);
- if (retval) {
- ss_perror(sci_idx, retval, "creating invocation");
- exit(1);
- }
- ss_get_readline(sci_idx);
-
- (void) ss_add_request_table (sci_idx, &ss_std_requests, 1, &retval);
- if (retval) {
- ss_perror(sci_idx, retval, "adding standard requests");
- exit (1);
- }
- if (extra_cmds)
- ss_add_request_table (sci_idx, extra_cmds, 1, &retval);
- if (retval) {
- ss_perror(sci_idx, retval, "adding extra requests");
- exit (1);
- }
- if (request) {
- retval = 0;
- retval = ss_execute_line(sci_idx, request);
- if (retval) {
- ss_perror(sci_idx, retval, request);
- exit_status++;
- }
- } else if (cmd_file) {
- exit_status = source_file(cmd_file, sci_idx);
- } else {
- ss_listen(sci_idx);
- }
-
- ss_delete_invocation(sci_idx);
-
- if (current_fs)
- close_filesystem();
-
- remove_error_table(&et_ext2_error_table);
- return exit_status;
-}
diff --git a/e2fsck/pass1.c.orig b/e2fsck/pass1.c.orig
deleted file mode 100644
index 3ba7fe1..0000000
--- a/e2fsck/pass1.c.orig
+++ /dev/null
@@ -1,3198 +0,0 @@
-/*
- * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
- *
- * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU Public
- * License.
- * %End-Header%
- *
- * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
- * and applies the following tests to each inode:
- *
- * - The mode field of the inode must be legal.
- * - The size and block count fields of the inode are correct.
- * - A data block must not be used by another inode
- *
- * Pass 1 also gathers the collects the following information:
- *
- * - A bitmap of which inodes are in use. (inode_used_map)
- * - A bitmap of which inodes are directories. (inode_dir_map)
- * - A bitmap of which inodes are regular files. (inode_reg_map)
- * - An icount mechanism is used to keep track of
- * inodes with bad fields and its badness (ctx->inode_badness)
- * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
- * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
- * - A bitmap of which inodes need to be expanded (expand_eisize_map)
- * - A bitmap of which blocks are in use. (block_found_map)
- * - A bitmap of which blocks are in use by two inodes (block_dup_map)
- * - The data blocks of the directory inodes. (dir_map)
- * - A bitmap of EA inodes. (inode_ea_map)
- *
- * Pass 1 is designed to stash away enough information so that the
- * other passes should not need to read in the inode information
- * during the normal course of a filesystem check. (Althogh if an
- * inconsistency is detected, other passes may need to read in an
- * inode to fix it.)
- *
- * Note that pass 1B will be invoked if there are any duplicate blocks
- * found.
- */
-
-#define _GNU_SOURCE 1 /* get strnlen() */
-#include <string.h>
-#include <time.h>
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#include "e2fsck.h"
-#include <ext2fs/ext2_ext_attr.h>
-#include "ext2fs/lfsck.h"
-
-#include "problem.h"
-
-#ifdef NO_INLINE_FUNCS
-#define _INLINE_
-#else
-#define _INLINE_ inline
-#endif
-
-static int process_block(ext2_filsys fs, blk64_t *blocknr,
- e2_blkcnt_t blockcnt, blk64_t ref_blk,
- int ref_offset, void *priv_data);
-static int process_bad_block(ext2_filsys fs, blk64_t *block_nr,
- e2_blkcnt_t blockcnt, blk64_t ref_blk,
- int ref_offset, void *priv_data);
-static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
- char *block_buf);
-static void mark_table_blocks(e2fsck_t ctx);
-static void alloc_bb_map(e2fsck_t ctx);
-static void alloc_imagic_map(e2fsck_t ctx);
-static void handle_fs_bad_blocks(e2fsck_t ctx);
-static void process_inodes(e2fsck_t ctx, char *block_buf);
-static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
-static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
- dgrp_t group, void * priv_data);
-static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
- char *block_buf, int adjust_sign);
-/* static char *describe_illegal_block(ext2_filsys fs, blk64_t block); */
-
-struct process_block_struct {
- ext2_ino_t ino;
- unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
- fragmented:1, compressed:1, bbcheck:1;
- blk64_t num_blocks;
- blk64_t max_blocks;
- e2_blkcnt_t last_block;
- e2_blkcnt_t last_db_block;
- int num_illegal_blocks;
- blk64_t previous_block;
- struct ext2_inode *inode;
- struct problem_context *pctx;
- ext2fs_block_bitmap fs_meta_blocks;
- e2fsck_t ctx;
-};
-
-struct process_inode_block {
- ext2_ino_t ino;
- struct ext2_inode inode;
-};
-
-struct scan_callback_struct {
- e2fsck_t ctx;
- char *block_buf;
-};
-
-/*
- * For the inodes to process list.
- */
-static struct process_inode_block *inodes_to_process;
-static int process_inode_count;
-
-static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
- EXT2_MIN_BLOCK_LOG_SIZE + 1];
-
-/*
- * Free all memory allocated by pass1 in preparation for restarting
- * things.
- */
-static void unwind_pass1(ext2_filsys fs EXT2FS_ATTR((unused)))
-{
- ext2fs_free_mem(&inodes_to_process);
- inodes_to_process = 0;
-}
-
-/*
- * Check to make sure a device inode is real. Returns 1 if the device
- * checks out, 0 if not.
- *
- * Note: this routine is now also used to check FIFO's and Sockets,
- * since they have the same requirement; the i_block fields should be
- * zero.
- */
-int e2fsck_pass1_check_device_inode(ext2_filsys fs EXT2FS_ATTR((unused)),
- struct ext2_inode *inode)
-{
- int i;
-
- /*
- * If the index flag is set, then this is a bogus
- * device/fifo/socket
- */
- if (inode->i_flags & (EXT2_INDEX_FL | EXT4_EXTENTS_FL))
- return 0;
-
- /*
- * We should be able to do the test below all the time, but
- * because the kernel doesn't forcibly clear the device
- * inode's additional i_block fields, there are some rare
- * occasions when a legitimate device inode will have non-zero
- * additional i_block fields. So for now, we only complain
- * when the immutable flag is set, which should never happen
- * for devices. (And that's when the problem is caused, since
- * you can't set or clear immutable flags for devices.) Once
- * the kernel has been fixed we can change this...
- */
- if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
- for (i=4; i < EXT2_N_BLOCKS; i++)
- if (inode->i_block[i])
- return 0;
- }
- return 1;
-}
-
-/*
- * Check to make sure a symlink inode is real. Returns 1 if the symlink
- * checks out, 0 if not.
- */
-int e2fsck_pass1_check_symlink(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode *inode, char *buf)
-{
- unsigned int len;
- int i;
- blk64_t blocks;
- ext2_extent_handle_t handle;
- struct ext2_extent_info info;
- struct ext2fs_extent extent;
-
- if ((inode->i_size_high || inode->i_size == 0) ||
- (inode->i_flags & EXT2_INDEX_FL))
- return 0;
-
- if (inode->i_flags & EXT4_EXTENTS_FL) {
- if (inode->i_size > fs->blocksize)
- return 0;
- if (ext2fs_extent_open2(fs, ino, inode, &handle))
- return 0;
- i = 0;
- if (ext2fs_extent_get_info(handle, &info) ||
- (info.num_entries != 1) ||
- (info.max_depth != 0))
- goto exit_extent;
- if (ext2fs_extent_get(handle, EXT2_EXTENT_ROOT, &extent) ||
- (extent.e_lblk != 0) ||
- (extent.e_len != 1) ||
- (extent.e_pblk < fs->super->s_first_data_block) ||
- (extent.e_pblk >= ext2fs_blocks_count(fs->super)))
- goto exit_extent;
- i = 1;
- exit_extent:
- ext2fs_extent_free(handle);
- return i;
- }
-
- blocks = ext2fs_inode_data_blocks2(fs, inode);
- if (blocks) {
- if ((inode->i_size >= fs->blocksize) ||
- (blocks != fs->blocksize >> 9) ||
- (inode->i_block[0] < fs->super->s_first_data_block) ||
- (inode->i_block[0] >= ext2fs_blocks_count(fs->super)))
- return 0;
-
- for (i = 1; i < EXT2_N_BLOCKS; i++)
- if (inode->i_block[i])
- return 0;
-
- if (io_channel_read_blk64(fs->io, inode->i_block[0], 1, buf))
- return 0;
-
- len = strnlen(buf, fs->blocksize);
- if (len == fs->blocksize)
- return 0;
- } else {
- if (inode->i_size >= sizeof(inode->i_block))
- return 0;
-
- len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
- if (len == sizeof(inode->i_block))
- return 0;
- }
- if (len != inode->i_size)
- return 0;
- return 1;
-}
-
-/*
- * If the immutable (or append-only) flag is set on the inode, offer
- * to clear it.
- */
-#define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
-static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
-{
- if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
- return;
-
- e2fsck_mark_inode_bad(ctx, pctx->ino, BADNESS_NORMAL);
- if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
- return;
-
- pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
- e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
-}
-
-/*
- * If device, fifo or socket, check size is zero -- if not offer to
- * clear it
- */
-static void check_size(e2fsck_t ctx, struct problem_context *pctx)
-{
- struct ext2_inode *inode = pctx->inode;
-
- if ((inode->i_size == 0) && (inode->i_size_high == 0))
- return;
-
- e2fsck_mark_inode_bad(ctx, pctx->ino, BADNESS_NORMAL);
- if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
- return;
-
- inode->i_size = 0;
- inode->i_size_high = 0;
- e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
-}
-
-static void e2fsck_block_alloc_stats(ext2_filsys fs, blk64_t blk, int inuse)
-{
- e2fsck_t ctx = (e2fsck_t) fs->priv_data;
-
- if (ctx->block_found_map) {
- if (inuse > 0)
- ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
- else
- ext2fs_unmark_block_bitmap2(ctx->block_found_map, blk);
- }
-}
-
-static void mark_inode_ea_map(e2fsck_t ctx, struct problem_context *pctx,
- ext2_ino_t ino)
-{
- if (!ctx->inode_ea_map) {
- pctx->errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
- _("EA inode map"),
- &ctx->inode_ea_map);
- if (pctx->errcode) {
- fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR,
- pctx);
- exit(1);
- }
- }
-
- ext2fs_mark_inode_bitmap2(ctx->inode_ea_map, ino);
-}
-
-/*
- * Delete an EA entry. If this is the last entry to be deleted, then i_file_acl
- * must have been freed, so we must update e2fsck block statistics and set
- * i_file_acl_deleted.
- * When we delete the entry successfully, this function returns 0, else
- * non-zero value.
- */
-
-static int e2fsck_ea_entry_delete(e2fsck_t ctx, struct ext2_ext_attr_entry *entry,
- struct problem_context *pctx,
- int *i_file_acl_deleted, problem_t prob)
-{
- blk_t i_file_acl = pctx->inode->i_file_acl;
- int err = 1;
-
- pctx->num = entry->e_value_inum;
-
- if (fix_problem(ctx, prob, pctx)) {
- /* Delete corrupt EA entry */
- err = ext2fs_attr_set(ctx->fs, pctx->ino, pctx->inode,
- entry->e_name_index, entry->e_name,
- 0, 0, 0);
- if (err == 0) {
- if (i_file_acl && pctx->inode->i_file_acl == 0) {
- e2fsck_block_alloc_stats(ctx->fs, i_file_acl, -1);
- *i_file_acl_deleted = 1;
- }
- return 0;
- }
- }
-
- return err;
-}
-
-/*
- * Check validity of EA inode. Return 0 if EA inode is valid, nonzero otherwise.
- */
-static int check_large_ea_inode(e2fsck_t ctx, struct ext2_ext_attr_entry *entry,
- struct problem_context *pctx,
- int *i_file_acl_deleted)
-{
- struct ext2_inode inode;
- int ret = 0;
-
- /* Check if inode is within valid range */
- if ((entry->e_value_inum < EXT2_FIRST_INODE(ctx->fs->super)) ||
- (entry->e_value_inum > ctx->fs->super->s_inodes_count)) {
- ret = e2fsck_ea_entry_delete(ctx, entry, pctx,
- i_file_acl_deleted,
- PR_1_ATTR_VALUE_EA_INODE);
- /* If user refuses to delete this entry, caller may try to set
- * the bit for this out-of-bound inode in inode_ea_map, so
- * always return failure */
- return 1;
- }
-
- e2fsck_read_inode(ctx, entry->e_value_inum, &inode, "pass1");
- if (!(inode.i_flags & EXT4_EA_INODE_FL)) {
- /* If EXT4_EA_INODE_FL flag is not present but back-pointer
- * matches then we should set this flag */
- if (inode.i_mtime == pctx->ino &&
- inode.i_generation == pctx->inode->i_generation &&
- fix_problem(ctx, PR_1_ATTR_SET_EA_INODE_FL, pctx)) {
- inode.i_flags |= EXT4_EA_INODE_FL;
- ext2fs_write_inode(ctx->fs, entry->e_value_inum, &inode);
- } else {
- ret = e2fsck_ea_entry_delete(ctx, entry, pctx,
- i_file_acl_deleted,
- PR_1_ATTR_NO_EA_INODE_FL);
- goto out;
- }
- } else if (inode.i_mtime != pctx->ino ||
- inode.i_generation != pctx->inode->i_generation) {
- ret = e2fsck_ea_entry_delete(ctx, entry, pctx,
- i_file_acl_deleted,
- PR_1_ATTR_INVAL_EA_INODE);
- goto out;
- }
-
-out:
- return ret;
-}
-
-static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
-{
- struct ext2_super_block *sb = ctx->fs->super;
- struct ext2_inode_large *inode;
- struct ext2_ext_attr_entry *entry;
- char *start, *end;
- unsigned int storage_size, remain;
- struct lov_user_md_v1 *lmm = NULL;
- struct lustre_mdt_attrs *lma = NULL;
- int problem = 0;
-
- inode = (struct ext2_inode_large *) pctx->inode;
- storage_size = EXT2_INODE_SIZE(ctx->fs->super) -
- EXT2_GOOD_OLD_INODE_SIZE - inode->i_extra_isize;
- entry = &IHDR(inode)->h_first_entry[0];
- start = (char *)entry;
- end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
-
- /* scan all entry's headers first */
-
- /* take finish entry 0UL into account */
- remain = storage_size - sizeof(__u32);
-
- while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
- __u32 hash;
-
- /* header eats this space */
- remain -= sizeof(struct ext2_ext_attr_entry);
-
- /* is attribute name valid? */
- if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
- pctx->num = entry->e_name_len;
- problem = PR_1_ATTR_NAME_LEN;
- goto fix;
- }
-
- /* attribute len eats this space */
- remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
-
- if (entry->e_value_size == 0) {
- pctx->num = entry->e_value_size;
- problem = PR_1_ATTR_VALUE_SIZE;
- goto fix;
- }
-
- if (entry->e_value_inum == 0) {
- /* check value size */
- if (entry->e_value_size > remain) {
- pctx->num = entry->e_value_size;
- problem = PR_1_ATTR_VALUE_SIZE;
- goto fix;
- }
- } else {
- int ret, tmp;
-
- ret = check_large_ea_inode(ctx, entry, pctx, &tmp);
- if (ret == 0)
- mark_inode_ea_map(ctx, pctx, entry->e_value_inum);
- }
-
- /* Value size cannot be larger than EA space in inode */
- if (entry->e_value_offs > storage_size ||
- (entry->e_value_inum == 0 &&
- entry->e_value_offs + entry->e_value_size > storage_size)) {
- problem = PR_1_INODE_EA_BAD_VALUE;
- goto fix;
- }
-
- hash = ext2fs_ext_attr_hash_entry(entry,
- start + entry->e_value_offs);
-
- /* e_hash may be 0 in older inode's ea */
- if (entry->e_hash != 0 && entry->e_hash != hash) {
- pctx->num = entry->e_hash;
- problem = PR_1_ATTR_HASH;
- goto fix;
- }
-
- e2fsck_lfsck_find_ea(ctx, inode, entry,
- start + entry->e_value_offs, &lmm, &lma);
-
- /* If EA value is stored in external inode then it does not
- * consume space here */
- if (entry->e_value_inum == 0)
- remain -= entry->e_value_size;
-
- entry = EXT2_EXT_ATTR_NEXT(entry);
- }
-
- if (lmm)
- e2fsck_lfsck_save_ea(ctx, pctx->ino, inode->i_generation,
- lmm, lma);
-fix:
- if (lmm)
- ext2fs_free_mem(&lmm);
- if (lma)
- ext2fs_free_mem(&lma);
- /*
- * it seems like a corruption. it's very unlikely we could repair
- * EA(s) in automatic fashion -bzzz
- */
- if (problem == 0 || !fix_problem(ctx, problem, pctx))
- return;
-
- /* simply remove all possible EA(s) */
- *((__u32 *)start) = 0UL;
- e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
- EXT2_INODE_SIZE(sb), "pass1");
-}
-
-static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
-{
- struct ext2_super_block *sb = ctx->fs->super;
- struct ext2_inode_large *inode;
- __u32 *eamagic;
- int min, max, dirty = 0;
-
- inode = (struct ext2_inode_large *) pctx->inode;
- if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
- /* this isn't large inode. so, nothing to check */
- return;
- }
-
-#if 0
- printf("inode #%u, i_extra_size %d\n", pctx->ino,
- inode->i_extra_isize);
-#endif
- /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
- min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
- max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
- /*
- * For now we will allow i_extra_isize to be 0, but really
- * implementations should never allow i_extra_isize to be 0
- */
- if (inode->i_extra_isize &&
- (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
- e2fsck_mark_inode_bad(ctx, pctx->ino, BADNESS_NORMAL);
- if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
- return;
- inode->i_extra_isize = ctx->want_extra_isize;
- dirty = 1;
-
- goto out;
- }
-
- if (EXT4_FITS_IN_INODE(inode, inode,i_crtime) && inode->i_crtime != 0 &&
- (EXT4_XTIME_FUTURE(ctx, sb, inode->i_crtime, 2 * ctx->time_fudge) ||
- EXT4_XTIME_ANCIENT(ctx, sb, inode->i_crtime, 2*ctx->time_fudge))) {
- pctx->num = inode->i_crtime;
- if (fix_problem(ctx, PR_1_CRTIME_BAD, pctx)) {
- inode->i_crtime = 0;
- dirty = 1;
- }
- e2fsck_mark_inode_bad(ctx, pctx->ino, BADNESS_HIGH);
- }
-
- eamagic = &IHDR(inode)->h_magic;
- if (*eamagic != EXT2_EXT_ATTR_MAGIC &&
- (ctx->flags & E2F_FLAG_EXPAND_EISIZE) &&
- (inode->i_extra_isize < ctx->want_extra_isize)) {
- fix_problem(ctx, PR_1_EXPAND_EISIZE, pctx);
- memset((char *)inode + EXT2_GOOD_OLD_INODE_SIZE, 0,
- EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE);
- inode->i_extra_isize = ctx->want_extra_isize;
- dirty = 1;
- if (inode->i_extra_isize < ctx->min_extra_isize)
- ctx->min_extra_isize = inode->i_extra_isize;
- }
-
- if (*eamagic == EXT2_EXT_ATTR_MAGIC)
- check_ea_in_inode(ctx, pctx);
-out:
- if (dirty)
- e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
- EXT2_INODE_SIZE(sb), "pass1");
-}
-
-/*
- * Check to see if the inode might really be a directory, despite i_mode
- *
- * This is a lot of complexity for something for which I'm not really
- * convinced happens frequently in the wild. If for any reason this
- * causes any problems, take this code out.
- * [tytso:20070331.0827EDT]
- */
-static void check_is_really_dir(e2fsck_t ctx, struct problem_context *pctx,
- char *buf)
-{
- struct ext2_inode *inode = pctx->inode;
- struct ext2_dir_entry *dirent;
- const char *old_op;
- errcode_t retval;
- blk64_t blk;
- unsigned int i, rec_len, not_device = 0;
- int extent_fs;
-
- /*
- * If the mode looks OK, we believe it. If the first block in
- * the i_block array is 0, this cannot be a directory. If the
- * inode is extent-mapped, it is still the case that the latter
- * cannot be 0 - the magic number in the extent header would make
- * it nonzero.
- */
- if (LINUX_S_ISDIR(inode->i_mode) || LINUX_S_ISREG(inode->i_mode) ||
- LINUX_S_ISLNK(inode->i_mode) || inode->i_block[0] == 0)
- return;
-
- /*
- * Check the block numbers in the i_block array for validity:
- * zero blocks are skipped (but the first one cannot be zero -
- * see above), other blocks are checked against the first and
- * max data blocks (from the the superblock) and against the
- * block bitmap. Any invalid block found means this cannot be
- * a directory.
- *
- * If there are non-zero blocks past the fourth entry, then
- * this cannot be a device file: we remember that for the next
- * check.
- *
- * For extent mapped files, we don't do any sanity checking:
- * just try to get the phys block of logical block 0 and run
- * with it.
- */
-
- extent_fs = (ctx->fs->super->s_feature_incompat &
- EXT3_FEATURE_INCOMPAT_EXTENTS);
- if (extent_fs && (inode->i_flags & EXT4_EXTENTS_FL)) {
- /* extent mapped */
- if (ext2fs_bmap2(ctx->fs, pctx->ino, inode, 0, 0, 0, 0,
- &blk))
- return;
- /* device files are never extent mapped */
- not_device++;
- } else {
- for (i=0; i < EXT2_N_BLOCKS; i++) {
- blk = inode->i_block[i];
- if (!blk)
- continue;
- if (i >= 4)
- not_device++;
-
- if (blk < ctx->fs->super->s_first_data_block ||
- blk >= ext2fs_blocks_count(ctx->fs->super) ||
- ext2fs_fast_test_block_bitmap2(ctx->block_found_map,
- blk))
- return; /* Invalid block, can't be dir */
- }
- blk = inode->i_block[0];
- }
-
- /*
- * If the mode says this is a device file and the i_links_count field
- * is sane and we have not ruled it out as a device file previously,
- * we declare it a device file, not a directory.
- */
- if ((LINUX_S_ISCHR(inode->i_mode) || LINUX_S_ISBLK(inode->i_mode)) &&
- (inode->i_links_count == 1) && !not_device)
- return;
-
- /* read the first block */
- old_op = ehandler_operation(_("reading directory block"));
- retval = ext2fs_read_dir_block3(ctx->fs, blk, buf, 0);
- ehandler_operation(0);
- if (retval)
- return;
-
- dirent = (struct ext2_dir_entry *) buf;
- retval = ext2fs_get_rec_len(ctx->fs, dirent, &rec_len);
- if (retval)
- return;
- if (((dirent->name_len & 0xFF) != 1) ||
- (dirent->name[0] != '.') ||
- (dirent->inode != pctx->ino) ||
- (rec_len < 12) ||
- (rec_len % 4) ||
- (rec_len >= ctx->fs->blocksize - 12))
- return;
-
- dirent = (struct ext2_dir_entry *) (buf + rec_len);
- retval = ext2fs_get_rec_len(ctx->fs, dirent, &rec_len);
- if (retval)
- return;
- if (((dirent->name_len & 0xFF) != 2) ||
- (dirent->name[0] != '.') ||
- (dirent->name[1] != '.') ||
- (rec_len < 12) ||
- (rec_len % 4))
- return;
-
- e2fsck_mark_inode_bad(ctx, pctx->ino, BADNESS_NORMAL);
- if (fix_problem(ctx, PR_1_TREAT_AS_DIRECTORY, pctx)) {
- inode->i_mode = (inode->i_mode & 07777) | LINUX_S_IFDIR;
- e2fsck_write_inode_full(ctx, pctx->ino, inode,
- EXT2_INODE_SIZE(ctx->fs->super),
- "check_is_really_dir");
- }
-}
-
-extern void e2fsck_setup_tdb_icount(e2fsck_t ctx, int flags,
- ext2_icount_t *ret)
-{
- unsigned int threshold;
- ext2_ino_t num_dirs;
- errcode_t retval;
- char *tdb_dir;
- int enable;
-
- *ret = 0;
-
- profile_get_string(ctx->profile, "scratch_files", "directory", 0, 0,
- &tdb_dir);
- profile_get_uint(ctx->profile, "scratch_files",
- "numdirs_threshold", 0, 0, &threshold);
- profile_get_boolean(ctx->profile, "scratch_files",
- "icount", 0, 1, &enable);
-
- retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
- if (retval)
- num_dirs = 1024; /* Guess */
-
- if (!enable || !tdb_dir || access(tdb_dir, W_OK) ||
- (threshold && num_dirs <= threshold))
- return;
-
- retval = ext2fs_create_icount_tdb(ctx->fs, tdb_dir, flags, ret);
- if (retval)
- *ret = 0;
-}
-
-int e2fsck_pass1_delete_attr(e2fsck_t ctx, struct ext2_inode_large *inode,
- struct problem_context *pctx, int needed_size)
-{
- struct ext2_ext_attr_header *header;
- struct ext2_ext_attr_entry *entry_ino, *entry_blk = NULL, *entry;
- char *start, name[4096], block_buf[4096];
- int len, index = EXT2_ATTR_INDEX_USER, entry_size, ea_size;
- int in_inode = 1, error;
- unsigned int freed_bytes = inode->i_extra_isize;
-
- entry_ino = &IHDR(inode)->h_first_entry[0];
- start = (char *)entry_ino;
-
- if (inode->i_file_acl) {
- error = ext2fs_read_ext_attr(ctx->fs, inode->i_file_acl,
- block_buf);
- /* We have already checked this block, shouldn't happen */
- if (error) {
- fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, pctx);
- return 0;
- }
- header = BHDR(block_buf);
- if (header->h_magic != EXT2_EXT_ATTR_MAGIC) {
- fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, pctx);
- return 0;
- }
-
- entry_blk = (struct ext2_ext_attr_entry *)(header+1);
- }
- entry = entry_ino;
- len = sizeof(entry->e_name);
- entry_size = ext2fs_attr_get_next_attr(entry, index, name, len, 1);
-
- while (freed_bytes < needed_size) {
- if (entry_size && name[0] != '\0') {
- pctx->str = name;
- if (fix_problem(ctx, PR_1_EISIZE_DELETE_EA, pctx)) {
- ea_size = EXT2_EXT_ATTR_LEN(entry->e_name_len) +
- EXT2_EXT_ATTR_SIZE(entry->e_value_size);
- error = ext2fs_attr_set(ctx->fs, pctx->ino,
- (struct ext2_inode *)inode,
- index, name, 0,0,0);
- if (!error)
- freed_bytes += ea_size;
- }
- }
- len = sizeof(entry->e_name);
- entry_size = ext2fs_attr_get_next_attr(entry, index,name,len,0);
- entry = EXT2_EXT_ATTR_NEXT(entry);
- if (EXT2_EXT_IS_LAST_ENTRY(entry)) {
- if (in_inode) {
- entry = entry_blk;
- len = sizeof(entry->e_name);
- entry_size = ext2fs_attr_get_next_attr(entry,
- index, name, len, 1);
- in_inode = 0;
- } else {
- index += 1;
- in_inode = 1;
- if (!entry && index < EXT2_ATTR_INDEX_MAX)
- entry = (struct ext2_ext_attr_entry *)start;
- else
- return freed_bytes;
- }
- }
- }
-
- return freed_bytes;
-}
-
-int e2fsck_pass1_expand_eisize(e2fsck_t ctx, struct ext2_inode_large *inode,
- struct problem_context *pctx)
-{
- int needed_size = 0, retval, ret = EXT2_EXPAND_EISIZE_UNSAFE;
- static int message;
-
-retry:
- retval = ext2fs_expand_extra_isize(ctx->fs, pctx->ino, inode,
- ctx->want_extra_isize, &ret,
- &needed_size);
- if (ret & EXT2_EXPAND_EISIZE_NEW_BLOCK)
- goto mark_expand_eisize_map;
- if (!retval) {
- e2fsck_write_inode_full(ctx, pctx->ino,
- (struct ext2_inode *)inode,
- EXT2_INODE_SIZE(ctx->fs->super),
- "pass1");
- return 0;
- }
-
- if (ret & EXT2_EXPAND_EISIZE_NOSPC) {
- if (ctx->options & (E2F_OPT_PREEN | E2F_OPT_YES)) {
- fix_problem(ctx, PR_1_EA_BLK_NOSPC, pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return -1;
- }
-
- if (!message) {
- pctx->num = ctx->fs->super->s_min_extra_isize;
- fix_problem(ctx, PR_1_EXPAND_EISIZE_WARNING, pctx);
- message = 1;
- }
-delete_EA:
- retval = e2fsck_pass1_delete_attr(ctx, inode, pctx,
- needed_size);
- if (retval >= ctx->want_extra_isize)
- goto retry;
-
- needed_size -= retval;
-
- /*
- * We loop here until either the user deletes EA(s) or
- * EXTRA_ISIZE feature is disabled.
- */
- if (fix_problem(ctx, PR_1_CLEAR_EXTRA_ISIZE, pctx)) {
- ctx->fs->super->s_feature_ro_compat &=
- ~EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE;
- ext2fs_mark_super_dirty(ctx->fs);
- } else {
- goto delete_EA;
- }
- ctx->fs_unexpanded_inodes++;
-
- /* No EA was deleted, inode cannot be expanded */
- return -1;
- }
-
-mark_expand_eisize_map:
- if (!ctx->expand_eisize_map) {
- pctx->errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
- _("expand extrz isize map"),
- &ctx->expand_eisize_map);
- if (pctx->errcode) {
- fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR,
- pctx);
- exit(1);
- }
- }
-
- /* Add this inode to the expand_eisize_map */
- ext2fs_mark_inode_bitmap2(ctx->expand_eisize_map, pctx->ino);
- return 0;
-}
-
-void e2fsck_pass1(e2fsck_t ctx)
-{
- int i;
- __u64 max_sizes;
- ext2_filsys fs = ctx->fs;
- ext2_ino_t ino;
- struct ext2_inode *inode;
- ext2_inode_scan scan;
- char *block_buf;
-#ifdef RESOURCE_TRACK
- struct resource_track rtrack;
-#endif
- unsigned char frag, fsize;
- struct problem_context pctx;
- struct scan_callback_struct scan_struct;
- struct ext2_super_block *sb = ctx->fs->super;
- const char *old_op;
- int imagic_fs, extent_fs;
- int busted_fs_time = 0;
- int inode_size;
- int inode_exp = 0;
-
-
- init_resource_track(&rtrack, ctx->fs->io);
- clear_problem_context(&pctx);
-
- if (!(ctx->options & E2F_OPT_PREEN))
- fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
-
- if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
- !(ctx->options & E2F_OPT_NO)) {
- if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
- ctx->dirs_to_hash = 0;
- }
-
-#ifdef MTRACE
- mtrace_print("Pass 1");
-#endif
-
-#define EXT2_BPP(bits) (1ULL << ((bits) - 2))
-
- for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
- max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
- max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
- max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
- max_sizes = (max_sizes * (1UL << i)) - 1;
- ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
- }
-#undef EXT2_BPP
-
- imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
- extent_fs = (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS);
-
- /*
- * Allocate bitmaps structures
- */
- pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
- &ctx->inode_used_map);
- if (pctx.errcode) {
- pctx.num = 1;
- fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
- _("directory inode map"), &ctx->inode_dir_map);
- if (pctx.errcode) {
- pctx.num = 2;
- fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
- _("regular file inode map"), &ctx->inode_reg_map);
- if (pctx.errcode) {
- pctx.num = 6;
- fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
- &ctx->block_found_map);
- if (pctx.errcode) {
- pctx.num = 1;
- fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- e2fsck_setup_tdb_icount(ctx, 0, &ctx->inode_link_info);
- if (!ctx->inode_link_info)
- pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
- &ctx->inode_link_info);
- if (pctx.errcode) {
- fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- inode_size = EXT2_INODE_SIZE(fs->super);
- inode = (struct ext2_inode *)
- e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
-
- inodes_to_process = (struct process_inode_block *)
- e2fsck_allocate_memory(ctx,
- (ctx->process_inode_size *
- sizeof(struct process_inode_block)),
- "array of inodes to process");
- process_inode_count = 0;
-
- pctx.errcode = ext2fs_init_dblist(fs, 0);
- if (pctx.errcode) {
- fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- ext2fs_free_mem(&inode);
- return;
- }
-
- /*
- * If the last orphan field is set, clear it, since the pass1
- * processing will automatically find and clear the orphans.
- * In the future, we may want to try using the last_orphan
- * linked list ourselves, but for now, we clear it so that the
- * ext3 mount code won't get confused.
- */
- if (!(ctx->options & E2F_OPT_READONLY)) {
- if (fs->super->s_last_orphan) {
- fs->super->s_last_orphan = 0;
- ext2fs_mark_super_dirty(fs);
- }
- }
-
- mark_table_blocks(ctx);
- block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
- "block interate buffer");
- e2fsck_use_inode_shortcuts(ctx, 1);
- old_op = ehandler_operation(_("opening inode scan"));
- pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
- &scan);
- ehandler_operation(old_op);
- if (pctx.errcode) {
- fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- ext2fs_free_mem(&block_buf);
- ext2fs_free_mem(&inode);
- return;
- }
- ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
- ctx->stashed_inode = inode;
- scan_struct.ctx = ctx;
- scan_struct.block_buf = block_buf;
- ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
- if (ctx->progress)
- if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
- return;
- if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
- (fs->super->s_mtime < fs->super->s_inodes_count))
- busted_fs_time = 1;
-
- if ((fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) &&
- !(fs->super->s_mmp_block <= fs->super->s_first_data_block ||
- fs->super->s_mmp_block >= fs->super->s_blocks_count))
- ext2fs_mark_block_bitmap2(ctx->block_found_map,
- fs->super->s_mmp_block);
-
- if (!(ctx->options & E2F_OPT_READONLY) &&
- (ctx->lustre_devtype & LUSTRE_TYPE) == LUSTRE_MDS) {
- if (e2fsck_lfsck_remove_pending(ctx, NULL))
- return;
- }
-
- while (1) {
- if (ino % EXT2_MMP_INODE_INTERVAL == 0) {
- if (e2fsck_mmp_update(fs))
- fatal_error(ctx, 0);
- }
- old_op = ehandler_operation(_("getting next inode from scan"));
- pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
- inode, inode_size);
- ehandler_operation(old_op);
- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
- return;
- if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
- if (!ctx->inode_bb_map)
- alloc_bb_map(ctx);
- ext2fs_mark_inode_bitmap2(ctx->inode_bb_map, ino);
- ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
- continue;
- }
- if (pctx.errcode) {
- fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- if (!ino)
- break;
- pctx.ino = ino;
- pctx.inode = inode;
- ctx->stashed_ino = ino;
- if (inode->i_links_count) {
- pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
- ino, inode->i_links_count);
- if (pctx.errcode) {
- pctx.num = inode->i_links_count;
- fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- }
-
- /*
- * Test for incorrect extent flag settings.
- *
- * On big-endian machines we must be careful:
- * When the inode is read, the i_block array is not swapped
- * if the extent flag is set. Therefore if we are testing
- * for or fixing a wrongly-set flag, we must potentially
- * (un)swap before testing, or after fixing.
- */
-
- /*
- * In this case the extents flag was set when read, so
- * extent_header_verify is ok. If the inode is cleared,
- * no need to swap... so no extra swapping here.
- */
- if ((inode->i_flags & EXT4_EXTENTS_FL) && !extent_fs &&
- (inode->i_links_count || (ino == EXT2_BAD_INO) ||
- (ino == EXT2_ROOT_INO) || (ino == EXT2_JOURNAL_INO))) {
- if ((ext2fs_extent_header_verify(inode->i_block,
- sizeof(inode->i_block)) == 0) &&
- fix_problem(ctx, PR_1_EXTENT_FEATURE, &pctx)) {
- sb->s_feature_incompat |= EXT3_FEATURE_INCOMPAT_EXTENTS;
- ext2fs_mark_super_dirty(fs);
- extent_fs = 1;
- } else if (fix_problem(ctx, PR_1_EXTENTS_SET, &pctx)) {
- clear_inode:
- e2fsck_clear_inode(ctx, ino, inode, 0, "pass1");
- if (ino == EXT2_BAD_INO)
- ext2fs_mark_inode_bitmap2(ctx->inode_used_map,
- ino);
- continue;
- }
- }
-
- /*
- * For big-endian machines:
- * If the inode didn't have the extents flag set when it
- * was read, then the i_blocks array was swapped. To test
- * as an extents header, we must swap it back first.
- * IF we then set the extents flag, the entire i_block
- * array must be un/re-swapped to make it proper extents data.
- */
- if (extent_fs && !(inode->i_flags & EXT4_EXTENTS_FL) &&
- (inode->i_links_count || (ino == EXT2_BAD_INO) ||
- (ino == EXT2_ROOT_INO) || (ino == EXT2_JOURNAL_INO)) &&
- (LINUX_S_ISREG(inode->i_mode) ||
- LINUX_S_ISDIR(inode->i_mode))) {
- void *ehp;
-#ifdef WORDS_BIGENDIAN
- __u32 tmp_block[EXT2_N_BLOCKS];
-
- for (i = 0; i < EXT2_N_BLOCKS; i++)
- tmp_block[i] = ext2fs_swab32(inode->i_block[i]);
- ehp = tmp_block;
-#else
- ehp = inode->i_block;
-#endif
- if ((ext2fs_extent_header_verify(ehp,
- sizeof(inode->i_block)) == 0)) {
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- if (fix_problem(ctx, PR_1_UNSET_EXTENT_FL, &pctx)) {
- inode->i_flags |= EXT4_EXTENTS_FL;
-#ifdef WORDS_BIGENDIAN
- memcpy(inode->i_block, tmp_block,
- sizeof(inode->i_block));
-#endif
- e2fsck_write_inode(ctx, ino, inode, "pass1");
- }
- }
- }
-
- if (ino == EXT2_BAD_INO) {
- struct process_block_struct pb;
-
- pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
- &pb.fs_meta_blocks);
- if (pctx.errcode) {
- pctx.num = 4;
- fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- pb.ino = EXT2_BAD_INO;
- pb.num_blocks = pb.last_block = 0;
- pb.last_db_block = -1;
- pb.num_illegal_blocks = 0;
- pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
- pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
- pb.inode = inode;
- pb.pctx = &pctx;
- pb.ctx = ctx;
- pctx.errcode = ext2fs_block_iterate3(fs, ino, 0,
- block_buf, process_bad_block, &pb);
- ext2fs_free_block_bitmap(pb.fs_meta_blocks);
- if (pctx.errcode) {
- fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- if (pb.bbcheck)
- if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
- clear_problem_context(&pctx);
- continue;
- } else if (ino == EXT2_ROOT_INO) {
- /*
- * Make sure the root inode is a directory; if
- * not, offer to clear it. It will be
- * regnerated in pass #3.
- */
- if (!LINUX_S_ISDIR(inode->i_mode)) {
- if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx))
- goto clear_inode;
- }
- /*
- * If dtime is set, offer to clear it. mke2fs
- * version 0.2b created filesystems with the
- * dtime field set for the root and lost+found
- * directories. We won't worry about
- * /lost+found, since that can be regenerated
- * easily. But we will fix the root directory
- * as a special case.
- */
- if (inode->i_dtime && inode->i_links_count) {
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
- inode->i_dtime = 0;
- e2fsck_write_inode(ctx, ino, inode,
- "pass1");
- }
- }
- } else if (ino == EXT2_JOURNAL_INO) {
- ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
- if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
- if (!LINUX_S_ISREG(inode->i_mode) &&
- fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
- &pctx)) {
- inode->i_mode = LINUX_S_IFREG;
- e2fsck_write_inode(ctx, ino, inode,
- "pass1");
- }
- check_blocks(ctx, &pctx, block_buf);
- continue;
- }
- if ((inode->i_links_count ||
- inode->i_blocks || inode->i_block[0]) &&
- fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
- &pctx)) {
- memset(inode, 0, inode_size);
- ext2fs_icount_store(ctx->inode_link_info,
- ino, 0);
- e2fsck_write_inode_full(ctx, ino, inode,
- inode_size, "pass1");
- }
- } else if (ino < EXT2_FIRST_INODE(fs->super)) {
- int problem = 0;
-
- ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
- if (ino == EXT2_BOOT_LOADER_INO) {
- if (LINUX_S_ISDIR(inode->i_mode))
- problem = PR_1_RESERVED_BAD_MODE;
- } else if (ino == EXT2_RESIZE_INO) {
- if (inode->i_mode &&
- !LINUX_S_ISREG(inode->i_mode))
- problem = PR_1_RESERVED_BAD_MODE;
- } else {
- if (inode->i_mode != 0)
- problem = PR_1_RESERVED_BAD_MODE;
- }
- if (problem) {
- if (fix_problem(ctx, problem, &pctx)) {
- inode->i_mode = 0;
- e2fsck_write_inode(ctx, ino, inode,
- "pass1");
- }
- }
- check_blocks(ctx, &pctx, block_buf);
- continue;
- }
- /*
- * Check for inodes who might have been part of the
- * orphaned list linked list. They should have gotten
- * dealt with by now, unless the list had somehow been
- * corrupted.
- *
- * FIXME: In the future, inodes which are still in use
- * (and which are therefore) pending truncation should
- * be handled specially. Right now we just clear the
- * dtime field, and the normal e2fsck handling of
- * inodes where i_size and the inode blocks are
- * inconsistent is to fix i_size, instead of releasing
- * the extra blocks. This won't catch the inodes that
- * was at the end of the orphan list, but it's better
- * than nothing. The right answer is that there
- * shouldn't be any bugs in the orphan list handling. :-)
- */
- if (inode->i_dtime && !busted_fs_time &&
- inode->i_dtime < ctx->fs->super->s_inodes_count) {
- if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
- inode->i_dtime = inode->i_links_count ?
- 0 : ctx->now;
- e2fsck_write_inode(ctx, ino, inode,
- "pass1");
- }
- }
-
- /*
- * This code assumes that deleted inodes have
- * i_links_count set to 0.
- */
- if (!inode->i_links_count) {
- if (!inode->i_dtime && inode->i_mode) {
- if (fix_problem(ctx,
- PR_1_ZERO_DTIME, &pctx)) {
- inode->i_dtime = ctx->now;
- e2fsck_write_inode(ctx, ino, inode,
- "pass1");
- }
- }
- continue;
- }
- /*
- * n.b. 0.3c ext2fs code didn't clear i_links_count for
- * deleted files. Oops.
- *
- * Since all new ext2 implementations get this right,
- * we now assume that the case of non-zero
- * i_links_count and non-zero dtime means that we
- * should keep the file, not delete it.
- *
- */
- if (inode->i_dtime) {
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
- inode->i_dtime = 0;
- e2fsck_write_inode(ctx, ino, inode, "pass1");
- }
- }
-
- ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
- switch (fs->super->s_creator_os) {
- case EXT2_OS_HURD:
- frag = inode->osd2.hurd2.h_i_frag;
- fsize = inode->osd2.hurd2.h_i_fsize;
- break;
- default:
- frag = fsize = 0;
- }
-
- /* Fixed in pass2, e2fsck_process_bad_inode(). */
- if (inode->i_faddr || frag || fsize ||
- (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- if (!(fs->super->s_feature_incompat &
- EXT4_FEATURE_INCOMPAT_64BIT) &&
- inode->osd2.linux2.l_i_file_acl_high != 0)
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- if ((fs->super->s_creator_os == EXT2_OS_LINUX) &&
- !(fs->super->s_feature_ro_compat &
- EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
- (inode->osd2.linux2.l_i_blocks_hi != 0))
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- if (inode->i_flags & EXT2_IMAGIC_FL) {
- if (imagic_fs) {
- if (!ctx->inode_imagic_map)
- alloc_imagic_map(ctx);
- ext2fs_mark_inode_bitmap2(ctx->inode_imagic_map,
- ino);
- } else {
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
- inode->i_flags &= ~EXT2_IMAGIC_FL;
- e2fsck_write_inode(ctx, ino,
- inode, "pass1");
- }
- }
- }
-
- check_inode_extra_space(ctx, &pctx);
- check_is_really_dir(ctx, &pctx, block_buf);
-
- /*
- * ext2fs_inode_has_valid_blocks does not actually look
- * at i_block[] values, so not endian-sensitive here.
- */
- if (extent_fs && (inode->i_flags & EXT4_EXTENTS_FL) &&
- LINUX_S_ISLNK(inode->i_mode) &&
- !ext2fs_inode_has_valid_blocks(inode) &&
- fix_problem(ctx, PR_1_FAST_SYMLINK_EXTENT_FL, &pctx)) {
- inode->i_flags &= ~EXT4_EXTENTS_FL;
- e2fsck_write_inode(ctx, ino, inode, "pass1");
- }
-
- if (LINUX_S_ISDIR(inode->i_mode)) {
- ext2fs_mark_inode_bitmap2(ctx->inode_dir_map, ino);
- e2fsck_add_dir_info(ctx, ino, 0);
- ctx->fs_directory_count++;
- } else if (LINUX_S_ISREG (inode->i_mode)) {
- ext2fs_mark_inode_bitmap2(ctx->inode_reg_map, ino);
- ctx->fs_regular_count++;
- } else if (LINUX_S_ISCHR (inode->i_mode) &&
- e2fsck_pass1_check_device_inode(fs, inode)) {
- check_immutable(ctx, &pctx);
- check_size(ctx, &pctx);
- ctx->fs_chardev_count++;
- } else if (LINUX_S_ISBLK (inode->i_mode) &&
- e2fsck_pass1_check_device_inode(fs, inode)) {
- check_immutable(ctx, &pctx);
- check_size(ctx, &pctx);
- ctx->fs_blockdev_count++;
- } else if (LINUX_S_ISLNK (inode->i_mode) &&
- e2fsck_pass1_check_symlink(fs, ino, inode,
- block_buf)) {
- check_immutable(ctx, &pctx);
- ctx->fs_symlinks_count++;
- if (ext2fs_inode_data_blocks(fs, inode) == 0) {
- ctx->fs_fast_symlinks_count++;
- check_blocks(ctx, &pctx, block_buf);
- continue;
- }
- } else if (LINUX_S_ISFIFO (inode->i_mode) &&
- e2fsck_pass1_check_device_inode(fs, inode)) {
- check_immutable(ctx, &pctx);
- check_size(ctx, &pctx);
- ctx->fs_fifo_count++;
- } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
- e2fsck_pass1_check_device_inode(fs, inode)) {
- check_immutable(ctx, &pctx);
- check_size(ctx, &pctx);
- ctx->fs_sockets_count++;
- } else {
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- }
-
- if (EXT4_XTIME_FUTURE(ctx, sb, inode->i_atime,ctx->time_fudge)||
- EXT4_XTIME_FUTURE(ctx, sb, inode->i_mtime,ctx->time_fudge))
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
-
- if (EXT4_XTIME_FUTURE(ctx, sb, inode->i_ctime,ctx->time_fudge)||
- EXT4_XTIME_ANCIENT(ctx, sb, inode->i_ctime,ctx->time_fudge))
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_HIGH);
-
- /* i_crtime is checked in check_inode_extra_space() */
-
- if (!(inode->i_flags & EXT4_EXTENTS_FL)) {
- if (inode->i_block[EXT2_IND_BLOCK])
- ctx->fs_ind_count++;
- if (inode->i_block[EXT2_DIND_BLOCK])
- ctx->fs_dind_count++;
- if (inode->i_block[EXT2_TIND_BLOCK])
- ctx->fs_tind_count++;
- }
- if (!(inode->i_flags & EXT4_EXTENTS_FL) &&
- (inode->i_block[EXT2_IND_BLOCK] ||
- inode->i_block[EXT2_DIND_BLOCK] ||
- inode->i_block[EXT2_TIND_BLOCK] ||
- ext2fs_file_acl_block(inode))) {
- inodes_to_process[process_inode_count].ino = ino;
- inodes_to_process[process_inode_count].inode = *inode;
- process_inode_count++;
- } else
- check_blocks(ctx, &pctx, block_buf);
-
- if (ctx->flags & E2F_FLAG_EXPAND_EISIZE) {
- struct ext2_inode_large *inode_l;
-
- inode_l = (struct ext2_inode_large *)inode;
-
- if (inode_l->i_extra_isize < ctx->want_extra_isize) {
- fix_problem(ctx, PR_1_EXPAND_EISIZE, &pctx);
- inode_exp = e2fsck_pass1_expand_eisize(ctx,
- inode_l,
- &pctx);
- }
- if ((inode_l->i_extra_isize < ctx->min_extra_isize) &&
- inode_exp == 0)
- ctx->min_extra_isize = inode_l->i_extra_isize;
- }
-
- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
- return;
-
- if (process_inode_count >= ctx->process_inode_size) {
- process_inodes(ctx, block_buf);
-
- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
- return;
- }
- }
- process_inodes(ctx, block_buf);
- ext2fs_close_inode_scan(scan);
-
- /*
- * If any extended attribute blocks' reference counts need to
- * be adjusted, either up (ctx->refcount_extra), or down
- * (ctx->refcount), then fix them.
- */
- if (ctx->refcount) {
- adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
- ea_refcount_free(ctx->refcount);
- ctx->refcount = 0;
- }
- if (ctx->refcount_extra) {
- adjust_extattr_refcount(ctx, ctx->refcount_extra,
- block_buf, +1);
- ea_refcount_free(ctx->refcount_extra);
- ctx->refcount_extra = 0;
- }
-
- if (ctx->invalid_bitmaps)
- handle_fs_bad_blocks(ctx);
-
- /* We don't need the block_ea_map any more */
- if (ctx->block_ea_map) {
- ext2fs_free_block_bitmap(ctx->block_ea_map);
- ctx->block_ea_map = 0;
- }
-
- if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
- ext2fs_block_bitmap save_bmap;
-
- save_bmap = fs->block_map;
- fs->block_map = ctx->block_found_map;
- clear_problem_context(&pctx);
- pctx.errcode = ext2fs_create_resize_inode(fs);
- if (pctx.errcode) {
- if (!fix_problem(ctx, PR_1_RESIZE_INODE_CREATE,
- &pctx)) {
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- pctx.errcode = 0;
- }
- if (!pctx.errcode) {
- e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
- "recreate inode");
- inode->i_mtime = ctx->now;
- e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
- "recreate inode");
- }
- fs->block_map = save_bmap;
- ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
- }
-
- if (ctx->flags & E2F_FLAG_RESTART) {
- /*
- * Only the master copy of the superblock and block
- * group descriptors are going to be written during a
- * restart, so set the superblock to be used to be the
- * master superblock.
- */
- ctx->use_superblock = 0;
- unwind_pass1(fs);
- goto endit;
- }
-
- if (ctx->block_dup_map) {
- if (ctx->options & E2F_OPT_PREEN) {
- clear_problem_context(&pctx);
- fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
- }
- e2fsck_pass1_dupblocks(ctx, block_buf);
- }
-
- e2fsck_lfsck_flush_ea(ctx);
-
- ext2fs_free_mem(&inodes_to_process);
-endit:
- e2fsck_use_inode_shortcuts(ctx, 0);
-
- ext2fs_free_mem(&block_buf);
- ext2fs_free_mem(&inode);
-
- print_resource_track(ctx, _("Pass 1"), &rtrack, ctx->fs->io);
-}
-
-/*
- * When the inode_scan routines call this callback at the end of the
- * glock group, call process_inodes.
- */
-static errcode_t scan_callback(ext2_filsys fs,
- ext2_inode_scan scan EXT2FS_ATTR((unused)),
- dgrp_t group, void * priv_data)
-{
- struct scan_callback_struct *scan_struct;
- e2fsck_t ctx;
-
- scan_struct = (struct scan_callback_struct *) priv_data;
- ctx = scan_struct->ctx;
-
- process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
-
- if (ctx->progress)
- if ((ctx->progress)(ctx, 1, group+1,
- ctx->fs->group_desc_count))
- return EXT2_ET_CANCEL_REQUESTED;
-
- return 0;
-}
-
-/*
- * Process the inodes in the "inodes to process" list.
- */
-static void process_inodes(e2fsck_t ctx, char *block_buf)
-{
- int i;
- struct ext2_inode *old_stashed_inode;
- ext2_ino_t old_stashed_ino;
- const char *old_operation;
- char buf[80];
- struct problem_context pctx;
-
-#if 0
- printf("begin process_inodes: ");
-#endif
- if (process_inode_count == 0)
- return;
- old_operation = ehandler_operation(0);
- old_stashed_inode = ctx->stashed_inode;
- old_stashed_ino = ctx->stashed_ino;
- qsort(inodes_to_process, process_inode_count,
- sizeof(struct process_inode_block), process_inode_cmp);
- clear_problem_context(&pctx);
- for (i=0; i < process_inode_count; i++) {
- pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
- pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
-
-#if 0
- printf("%u ", pctx.ino);
-#endif
- sprintf(buf, _("reading indirect blocks of inode %u"),
- pctx.ino);
- ehandler_operation(buf);
- check_blocks(ctx, &pctx, block_buf);
- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
- break;
- }
- ctx->stashed_inode = old_stashed_inode;
- ctx->stashed_ino = old_stashed_ino;
- process_inode_count = 0;
-#if 0
- printf("end process inodes\n");
-#endif
- ehandler_operation(old_operation);
-}
-
-static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b)
-{
- const struct process_inode_block *ib_a =
- (const struct process_inode_block *) a;
- const struct process_inode_block *ib_b =
- (const struct process_inode_block *) b;
- int ret;
-
- ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
- ib_b->inode.i_block[EXT2_IND_BLOCK]);
- if (ret == 0)
- ret = ext2fs_file_acl_block(&(ib_a->inode)) -
- ext2fs_file_acl_block(&ib_b->inode);
- if (ret == 0)
- ret = ib_a->ino - ib_b->ino;
- return ret;
-}
-
-/*
- * Mark an inode as being bad and increment its badness counter.
- */
-void e2fsck_mark_inode_bad_loc(e2fsck_t ctx, ino_t ino, int count,
- const char *func, const int line)
-{
- struct problem_context pctx;
- __u16 result;
-
- if (!ctx->inode_badness) {
- clear_problem_context(&pctx);
-
- pctx.errcode = ext2fs_create_icount2(ctx->fs, 0, 0, NULL,
- &ctx->inode_badness);
- if (pctx.errcode) {
- fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- }
- ext2fs_icount_fetch(ctx->inode_badness, ino, &result);
- ext2fs_icount_store(ctx->inode_badness, ino, count + result);
-
- if (ctx->options & E2F_OPT_DEBUG)
- fprintf(stderr, "%s:%d: increase inode %lu badness %u to %u\n",
- func, line, (unsigned long)ino, result, count + result);
-}
-
-
-/*
- * This procedure will allocate the inode "bb" (badblock) map table
- */
-static void alloc_bb_map(e2fsck_t ctx)
-{
- struct problem_context pctx;
-
- clear_problem_context(&pctx);
- pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
- _("inode in bad block map"),
- &ctx->inode_bb_map);
- if (pctx.errcode) {
- pctx.num = 4;
- fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
- /* Should never get here */
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
-}
-
-/*
- * This procedure will allocate the inode imagic table
- */
-static void alloc_imagic_map(e2fsck_t ctx)
-{
- struct problem_context pctx;
-
- clear_problem_context(&pctx);
- pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
- _("imagic inode map"),
- &ctx->inode_imagic_map);
- if (pctx.errcode) {
- pctx.num = 5;
- fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
- /* Should never get here */
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
-}
-
-/*
- * Marks a block as in use, setting the dup_map if it's been set
- * already. Called by process_block and process_bad_block.
- *
- * WARNING: Assumes checks have already been done to make sure block
- * is valid. This is true in both process_block and process_bad_block.
- */
-static _INLINE_ void mark_block_used(e2fsck_t ctx, blk64_t block)
-{
- struct problem_context pctx;
-
- clear_problem_context(&pctx);
-
- if (ext2fs_fast_test_block_bitmap2(ctx->block_found_map, block)) {
- if (!ctx->block_dup_map) {
- pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
- _("multiply claimed block map"),
- &ctx->block_dup_map);
- if (pctx.errcode) {
- pctx.num = 3;
- fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
- &pctx);
- /* Should never get here */
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- }
- ext2fs_fast_mark_block_bitmap2(ctx->block_dup_map, block);
- } else {
- ext2fs_fast_mark_block_bitmap2(ctx->block_found_map, block);
- }
-}
-
-/*
- * Adjust the extended attribute block's reference counts at the end
- * of pass 1, either by subtracting out references for EA blocks that
- * are still referenced in ctx->refcount, or by adding references for
- * EA blocks that had extra references as accounted for in
- * ctx->refcount_extra.
- */
-static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
- char *block_buf, int adjust_sign)
-{
- struct ext2_ext_attr_header *header;
- struct problem_context pctx;
- ext2_filsys fs = ctx->fs;
- blk64_t blk;
- __u32 should_be;
- int count;
-
- clear_problem_context(&pctx);
-
- ea_refcount_intr_begin(refcount);
- while (1) {
- if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
- break;
- pctx.blk = blk;
- pctx.errcode = ext2fs_read_ext_attr2(fs, blk, block_buf);
- /* We already checked this block, shouldn't happen */
- if (pctx.errcode) {
- fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
- return;
- }
- header = BHDR(block_buf);
- if (header->h_magic != EXT2_EXT_ATTR_MAGIC) {
- fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
- return;
- }
-
- pctx.blkcount = header->h_refcount;
- should_be = header->h_refcount + adjust_sign * count;
- pctx.num = should_be;
- if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
- header->h_refcount = should_be;
- pctx.errcode = ext2fs_write_ext_attr2(fs, blk,
- block_buf);
- if (pctx.errcode) {
- fix_problem(ctx, PR_1_EXTATTR_WRITE_ABORT,
- &pctx);
- continue;
- }
- }
- }
-}
-
-/*
- * Handle processing the extended attribute blocks
- */
-static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
- char *block_buf)
-{
- ext2_filsys fs = ctx->fs;
- ext2_ino_t ino = pctx->ino;
- struct ext2_inode *inode = pctx->inode;
- blk64_t blk;
- char * end;
- struct ext2_ext_attr_header *header;
- struct ext2_ext_attr_entry *entry;
- int count;
- region_t region = 0;
- struct lov_user_md_v1 *lmm = NULL;
- struct lustre_mdt_attrs *lma = NULL;
- int ret;
-
- blk = ext2fs_file_acl_block(inode);
- if (blk == 0)
- return 0;
-
- /*
- * If the Extended attribute flag isn't set, then a non-zero
- * file acl means that the inode is corrupted.
- *
- * Or if the extended attribute block is an invalid block,
- * then the inode is also corrupted.
- */
- if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
- (blk < fs->super->s_first_data_block) ||
- (blk >= ext2fs_blocks_count(fs->super))) {
- /* Fixed in pass2, e2fsck_process_bad_inode(). */
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- return 0;
- }
-
- /* If ea bitmap hasn't been allocated, create it */
- if (!ctx->block_ea_map) {
- pctx->errcode = ext2fs_allocate_block_bitmap(fs,
- _("ext attr block map"),
- &ctx->block_ea_map);
- if (pctx->errcode) {
- pctx->num = 2;
- fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return 0;
- }
- }
-
- /* Create the EA refcount structure if necessary */
- if (!ctx->refcount) {
- pctx->errcode = ea_refcount_create(0, &ctx->refcount);
- if (pctx->errcode) {
- pctx->num = 1;
- fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return 0;
- }
- }
-
-#if 0
- /* Debugging text */
- printf("Inode %u has EA block %u\n", ino, blk);
-#endif
-
- /* Have we seen this EA block before? */
- if (ext2fs_fast_test_block_bitmap2(ctx->block_ea_map, blk)) {
- if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
- return 1;
- /* Ooops, this EA was referenced more than it stated */
- if (!ctx->refcount_extra) {
- pctx->errcode = ea_refcount_create(0,
- &ctx->refcount_extra);
- if (pctx->errcode) {
- pctx->num = 2;
- fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return 0;
- }
- }
- ea_refcount_increment(ctx->refcount_extra, blk, 0);
- return 1;
- }
-
- /*
- * OK, we haven't seen this EA block yet. So we need to
- * validate it
- */
- pctx->blk = blk;
- pctx->errcode = ext2fs_read_ext_attr2(fs, blk, block_buf);
- if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
- goto clear_extattr;
- header = BHDR(block_buf);
- pctx->blk = ext2fs_file_acl_block(inode);
- if (((ctx->ext_attr_ver == 1) &&
- (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
- ((ctx->ext_attr_ver == 2) &&
- (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
- if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
- goto clear_extattr;
- }
-
- if (header->h_blocks != 1) {
- if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
- goto clear_extattr;
- }
-
- region = region_create(0, fs->blocksize);
- if (!region) {
- fix_problem(ctx, PR_1_EA_ALLOC_REGION_ABORT, pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return 0;
- }
- if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
- if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
- goto clear_extattr;
- }
-
- entry = (struct ext2_ext_attr_entry *)(header+1);
- end = block_buf + fs->blocksize;
- while ((char *)entry < end && *(__u32 *)entry) {
- __u32 hash;
-
- if (region_allocate(region, (char *)entry - (char *)header,
- EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
- if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
- goto clear_extattr;
- break;
- }
- if ((ctx->ext_attr_ver == 1 &&
- (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
- (ctx->ext_attr_ver == 2 &&
- entry->e_name_index == 0)) {
- if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
- goto clear_extattr;
- break;
- }
- if (entry->e_value_inum == 0) {
- if (entry->e_value_offs + entry->e_value_size > fs->blocksize) {
- if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
- goto clear_extattr;
- break;
- }
- if (entry->e_value_size &&
- region_allocate(region, entry->e_value_offs,
- EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
- if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
- goto clear_extattr;
- }
- } else {
- int i_file_acl_deleted = 0;
-
- ret = check_large_ea_inode(ctx, entry, pctx,
- &i_file_acl_deleted);
- if (ret == 0)
- mark_inode_ea_map(ctx, pctx, entry->e_value_inum);
-
- if (i_file_acl_deleted)
- goto clear_extattr;
- }
-
- hash = ext2fs_ext_attr_hash_entry(entry, block_buf +
- entry->e_value_offs);
-
- if (entry->e_hash != hash) {
- pctx->num = entry->e_hash;
- if (fix_problem(ctx, PR_1_ATTR_HASH, pctx))
- goto clear_extattr;
- entry->e_hash = hash;
- }
-
- if (e2fsck_lfsck_find_ea(ctx, (struct ext2_inode_large *)inode,
- entry, block_buf +entry->e_value_offs,
- &lmm, &lma) != 0) {
- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
- return 0;
- }
-
- entry = EXT2_EXT_ATTR_NEXT(entry);
- }
-
- if (lmm)
- e2fsck_lfsck_save_ea(ctx, ino, inode->i_generation, lmm, lma);
-
- if (region_allocate(region, (char *)entry - (char *)header, 4)) {
- if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
- goto clear_extattr;
- }
- region_free(region);
- if (lmm)
- ext2fs_free_mem(&lmm);
- if (lma)
- ext2fs_free_mem(&lma);
-
- count = header->h_refcount - 1;
- if (count)
- ea_refcount_store(ctx->refcount, blk, count);
- mark_block_used(ctx, blk);
- ext2fs_fast_mark_block_bitmap2(ctx->block_ea_map, blk);
- return 1;
-
-clear_extattr:
- if (lmm)
- ext2fs_free_mem(&lmm);
- if (lma)
- ext2fs_free_mem(&lma);
-
- if (region)
- region_free(region);
- ext2fs_file_acl_block_set(inode, 0);
- e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
- return 0;
-}
-
-/* Returns 1 if bad htree, 0 if OK */
-static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
- ext2_ino_t ino, struct ext2_inode *inode,
- char *block_buf)
-{
- struct ext2_dx_root_info *root;
- ext2_filsys fs = ctx->fs;
- errcode_t retval;
- blk64_t blk;
-
- if ((!LINUX_S_ISDIR(inode->i_mode) &&
- fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
- (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX))) {
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- if (fix_problem(ctx, PR_1_HTREE_SET, pctx))
- return 1;
- }
-
- pctx->errcode = ext2fs_bmap2(fs, ino, inode, 0, 0, 0, 0, &blk);
-
- if ((pctx->errcode) ||
- (blk == 0) ||
- (blk < fs->super->s_first_data_block) ||
- (blk >= ext2fs_blocks_count(fs->super))) {
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- if (fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
- return 1;
- else
- return 0;
- }
-
- retval = io_channel_read_blk64(fs->io, blk, 1, block_buf);
- if (retval) {
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- if (fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
- return 1;
- }
-
- /* XXX should check that beginning matches a directory */
- root = (struct ext2_dx_root_info *) (block_buf + 24);
-
- if ((root->reserved_zero || root->info_length < 8) &&
- fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
- return 1;
-
- pctx->num = root->hash_version;
- if ((root->hash_version != EXT2_HASH_LEGACY) &&
- (root->hash_version != EXT2_HASH_HALF_MD4) &&
- (root->hash_version != EXT2_HASH_TEA) &&
- fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
- return 1;
-
- if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
- fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
- return 1;
-
- pctx->num = root->indirect_levels;
- if ((root->indirect_levels > 1) &&
- fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
- return 1;
-
- return 0;
-}
-
-void e2fsck_clear_inode(e2fsck_t ctx, ext2_ino_t ino,
- struct ext2_inode *inode, int restart_flag,
- const char *source)
-{
- inode->i_flags = 0;
- inode->i_links_count = 0;
- ext2fs_icount_store(ctx->inode_link_info, ino, 0);
- inode->i_dtime = ctx->now;
-
- ext2fs_unmark_inode_bitmap2(ctx->inode_dir_map, ino);
- ext2fs_unmark_inode_bitmap2(ctx->inode_used_map, ino);
- if (ctx->inode_reg_map)
- ext2fs_unmark_inode_bitmap2(ctx->inode_reg_map, ino);
- if (ctx->inode_badness)
- ext2fs_icount_store(ctx->inode_badness, ino, 0);
-
- /*
- * If the inode was partially accounted for before processing
- * was aborted, we need to restart the pass 1 scan.
- */
- ctx->flags |= restart_flag;
-
- e2fsck_write_inode(ctx, ino, inode, source);
-}
-
-/* Workaround to handle problems with old Lustre extents patches that didn't
- * clear the ee_start_hi or ei_leaf_hi fields. Could be removed as soon as
- * the f_extent tests are fixed to clear these _hi fields. */
-static errcode_t e2fsck_ext2fs_extent_get(e2fsck_t ctx,
- struct problem_context *pctx,
- ext2_extent_handle_t ehandle,int flags,
- struct ext2fs_extent *extent)
-{
- __u16 blk_hi;
- int high_bits_ok = ext2fs_blocks_count(ctx->fs->super) > 0xffffffffULL;
- int rc = 0;
-
- rc = ext2fs_extent_get(ehandle, flags, extent);
- if (rc)
- return rc;
-
- blk_hi = extent->e_pblk >> 32;
-
- if (blk_hi && !high_bits_ok &&
- fix_problem(ctx, PR_1_EXTENT_HI, pctx)) {
- extent->e_pblk &= 0xFFFFFFFFULL;
- rc = ext2fs_extent_replace(ehandle, 0, extent);
- if (rc)
- return rc;
- }
-
- return rc;
-}
-
-static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
- struct process_block_struct *pb,
- blk64_t start_block,
- ext2_extent_handle_t ehandle)
-{
- struct ext2fs_extent extent;
- blk64_t blk;
- e2_blkcnt_t blockcnt;
- unsigned int i;
- int is_dir, is_leaf;
- errcode_t problem;
- struct ext2_extent_info info;
-
- pctx->errcode = ext2fs_extent_get_info(ehandle, &info);
- if (pctx->errcode)
- return;
-
- pctx->errcode = e2fsck_ext2fs_extent_get(ctx, pctx, ehandle,
- EXT2_EXTENT_FIRST_SIB, &extent);
- while (!pctx->errcode && info.num_entries-- > 0) {
- is_leaf = extent.e_flags & EXT2_EXTENT_FLAGS_LEAF;
- is_dir = LINUX_S_ISDIR(pctx->inode->i_mode);
-
- problem = 0;
- if (extent.e_pblk == 0 ||
- extent.e_pblk < ctx->fs->super->s_first_data_block ||
- extent.e_pblk >= ext2fs_blocks_count(ctx->fs->super))
- problem = PR_1_EXTENT_BAD_START_BLK;
- else if (extent.e_lblk < start_block)
- problem = PR_1_OUT_OF_ORDER_EXTENTS;
- else if (is_leaf &&
- (extent.e_pblk + extent.e_len) >
- ext2fs_blocks_count(ctx->fs->super))
- problem = PR_1_EXTENT_ENDS_BEYOND;
-
- if (problem) {
- /* To ensure that extent is in inode */
- if (info.curr_level == 0)
- e2fsck_mark_inode_bad(ctx, pctx->ino,
- BADNESS_HIGH);
-
- report_problem:
- pctx->blk = extent.e_pblk;
- pctx->blk2 = extent.e_lblk;
- pctx->num = extent.e_len;
- if (fix_problem(ctx, problem, pctx)) {
- e2fsck_read_bitmaps(ctx);
- pctx->errcode =
- ext2fs_extent_delete(ehandle, 0);
- if (pctx->errcode) {
- pctx->str = "ext2fs_extent_delete";
- return;
- }
- pctx->errcode = e2fsck_ext2fs_extent_get(ctx,
- pctx, ehandle,
- EXT2_EXTENT_CURRENT, &extent);
- if (pctx->errcode == EXT2_ET_NO_CURRENT_NODE) {
- pctx->errcode = 0;
- break;
- }
- continue;
- }
- goto next;
- }
-
- if (!is_leaf) {
- blk = extent.e_pblk;
- pctx->errcode = e2fsck_ext2fs_extent_get(ctx, pctx,
- ehandle, EXT2_EXTENT_DOWN, &extent);
- if (pctx->errcode) {
- pctx->str = "EXT2_EXTENT_DOWN";
- problem = PR_1_EXTENT_HEADER_INVALID;
- if (pctx->errcode == EXT2_ET_EXTENT_HEADER_BAD)
- goto report_problem;
- return;
- }
- scan_extent_node(ctx, pctx, pb, extent.e_lblk, ehandle);
- if (pctx->errcode)
- return;
- pctx->errcode = e2fsck_ext2fs_extent_get(ctx, pctx,
- ehandle, EXT2_EXTENT_UP, &extent);
- if (pctx->errcode) {
- pctx->str = "EXT2_EXTENT_UP";
- return;
- }
- mark_block_used(ctx, blk);
- pb->num_blocks++;
- goto next;
- }
-
- if ((pb->previous_block != 0) &&
- (pb->previous_block+1 != extent.e_pblk)) {
- if (ctx->options & E2F_OPT_FRAGCHECK) {
- char type = '?';
-
- if (pb->is_dir)
- type = 'd';
- else if (pb->is_reg)
- type = 'f';
-
- printf(("%6lu(%c): expecting %6lu "
- "actual extent "
- "phys %6lu log %lu len %lu\n"),
- (unsigned long) pctx->ino, type,
- (unsigned long) pb->previous_block+1,
- (unsigned long) extent.e_pblk,
- (unsigned long) extent.e_lblk,
- (unsigned long) extent.e_len);
- }
- pb->fragmented = 1;
- }
- while (is_dir && ++pb->last_db_block < extent.e_lblk) {
- pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist,
- pb->ino, 0,
- pb->last_db_block);
- if (pctx->errcode) {
- pctx->blk = 0;
- pctx->num = pb->last_db_block;
- goto failed_add_dir_block;
- }
- }
- for (blk = extent.e_pblk, blockcnt = extent.e_lblk, i = 0;
- i < extent.e_len;
- blk++, blockcnt++, i++) {
- mark_block_used(ctx, blk);
-
- if (is_dir) {
- pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist, pctx->ino, blk, blockcnt);
- if (pctx->errcode) {
- pctx->blk = blk;
- pctx->num = blockcnt;
- failed_add_dir_block:
- fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
- /* Should never get here */
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- }
- }
- if (is_dir && extent.e_len > 0)
- pb->last_db_block = blockcnt - 1;
- pb->num_blocks += extent.e_len;
- pb->previous_block = extent.e_pblk + extent.e_len - 1;
- start_block = pb->last_block = extent.e_lblk + extent.e_len - 1;
- next:
- pctx->errcode = e2fsck_ext2fs_extent_get(ctx, pctx, ehandle,
- EXT2_EXTENT_NEXT_SIB,
- &extent);
- }
- if (pctx->errcode == EXT2_ET_EXTENT_NO_NEXT)
- pctx->errcode = 0;
-}
-
-static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
- struct process_block_struct *pb)
-{
- struct ext2_extent_info info;
- struct ext2_inode *inode = pctx->inode;
- ext2_extent_handle_t ehandle;
- ext2_filsys fs = ctx->fs;
- ext2_ino_t ino = pctx->ino;
- errcode_t retval;
-
- pctx->errcode = ext2fs_extent_open2(fs, ino, inode, &ehandle);
- if (pctx->errcode) {
- if (fix_problem(ctx, PR_1_READ_EXTENT, pctx))
- e2fsck_clear_inode(ctx, ino, inode, 0,
- "check_blocks_extents");
- pctx->errcode = 0;
- return;
- }
-
- retval = ext2fs_extent_get_info(ehandle, &info);
- if (retval == 0) {
- if (info.max_depth >= MAX_EXTENT_DEPTH_COUNT)
- info.max_depth = MAX_EXTENT_DEPTH_COUNT-1;
- ctx->extent_depth_count[info.max_depth]++;
- }
-
- scan_extent_node(ctx, pctx, pb, 0, ehandle);
- if (pctx->errcode &&
- fix_problem(ctx, PR_1_EXTENT_ITERATE_FAILURE, pctx)) {
- pb->num_blocks = 0;
- inode->i_blocks = 0;
- e2fsck_clear_inode(ctx, ino, inode, E2F_FLAG_RESTART,
- "check_blocks_extents");
- pctx->errcode = 0;
- }
- ext2fs_extent_free(ehandle);
-}
-
-/*
- * This subroutine is called on each inode to account for all of the
- * blocks used by that inode.
- */
-static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
- char *block_buf)
-{
- ext2_filsys fs = ctx->fs;
- struct process_block_struct pb;
- ext2_ino_t ino = pctx->ino;
- struct ext2_inode *inode = pctx->inode;
- int bad_size = 0;
- int dirty_inode = 0;
- int extent_fs;
- __u64 size;
-
- pb.ino = ino;
- pb.num_blocks = 0;
- pb.last_block = -1;
- pb.last_db_block = -1;
- pb.num_illegal_blocks = 0;
- pb.suppress = 0; pb.clear = 0;
- pb.fragmented = 0;
- pb.compressed = 0;
- pb.previous_block = 0;
- pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
- pb.is_reg = LINUX_S_ISREG(inode->i_mode);
- pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
- pb.inode = inode;
- pb.pctx = pctx;
- pb.ctx = ctx;
- pctx->ino = ino;
- pctx->errcode = 0;
-
- extent_fs = (ctx->fs->super->s_feature_incompat &
- EXT3_FEATURE_INCOMPAT_EXTENTS);
-
- if (inode->i_flags & EXT2_COMPRBLK_FL) {
- if (fs->super->s_feature_incompat &
- EXT2_FEATURE_INCOMPAT_COMPRESSION)
- pb.compressed = 1;
- else {
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
- inode->i_flags &= ~EXT2_COMPRBLK_FL;
- dirty_inode++;
- }
- }
- }
-
- if (ext2fs_file_acl_block(inode) &&
- check_ext_attr(ctx, pctx, block_buf)) {
- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
- goto out;
- pb.num_blocks++;
- }
-
- if (ext2fs_inode_has_valid_blocks(inode)) {
- if (extent_fs && (inode->i_flags & EXT4_EXTENTS_FL))
- check_blocks_extents(ctx, pctx, &pb);
- else
- pctx->errcode = ext2fs_block_iterate3(fs, ino,
- pb.is_dir ? BLOCK_FLAG_HOLE : 0,
- block_buf, process_block, &pb);
- }
- end_problem_latch(ctx, PR_LATCH_BLOCK);
- end_problem_latch(ctx, PR_LATCH_TOOBIG);
- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
- goto out;
- if (pctx->errcode)
- fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
-
- if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group) {
- if (LINUX_S_ISDIR(inode->i_mode))
- ctx->fs_fragmented_dir++;
- else
- ctx->fs_fragmented++;
- }
-
- if (pb.clear) {
- e2fsck_clear_inode(ctx, ino, inode, E2F_FLAG_RESTART,
- "check_blocks");
- return;
- }
-
- if (inode->i_flags & EXT2_INDEX_FL) {
- if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
- inode->i_flags &= ~EXT2_INDEX_FL;
- dirty_inode++;
- } else {
-#ifdef ENABLE_HTREE
- e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
-#endif
- }
- }
-
- if (!pb.num_blocks && pb.is_dir) {
- /*
- * The mode might be in-correct. Increasing the badness by
- * small amount won't hurt much.
- */
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
- e2fsck_clear_inode(ctx, ino, inode, 0, "check_blocks");
- ctx->fs_directory_count--;
- return;
- }
- }
-
- if (!(fs->super->s_feature_ro_compat &
- EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ||
- !(inode->i_flags & EXT4_HUGE_FILE_FL))
- pb.num_blocks *= (fs->blocksize / 512);
-#if 0
- printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
- ino, inode->i_size, pb.last_block, ext2fs_inode_i_blocks(fs, inode),
- pb.num_blocks);
-#endif
- if (pb.is_dir) {
- int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
- if (inode->i_size & (fs->blocksize - 1))
- bad_size = 5;
- else if (nblock > (pb.last_block + 1))
- bad_size = 1;
- else if (nblock < (pb.last_block + 1)) {
- if (((pb.last_block + 1) - nblock) >
- fs->super->s_prealloc_dir_blocks)
- bad_size = 2;
- }
- } else {
- e2_blkcnt_t blkpg = ctx->blocks_per_page;
-
- size = EXT2_I_SIZE(inode);
- if ((pb.last_block >= 0) &&
- /* allow allocated blocks to end of PAGE_SIZE */
- (size < (__u64)pb.last_block * fs->blocksize) &&
- ((pb.last_block + 1) / blkpg * blkpg != (pb.last_block+1) ||
- size < (__u64)(pb.last_block & ~(blkpg-1))*fs->blocksize)&&
- !(inode->i_flags & EXT4_EOFBLOCKS_FL))
- bad_size = 3;
- else if (!(extent_fs && (inode->i_flags & EXT4_EXTENTS_FL)) &&
- size > ext2_max_sizes[fs->super->s_log_block_size])
- /* too big for a direct/indirect-mapped file */
- bad_size = 4;
- else if ((extent_fs && (inode->i_flags & EXT4_EXTENTS_FL)) &&
- size >
- ((1ULL << (32 + EXT2_BLOCK_SIZE_BITS(fs->super))) - 1))
- /* too big for an extent-based file - 32bit ee_block */
- bad_size = 6;
-
- /*
- * Check to see if the EOFBLOCKS flag is set where it
- * doesn't need to be.
- */
- if ((inode->i_flags & EXT4_EOFBLOCKS_FL) &&
- (size >= (((__u64)pb.last_block + 1) * fs->blocksize))) {
- pctx->blkcount = pb.last_block;
- if (fix_problem(ctx, PR_1_EOFBLOCKS_FL_SET, pctx)) {
- inode->i_flags &= ~EXT4_EOFBLOCKS_FL;
- dirty_inode++;
- }
- }
- }
- /* i_size for symlinks is checked elsewhere */
- if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
- pctx->num = (pb.last_block+1) * fs->blocksize;
- pctx->group = bad_size;
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
- inode->i_size = pctx->num;
- if (!LINUX_S_ISDIR(inode->i_mode))
- inode->i_size_high = pctx->num >> 32;
- dirty_inode++;
- }
- pctx->num = 0;
- }
- if (LINUX_S_ISREG(inode->i_mode) && EXT2_I_SIZE(inode) >= 0x80000000UL)
- ctx->large_files++;
- if ((pb.num_blocks != ext2fs_inode_i_blocks(fs, inode)) ||
- ((fs->super->s_feature_ro_compat &
- EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
- (inode->i_flags & EXT4_HUGE_FILE_FL) &&
- (inode->osd2.linux2.l_i_blocks_hi != 0))) {
- pctx->num = pb.num_blocks;
- e2fsck_mark_inode_bad(ctx, ino, BADNESS_NORMAL);
- if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
- inode->i_blocks = pb.num_blocks;
- inode->osd2.linux2.l_i_blocks_hi = pb.num_blocks >> 32;
- dirty_inode++;
- }
- pctx->num = 0;
- }
-
- if (ctx->dirs_to_hash && pb.is_dir &&
- !(inode->i_flags & EXT2_INDEX_FL) &&
- ((inode->i_size / fs->blocksize) >= 3))
- ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
-
-out:
- if (dirty_inode)
- e2fsck_write_inode(ctx, ino, inode, "check_blocks");
-}
-
-#if 0
-/*
- * Helper function called by process block when an illegal block is
- * found. It returns a description about why the block is illegal
- */
-static char *describe_illegal_block(ext2_filsys fs, blk64_t block)
-{
- blk64_t super;
- int i;
- static char problem[80];
-
- super = fs->super->s_first_data_block;
- strcpy(problem, "PROGRAMMING ERROR: Unknown reason for illegal block");
- if (block < super) {
- sprintf(problem, "< FIRSTBLOCK (%u)", super);
- return(problem);
- } else if (block >= ext2fs_blocks_count(fs->super)) {
- sprintf(problem, "> BLOCKS (%u)", ext2fs_blocks_count(fs->super));
- return(problem);
- }
- for (i = 0; i < fs->group_desc_count; i++) {
- if (block == super) {
- sprintf(problem, "is the superblock in group %d", i);
- break;
- }
- if (block > super &&
- block <= (super + fs->desc_blocks)) {
- sprintf(problem, "is in the group descriptors "
- "of group %d", i);
- break;
- }
- if (block == ext2fs_block_bitmap_loc(fs, i)) {
- sprintf(problem, "is the block bitmap of group %d", i);
- break;
- }
- if (block == ext2fs_inode_bitmap_loc(fs, i)) {
- sprintf(problem, "is the inode bitmap of group %d", i);
- break;
- }
- if (block >= ext2fs_inode_table_loc(fs, i) &&
- (block < ext2fs_inode_table_loc(fs, i)
- + fs->inode_blocks_per_group)) {
- sprintf(problem, "is in the inode table of group %d",
- i);
- break;
- }
- super += fs->super->s_blocks_per_group;
- }
- return(problem);
-}
-#endif
-
-/*
- * This is a helper function for check_blocks().
- */
-static int process_block(ext2_filsys fs,
- blk64_t *block_nr,
- e2_blkcnt_t blockcnt,
- blk64_t ref_block EXT2FS_ATTR((unused)),
- int ref_offset EXT2FS_ATTR((unused)),
- void *priv_data)
-{
- struct process_block_struct *p;
- struct problem_context *pctx;
- blk64_t blk = *block_nr;
- int ret_code = 0;
- int problem = 0;
- e2fsck_t ctx;
-
- p = (struct process_block_struct *) priv_data;
- pctx = p->pctx;
- ctx = p->ctx;
-
- if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
- /* todo: Check that the comprblk_fl is high, that the
- blkaddr pattern looks right (all non-holes up to
- first EXT2FS_COMPRESSED_BLKADDR, then all
- EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
- that the feature_incompat bit is high, and that the
- inode is a regular file. If we're doing a "full
- check" (a concept introduced to e2fsck by e2compr,
- meaning that we look at data blocks as well as
- metadata) then call some library routine that
- checks the compressed data. I'll have to think
- about this, because one particularly important
- problem to be able to fix is to recalculate the
- cluster size if necessary. I think that perhaps
- we'd better do most/all e2compr-specific checks
- separately, after the non-e2compr checks. If not
- doing a full check, it may be useful to test that
- the personality is linux; e.g. if it isn't then
- perhaps this really is just an illegal block. */
- return 0;
- }
-
- if (blk == 0)
- return 0;
-
-#if 0
- printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
- blockcnt);
-#endif
-
- /*
- * Simplistic fragmentation check. We merely require that the
- * file be contiguous. (Which can never be true for really
- * big files that are greater than a block group.)
- */
- if (!HOLE_BLKADDR(p->previous_block) && p->ino != EXT2_RESIZE_INO) {
- if (p->previous_block+1 != blk) {
- if (ctx->options & E2F_OPT_FRAGCHECK) {
- char type = '?';
-
- if (p->is_dir)
- type = 'd';
- else if (p->is_reg)
- type = 'f';
-
- printf(_("%6lu(%c): expecting %6lu "
- "got phys %6lu (blkcnt %lld)\n"),
- (unsigned long) pctx->ino, type,
- (unsigned long) p->previous_block+1,
- (unsigned long) blk,
- blockcnt);
- }
- p->fragmented = 1;
- }
- }
- p->previous_block = blk;
-
- if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
- problem = PR_1_TOOBIG_DIR;
- if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
- problem = PR_1_TOOBIG_REG;
- if (!p->is_dir && !p->is_reg && blockcnt > 0)
- problem = PR_1_TOOBIG_SYMLINK;
-
- if (blk < fs->super->s_first_data_block ||
- blk >= ext2fs_blocks_count(fs->super)) {
- problem = PR_1_ILLEGAL_BLOCK_NUM;
- e2fsck_mark_inode_bad(ctx, pctx->ino, BADNESS_NORMAL);
- }
-
- if (problem) {
- p->num_illegal_blocks++;
- if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
- if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
- p->clear = 1;
- return BLOCK_ABORT;
- }
- if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
- p->suppress = 1;
- set_latch_flags(PR_LATCH_BLOCK,
- PRL_SUPPRESS, 0);
- }
- }
- pctx->blk = blk;
- pctx->blkcount = blockcnt;
- if (fix_problem(ctx, problem, pctx)) {
- blk = *block_nr = 0;
- ret_code = BLOCK_CHANGED;
- goto mark_dir;
- } else
- return 0;
- }
-
- if (p->ino == EXT2_RESIZE_INO) {
- /*
- * The resize inode has already be sanity checked
- * during pass #0 (the superblock checks). All we
- * have to do is mark the double indirect block as
- * being in use; all of the other blocks are handled
- * by mark_table_blocks()).
- */
- if (blockcnt == BLOCK_COUNT_DIND)
- mark_block_used(ctx, blk);
- } else
- mark_block_used(ctx, blk);
- p->num_blocks++;
- if (blockcnt >= 0)
- p->last_block = blockcnt;
-mark_dir:
- if (p->is_dir && (blockcnt >= 0)) {
- while (++p->last_db_block < blockcnt) {
- pctx->errcode = ext2fs_add_dir_block2(fs->dblist,
- p->ino, 0,
- p->last_db_block);
- if (pctx->errcode) {
- pctx->blk = 0;
- pctx->num = p->last_db_block;
- goto failed_add_dir_block;
- }
- }
- pctx->errcode = ext2fs_add_dir_block2(fs->dblist, p->ino,
- blk, blockcnt);
- if (pctx->errcode) {
- pctx->blk = blk;
- pctx->num = blockcnt;
- failed_add_dir_block:
- fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
- /* Should never get here */
- ctx->flags |= E2F_FLAG_ABORT;
- return BLOCK_ABORT;
- }
- }
- return ret_code;
-}
-
-static int process_bad_block(ext2_filsys fs,
- blk64_t *block_nr,
- e2_blkcnt_t blockcnt,
- blk64_t ref_block EXT2FS_ATTR((unused)),
- int ref_offset EXT2FS_ATTR((unused)),
- void *priv_data)
-{
- struct process_block_struct *p;
- blk64_t blk = *block_nr;
- blk64_t first_block;
- dgrp_t i;
- struct problem_context *pctx;
- e2fsck_t ctx;
-
- /*
- * Note: This function processes blocks for the bad blocks
- * inode, which is never compressed. So we don't use HOLE_BLKADDR().
- */
-
- if (!blk)
- return 0;
-
- p = (struct process_block_struct *) priv_data;
- ctx = p->ctx;
- pctx = p->pctx;
-
- pctx->ino = EXT2_BAD_INO;
- pctx->blk = blk;
- pctx->blkcount = blockcnt;
-
- if ((blk < fs->super->s_first_data_block) ||
- (blk >= ext2fs_blocks_count(fs->super))) {
- if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
- *block_nr = 0;
- return BLOCK_CHANGED;
- } else
- return 0;
- }
-
- if (blockcnt < 0) {
- if (ext2fs_test_block_bitmap2(p->fs_meta_blocks, blk)) {
- p->bbcheck = 1;
- if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
- *block_nr = 0;
- return BLOCK_CHANGED;
- }
- } else if (ext2fs_test_block_bitmap2(ctx->block_found_map,
- blk)) {
- p->bbcheck = 1;
- if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
- pctx)) {
- *block_nr = 0;
- return BLOCK_CHANGED;
- }
- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
- return BLOCK_ABORT;
- } else
- mark_block_used(ctx, blk);
- return 0;
- }
-#if 0
- printf ("DEBUG: Marking %u as bad.\n", blk);
-#endif
- ctx->fs_badblocks_count++;
- /*
- * If the block is not used, then mark it as used and return.
- * If it is already marked as found, this must mean that
- * there's an overlap between the filesystem table blocks
- * (bitmaps and inode table) and the bad block list.
- */
- if (!ext2fs_test_block_bitmap2(ctx->block_found_map, blk)) {
- ext2fs_mark_block_bitmap2(ctx->block_found_map, blk);
- return 0;
- }
- /*
- * Try to find the where the filesystem block was used...
- */
- first_block = fs->super->s_first_data_block;
-
- for (i = 0; i < fs->group_desc_count; i++ ) {
- pctx->group = i;
- pctx->blk = blk;
- if (!ext2fs_bg_has_super(fs, i))
- goto skip_super;
- if (blk == first_block) {
- if (i == 0) {
- if (fix_problem(ctx,
- PR_1_BAD_PRIMARY_SUPERBLOCK,
- pctx)) {
- *block_nr = 0;
- return BLOCK_CHANGED;
- }
- return 0;
- }
- fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
- return 0;
- }
- if ((blk > first_block) &&
- (blk <= first_block + fs->desc_blocks)) {
- if (i == 0) {
- pctx->blk = *block_nr;
- if (fix_problem(ctx,
- PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
- *block_nr = 0;
- return BLOCK_CHANGED;
- }
- return 0;
- }
- fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
- return 0;
- }
- skip_super:
- if (blk == ext2fs_block_bitmap_loc(fs, i)) {
- if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
- ctx->invalid_block_bitmap_flag[i]++;
- ctx->invalid_bitmaps++;
- }
- return 0;
- }
- if (blk == ext2fs_inode_bitmap_loc(fs, i)) {
- if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
- ctx->invalid_inode_bitmap_flag[i]++;
- ctx->invalid_bitmaps++;
- }
- return 0;
- }
- if ((blk >= ext2fs_inode_table_loc(fs, i)) &&
- (blk < (ext2fs_inode_table_loc(fs, i) +
- fs->inode_blocks_per_group))) {
- /*
- * If there are bad blocks in the inode table,
- * the inode scan code will try to do
- * something reasonable automatically.
- */
- return 0;
- }
- first_block += fs->super->s_blocks_per_group;
- }
- /*
- * If we've gotten to this point, then the only
- * possibility is that the bad block inode meta data
- * is using a bad block.
- */
- if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
- (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
- (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
- p->bbcheck = 1;
- if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
- *block_nr = 0;
- return BLOCK_CHANGED;
- }
- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
- return BLOCK_ABORT;
- return 0;
- }
-
- pctx->group = -1;
-
- /* Warn user that the block wasn't claimed */
- fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
-
- return 0;
-}
-
-static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
- const char *name, int num, blk64_t *new_block)
-{
- ext2_filsys fs = ctx->fs;
- dgrp_t last_grp;
- blk64_t old_block = *new_block;
- blk64_t last_block;
- int i, is_flexbg, flexbg, flexbg_size;
- char *buf;
- struct problem_context pctx;
-
- clear_problem_context(&pctx);
-
- pctx.group = group;
- pctx.blk = old_block;
- pctx.str = name;
-
- /*
- * For flex_bg filesystems, first try to allocate the metadata
- * within the flex_bg, and if that fails then try finding the
- * space anywhere in the filesystem.
- */
- is_flexbg = EXT2_HAS_INCOMPAT_FEATURE(fs->super,
- EXT4_FEATURE_INCOMPAT_FLEX_BG);
- if (is_flexbg) {
- flexbg_size = 1 << fs->super->s_log_groups_per_flex;
- flexbg = group / flexbg_size;
- first_block = ext2fs_group_first_block2(fs,
- flexbg_size * flexbg);
- last_grp = group | (flexbg_size - 1);
- if (last_grp > fs->group_desc_count)
- last_grp = fs->group_desc_count;
- last_block = ext2fs_group_last_block2(fs, last_grp);
- } else
- last_block = ext2fs_group_last_block2(fs, group);
- pctx.errcode = ext2fs_get_free_blocks2(fs, first_block, last_block,
- num, ctx->block_found_map,
- new_block);
- if (is_flexbg && (pctx.errcode == EXT2_ET_BLOCK_ALLOC_FAIL))
- pctx.errcode = ext2fs_get_free_blocks2(fs,
- fs->super->s_first_data_block,
- ext2fs_blocks_count(fs->super),
- num, ctx->block_found_map, new_block);
- if (pctx.errcode) {
- pctx.num = num;
- fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
- ext2fs_unmark_valid(fs);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
- if (pctx.errcode) {
- fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
- ext2fs_unmark_valid(fs);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- ext2fs_mark_super_dirty(fs);
- fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
- pctx.blk2 = *new_block;
- fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
- PR_1_RELOC_TO), &pctx);
- pctx.blk2 = 0;
- for (i = 0; i < num; i++) {
- pctx.blk = i;
- ext2fs_mark_block_bitmap2(ctx->block_found_map, (*new_block)+i);
- if (old_block) {
- pctx.errcode = io_channel_read_blk64(fs->io,
- old_block + i, 1, buf);
- if (pctx.errcode)
- fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
- } else
- memset(buf, 0, fs->blocksize);
-
- pctx.blk = (*new_block) + i;
- pctx.errcode = io_channel_write_blk64(fs->io, pctx.blk,
- 1, buf);
- if (pctx.errcode)
- fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
- }
- ext2fs_free_mem(&buf);
-}
-
-/*
- * This routine gets called at the end of pass 1 if bad blocks are
- * detected in the superblock, group descriptors, inode_bitmaps, or
- * block bitmaps. At this point, all of the blocks have been mapped
- * out, so we can try to allocate new block(s) to replace the bad
- * blocks.
- */
-static void handle_fs_bad_blocks(e2fsck_t ctx)
-{
- ext2_filsys fs = ctx->fs;
- dgrp_t i;
- blk64_t first_block;
- blk64_t new_blk;
-
- for (i = 0; i < fs->group_desc_count; i++) {
- first_block = ext2fs_group_first_block2(fs, i);
-
- if (ctx->invalid_block_bitmap_flag[i]) {
- new_blk = ext2fs_block_bitmap_loc(fs, i);
- new_table_block(ctx, first_block, i, _("block bitmap"),
- 1, &new_blk);
- ext2fs_block_bitmap_loc_set(fs, i, new_blk);
- }
- if (ctx->invalid_inode_bitmap_flag[i]) {
- new_blk = ext2fs_inode_bitmap_loc(fs, i);
- new_table_block(ctx, first_block, i, _("inode bitmap"),
- 1, &new_blk);
- ext2fs_inode_bitmap_loc_set(fs, i, new_blk);
- }
- if (ctx->invalid_inode_table_flag[i]) {
- new_blk = ext2fs_inode_table_loc(fs, i);
- new_table_block(ctx, first_block, i, _("inode table"),
- fs->inode_blocks_per_group,
- &new_blk);
- ext2fs_inode_table_loc_set(fs, i, new_blk);
- ctx->flags |= E2F_FLAG_RESTART;
- }
- }
- ctx->invalid_bitmaps = 0;
-}
-
-/*
- * This routine marks all blocks which are used by the superblock,
- * group descriptors, inode bitmaps, and block bitmaps.
- */
-static void mark_table_blocks(e2fsck_t ctx)
-{
- ext2_filsys fs = ctx->fs;
- blk64_t b;
- dgrp_t i;
- int j;
- struct problem_context pctx;
-
- clear_problem_context(&pctx);
-
- for (i = 0; i < fs->group_desc_count; i++) {
- pctx.group = i;
-
- ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
-
- /*
- * Mark the blocks used for the inode table
- */
- if (ext2fs_inode_table_loc(fs, i)) {
- for (j = 0, b = ext2fs_inode_table_loc(fs, i);
- j < fs->inode_blocks_per_group;
- j++, b++) {
- if (ext2fs_test_block_bitmap2(ctx->block_found_map,
- b)) {
- pctx.blk = b;
- if (!ctx->invalid_inode_table_flag[i] &&
- fix_problem(ctx,
- PR_1_ITABLE_CONFLICT, &pctx)) {
- ctx->invalid_inode_table_flag[i]++;
- ctx->invalid_bitmaps++;
- }
- } else {
- ext2fs_mark_block_bitmap2(ctx->block_found_map,
- b);
- }
- }
- }
-
- /*
- * Mark block used for the block bitmap
- */
- if (ext2fs_block_bitmap_loc(fs, i)) {
- if (ext2fs_test_block_bitmap2(ctx->block_found_map,
- ext2fs_block_bitmap_loc(fs, i))) {
- pctx.blk = ext2fs_block_bitmap_loc(fs, i);
- if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
- ctx->invalid_block_bitmap_flag[i]++;
- ctx->invalid_bitmaps++;
- }
- } else {
- ext2fs_mark_block_bitmap2(ctx->block_found_map,
- ext2fs_block_bitmap_loc(fs, i));
- }
-
- }
- /*
- * Mark block used for the inode bitmap
- */
- if (ext2fs_inode_bitmap_loc(fs, i)) {
- if (ext2fs_test_block_bitmap2(ctx->block_found_map,
- ext2fs_inode_bitmap_loc(fs, i))) {
- pctx.blk = ext2fs_inode_bitmap_loc(fs, i);
- if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
- ctx->invalid_inode_bitmap_flag[i]++;
- ctx->invalid_bitmaps++;
- }
- } else {
- ext2fs_mark_block_bitmap2(ctx->block_found_map,
- ext2fs_inode_bitmap_loc(fs, i));
- }
- }
- }
-}
-
-/*
- * Thes subroutines short circuits ext2fs_get_blocks and
- * ext2fs_check_directory; we use them since we already have the inode
- * structure, so there's no point in letting the ext2fs library read
- * the inode again.
- */
-static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
- blk_t *blocks)
-{
- e2fsck_t ctx = (e2fsck_t) fs->priv_data;
- int i;
-
- if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
- return EXT2_ET_CALLBACK_NOTHANDLED;
-
- for (i=0; i < EXT2_N_BLOCKS; i++)
- blocks[i] = ctx->stashed_inode->i_block[i];
- return 0;
-}
-
-static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode *inode)
-{
- e2fsck_t ctx = (e2fsck_t) fs->priv_data;
-
- if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
- return EXT2_ET_CALLBACK_NOTHANDLED;
- *inode = *ctx->stashed_inode;
- return 0;
-}
-
-static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode *inode)
-{
- e2fsck_t ctx = (e2fsck_t) fs->priv_data;
-
- if ((ino == ctx->stashed_ino) && ctx->stashed_inode &&
- (inode != ctx->stashed_inode))
- *ctx->stashed_inode = *inode;
- return EXT2_ET_CALLBACK_NOTHANDLED;
-}
-
-static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
-{
- e2fsck_t ctx = (e2fsck_t) fs->priv_data;
-
- if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
- return EXT2_ET_CALLBACK_NOTHANDLED;
-
- if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
- return EXT2_ET_NO_DIRECTORY;
- return 0;
-}
-
-static errcode_t e2fsck_get_alloc_block(ext2_filsys fs, blk64_t goal,
- blk64_t *ret)
-{
- e2fsck_t ctx = (e2fsck_t) fs->priv_data;
- errcode_t retval;
- blk64_t new_block;
-
- if (ctx->block_found_map) {
- retval = ext2fs_new_block2(fs, goal, ctx->block_found_map,
- &new_block);
- if (retval)
- return retval;
- if (fs->block_map) {
- ext2fs_mark_block_bitmap2(fs->block_map, new_block);
- ext2fs_mark_bb_dirty(fs);
- }
- } else {
- if (!fs->block_map) {
- retval = ext2fs_read_block_bitmap(fs);
- if (retval)
- return retval;
- }
-
- retval = ext2fs_new_block2(fs, goal, 0, &new_block);
- if (retval)
- return retval;
- }
-
- *ret = new_block;
- return (0);
-}
-
-void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
-{
- ext2_filsys fs = ctx->fs;
-
- if (bool) {
- fs->get_blocks = pass1_get_blocks;
- fs->check_directory = pass1_check_directory;
- fs->read_inode = pass1_read_inode;
- fs->write_inode = pass1_write_inode;
- ctx->stashed_ino = 0;
- ext2fs_set_alloc_block_callback(fs, e2fsck_get_alloc_block,
- 0);
- ext2fs_set_block_alloc_stats_callback(fs,
- e2fsck_block_alloc_stats,
- 0);
- } else {
- fs->get_blocks = 0;
- fs->check_directory = 0;
- fs->read_inode = 0;
- fs->write_inode = 0;
- }
-}
diff --git a/e2fsck/problem.c.orig b/e2fsck/problem.c.orig
deleted file mode 100644
index 9a5f1a6..0000000
--- a/e2fsck/problem.c.orig
+++ /dev/null
@@ -1,2071 +0,0 @@
-/*
- * problem.c --- report filesystem problems to the user
- *
- * Copyright 1996, 1997 by Theodore Ts'o
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU Public
- * License.
- * %End-Header%
- */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <ctype.h>
-#include <termios.h>
-
-#include "e2fsck.h"
-
-#include "problem.h"
-#include "problemP.h"
-
-#define PROMPT_NONE 0
-#define PROMPT_FIX 1
-#define PROMPT_CLEAR 2
-#define PROMPT_RELOCATE 3
-#define PROMPT_ALLOCATE 4
-#define PROMPT_EXPAND 5
-#define PROMPT_CONNECT 6
-#define PROMPT_CREATE 7
-#define PROMPT_SALVAGE 8
-#define PROMPT_TRUNCATE 9
-#define PROMPT_CLEAR_INODE 10
-#define PROMPT_ABORT 11
-#define PROMPT_SPLIT 12
-#define PROMPT_CONTINUE 13
-#define PROMPT_CLONE 14
-#define PROMPT_DELETE 15
-#define PROMPT_SUPPRESS 16
-#define PROMPT_UNLINK 17
-#define PROMPT_CLEAR_HTREE 18
-#define PROMPT_RECREATE 19
-#define PROMPT_NULL 20
-
-/*
- * These are the prompts which are used to ask the user if they want
- * to fix a problem.
- */
-static const char *prompt[] = {
- N_("(no prompt)"), /* 0 */
- N_("Fix"), /* 1 */
- N_("Clear"), /* 2 */
- N_("Relocate"), /* 3 */
- N_("Allocate"), /* 4 */
- N_("Expand"), /* 5 */
- N_("Connect to /lost+found"), /* 6 */
- N_("Create"), /* 7 */
- N_("Salvage"), /* 8 */
- N_("Truncate"), /* 9 */
- N_("Clear inode"), /* 10 */
- N_("Abort"), /* 11 */
- N_("Split"), /* 12 */
- N_("Continue"), /* 13 */
- N_("Clone multiply-claimed blocks"), /* 14 */
- N_("Delete file"), /* 15 */
- N_("Suppress messages"),/* 16 */
- N_("Unlink"), /* 17 */
- N_("Clear HTree index"),/* 18 */
- N_("Recreate"), /* 19 */
- "", /* 20 */
-};
-
-/*
- * These messages are printed when we are preen mode and we will be
- * automatically fixing the problem.
- */
-static const char *preen_msg[] = {
- N_("(NONE)"), /* 0 */
- N_("FIXED"), /* 1 */
- N_("CLEARED"), /* 2 */
- N_("RELOCATED"), /* 3 */
- N_("ALLOCATED"), /* 4 */
- N_("EXPANDED"), /* 5 */
- N_("RECONNECTED"), /* 6 */
- N_("CREATED"), /* 7 */
- N_("SALVAGED"), /* 8 */
- N_("TRUNCATED"), /* 9 */
- N_("INODE CLEARED"), /* 10 */
- N_("ABORTED"), /* 11 */
- N_("SPLIT"), /* 12 */
- N_("CONTINUING"), /* 13 */
- N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
- N_("FILE DELETED"), /* 15 */
- N_("SUPPRESSED"), /* 16 */
- N_("UNLINKED"), /* 17 */
- N_("HTREE INDEX CLEARED"),/* 18 */
- N_("WILL RECREATE"), /* 19 */
- "", /* 20 */
-};
-
-static struct e2fsck_problem problem_table[] = {
-
- /* Pre-Pass 1 errors */
-
- /* Block bitmap not in group */
- { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
- PROMPT_RELOCATE, PR_LATCH_RELOC },
-
- /* Inode bitmap not in group */
- { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
- PROMPT_RELOCATE, PR_LATCH_RELOC },
-
- /* Inode table not in group */
- { PR_0_ITABLE_NOT_GROUP,
- N_("@i table for @g %g is not in @g. (@b %b)\n"
- "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
- PROMPT_RELOCATE, PR_LATCH_RELOC },
-
- /* Superblock corrupt */
- { PR_0_SB_CORRUPT,
- N_("\nThe @S could not be read or does not describe a correct ext2\n"
- "@f. If the @v is valid and it really contains an ext2\n"
- "@f (and not swap or ufs or something else), then the @S\n"
- "is corrupt, and you might try running e2fsck with an alternate @S:\n"
- " e2fsck -b %S <@v>\n\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Filesystem size is wrong */
- { PR_0_FS_SIZE_WRONG,
- N_("The @f size (according to the @S) is %b @bs\n"
- "The physical size of the @v is %c @bs\n"
- "Either the @S or the partition table is likely to be corrupt!\n"),
- PROMPT_ABORT, 0 },
-
- /* Fragments not supported */
- { PR_0_NO_FRAGMENTS,
- N_("@S @b_size = %b, fragsize = %c.\n"
- "This version of e2fsck does not support fragment sizes different\n"
- "from the @b size.\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Bad blocks_per_group */
- { PR_0_BLOCKS_PER_GROUP,
- N_("@S @bs_per_group = %b, should have been %c\n"),
- PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
-
- /* Bad first_data_block */
- { PR_0_FIRST_DATA_BLOCK,
- N_("@S first_data_ at b = %b, should have been %c\n"),
- PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
-
- /* Adding UUID to filesystem */
- { PR_0_ADD_UUID,
- N_("@f did not have a UUID; generating one.\n\n"),
- PROMPT_NONE, 0 },
-
- /* Relocate hint */
- { PR_0_RELOCATE_HINT,
- N_("Note: if several inode or block bitmap blocks or part\n"
- "of the inode table require relocation, you may wish to try\n"
- "running e2fsck with the '-b %S' option first. The problem\n"
- "may lie only with the primary block group descriptors, and\n"
- "the backup block group descriptors may be OK.\n\n"),
- PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
-
- /* Miscellaneous superblock corruption */
- { PR_0_MISC_CORRUPT_SUPER,
- N_("Corruption found in @S. (%s = %N).\n"),
- PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
-
- /* Error determing physical device size of filesystem */
- { PR_0_GETSIZE_ERROR,
- N_("Error determining size of the physical @v: %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Inode count in superblock is incorrect */
- { PR_0_INODE_COUNT_WRONG,
- N_("@i count in @S is %i, @s %j.\n"),
- PROMPT_FIX, 0 },
-
- { PR_0_HURD_CLEAR_FILETYPE,
- N_("The Hurd does not support the filetype feature.\n"),
- PROMPT_CLEAR, 0 },
-
- /* Journal inode is invalid */
- { PR_0_JOURNAL_BAD_INODE,
- N_("@S has an @n @j (@i %i).\n"),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* The external journal has (unsupported) multiple filesystems */
- { PR_0_JOURNAL_UNSUPP_MULTIFS,
- N_("External @j has multiple @f users (unsupported).\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Can't find external journal */
- { PR_0_CANT_FIND_JOURNAL,
- N_("Can't find external @j\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* External journal has bad superblock */
- { PR_0_EXT_JOURNAL_BAD_SUPER,
- N_("External @j has bad @S\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Superblock has a bad journal UUID */
- { PR_0_JOURNAL_BAD_UUID,
- N_("External @j does not support this @f\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Journal has an unknown superblock type */
- { PR_0_JOURNAL_UNSUPP_SUPER,
- N_("@f @j @S is unknown type %N (unsupported).\n"
- "It is likely that your copy of e2fsck is old and/or doesn't "
- "support this @j format.\n"
- "It is also possible the @j @S is corrupt.\n"),
- PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
-
- /* Journal superblock is corrupt */
- { PR_0_JOURNAL_BAD_SUPER,
- N_("@j @S is corrupt.\n"),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Superblock has_journal flag is clear but has a journal */
- { PR_0_JOURNAL_HAS_JOURNAL,
- N_("@S has_ at j flag is clear, but a @j %s is present.\n"),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* Superblock needs_recovery flag is set but not journal is present */
- { PR_0_JOURNAL_RECOVER_SET,
- N_("@S needs_recovery flag is set, but no @j is present.\n"),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* Superblock needs_recovery flag is set, but journal has data */
- { PR_0_JOURNAL_RECOVERY_CLEAR,
- N_("@S needs_recovery flag is clear, but @j has data.\n"),
- PROMPT_NONE, 0 },
-
- /* Ask if we should clear the journal */
- { PR_0_JOURNAL_RESET_JOURNAL,
- N_("Clear @j"),
- PROMPT_NULL, PR_PREEN_NOMSG },
-
- /* Filesystem revision is 0, but feature flags are set */
- { PR_0_FS_REV_LEVEL,
- N_("@f has feature flag(s) set, but is a revision 0 @f. "),
- PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
-
- /* Clearing orphan inode */
- { PR_0_ORPHAN_CLEAR_INODE,
- N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
- PROMPT_NONE, 0 },
-
- /* Illegal block found in orphaned inode */
- { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
- N_("@I %B (%b) found in @o @i %i.\n"),
- PROMPT_NONE, 0 },
-
- /* Already cleared block found in orphaned inode */
- { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
- N_("Already cleared %B (%b) found in @o @i %i.\n"),
- PROMPT_NONE, 0 },
-
- /* Illegal orphan inode in superblock */
- { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
- N_("@I @o @i %i in @S.\n"),
- PROMPT_NONE, 0 },
-
- /* Illegal inode in orphaned inode list */
- { PR_0_ORPHAN_ILLEGAL_INODE,
- N_("@I @i %i in @o @i list.\n"),
- PROMPT_NONE, 0 },
-
- /* Journal superblock has an unknown read-only feature flag set */
- { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
- N_("@j @S has an unknown read-only feature flag set.\n"),
- PROMPT_ABORT, 0 },
-
- /* Journal superblock has an unknown incompatible feature flag set */
- { PR_0_JOURNAL_UNSUPP_INCOMPAT,
- N_("@j @S has an unknown incompatible feature flag set.\n"),
- PROMPT_ABORT, 0 },
-
- /* Journal has unsupported version number */
- { PR_0_JOURNAL_UNSUPP_VERSION,
- N_("@j version not supported by this e2fsck.\n"),
- PROMPT_ABORT, 0 },
-
- /* Moving journal to hidden file */
- { PR_0_MOVE_JOURNAL,
- N_("Moving @j from /%s to hidden @i.\n\n"),
- PROMPT_NONE, 0 },
-
- /* Error moving journal to hidden file */
- { PR_0_ERR_MOVE_JOURNAL,
- N_("Error moving @j: %m\n\n"),
- PROMPT_NONE, 0 },
-
- /* Clearing V2 journal superblock */
- { PR_0_CLEAR_V2_JOURNAL,
- N_("Found @n V2 @j @S fields (from V1 @j).\n"
- "Clearing fields beyond the V1 @j @S...\n\n"),
- PROMPT_NONE, 0 },
-
- /* Ask if we should run the journal anyway */
- { PR_0_JOURNAL_RUN,
- N_("Run @j anyway"),
- PROMPT_NULL, 0 },
-
- /* Run the journal by default */
- { PR_0_JOURNAL_RUN_DEFAULT,
- N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
- PROMPT_NONE, 0 },
-
- /* Backup journal inode blocks */
- { PR_0_BACKUP_JNL,
- N_("Backing up @j @i @b information.\n\n"),
- PROMPT_NONE, 0 },
-
- /* Reserved blocks w/o resize_inode */
- { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
- N_("@f does not have resize_ at i enabled, but s_reserved_gdt_ at bs\n"
- "is %N; @s zero. "),
- PROMPT_FIX, 0 },
-
- /* Resize_inode not enabled, but resize inode is non-zero */
- { PR_0_CLEAR_RESIZE_INODE,
- N_("Resize_ at i not enabled, but the resize @i is non-zero. "),
- PROMPT_CLEAR, 0 },
-
- /* Resize inode invalid */
- { PR_0_RESIZE_INODE_INVALID,
- N_("Resize @i not valid. "),
- PROMPT_RECREATE, 0 },
-
- /* Last mount time is in the future */
- { PR_0_FUTURE_SB_LAST_MOUNT,
- N_("@S last mount time (%t,\n\tnow = %T) is in the future.\n"),
- PROMPT_FIX, PR_NO_OK },
-
- /* Last write time is in the future */
- { PR_0_FUTURE_SB_LAST_WRITE,
- N_("@S last write time (%t,\n\tnow = %T) is in the future.\n"),
- PROMPT_FIX, PR_NO_OK },
-
- { PR_0_EXTERNAL_JOURNAL_HINT,
- N_("@S hint for external superblock @s %X. "),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Adding dirhash hint */
- { PR_0_DIRHASH_HINT,
- N_("Adding dirhash hint to @f.\n\n"),
- PROMPT_NONE, 0 },
-
- /* group descriptor N checksum is invalid. */
- { PR_0_GDT_CSUM,
- N_("@g descriptor %g checksum is invalid. "),
- PROMPT_FIX, PR_LATCH_BG_CHECKSUM },
-
- /* group descriptor N marked uninitialized without feature set. */
- { PR_0_GDT_UNINIT,
- N_("@g descriptor %g marked uninitialized without feature set.\n"),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* group N block bitmap uninitialized but inode bitmap in use. */
- { PR_0_BB_UNINIT_IB_INIT,
- N_("@g %g @b @B uninitialized but @i @B in use.\n"),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Group descriptor N has invalid unused inodes count. */
- { PR_0_GDT_ITABLE_UNUSED,
- N_("@g descriptor %g has invalid unused inodes count %b. "),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Last group block bitmap uninitialized. */
- { PR_0_BB_UNINIT_LAST,
- N_("Last @g @b @B uninitialized. "),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Journal transaction found corrupt */
- { PR_0_JNL_TXN_CORRUPT,
- N_("Journal transaction %i was corrupt, replay was aborted.\n"),
- PROMPT_NONE, 0 },
-
- { PR_0_CLEAR_TESTFS_FLAG,
- N_("The test_fs flag is set (and ext4 is available). "),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* Last mount time is in the future (fudged) */
- { PR_0_FUTURE_SB_LAST_MOUNT_FUDGED,
- N_("@S last mount time is in the future.\n\t(by less than a day, "
- "probably due to the hardware clock being incorrectly set) "),
- PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
-
- /* Last write time is in the future (fudged) */
- { PR_0_FUTURE_SB_LAST_WRITE_FUDGED,
- N_("@S last write time is in the future.\n\t(by less than a day, "
- "probably due to the hardware clock being incorrectly set). "),
- PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
-
- /* Block group checksum (latch question) is invalid. */
- { PR_0_GDT_CSUM_LATCH,
- N_("One or more @b @g descriptor checksums are invalid. "),
- PROMPT_FIX, PR_PREEN_OK },
-
- { PR_0_MIN_EXTRA_ISIZE_INVALID,
- N_("@S has invalid s_min_extra_isize. "),
- PROMPT_FIX, PR_PREEN_OK },
-
- { PR_0_WANT_EXTRA_ISIZE_INVALID,
- N_("@S has invalid s_want_extra_isize. "),
- PROMPT_FIX, PR_PREEN_OK },
-
- { PR_0_CLEAR_EXTRA_ISIZE,
- N_("Disable extra_isize feature since @f has 128 byte inodes.\n"),
- PROMPT_NONE, 0 },
-
- /* Superblock has invalid MMP block. */
- { PR_0_MMP_INVALID_BLK,
- N_("@S has invalid MMP block. "),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* Superblock has invalid MMP magic. */
- { PR_0_MMP_INVALID_MAGIC,
- N_("@S has invalid MMP magic. "),
- PROMPT_FIX, PR_PREEN_OK | PR_NO_OK},
-
- /* Pass 1 errors */
-
- /* Pass 1: Checking inodes, blocks, and sizes */
- { PR_1_PASS_HEADER,
- N_("Pass 1: Checking @is, @bs, and sizes\n"),
- PROMPT_NONE, 0 },
-
- /* Root directory is not an inode */
- { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
- PROMPT_CLEAR, 0 },
-
- /* Root directory has dtime set */
- { PR_1_ROOT_DTIME,
- N_("@r has dtime set (probably due to old mke2fs). "),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Reserved inode has bad mode */
- { PR_1_RESERVED_BAD_MODE,
- N_("Reserved @i %i (%Q) has @n mode. "),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* Deleted inode has zero dtime */
- { PR_1_ZERO_DTIME,
- N_("@D @i %i has zero dtime. "),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Inode in use, but dtime set */
- { PR_1_SET_DTIME,
- N_("@i %i is in use, but has dtime set. "),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Zero-length directory */
- { PR_1_ZERO_LENGTH_DIR,
- N_("@i %i is a @z @d. "),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* Block bitmap conflicts with some other fs block */
- { PR_1_BB_CONFLICT,
- N_("@g %g's @b @B at %b @C.\n"),
- PROMPT_RELOCATE, 0 },
-
- /* Inode bitmap conflicts with some other fs block */
- { PR_1_IB_CONFLICT,
- N_("@g %g's @i @B at %b @C.\n"),
- PROMPT_RELOCATE, 0 },
-
- /* Inode table conflicts with some other fs block */
- { PR_1_ITABLE_CONFLICT,
- N_("@g %g's @i table at %b @C.\n"),
- PROMPT_RELOCATE, 0 },
-
- /* Block bitmap is on a bad block */
- { PR_1_BB_BAD_BLOCK,
- N_("@g %g's @b @B (%b) is bad. "),
- PROMPT_RELOCATE, 0 },
-
- /* Inode bitmap is on a bad block */
- { PR_1_IB_BAD_BLOCK,
- N_("@g %g's @i @B (%b) is bad. "),
- PROMPT_RELOCATE, 0 },
-
- /* Inode has incorrect i_size */
- { PR_1_BAD_I_SIZE,
- N_("@i %i, i_size is %Is, @s %N. "),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Inode has incorrect i_blocks */
- { PR_1_BAD_I_BLOCKS,
- N_("@i %i, i_ at bs is %Ib, @s %N. "),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Illegal blocknumber in inode */
- { PR_1_ILLEGAL_BLOCK_NUM,
- N_("@I %B (%b) in @i %i. "),
- PROMPT_CLEAR, PR_LATCH_BLOCK },
-
- /* Block number overlaps fs metadata */
- { PR_1_BLOCK_OVERLAPS_METADATA,
- N_("%B (%b) overlaps @f metadata in @i %i. "),
- PROMPT_CLEAR, PR_LATCH_BLOCK },
-
- /* Inode has illegal blocks (latch question) */
- { PR_1_INODE_BLOCK_LATCH,
- N_("@i %i has illegal @b(s). "),
- PROMPT_CLEAR, 0 },
-
- /* Too many bad blocks in inode */
- { PR_1_TOO_MANY_BAD_BLOCKS,
- N_("Too many illegal @bs in @i %i.\n"),
- PROMPT_CLEAR_INODE, PR_NO_OK },
-
- /* Illegal block number in bad block inode */
- { PR_1_BB_ILLEGAL_BLOCK_NUM,
- N_("@I %B (%b) in bad @b @i. "),
- PROMPT_CLEAR, PR_LATCH_BBLOCK },
-
- /* Bad block inode has illegal blocks (latch question) */
- { PR_1_INODE_BBLOCK_LATCH,
- N_("Bad @b @i has illegal @b(s). "),
- PROMPT_CLEAR, 0 },
-
- /* Duplicate or bad blocks in use! */
- { PR_1_DUP_BLOCKS_PREENSTOP,
- N_("Duplicate or bad @b in use!\n"),
- PROMPT_NONE, 0 },
-
- /* Bad block used as bad block indirect block */
- { PR_1_BBINODE_BAD_METABLOCK,
- N_("Bad @b %b used as bad @b @i indirect @b. "),
- PROMPT_CLEAR, PR_LATCH_BBLOCK },
-
- /* Inconsistency can't be fixed prompt */
- { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
- N_("\nThe bad @b @i has probably been corrupted. You probably\n"
- "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
- "in the @f.\n"),
- PROMPT_CONTINUE, PR_PREEN_NOMSG },
-
- /* Bad primary block */
- { PR_1_BAD_PRIMARY_BLOCK,
- N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
- PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
-
- /* Bad primary block prompt */
- { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
- N_("You can remove this @b from the bad @b list and hope\n"
- "that the @b is really OK. But there are no guarantees.\n\n"),
- PROMPT_CLEAR, PR_PREEN_NOMSG },
-
- /* Bad primary superblock */
- { PR_1_BAD_PRIMARY_SUPERBLOCK,
- N_("The primary @S (%b) is on the bad @b list.\n"),
- PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
-
- /* Bad primary block group descriptors */
- { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
- N_("Block %b in the primary @g descriptors "
- "is on the bad @b list\n"),
- PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
-
- /* Bad superblock in group */
- { PR_1_BAD_SUPERBLOCK,
- N_("Warning: Group %g's @S (%b) is bad.\n"),
- PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Bad block group descriptors in group */
- { PR_1_BAD_GROUP_DESCRIPTORS,
- N_("Warning: Group %g's copy of the @g descriptors has a bad "
- "@b (%b).\n"),
- PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Block claimed for no reason */
- { PR_1_PROGERR_CLAIMED_BLOCK,
- N_("Programming error? @b #%b claimed for no reason in "
- "process_bad_ at b.\n"),
- PROMPT_NONE, PR_PREEN_OK },
-
- /* Error allocating blocks for relocating metadata */
- { PR_1_RELOC_BLOCK_ALLOCATE,
- N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
- PROMPT_NONE, PR_PREEN_OK },
-
- /* Error allocating block buffer during relocation process */
- { PR_1_RELOC_MEMORY_ALLOCATE,
- N_("@A @b buffer for relocating %s\n"),
- PROMPT_NONE, PR_PREEN_OK },
-
- /* Relocating metadata group information from X to Y */
- { PR_1_RELOC_FROM_TO,
- N_("Relocating @g %g's %s from %b to %c...\n"),
- PROMPT_NONE, PR_PREEN_OK },
-
- /* Relocating metatdata group information to X */
- { PR_1_RELOC_TO,
- N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
- PROMPT_NONE, PR_PREEN_OK },
-
- /* Block read error during relocation process */
- { PR_1_RELOC_READ_ERR,
- N_("Warning: could not read @b %b of %s: %m\n"),
- PROMPT_NONE, PR_PREEN_OK },
-
- /* Block write error during relocation process */
- { PR_1_RELOC_WRITE_ERR,
- N_("Warning: could not write @b %b for %s: %m\n"),
- PROMPT_NONE, PR_PREEN_OK },
-
- /* Error allocating inode bitmap */
- { PR_1_ALLOCATE_IBITMAP_ERROR,
- N_("@A @i @B (%N): %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error allocating block bitmap */
- { PR_1_ALLOCATE_BBITMAP_ERROR,
- N_("@A @b @B (%N): %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error allocating icount link information */
- { PR_1_ALLOCATE_ICOUNT,
- N_("@A icount link information: %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error allocating directory block array */
- { PR_1_ALLOCATE_DBCOUNT,
- N_("@A @d @b array: %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error while scanning inodes */
- { PR_1_ISCAN_ERROR,
- N_("Error while scanning @is (%i): %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error while iterating over blocks */
- { PR_1_BLOCK_ITERATE,
- N_("Error while iterating over @bs in @i %i: %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error while storing inode count information */
- { PR_1_ICOUNT_STORE,
- N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error while storing directory block information */
- { PR_1_ADD_DBLOCK,
- N_("Error storing @d @b information "
- "(@i=%i, @b=%b, num=%N): %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error while reading inode (for clearing) */
- { PR_1_READ_INODE,
- N_("Error reading @i %i: %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Suppress messages prompt */
- { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
-
- /* Imagic flag set on an inode when filesystem doesn't support it */
- { PR_1_SET_IMAGIC,
- N_("@i %i has imagic flag set. "),
- PROMPT_CLEAR, 0 },
-
- /* Immutable flag set on a device or socket inode */
- { PR_1_SET_IMMUTABLE,
- N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
- "or append-only flag set. "),
- PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
-
- /* Compression flag set on an inode when filesystem doesn't support it */
- { PR_1_COMPR_SET,
- N_("@i %i has @cion flag set on @f without @cion support. "),
- PROMPT_CLEAR, 0 },
-
- /* Non-zero size for device, fifo or socket inode */
- { PR_1_SET_NONZSIZE,
- N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Filesystem revision is 0, but feature flags are set */
- { PR_1_FS_REV_LEVEL,
- N_("@f has feature flag(s) set, but is a revision 0 @f. "),
- PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
-
- /* Journal inode is not in use, but contains data */
- { PR_1_JOURNAL_INODE_NOT_CLEAR,
- N_("@j @i is not in use, but contains data. "),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* Journal has bad mode */
- { PR_1_JOURNAL_BAD_MODE,
- N_("@j is not regular file. "),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Deal with inodes that were part of orphan linked list */
- { PR_1_LOW_DTIME,
- N_("@i %i was part of the @o @i list. "),
- PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
-
- /* Deal with inodes that were part of corrupted orphan linked
- list (latch question) */
- { PR_1_ORPHAN_LIST_REFUGEES,
- N_("@is that were part of a corrupted orphan linked list found. "),
- PROMPT_FIX, 0 },
-
- /* Error allocating refcount structure */
- { PR_1_ALLOCATE_REFCOUNT,
- N_("@A refcount structure (%N): %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error reading extended attribute block */
- { PR_1_READ_EA_BLOCK,
- N_("Error reading @a @b %b for @i %i. "),
- PROMPT_CLEAR, 0 },
-
- /* Invalid extended attribute block */
- { PR_1_BAD_EA_BLOCK,
- N_("@i %i has a bad @a @b %b. "),
- PROMPT_CLEAR, 0 },
-
- /* Error reading Extended Attribute block while fixing refcount */
- { PR_1_EXTATTR_READ_ABORT,
- N_("Error reading @a @b %b (%m). "),
- PROMPT_NONE, PR_FATAL },
-
- /* Extended attribute reference count incorrect */
- { PR_1_EXTATTR_REFCOUNT,
- N_("@a @b %b has reference count %r, @s %N. "),
- PROMPT_FIX, 0 },
-
- /* Error writing Extended Attribute block while fixing refcount */
- { PR_1_EXTATTR_WRITE_ABORT,
- N_("Error writing @a @b %b (%m). "),
- PROMPT_NONE, PR_FATAL },
-
- /* Multiple EA blocks not supported */
- { PR_1_EA_MULTI_BLOCK,
- N_("@a @b %b has h_ at bs > 1. "),
- PROMPT_CLEAR, 0},
-
- /* Error allocating EA region allocation structure */
- { PR_1_EA_ALLOC_REGION_ABORT,
- N_("@A @a @b %b. "),
- PROMPT_NONE, PR_FATAL},
-
- /* Error EA allocation collision */
- { PR_1_EA_ALLOC_COLLISION,
- N_("@a @b %b is corrupt (allocation collision). "),
- PROMPT_CLEAR, 0},
-
- /* Bad extended attribute name */
- { PR_1_EA_BAD_NAME,
- N_("@a @b %b is corrupt (@n name). "),
- PROMPT_CLEAR, 0},
-
- /* Bad extended attribute value */
- { PR_1_EA_BAD_VALUE,
- N_("@a @b %b is corrupt (@n value). "),
- PROMPT_CLEAR, 0},
-
- /* Inode too big (latch question) */
- { PR_1_INODE_TOOBIG,
- N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
-
- /* Directory too big */
- { PR_1_TOOBIG_DIR,
- N_("%B (%b) causes @d to be too big. "),
- PROMPT_CLEAR, PR_LATCH_TOOBIG },
-
- /* Regular file too big */
- { PR_1_TOOBIG_REG,
- N_("%B (%b) causes file to be too big. "),
- PROMPT_CLEAR, PR_LATCH_TOOBIG },
-
- /* Symlink too big */
- { PR_1_TOOBIG_SYMLINK,
- N_("%B (%b) causes symlink to be too big. "),
- PROMPT_CLEAR, PR_LATCH_TOOBIG },
-
- /* INDEX_FL flag set on a non-HTREE filesystem */
- { PR_1_HTREE_SET,
- N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
- PROMPT_CLEAR_HTREE, PR_PREEN_OK },
-
- /* INDEX_FL flag set on a non-directory */
- { PR_1_HTREE_NODIR,
- N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
- PROMPT_CLEAR_HTREE, PR_PREEN_OK },
-
- /* Invalid root node in HTREE directory */
- { PR_1_HTREE_BADROOT,
- N_("@h %i has an @n root node.\n"),
- PROMPT_CLEAR_HTREE, PR_PREEN_OK },
-
- /* Unsupported hash version in HTREE directory */
- { PR_1_HTREE_HASHV,
- N_("@h %i has an unsupported hash version (%N)\n"),
- PROMPT_CLEAR_HTREE, PR_PREEN_OK },
-
- /* Incompatible flag in HTREE root node */
- { PR_1_HTREE_INCOMPAT,
- N_("@h %i uses an incompatible htree root node flag.\n"),
- PROMPT_CLEAR_HTREE, PR_PREEN_OK },
-
- /* HTREE too deep */
- { PR_1_HTREE_DEPTH,
- N_("@h %i has a tree depth (%N) which is too big\n"),
- PROMPT_CLEAR_HTREE, PR_PREEN_OK },
-
- /* Bad block has indirect block that conflicts with filesystem block */
- { PR_1_BB_FS_BLOCK,
- N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
- "@f metadata. "),
- PROMPT_CLEAR, PR_LATCH_BBLOCK },
-
- /* Resize inode failed */
- { PR_1_RESIZE_INODE_CREATE,
- N_("Resize @i (re)creation failed: %m."),
- PROMPT_CONTINUE, 0 },
-
- /* invalid inode->i_extra_isize */
- { PR_1_EXTRA_ISIZE,
- N_("@i %i has a extra size (%IS) which is @n\n"),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* invalid ea entry->e_name_len */
- { PR_1_ATTR_NAME_LEN,
- N_("@a in @i %i has a namelen (%N) which is @n\n"),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* invalid ea entry->e_value_offs */
- { PR_1_ATTR_VALUE_OFFSET,
- N_("@a in @i %i has a value offset (%N) which is @n\n"),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* invalid ea entry->e_value_block */
- { PR_1_ATTR_VALUE_BLOCK,
- N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* invalid ea entry->e_value_size */
- { PR_1_ATTR_VALUE_SIZE,
- N_("@a in @i %i has a value size (%N) which is @n\n"),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* invalid ea entry->e_hash */
- { PR_1_ATTR_HASH,
- N_("@a in @i %i has a hash (%N) which is @n\n"),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* inode appears to be a directory */
- { PR_1_TREAT_AS_DIRECTORY,
- N_("@i %i is a %It but it looks like it is really a directory.\n"),
- PROMPT_FIX, 0 },
-
- /* Error while reading extent tree */
- { PR_1_READ_EXTENT,
- N_("Error while reading over @x tree in @i %i: %m\n"),
- PROMPT_CLEAR_INODE, 0 },
-
- /* Failure to iterate extents */
- { PR_1_EXTENT_ITERATE_FAILURE,
- N_("Failed to iterate extents in @i %i\n"
- "\t(op %s, blk %b, lblk %c): %m\n"),
- PROMPT_CLEAR_INODE, 0 },
-
- /* Bad starting block in extent */
- { PR_1_EXTENT_BAD_START_BLK,
- N_("@i %i has an @n extent\n\t(logical @b %c, @n physical @b %b, len %N)\n"),
- PROMPT_CLEAR, 0 },
-
- /* Extent ends beyond filesystem */
- { PR_1_EXTENT_ENDS_BEYOND,
- N_("@i %i has an @n extent\n\t(logical @b %c, physical @b %b, @n len %N)\n"),
- PROMPT_CLEAR, 0 },
-
- /* EXTENTS_FL flag set on a non-extents filesystem */
- { PR_1_EXTENTS_SET,
- N_("@i %i has EXTENTS_FL flag set on @f without extents support.\n"),
- PROMPT_CLEAR, 0 },
-
- /* inode has extents, superblock missing INCOMPAT_EXTENTS feature */
- { PR_1_EXTENT_FEATURE,
- N_("@i %i is in extent format, but @S is missing EXTENTS feature\n"),
- PROMPT_FIX, 0 },
-
- /* inode missing EXTENTS_FL, but is an extent inode */
- { PR_1_UNSET_EXTENT_FL,
- N_("@i %i missing EXTENT_FL, but is in extents format\n"),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Fast symlink has EXTENTS_FL set */
- { PR_1_FAST_SYMLINK_EXTENT_FL,
- N_("Fast symlink %i has EXTENT_FL set. "),
- PROMPT_CLEAR, 0 },
-
- /* Extents are out of order */
- { PR_1_OUT_OF_ORDER_EXTENTS,
- N_("@i %i has out of order extents\n\t(@n logical @b %c, physical @b %b, len %N)\n"),
- PROMPT_CLEAR, 0 },
-
- { PR_1_EXTENT_HEADER_INVALID,
- N_("@i %i has an invalid extent node (blk %b, lblk %c)\n"),
- PROMPT_CLEAR, 0 },
-
- { PR_1_EOFBLOCKS_FL_SET,
- N_("@i %i should not have EOFBLOCKS_FL set "
- "(size %Is, lblk %r)\n"),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* Bad extended attribute value in inode */
- { PR_1_INODE_EA_BAD_VALUE,
- N_("@a in @i %i is corrupt (@n value)."),
- PROMPT_CLEAR, 0},
-
- /* extent has high 16 bits set */
- { PR_1_EXTENT_HI,
- N_("High 16 bits of extent/index @b set\n"),
- PROMPT_CLEAR, PR_LATCH_EXTENT_HI|PR_PREEN_OK|PR_NO_OK|PR_PREEN_NOMSG},
-
- /* extent has high 16 bits set header */
- { PR_1_EXTENT_HI_LATCH,
- N_("@i %i has high 16 bits of extent/index @b set\n"),
- PROMPT_CLEAR, PR_PREEN_OK | PR_NO_OK | PR_PREEN_NOMSG },
-
- /* eh_depth should be 0 */
- { PR_1_EXTENT_EH_DEPTH_BAD,
- N_("@i %i has extent header with incorrect eh_depth\n"),
- PROMPT_FIX, 0 },
-
- /* invalid inode creation time */
- { PR_1_CRTIME_BAD,
- N_("@i %i creation time (%t) invalid.\n"),
- PROMPT_CLEAR, PR_PREEN_OK | PR_NO_OK },
-
- /* expand inode */
- { PR_1_EXPAND_EISIZE_WARNING,
- N_("\ne2fsck is being run with \"expand_extra_isize\" option or\n"
- "s_min_extra_isize of %d bytes has been set in the superblock.\n"
- "Inode %i does not have enough free space. Either some EAs\n"
- "need to be deleted from this inode or the RO_COMPAT_EXTRA_ISIZE\n"
- "flag must be cleared.\n\n"), PROMPT_NONE, PR_PREEN_OK | PR_NO_OK |
- PR_PREEN_NOMSG },
-
- /* expand inode */
- { PR_1_EXPAND_EISIZE,
- N_("Expanding @i %i.\n"),
- PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_PREEN_NOMSG },
-
- /* delete an EA so that EXTRA_ISIZE feature may be enabled */
- { PR_1_EISIZE_DELETE_EA,
- N_("Delete EA %s of @i %i so that EXTRA_ISIZE feature may be "
- "enabled?\n"), PROMPT_FIX, PR_NO_OK | PR_PREEN_NO },
-
- /* an EA needs to be deleted by e2fsck is being run with -p or -y */
- { PR_1_EA_BLK_NOSPC,
- N_("An EA needs to be deleted for @i %i but e2fsck is being run\n"
- "with -p or -y mode.\n"),
- PROMPT_ABORT, 0 },
-
- /* disable EXTRA_ISIZE feature since inode cannot be expanded */
- { PR_1_CLEAR_EXTRA_ISIZE,
- N_("Disable EXTRA_ISIZE feature since @i %i cannot be expanded\n"
- "without deletion of an EA.\n"),
- PROMPT_FIX, 0 },
-
- /* Inode has illegal extended attribute value inode */
- { PR_1_ATTR_VALUE_EA_INODE,
- N_("@i %i has @I @a value @i %N.\n"),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Invalid backpointer from extended attribute inode to parent inode */
- { PR_1_ATTR_INVAL_EA_INODE,
- N_("@n backpointer from @a @i %N to parent @i %i.\n"),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* Inode has invalid extended attribute. EA inode missing
- * EA_INODE flag. */
- { PR_1_ATTR_NO_EA_INODE_FL,
- N_("@i %i has @n @a. EA @i %N missing EA_INODE flag.\n"),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* EA inode for parent inode missing EA_INODE flag. */
- { PR_1_ATTR_SET_EA_INODE_FL,
- N_("EA @i %N for parent @i %i missing EA_INODE flag.\n "),
- PROMPT_FIX, PR_PREEN_OK },
-
-
- /* Pass 1b errors */
-
- /* Pass 1B: Rescan for duplicate/bad blocks */
- { PR_1B_PASS_HEADER,
- N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
- "Pass 1B: Rescanning for @m @bs\n"),
- PROMPT_NONE, 0 },
-
- /* Duplicate/bad block(s) header */
- { PR_1B_DUP_BLOCK_HEADER,
- N_("@m @b(s) in @i %i:"),
- PROMPT_NONE, 0 },
-
- /* Duplicate/bad block(s) in inode */
- { PR_1B_DUP_BLOCK,
- " %b",
- PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
-
- /* Duplicate/bad block(s) end */
- { PR_1B_DUP_BLOCK_END,
- "\n",
- PROMPT_NONE, PR_PREEN_NOHDR },
-
- /* Error while scanning inodes */
- { PR_1B_ISCAN_ERROR,
- N_("Error while scanning inodes (%i): %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error allocating inode bitmap */
- { PR_1B_ALLOCATE_IBITMAP_ERROR,
- N_("@A @i @B (@i_dup_map): %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error while iterating over blocks */
- { PR_1B_BLOCK_ITERATE,
- N_("Error while iterating over @bs in @i %i (%s): %m\n"),
- PROMPT_NONE, 0 },
-
- /* Error adjusting EA refcount */
- { PR_1B_ADJ_EA_REFCOUNT,
- N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
- PROMPT_NONE, 0 },
-
-
- /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
- { PR_1C_PASS_HEADER,
- N_("Pass 1C: Scanning directories for @is with @m @bs\n"),
- PROMPT_NONE, 0 },
-
-
- /* Pass 1D: Reconciling multiply-claimed blocks */
- { PR_1D_PASS_HEADER,
- N_("Pass 1D: Reconciling @m @bs\n"),
- PROMPT_NONE, 0 },
-
- /* File has duplicate blocks */
- { PR_1D_DUP_FILE,
- N_("File %Q (@i #%i, mod time %IM) \n"
- " has %r @m @b(s), shared with %N file(s):\n"),
- PROMPT_NONE, 0 },
-
- /* List of files sharing duplicate blocks */
- { PR_1D_DUP_FILE_LIST,
- N_("\t%Q (@i #%i, mod time %IM)\n"),
- PROMPT_NONE, 0 },
-
- /* File sharing blocks with filesystem metadata */
- { PR_1D_SHARE_METADATA,
- N_("\t<@f metadata>\n"),
- PROMPT_NONE, 0 },
-
- /* Report of how many duplicate/bad inodes */
- { PR_1D_NUM_DUP_INODES,
- N_("(There are %N @is containing @m @bs.)\n\n"),
- PROMPT_NONE, 0 },
-
- /* Duplicated blocks already reassigned or cloned. */
- { PR_1D_DUP_BLOCKS_DEALT,
- N_("@m @bs already reassigned or cloned.\n\n"),
- PROMPT_NONE, 0 },
-
- /* Clone duplicate/bad blocks? */
- { PR_1D_CLONE_QUESTION,
- "", PROMPT_CLONE, PR_NO_OK },
-
- /* Delete file? */
- { PR_1D_DELETE_QUESTION,
- "", PROMPT_DELETE, 0 },
-
- /* Couldn't clone file (error) */
- { PR_1D_CLONE_ERROR,
- N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
-
- /* File with shared blocks found */
- { PR_1D_DISCONNECT_QUESTION,
- N_("File with shared blocks found\n"), PROMPT_CONNECT, 0 },
-
- /* Couldn't unlink file (error) */
- { PR_1D_DISCONNECT_ERROR,
- N_("Couldn't unlink file: %m\n"), PROMPT_NONE, 0 },
-
- /* Pass 2 errors */
-
- /* Pass 2: Checking directory structure */
- { PR_2_PASS_HEADER,
- N_("Pass 2: Checking @d structure\n"),
- PROMPT_NONE, 0 },
-
- /* Bad inode number for '.' */
- { PR_2_BAD_INODE_DOT,
- N_("@n @i number for '.' in @d @i %i.\n"),
- PROMPT_FIX, 0 },
-
- /* Directory entry has bad inode number */
- { PR_2_BAD_INO,
- N_("@E has @n @i #: %Di.\n"),
- PROMPT_CLEAR, 0 },
-
- /* Directory entry has deleted or unused inode */
- { PR_2_UNUSED_INODE,
- N_("@E has @D/unused @i %Di. "),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* Directry entry is link to '.' */
- { PR_2_LINK_DOT,
- N_("@E @L to '.' "),
- PROMPT_CLEAR, 0 },
-
- /* Directory entry points to inode now located in a bad block */
- { PR_2_BB_INODE,
- N_("@E points to @i (%Di) located in a bad @b.\n"),
- PROMPT_CLEAR, 0 },
-
- /* Directory entry contains a link to a directory */
- { PR_2_LINK_DIR,
- N_("@E @L to @d %P (%Di).\n"),
- PROMPT_CLEAR, 0 },
-
- /* Directory entry contains a link to the root directry */
- { PR_2_LINK_ROOT,
- N_("@E @L to the @r.\n"),
- PROMPT_CLEAR, 0 },
-
- /* Directory entry has illegal characters in its name */
- { PR_2_BAD_NAME,
- N_("@E has illegal characters in its name.\n"),
- PROMPT_FIX, 0 },
-
- /* Missing '.' in directory inode */
- { PR_2_MISSING_DOT,
- N_("Missing '.' in @d @i %i.\n"),
- PROMPT_FIX, 0 },
-
- /* Missing '..' in directory inode */
- { PR_2_MISSING_DOT_DOT,
- N_("Missing '..' in @d @i %i.\n"),
- PROMPT_FIX, 0 },
-
- /* First entry in directory inode doesn't contain '.' */
- { PR_2_1ST_NOT_DOT,
- N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
- PROMPT_FIX, 0 },
-
- /* Second entry in directory inode doesn't contain '..' */
- { PR_2_2ND_NOT_DOT_DOT,
- N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
- PROMPT_FIX, 0 },
-
- /* i_faddr should be zero */
- { PR_2_FADDR_ZERO,
- N_("i_faddr @F %IF, @s zero.\n"),
- PROMPT_CLEAR, 0 },
-
- /* i_file_acl should be zero */
- { PR_2_FILE_ACL_ZERO,
- N_("i_file_acl @F %If, @s zero.\n"),
- PROMPT_CLEAR, 0 },
-
- /* i_dir_acl should be zero */
- { PR_2_DIR_ACL_ZERO,
- N_("i_dir_acl @F %Id, @s zero.\n"),
- PROMPT_CLEAR, 0 },
-
- /* i_frag should be zero */
- { PR_2_FRAG_ZERO,
- N_("i_frag @F %N, @s zero.\n"),
- PROMPT_CLEAR, 0 },
-
- /* i_fsize should be zero */
- { PR_2_FSIZE_ZERO,
- N_("i_fsize @F %N, @s zero.\n"),
- PROMPT_CLEAR, 0 },
-
- /* inode has bad mode */
- { PR_2_BAD_MODE,
- N_("@i %i (%Q) has @n mode (%Im).\n"),
- PROMPT_CLEAR, 0 },
-
- /* directory corrupted */
- { PR_2_DIR_CORRUPTED,
- N_("@d @i %i, %B, offset %N: @d corrupted\n"),
- PROMPT_SALVAGE, 0 },
-
- /* filename too long */
- { PR_2_FILENAME_LONG,
- N_("@d @i %i, %B, offset %N: filename too long\n"),
- PROMPT_TRUNCATE, 0 },
-
- /* Directory inode has a missing block (hole) */
- { PR_2_DIRECTORY_HOLE,
- N_("@d @i %i has an unallocated %B. "),
- PROMPT_ALLOCATE, 0 },
-
- /* '.' is not NULL terminated */
- { PR_2_DOT_NULL_TERM,
- N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
- PROMPT_FIX, 0 },
-
- /* '..' is not NULL terminated */
- { PR_2_DOT_DOT_NULL_TERM,
- N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
- PROMPT_FIX, 0 },
-
- /* Illegal character device inode */
- { PR_2_BAD_CHAR_DEV,
- N_("@i %i (%Q) is an @I character @v.\n"),
- PROMPT_CLEAR, 0 },
-
- /* Illegal block device inode */
- { PR_2_BAD_BLOCK_DEV,
- N_("@i %i (%Q) is an @I @b @v.\n"),
- PROMPT_CLEAR, 0 },
-
- /* Duplicate '.' entry */
- { PR_2_DUP_DOT,
- N_("@E is duplicate '.' @e.\n"),
- PROMPT_FIX, 0 },
-
- /* Duplicate '..' entry */
- { PR_2_DUP_DOT_DOT,
- N_("@E is duplicate '..' @e.\n"),
- PROMPT_FIX, 0 },
-
- /* Internal error: couldn't find dir_info */
- { PR_2_NO_DIRINFO,
- N_("Internal error: couldn't find dir_info for %i.\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Final rec_len is wrong */
- { PR_2_FINAL_RECLEN,
- N_("@E has rec_len of %Dr, @s %N.\n"),
- PROMPT_FIX, 0 },
-
- /* Error allocating icount structure */
- { PR_2_ALLOCATE_ICOUNT,
- N_("@A icount structure: %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error iterating over directory blocks */
- { PR_2_DBLIST_ITERATE,
- N_("Error iterating over @d @bs: %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error reading directory block */
- { PR_2_READ_DIRBLOCK,
- N_("Error reading @d @b %b (@i %i): %m\n"),
- PROMPT_CONTINUE, 0 },
-
- /* Error writing directory block */
- { PR_2_WRITE_DIRBLOCK,
- N_("Error writing @d @b %b (@i %i): %m\n"),
- PROMPT_CONTINUE, 0 },
-
- /* Error allocating new directory block */
- { PR_2_ALLOC_DIRBOCK,
- N_("@A new @d @b for @i %i (%s): %m\n"),
- PROMPT_NONE, 0 },
-
- /* Error deallocating inode */
- { PR_2_DEALLOC_INODE,
- N_("Error deallocating @i %i: %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Directory entry for '.' is big. Split? */
- { PR_2_SPLIT_DOT,
- N_("@d @e for '.' in %p (%i) is big.\n"),
- PROMPT_SPLIT, PR_NO_OK },
-
- /* Illegal FIFO inode */
- { PR_2_BAD_FIFO,
- N_("@i %i (%Q) is an @I FIFO.\n"),
- PROMPT_CLEAR, 0 },
-
- /* Illegal socket inode */
- { PR_2_BAD_SOCKET,
- N_("@i %i (%Q) is an @I socket.\n"),
- PROMPT_CLEAR, 0 },
-
- /* Directory filetype not set */
- { PR_2_SET_FILETYPE,
- N_("Setting filetype for @E to %N.\n"),
- PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
-
- /* Directory filetype incorrect */
- { PR_2_BAD_FILETYPE,
- N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
- PROMPT_FIX, 0 },
-
- /* Directory filetype set on filesystem */
- { PR_2_CLEAR_FILETYPE,
- N_("@E has filetype set.\n"),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* Directory filename is null */
- { PR_2_NULL_NAME,
- N_("@E has a @z name.\n"),
- PROMPT_CLEAR, 0 },
-
- /* Invalid symlink */
- { PR_2_INVALID_SYMLINK,
- N_("Symlink %Q (@i #%i) is @n.\n"),
- PROMPT_CLEAR, 0 },
-
- /* i_file_acl (extended attribute block) is bad */
- { PR_2_FILE_ACL_BAD,
- N_("@a @b @F @n (%If).\n"),
- PROMPT_CLEAR, 0 },
-
- /* Filesystem contains large files, but has no such flag in sb */
- { PR_2_FEATURE_LARGE_FILES,
- N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
- PROMPT_FIX, 0 },
-
- /* Node in HTREE directory not referenced */
- { PR_2_HTREE_NOTREF,
- N_("@p @h %d: %B not referenced\n"),
- PROMPT_NONE, 0 },
-
- /* Node in HTREE directory referenced twice */
- { PR_2_HTREE_DUPREF,
- N_("@p @h %d: %B referenced twice\n"),
- PROMPT_NONE, 0 },
-
- /* Node in HTREE directory has bad min hash */
- { PR_2_HTREE_MIN_HASH,
- N_("@p @h %d: %B has bad min hash\n"),
- PROMPT_NONE, 0 },
-
- /* Node in HTREE directory has bad max hash */
- { PR_2_HTREE_MAX_HASH,
- N_("@p @h %d: %B has bad max hash\n"),
- PROMPT_NONE, 0 },
-
- /* Clear invalid HTREE directory */
- { PR_2_HTREE_CLEAR,
- N_("@n @h %d (%q). "), PROMPT_CLEAR_HTREE, 0 },
-
- /* Bad block in htree interior node */
- { PR_2_HTREE_BADBLK,
- N_("@p @h %d (%q): bad @b number %b.\n"),
- PROMPT_CLEAR_HTREE, 0 },
-
- /* Error adjusting EA refcount */
- { PR_2_ADJ_EA_REFCOUNT,
- N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Invalid HTREE root node */
- { PR_2_HTREE_BAD_ROOT,
- N_("@p @h %d: root node is @n\n"),
- PROMPT_CLEAR_HTREE, PR_PREEN_OK },
-
- /* Invalid HTREE limit */
- { PR_2_HTREE_BAD_LIMIT,
- N_("@p @h %d: %B has @n limit (%N)\n"),
- PROMPT_CLEAR_HTREE, PR_PREEN_OK },
-
- /* Invalid HTREE count */
- { PR_2_HTREE_BAD_COUNT,
- N_("@p @h %d: %B has @n count (%N)\n"),
- PROMPT_CLEAR_HTREE, PR_PREEN_OK },
-
- /* HTREE interior node has out-of-order hashes in table */
- { PR_2_HTREE_HASH_ORDER,
- N_("@p @h %d: %B has an unordered hash table\n"),
- PROMPT_CLEAR_HTREE, PR_PREEN_OK },
-
- /* Node in HTREE directory has invalid depth */
- { PR_2_HTREE_BAD_DEPTH,
- N_("@p @h %d: %B has @n depth (%N)\n"),
- PROMPT_NONE, 0 },
-
- /* Duplicate directory entry found */
- { PR_2_DUPLICATE_DIRENT,
- N_("Duplicate @E found. "),
- PROMPT_CLEAR, 0 },
-
- /* Non-unique filename found */
- { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
- N_("@E has a non-unique filename.\nRename to %s"),
- PROMPT_NULL, 0 },
-
- /* Duplicate directory entry found */
- { PR_2_REPORT_DUP_DIRENT,
- N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
- PROMPT_NONE, 0 },
-
- /* i_blocks_hi should be zero */
- { PR_2_BLOCKS_HI_ZERO,
- N_("i_blocks_hi @F %N, @s zero.\n"),
- PROMPT_CLEAR, 0 },
-
- /* Unexpected HTREE block */
- { PR_2_UNEXPECTED_HTREE_BLOCK,
- N_("Unexpected @b in @h %d (%q).\n"), PROMPT_CLEAR_HTREE, 0 },
-
- /* Inode found in group where _INODE_UNINIT is set */
- { PR_2_INOREF_BG_INO_UNINIT,
- N_("@E references @i %Di in @g %g where _INODE_UNINIT is set.\n"),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Inode found in group unused inodes area */
- { PR_2_INOREF_IN_UNUSED,
- N_("@E references @i %Di found in @g %g's unused inodes area.\n"),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* i_blocks_hi should be zero */
- { PR_2_I_FILE_ACL_HI_ZERO,
- N_("i_file_acl_hi @F %N, @s zero.\n"),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* Inode too bad */
- { PR_2_INODE_TOOBAD,
- N_("@i %i is badly corrupt (badness value = %N). "),
- PROMPT_CLEAR, PR_PREEN_OK },
-
- /* Pass 3 errors */
-
- /* Pass 3: Checking directory connectivity */
- { PR_3_PASS_HEADER,
- N_("Pass 3: Checking @d connectivity\n"),
- PROMPT_NONE, 0 },
-
- /* Root inode not allocated */
- { PR_3_NO_ROOT_INODE,
- N_("@r not allocated. "),
- PROMPT_ALLOCATE, 0 },
-
- /* No room in lost+found */
- { PR_3_EXPAND_LF_DIR,
- N_("No room in @l @d. "),
- PROMPT_EXPAND, 0 },
-
- /* Unconnected directory inode */
- { PR_3_UNCONNECTED_DIR,
- N_("Unconnected @d @i %i (%p)\n"),
- PROMPT_CONNECT, 0 },
-
- /* /lost+found not found */
- { PR_3_NO_LF_DIR,
- N_("/@l not found. "),
- PROMPT_CREATE, PR_PREEN_OK },
-
- /* .. entry is incorrect */
- { PR_3_BAD_DOT_DOT,
- N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
- PROMPT_FIX, 0 },
-
- /* Bad or non-existent /lost+found. Cannot reconnect */
- { PR_3_NO_LPF,
- N_("Bad or non-existent /@l. Cannot reconnect.\n"),
- PROMPT_NONE, 0 },
-
- /* Could not expand /lost+found */
- { PR_3_CANT_EXPAND_LPF,
- N_("Could not expand /@l: %m\n"),
- PROMPT_NONE, 0 },
-
- /* Could not reconnect inode */
- { PR_3_CANT_RECONNECT,
- N_("Could not reconnect %i: %m\n"),
- PROMPT_NONE, 0 },
-
- /* Error while trying to find /lost+found */
- { PR_3_ERR_FIND_LPF,
- N_("Error while trying to find /@l: %m\n"),
- PROMPT_NONE, 0 },
-
- /* Error in ext2fs_new_block while creating /lost+found */
- { PR_3_ERR_LPF_NEW_BLOCK,
- N_("ext2fs_new_ at b: %m while trying to create /@l @d\n"),
- PROMPT_NONE, 0 },
-
- /* Error in ext2fs_new_inode while creating /lost+found */
- { PR_3_ERR_LPF_NEW_INODE,
- N_("ext2fs_new_ at i: %m while trying to create /@l @d\n"),
- PROMPT_NONE, 0 },
-
- /* Error in ext2fs_new_dir_block while creating /lost+found */
- { PR_3_ERR_LPF_NEW_DIR_BLOCK,
- N_("ext2fs_new_dir_ at b: %m while creating new @d @b\n"),
- PROMPT_NONE, 0 },
-
- /* Error while writing directory block for /lost+found */
- { PR_3_ERR_LPF_WRITE_BLOCK,
- N_("ext2fs_write_dir_ at b: %m while writing the @d @b for /@l\n"),
- PROMPT_NONE, 0 },
-
- /* Error while adjusting inode count */
- { PR_3_ADJUST_INODE,
- N_("Error while adjusting @i count on @i %i\n"),
- PROMPT_NONE, 0 },
-
- /* Couldn't fix parent directory -- error */
- { PR_3_FIX_PARENT_ERR,
- N_("Couldn't fix parent of @i %i: %m\n\n"),
- PROMPT_NONE, 0 },
-
- /* Couldn't fix parent directory -- couldn't find it */
- { PR_3_FIX_PARENT_NOFIND,
- N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
- PROMPT_NONE, 0 },
-
- /* Error allocating inode bitmap */
- { PR_3_ALLOCATE_IBITMAP_ERROR,
- N_("@A @i @B (%N): %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error creating root directory */
- { PR_3_CREATE_ROOT_ERROR,
- N_("Error creating root @d (%s): %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error creating lost and found directory */
- { PR_3_CREATE_LPF_ERROR,
- N_("Error creating /@l @d (%s): %m\n"),
- PROMPT_NONE, 0 },
-
- /* Root inode is not directory; aborting */
- { PR_3_ROOT_NOT_DIR_ABORT,
- N_("@r is not a @d; aborting.\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Cannot proceed without a root inode. */
- { PR_3_NO_ROOT_INODE_ABORT,
- N_("Cannot proceed without a @r.\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Internal error: couldn't find dir_info */
- { PR_3_NO_DIRINFO,
- N_("Internal error: couldn't find dir_info for %i.\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Lost+found not a directory */
- { PR_3_LPF_NOTDIR,
- N_("/@l is not a @d (ino=%i)\n"),
- PROMPT_UNLINK, 0 },
-
- /* Pass 3A Directory Optimization */
-
- /* Pass 3A: Optimizing directories */
- { PR_3A_PASS_HEADER,
- N_("Pass 3A: Optimizing directories\n"),
- PROMPT_NONE, PR_PREEN_NOMSG },
-
- /* Error iterating over directories */
- { PR_3A_OPTIMIZE_ITER,
- N_("Failed to create dirs_to_hash iterator: %m\n"),
- PROMPT_NONE, 0 },
-
- /* Error rehash directory */
- { PR_3A_OPTIMIZE_DIR_ERR,
- N_("Failed to optimize directory %q (%d): %m\n"),
- PROMPT_NONE, 0 },
-
- /* Rehashing dir header */
- { PR_3A_OPTIMIZE_DIR_HEADER,
- N_("Optimizing directories: "),
- PROMPT_NONE, PR_MSG_ONLY },
-
- /* Rehashing directory %d */
- { PR_3A_OPTIMIZE_DIR,
- " %d",
- PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
-
- /* Rehashing dir end */
- { PR_3A_OPTIMIZE_DIR_END,
- "\n",
- PROMPT_NONE, PR_PREEN_NOHDR },
-
- /* Pass 4 errors */
-
- /* Pass 4: Checking reference counts */
- { PR_4_PASS_HEADER,
- N_("Pass 4: Checking reference counts\n"),
- PROMPT_NONE, 0 },
-
- /* Unattached zero-length inode */
- { PR_4_ZERO_LEN_INODE,
- N_("@u @z @i %i. "),
- PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
-
- /* Unattached inode */
- { PR_4_UNATTACHED_INODE,
- N_("@u @i %i\n"),
- PROMPT_CONNECT, 0 },
-
- /* Inode ref count wrong */
- { PR_4_BAD_REF_COUNT,
- N_("@i %i ref count is %Il, @s %N. "),
- PROMPT_FIX, PR_PREEN_OK },
-
- { PR_4_INCONSISTENT_COUNT,
- N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
- "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
- "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
- "They @s the same!\n"),
- PROMPT_NONE, 0 },
-
- /* Pass 5 errors */
-
- /* Pass 5: Checking group summary information */
- { PR_5_PASS_HEADER,
- N_("Pass 5: Checking @g summary information\n"),
- PROMPT_NONE, 0 },
-
- /* Padding at end of inode bitmap is not set. */
- { PR_5_INODE_BMAP_PADDING,
- N_("Padding at end of @i @B is not set. "),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Padding at end of block bitmap is not set. */
- { PR_5_BLOCK_BMAP_PADDING,
- N_("Padding at end of @b @B is not set. "),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Block bitmap differences header */
- { PR_5_BLOCK_BITMAP_HEADER,
- N_("@b @B differences: "),
- PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
-
- /* Block not used, but marked in bitmap */
- { PR_5_BLOCK_UNUSED,
- " -%b",
- PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Block used, but not marked used in bitmap */
- { PR_5_BLOCK_USED,
- " +%b",
- PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Block bitmap differences end */
- { PR_5_BLOCK_BITMAP_END,
- "\n",
- PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Inode bitmap differences header */
- { PR_5_INODE_BITMAP_HEADER,
- N_("@i @B differences: "),
- PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Inode not used, but marked in bitmap */
- { PR_5_INODE_UNUSED,
- " -%i",
- PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Inode used, but not marked used in bitmap */
- { PR_5_INODE_USED,
- " +%i",
- PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Inode bitmap differences end */
- { PR_5_INODE_BITMAP_END,
- "\n",
- PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Free inodes count for group wrong */
- { PR_5_FREE_INODE_COUNT_GROUP,
- N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
- PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Directories count for group wrong */
- { PR_5_FREE_DIR_COUNT_GROUP,
- N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
- PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Free inodes count wrong */
- { PR_5_FREE_INODE_COUNT,
- N_("Free @is count wrong (%i, counted=%j).\n"),
- PROMPT_FIX, PR_PREEN_OK | PR_NO_OK | PR_PREEN_NOMSG },
-
- /* Free blocks count for group wrong */
- { PR_5_FREE_BLOCK_COUNT_GROUP,
- N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
- PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Free blocks count wrong */
- { PR_5_FREE_BLOCK_COUNT,
- N_("Free @bs count wrong (%b, counted=%c).\n"),
- PROMPT_FIX, PR_PREEN_OK | PR_NO_OK | PR_PREEN_NOMSG },
-
- /* Programming error: bitmap endpoints don't match */
- { PR_5_BMAP_ENDPOINTS,
- N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
- "match calculated @B endpoints (%i, %j)\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Internal error: fudging end of bitmap */
- { PR_5_FUDGE_BITMAP_ERROR,
- N_("Internal error: fudging end of bitmap (%N)\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error copying in replacement inode bitmap */
- { PR_5_COPY_IBITMAP_ERROR,
- N_("Error copying in replacement @i @B: %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Error copying in replacement block bitmap */
- { PR_5_COPY_BBITMAP_ERROR,
- N_("Error copying in replacement @b @B: %m\n"),
- PROMPT_NONE, PR_FATAL },
-
- /* Block range not used, but marked in bitmap */
- { PR_5_BLOCK_RANGE_UNUSED,
- " -(%b--%c)",
- PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Block range used, but not marked used in bitmap */
- { PR_5_BLOCK_RANGE_USED,
- " +(%b--%c)",
- PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Inode range not used, but marked in bitmap */
- { PR_5_INODE_RANGE_UNUSED,
- " -(%i--%j)",
- PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Inode range used, but not marked used in bitmap */
- { PR_5_INODE_RANGE_USED,
- " +(%i--%j)",
- PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
-
- /* Group N block(s) in use but group is marked BLOCK_UNINIT */
- { PR_5_BLOCK_UNINIT,
- N_("@g %g @b(s) in use but @g is marked BLOCK_UNINIT\n"),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Group N inode(s) in use but group is marked INODE_UNINIT */
- { PR_5_INODE_UNINIT,
- N_("@g %g @i(s) in use but @g is marked INODE_UNINIT\n"),
- PROMPT_FIX, PR_PREEN_OK },
-
- /* Expand inode */
- { PR_5_EXPAND_EISIZE,
- N_("Expanding @i %i.\n"),
- PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_PREEN_NOMSG },
-
- /* Post-Pass 5 errors */
-
- /* Recreate journal if E2F_FLAG_JOURNAL_INODE flag is set */
- { PR_6_RECREATE_JOURNAL,
- N_("Recreate @j"),
- PROMPT_NULL, PR_PREEN_OK | PR_NO_OK },
-
- { 0 }
-};
-
-/*
- * This is the latch flags register. It allows several problems to be
- * "latched" together. This means that the user has to answer but one
- * question for the set of problems, and all of the associated
- * problems will be either fixed or not fixed.
- */
-static struct latch_descr pr_latch_info[] = {
- { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
- { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
- { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
- { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
- { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
- { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
- { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
- { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
- { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
- { PR_LATCH_BG_CHECKSUM, PR_0_GDT_CSUM_LATCH, 0 },
- { PR_LATCH_EXTENT_HI, PR_1_EXTENT_HI_LATCH, 0 },
- { -1, 0, 0 },
-};
-
-static struct e2fsck_problem *find_problem(problem_t code)
-{
- int i;
-
- for (i=0; problem_table[i].e2p_code; i++) {
- if (problem_table[i].e2p_code == code)
- return &problem_table[i];
- }
- return 0;
-}
-
-static struct latch_descr *find_latch(int code)
-{
- int i;
-
- for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
- if (pr_latch_info[i].latch_code == code)
- return &pr_latch_info[i];
- }
- return 0;
-}
-
-int end_problem_latch(e2fsck_t ctx, int mask)
-{
- struct latch_descr *ldesc;
- struct problem_context pctx;
- int answer = -1;
-
- ldesc = find_latch(mask);
- if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
- clear_problem_context(&pctx);
- answer = fix_problem(ctx, ldesc->end_message, &pctx);
- }
- ldesc->flags &= ~(PRL_VARIABLE);
- return answer;
-}
-
-int set_latch_flags(int mask, int setflags, int clearflags)
-{
- struct latch_descr *ldesc;
-
- ldesc = find_latch(mask);
- if (!ldesc)
- return -1;
- ldesc->flags |= setflags;
- ldesc->flags &= ~clearflags;
- return 0;
-}
-
-int get_latch_flags(int mask, int *value)
-{
- struct latch_descr *ldesc;
-
- ldesc = find_latch(mask);
- if (!ldesc)
- return -1;
- *value = ldesc->flags;
- return 0;
-}
-
-void clear_problem_context(struct problem_context *ctx)
-{
- memset(ctx, 0, sizeof(struct problem_context));
- ctx->blkcount = -1;
- ctx->group = -1;
-}
-
-static void reconfigure_bool(e2fsck_t ctx, struct e2fsck_problem *ptr,
- const char *key, int mask, const char *name)
-{
- int bool;
-
- bool = (ptr->flags & mask);
- profile_get_boolean(ctx->profile, "problems", key, name, bool, &bool);
- if (bool)
- ptr->flags |= mask;
- else
- ptr->flags &= ~mask;
-}
-
-
-int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
-{
- ext2_filsys fs = ctx->fs;
- struct e2fsck_problem *ptr;
- struct latch_descr *ldesc = 0;
- const char *message;
- int def_yn, answer, ans;
- int print_answer = 0;
- int suppress = 0;
-
- ptr = find_problem(code);
- if (!ptr) {
- printf(_("Unhandled error code (0x%x)!\n"), code);
- return 0;
- }
- if (!(ptr->flags & PR_CONFIG)) {
- char key[9], *new_desc;
-
- sprintf(key, "0x%06x", code);
-
- profile_get_string(ctx->profile, "problems", key,
- "description", 0, &new_desc);
- if (new_desc)
- ptr->e2p_description = new_desc;
-
- reconfigure_bool(ctx, ptr, key, PR_PREEN_OK, "preen_ok");
- reconfigure_bool(ctx, ptr, key, PR_NO_OK, "no_ok");
- reconfigure_bool(ctx, ptr, key, PR_NO_DEFAULT, "no_default");
- reconfigure_bool(ctx, ptr, key, PR_MSG_ONLY, "print_message_only");
- reconfigure_bool(ctx, ptr, key, PR_PREEN_NOMSG, "preen_nomessage");
- reconfigure_bool(ctx, ptr, key, PR_NOCOLLATE, "no_collate");
- reconfigure_bool(ctx, ptr, key, PR_NO_NOMSG, "no_nomsg");
- reconfigure_bool(ctx, ptr, key, PR_PREEN_NOHDR, "preen_noheader");
- reconfigure_bool(ctx, ptr, key, PR_FORCE_NO, "force_no");
-
- ptr->flags |= PR_CONFIG;
- }
- def_yn = 1;
- if ((ptr->flags & PR_NO_DEFAULT) ||
- ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
- (ctx->options & E2F_OPT_NO))
- def_yn= 0;
-
- /*
- * Do special latch processing. This is where we ask the
- * latch question, if it exists
- */
- if (ptr->flags & PR_LATCH_MASK) {
- ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
- if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
- ans = fix_problem(ctx, ldesc->question, pctx);
- if (ans == 1)
- ldesc->flags |= PRL_YES;
- if (ans == 0)
- ldesc->flags |= PRL_NO;
- ldesc->flags |= PRL_LATCHED;
- }
- if (ldesc->flags & PRL_SUPPRESS)
- suppress++;
- }
- if ((ptr->flags & PR_PREEN_NOMSG) &&
- (ctx->options & E2F_OPT_PREEN))
- suppress++;
- if ((ptr->flags & PR_NO_NOMSG) &&
- ((ctx->options & E2F_OPT_NO) || (ptr->flags & PR_FORCE_NO)))
- suppress++;
- if (!suppress) {
- message = ptr->e2p_description;
- if ((ctx->options & E2F_OPT_PREEN) &&
- !(ptr->flags & PR_PREEN_NOHDR)) {
- printf("%s: ", ctx->device_name ?
- ctx->device_name : ctx->filesystem_name);
- }
- if (*message)
- print_e2fsck_message(ctx, _(message), pctx, 1, 0);
- }
- if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
- preenhalt(ctx);
-
- if (ptr->flags & PR_FATAL)
- fatal_error(ctx, 0);
-
- if (ptr->prompt == PROMPT_NONE) {
- if (ptr->flags & PR_NOCOLLATE)
- answer = -1;
- else
- answer = def_yn;
- } else {
- if (ptr->flags & PR_FORCE_NO) {
- answer = 0;
- if (!suppress)
- print_answer = 1;
- } else if (ctx->options & E2F_OPT_PREEN) {
- answer = def_yn;
- if (!(ptr->flags & PR_PREEN_NOMSG))
- print_answer = 1;
- } else if ((ptr->flags & PR_LATCH_MASK) &&
- (ldesc->flags & (PRL_YES | PRL_NO))) {
- if (!suppress)
- print_answer = 1;
- if (ldesc->flags & PRL_YES)
- answer = 1;
- else
- answer = 0;
- } else
- answer = ask(ctx, (ptr->prompt == PROMPT_NULL) ? "" :
- _(prompt[(int) ptr->prompt]), def_yn);
- if (!answer && !(ptr->flags & PR_NO_OK))
- ext2fs_unmark_valid(fs);
-
- if (print_answer)
- printf("%s.\n", answer ?
- _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
-
- }
-
- if ((ptr->prompt == PROMPT_ABORT) && answer)
- fatal_error(ctx, 0);
-
- if (ptr->flags & PR_AFTER_CODE)
- answer = fix_problem(ctx, ptr->second_code, pctx);
-
- return answer;
-}
-
-#ifdef UNITTEST
-
-#include <stdlib.h>
-#include <stdio.h>
-
-errcode_t
-profile_get_boolean(profile_t profile, const char *name, const char *subname,
- const char *subsubname, int def_val, int *ret_boolean)
-{
- return 0;
-}
-
-void print_e2fsck_message(e2fsck_t ctx, const char *msg,
- struct problem_context *pctx, int first,
- int recurse)
-{
- return;
-}
-
-void fatal_error(e2fsck_t ctx, const char *msg)
-{
- return;
-}
-
-void preenhalt(e2fsck_t ctx)
-{
- return;
-}
-
-errcode_t
-profile_get_string(profile_t profile, const char *name, const char *subname,
- const char *subsubname, const char *def_val,
- char **ret_string)
-{
- return 0;
-}
-
-int ask (e2fsck_t ctx, const char * string, int def)
-{
- return 0;
-}
-
-int verify_problem_table(e2fsck_t ctx)
-{
- struct e2fsck_problem *curr, *prev = NULL;
- int rc = 0;
-
- for (prev = NULL, curr = problem_table; curr->e2p_code; prev = curr++) {
- if (prev == NULL)
- continue;
-
- if (curr->e2p_code > prev->e2p_code)
- continue;
-
- if (curr->e2p_code == prev->e2p_code)
- fprintf(stderr, "*** Duplicate in problem table:\n");
- else
- fprintf(stderr, "*** Unordered problem table:\n");
-
- fprintf(stderr, "curr code = 0x%08x: %s\n",
- curr->e2p_code, curr->e2p_description);
- fprintf(stderr, "*** prev code = 0x%08x: %s\n",
- prev->e2p_code, prev->e2p_description);
-
- fprintf(stderr, "*** This is a %sprogramming error in e2fsck\n",
- (curr->e2p_code == prev->e2p_code) ? "fatal " : "");
-
- rc = 1;
- }
-
- return rc;
-}
-
-int main(int argc, char *argv[])
-{
- e2fsck_t ctx;
- int rc;
-
- rc = verify_problem_table(ctx);
- if (rc == 0)
- printf("e2fsck problem table verified\n");
-
- return rc;
-}
-#endif /* UNITTEST */
diff --git a/e2fsck/super.c.orig b/e2fsck/super.c.orig
deleted file mode 100644
index 19d7153..0000000
--- a/e2fsck/super.c.orig
+++ /dev/null
@@ -1,967 +0,0 @@
-/*
- * e2fsck.c - superblock checks
- *
- * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU Public
- * License.
- * %End-Header%
- */
-
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-
-#ifndef EXT2_SKIP_UUID
-#include "uuid/uuid.h"
-#endif
-#include "e2fsck.h"
-#include "problem.h"
-
-#define MIN_CHECK 1
-#define MAX_CHECK 2
-
-static void check_super_value(e2fsck_t ctx, const char *descr,
- unsigned long value, int flags,
- unsigned long min_val, unsigned long max_val)
-{
- struct problem_context pctx;
-
- if (((flags & MIN_CHECK) && (value < min_val)) ||
- ((flags & MAX_CHECK) && (value > max_val))) {
- clear_problem_context(&pctx);
- pctx.num = value;
- pctx.str = descr;
- fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
- ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
- }
-}
-
-/*
- * helper function to release an inode
- */
-struct process_block_struct {
- e2fsck_t ctx;
- char *buf;
- struct problem_context *pctx;
- int truncating;
- int truncate_offset;
- e2_blkcnt_t truncate_block;
- int truncated_blocks;
- int abort;
- errcode_t errcode;
-};
-
-static int release_inode_block(ext2_filsys fs,
- blk64_t *block_nr,
- e2_blkcnt_t blockcnt,
- blk64_t ref_blk EXT2FS_ATTR((unused)),
- int ref_offset EXT2FS_ATTR((unused)),
- void *priv_data)
-{
- struct process_block_struct *pb;
- e2fsck_t ctx;
- struct problem_context *pctx;
- blk64_t blk = *block_nr;
- int retval = 0;
-
- pb = (struct process_block_struct *) priv_data;
- ctx = pb->ctx;
- pctx = pb->pctx;
-
- pctx->blk = blk;
- pctx->blkcount = blockcnt;
-
- if (HOLE_BLKADDR(blk))
- return 0;
-
- if ((blk < fs->super->s_first_data_block) ||
- (blk >= ext2fs_blocks_count(fs->super))) {
- fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
- return_abort:
- pb->abort = 1;
- return BLOCK_ABORT;
- }
-
- if (!ext2fs_test_block_bitmap2(fs->block_map, blk)) {
- fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
- goto return_abort;
- }
-
- /*
- * If we are deleting an orphan, then we leave the fields alone.
- * If we are truncating an orphan, then update the inode fields
- * and clean up any partial block data.
- */
- if (pb->truncating) {
- /*
- * We only remove indirect blocks if they are
- * completely empty.
- */
- if (blockcnt < 0) {
- int i, limit;
- blk_t *bp;
-
- pb->errcode = io_channel_read_blk64(fs->io, blk, 1,
- pb->buf);
- if (pb->errcode)
- goto return_abort;
-
- limit = fs->blocksize >> 2;
- for (i = 0, bp = (blk_t *) pb->buf;
- i < limit; i++, bp++)
- if (*bp)
- return 0;
- }
- /*
- * We don't remove direct blocks until we've reached
- * the truncation block.
- */
- if (blockcnt >= 0 && blockcnt < pb->truncate_block)
- return 0;
- /*
- * If part of the last block needs truncating, we do
- * it here.
- */
- if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
- pb->errcode = io_channel_read_blk64(fs->io, blk, 1,
- pb->buf);
- if (pb->errcode)
- goto return_abort;
- memset(pb->buf + pb->truncate_offset, 0,
- fs->blocksize - pb->truncate_offset);
- pb->errcode = io_channel_write_blk64(fs->io, blk, 1,
- pb->buf);
- if (pb->errcode)
- goto return_abort;
- }
- pb->truncated_blocks++;
- *block_nr = 0;
- retval |= BLOCK_CHANGED;
- }
-
- ext2fs_block_alloc_stats2(fs, blk, -1);
- return retval;
-}
-
-/*
- * This function releases an inode. Returns 1 if an inconsistency was
- * found. If the inode has a link count, then it is being truncated and
- * not deleted.
- */
-static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
- struct ext2_inode *inode, char *block_buf,
- struct problem_context *pctx)
-{
- struct process_block_struct pb;
- ext2_filsys fs = ctx->fs;
- errcode_t retval;
- __u32 count;
-
- if (!ext2fs_inode_has_valid_blocks(inode))
- return 0;
-
- pb.buf = block_buf + 3 * ctx->fs->blocksize;
- pb.ctx = ctx;
- pb.abort = 0;
- pb.errcode = 0;
- pb.pctx = pctx;
- if (inode->i_links_count) {
- pb.truncating = 1;
- pb.truncate_block = (e2_blkcnt_t)
- ((EXT2_I_SIZE(inode) + fs->blocksize - 1) /
- fs->blocksize);
- pb.truncate_offset = inode->i_size % fs->blocksize;
- } else {
- pb.truncating = 0;
- pb.truncate_block = 0;
- pb.truncate_offset = 0;
- }
- pb.truncated_blocks = 0;
- retval = ext2fs_block_iterate3(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
- block_buf, release_inode_block, &pb);
- if (retval) {
- com_err("release_inode_blocks", retval,
- _("while calling ext2fs_block_iterate for inode %d"),
- ino);
- return 1;
- }
- if (pb.abort)
- return 1;
-
- /* Refresh the inode since ext2fs_block_iterate may have changed it */
- e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
-
- if (pb.truncated_blocks)
- ext2fs_iblk_sub_blocks(fs, inode, pb.truncated_blocks);
-
- if (ext2fs_file_acl_block(inode)) {
- retval = ext2fs_adjust_ea_refcount2(fs, ext2fs_file_acl_block(inode),
- block_buf, -1, &count);
- if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
- retval = 0;
- count = 1;
- }
- if (retval) {
- com_err("release_inode_blocks", retval,
- _("while calling ext2fs_adjust_ea_refcount2 for inode %d"),
- ino);
- return 1;
- }
- if (count == 0)
- ext2fs_block_alloc_stats2(fs,
- ext2fs_file_acl_block(inode),
- -1);
- ext2fs_file_acl_block_set(inode, 0);
- }
- return 0;
-}
-
-/*
- * This function releases all of the orphan inodes. It returns 1 if
- * it hit some error, and 0 on success.
- */
-static int release_orphan_inodes(e2fsck_t ctx)
-{
- ext2_filsys fs = ctx->fs;
- ext2_ino_t ino, next_ino;
- struct ext2_inode inode;
- struct problem_context pctx;
- char *block_buf;
-
- if ((ino = fs->super->s_last_orphan) == 0)
- return 0;
-
- /*
- * Win or lose, we won't be using the head of the orphan inode
- * list again.
- */
- fs->super->s_last_orphan = 0;
- ext2fs_mark_super_dirty(fs);
-
- /*
- * If the filesystem contains errors, don't run the orphan
- * list, since the orphan list can't be trusted; and we're
- * going to be running a full e2fsck run anyway...
- */
- if (fs->super->s_state & EXT2_ERROR_FS)
- return 0;
-
- if ((ino < EXT2_FIRST_INODE(fs->super)) ||
- (ino > fs->super->s_inodes_count)) {
- clear_problem_context(&pctx);
- pctx.ino = ino;
- fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
- return 1;
- }
-
- block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
- "block iterate buffer");
- e2fsck_read_bitmaps(ctx);
-
- while (ino) {
- e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
- clear_problem_context(&pctx);
- pctx.ino = ino;
- pctx.inode = &inode;
- pctx.str = inode.i_links_count ? _("Truncating") :
- _("Clearing");
-
- fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
-
- next_ino = inode.i_dtime;
- if (next_ino &&
- ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
- (next_ino > fs->super->s_inodes_count))) {
- pctx.ino = next_ino;
- fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
- goto return_abort;
- }
-
- if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
- goto return_abort;
-
- if (!inode.i_links_count) {
- ext2fs_inode_alloc_stats2(fs, ino, -1,
- LINUX_S_ISDIR(inode.i_mode));
- inode.i_dtime = ctx->now;
- } else {
- inode.i_dtime = 0;
- }
- e2fsck_write_inode(ctx, ino, &inode, "delete_file");
- ino = next_ino;
- }
- ext2fs_free_mem(&block_buf);
- return 0;
-return_abort:
- ext2fs_free_mem(&block_buf);
- return 1;
-}
-
-/*
- * Check the resize inode to make sure it is sane. We check both for
- * the case where on-line resizing is not enabled (in which case the
- * resize inode should be cleared) as well as the case where on-line
- * resizing is enabled.
- */
-void check_resize_inode(e2fsck_t ctx)
-{
- ext2_filsys fs = ctx->fs;
- struct ext2_inode inode;
- struct problem_context pctx;
- int i, gdt_off, ind_off;
- dgrp_t j;
- blk64_t blk, pblk, expect;
- __u32 *dind_buf = 0, *ind_buf;
- errcode_t retval;
-
- clear_problem_context(&pctx);
-
- /*
- * If the resize inode feature isn't set, then
- * s_reserved_gdt_blocks must be zero.
- */
- if (!(fs->super->s_feature_compat &
- EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
- if (fs->super->s_reserved_gdt_blocks) {
- pctx.num = fs->super->s_reserved_gdt_blocks;
- if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
- &pctx)) {
- fs->super->s_reserved_gdt_blocks = 0;
- ext2fs_mark_super_dirty(fs);
- }
- }
- }
-
- /* Read the resize inode */
- pctx.ino = EXT2_RESIZE_INO;
- retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
- if (retval) {
- if (fs->super->s_feature_compat &
- EXT2_FEATURE_COMPAT_RESIZE_INODE)
- ctx->flags |= E2F_FLAG_RESIZE_INODE;
- return;
- }
-
- /*
- * If the resize inode feature isn't set, check to make sure
- * the resize inode is cleared; then we're done.
- */
- if (!(fs->super->s_feature_compat &
- EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
- for (i=0; i < EXT2_N_BLOCKS; i++) {
- if (inode.i_block[i])
- break;
- }
- if ((i < EXT2_N_BLOCKS) &&
- fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
- memset(&inode, 0, sizeof(inode));
- e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
- "clear_resize");
- }
- return;
- }
-
- /*
- * The resize inode feature is enabled; check to make sure the
- * only block in use is the double indirect block
- */
- blk = inode.i_block[EXT2_DIND_BLOCK];
- for (i=0; i < EXT2_N_BLOCKS; i++) {
- if (i != EXT2_DIND_BLOCK && inode.i_block[i])
- break;
- }
- if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
- !(inode.i_mode & LINUX_S_IFREG) ||
- (blk < fs->super->s_first_data_block ||
- blk >= ext2fs_blocks_count(fs->super))) {
- resize_inode_invalid:
- if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
- memset(&inode, 0, sizeof(inode));
- e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
- "clear_resize");
- ctx->flags |= E2F_FLAG_RESIZE_INODE;
- }
- if (!(ctx->options & E2F_OPT_READONLY)) {
- fs->super->s_state &= ~EXT2_VALID_FS;
- ext2fs_mark_super_dirty(fs);
- }
- goto cleanup;
- }
- dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
- "resize dind buffer");
- ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
-
- retval = ext2fs_read_ind_block(fs, blk, dind_buf);
- if (retval)
- goto resize_inode_invalid;
-
- gdt_off = fs->desc_blocks;
- pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
- for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
- i++, gdt_off++, pblk++) {
- gdt_off %= fs->blocksize/4;
- if (dind_buf[gdt_off] != pblk)
- goto resize_inode_invalid;
- retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
- if (retval)
- goto resize_inode_invalid;
- ind_off = 0;
- for (j = 1; j < fs->group_desc_count; j++) {
- if (!ext2fs_bg_has_super(fs, j))
- continue;
- expect = pblk + (j * fs->super->s_blocks_per_group);
- if (ind_buf[ind_off] != expect)
- goto resize_inode_invalid;
- ind_off++;
- }
- }
-
-cleanup:
- if (dind_buf)
- ext2fs_free_mem(&dind_buf);
-
- }
-
-/*
- * This function checks the dirhash signed/unsigned hint if necessary.
- */
-static void e2fsck_fix_dirhash_hint(e2fsck_t ctx)
-{
- struct ext2_super_block *sb = ctx->fs->super;
- struct problem_context pctx;
- char c;
-
- if ((ctx->options & E2F_OPT_READONLY) ||
- !(sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
- (sb->s_flags & (EXT2_FLAGS_SIGNED_HASH|EXT2_FLAGS_UNSIGNED_HASH)))
- return;
-
- c = (char) 255;
-
- clear_problem_context(&pctx);
- if (fix_problem(ctx, PR_0_DIRHASH_HINT, &pctx)) {
- if (((int) c) == -1) {
- sb->s_flags |= EXT2_FLAGS_SIGNED_HASH;
- } else {
- sb->s_flags |= EXT2_FLAGS_UNSIGNED_HASH;
- }
- ext2fs_mark_super_dirty(ctx->fs);
- }
-}
-
-
-void check_super_block(e2fsck_t ctx)
-{
- ext2_filsys fs = ctx->fs;
- blk64_t first_block, last_block;
- struct ext2_super_block *sb = fs->super;
- problem_t problem;
- blk64_t blocks_per_group = fs->super->s_blocks_per_group;
- __u32 bpg_max;
- int inodes_per_block;
- int ipg_max;
- int inode_size;
- int accept_time_fudge;
- int broken_system_clock;
- dgrp_t i;
- blk64_t should_be;
- struct problem_context pctx;
- blk64_t free_blocks = 0;
- ino_t free_inodes = 0;
- int csum_flag, clear_test_fs_flag;
-
- inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
- ipg_max = inodes_per_block * (blocks_per_group - 4);
- if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
- ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
- bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
- if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
- bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
-
- ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
- sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
- ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
- sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
- ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
- sizeof(int) * fs->group_desc_count, "invalid_inode_table");
-
- clear_problem_context(&pctx);
-
- /*
- * Verify the super block constants...
- */
- check_super_value(ctx, "inodes_count", sb->s_inodes_count,
- MIN_CHECK, 1, 0);
- check_super_value(ctx, "blocks_count", ext2fs_blocks_count(sb),
- MIN_CHECK, 1, 0);
- check_super_value(ctx, "first_data_block", sb->s_first_data_block,
- MAX_CHECK, 0, ext2fs_blocks_count(sb));
- check_super_value(ctx, "log_block_size", sb->s_log_block_size,
- MIN_CHECK | MAX_CHECK, 0,
- EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
- check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
- MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
- check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
- MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
- bpg_max);
- check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
- MIN_CHECK | MAX_CHECK, 8, bpg_max);
- check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
- MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
- check_super_value(ctx, "r_blocks_count", ext2fs_r_blocks_count(sb),
- MAX_CHECK, 0, ext2fs_blocks_count(sb) / 2);
- check_super_value(ctx, "reserved_gdt_blocks",
- sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
- fs->blocksize/4);
- if (sb->s_rev_level > EXT2_GOOD_OLD_REV)
- check_super_value(ctx, "first_ino", sb->s_first_ino,
- MIN_CHECK | MAX_CHECK,
- EXT2_GOOD_OLD_FIRST_INO, sb->s_inodes_count);
- inode_size = EXT2_INODE_SIZE(sb);
- check_super_value(ctx, "inode_size",
- inode_size, MIN_CHECK | MAX_CHECK,
- EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
- if (inode_size & (inode_size - 1)) {
- pctx.num = inode_size;
- pctx.str = "inode_size";
- fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
- ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
- return;
- }
-
- if ((ctx->flags & E2F_FLAG_GOT_DEVSIZE) &&
- (ctx->num_blocks < ext2fs_blocks_count(sb))) {
- pctx.blk = ext2fs_blocks_count(sb);
- pctx.blk2 = ctx->num_blocks;
- if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
- }
-
- if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
- pctx.blk = EXT2_BLOCK_SIZE(sb);
- pctx.blk2 = EXT2_FRAG_SIZE(sb);
- fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
-
- should_be = sb->s_frags_per_group >>
- (sb->s_log_block_size - sb->s_log_frag_size);
- if (sb->s_blocks_per_group != should_be) {
- pctx.blk = sb->s_blocks_per_group;
- pctx.blk2 = should_be;
- fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
-
- should_be = (sb->s_log_block_size == 0) ? 1 : 0;
- if (sb->s_first_data_block != should_be) {
- pctx.blk = sb->s_first_data_block;
- pctx.blk2 = should_be;
- fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
- ctx->flags |= E2F_FLAG_ABORT;
- return;
- }
-
- should_be = sb->s_inodes_per_group * fs->group_desc_count;
- if (sb->s_inodes_count != should_be) {
- pctx.ino = sb->s_inodes_count;
- pctx.ino2 = should_be;
- if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
- sb->s_inodes_count = should_be;
- ext2fs_mark_super_dirty(fs);
- }
- }
-
- /*
- * Verify the group descriptors....
- */
- first_block = sb->s_first_data_block;
- last_block = ext2fs_blocks_count(sb)-1;
-
- csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
- EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
- for (i = 0; i < fs->group_desc_count; i++) {
- pctx.group = i;
-
- if (!EXT2_HAS_INCOMPAT_FEATURE(fs->super,
- EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
- first_block = ext2fs_group_first_block2(fs, i);
- last_block = ext2fs_group_last_block2(fs, i);
- }
-
- if ((ext2fs_block_bitmap_loc(fs, i) < first_block) ||
- (ext2fs_block_bitmap_loc(fs, i) > last_block)) {
- pctx.blk = ext2fs_block_bitmap_loc(fs, i);
- if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
- ext2fs_block_bitmap_loc_set(fs, i, 0);
- }
- if (ext2fs_block_bitmap_loc(fs, i) == 0) {
- ctx->invalid_block_bitmap_flag[i]++;
- ctx->invalid_bitmaps++;
- }
- if ((ext2fs_inode_bitmap_loc(fs, i) < first_block) ||
- (ext2fs_inode_bitmap_loc(fs, i) > last_block)) {
- pctx.blk = ext2fs_inode_bitmap_loc(fs, i);
- if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
- ext2fs_inode_bitmap_loc_set(fs, i, 0);
- }
- if (ext2fs_inode_bitmap_loc(fs, i) == 0) {
- ctx->invalid_inode_bitmap_flag[i]++;
- ctx->invalid_bitmaps++;
- }
- if ((ext2fs_inode_table_loc(fs, i) < first_block) ||
- ((ext2fs_inode_table_loc(fs, i) +
- fs->inode_blocks_per_group - 1) > last_block)) {
- pctx.blk = ext2fs_inode_table_loc(fs, i);
- if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
- ext2fs_inode_table_loc_set(fs, i, 0);
- }
- if (ext2fs_inode_table_loc(fs, i) == 0) {
- ctx->invalid_inode_table_flag[i]++;
- ctx->invalid_bitmaps++;
- }
- free_blocks += ext2fs_bg_free_blocks_count(fs, i);
- free_inodes += ext2fs_bg_free_inodes_count(fs, i);
-
- if ((ext2fs_bg_free_blocks_count(fs, i) > sb->s_blocks_per_group) ||
- (ext2fs_bg_free_inodes_count(fs, i) > sb->s_inodes_per_group) ||
- (ext2fs_bg_used_dirs_count(fs, i) > sb->s_inodes_per_group))
- ext2fs_unmark_valid(fs);
-
- should_be = 0;
- if (!ext2fs_group_desc_csum_verify(fs, i)) {
- if (fix_problem(ctx, PR_0_GDT_CSUM, &pctx)) {
- ext2fs_bg_flags_clear(fs, i, EXT2_BG_BLOCK_UNINIT);
- ext2fs_bg_flags_clear(fs, i, EXT2_BG_INODE_UNINIT);
- ext2fs_bg_itable_unused_set(fs, i, 0);
- should_be = 1;
- }
- ext2fs_unmark_valid(fs);
- }
-
- if (!csum_flag &&
- (ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) ||
- ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT) ||
- ext2fs_bg_itable_unused(fs, i) != 0)) {
- if (fix_problem(ctx, PR_0_GDT_UNINIT, &pctx)) {
- ext2fs_bg_flags_clear(fs, i, EXT2_BG_BLOCK_UNINIT);
- ext2fs_bg_flags_clear(fs, i, EXT2_BG_INODE_UNINIT);
- ext2fs_bg_itable_unused_set(fs, i, 0);
- should_be = 1;
- }
- ext2fs_unmark_valid(fs);
- }
-
- if (i == fs->group_desc_count - 1 &&
- ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT)) {
- if (fix_problem(ctx, PR_0_BB_UNINIT_LAST, &pctx)) {
- ext2fs_bg_flags_clear(fs, i, EXT2_BG_BLOCK_UNINIT);
- should_be = 1;
- }
- ext2fs_unmark_valid(fs);
- }
-
- if (ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT) &&
- !ext2fs_bg_flags_test(fs, i, EXT2_BG_INODE_UNINIT)) {
- if (fix_problem(ctx, PR_0_BB_UNINIT_IB_INIT, &pctx)) {
- ext2fs_bg_flags_clear(fs, i, EXT2_BG_BLOCK_UNINIT);
- should_be = 1;
- }
- ext2fs_unmark_valid(fs);
- }
-
- if (csum_flag &&
- (ext2fs_bg_itable_unused(fs, i) > ext2fs_bg_free_inodes_count(fs, i) ||
- ext2fs_bg_itable_unused(fs, i) > sb->s_inodes_per_group)) {
- pctx.blk = ext2fs_bg_itable_unused(fs, i);
- if (fix_problem(ctx, PR_0_GDT_ITABLE_UNUSED, &pctx)) {
- ext2fs_bg_itable_unused_set(fs, i, 0);
- should_be = 1;
- }
- ext2fs_unmark_valid(fs);
- }
-
- if (should_be)
- ext2fs_group_desc_csum_set(fs, i);
- /* If the user aborts e2fsck by typing ^C, stop right away */
- if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
- return;
- }
-
- /*
- * Update the global counts from the block group counts. This
- * is needed for an experimental patch which eliminates
- * locking the entire filesystem when allocating blocks or
- * inodes; if the filesystem is not unmounted cleanly, the
- * global counts may not be accurate.
- */
- if ((free_blocks != ext2fs_free_blocks_count(sb)) ||
- (free_inodes != sb->s_free_inodes_count)) {
- if (ctx->options & E2F_OPT_READONLY)
- ext2fs_unmark_valid(fs);
- else {
- ext2fs_free_blocks_count_set(sb, free_blocks);
- sb->s_free_inodes_count = free_inodes;
- ext2fs_mark_super_dirty(fs);
- }
- }
-
- if ((ext2fs_free_blocks_count(sb) > ext2fs_blocks_count(sb)) ||
- (sb->s_free_inodes_count > sb->s_inodes_count))
- ext2fs_unmark_valid(fs);
-
-
- /*
- * If we have invalid bitmaps, set the error state of the
- * filesystem.
- */
- if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
- sb->s_state &= ~EXT2_VALID_FS;
- ext2fs_mark_super_dirty(fs);
- }
-
- clear_problem_context(&pctx);
-
-#ifndef EXT2_SKIP_UUID
- /*
- * If the UUID field isn't assigned, assign it.
- */
- if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
- if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
- uuid_generate(sb->s_uuid);
- ext2fs_mark_super_dirty(fs);
- fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
- }
- }
-#endif
-
- /*
- * Check to see if we should disable the test_fs flag
- */
- profile_get_boolean(ctx->profile, "options",
- "clear_test_fs_flag", 0, 1,
- &clear_test_fs_flag);
- if (!(ctx->options & E2F_OPT_READONLY) &&
- clear_test_fs_flag &&
- (fs->super->s_flags & EXT2_FLAGS_TEST_FILESYS) &&
- (fs_proc_check("ext4") || check_for_modules("ext4"))) {
- if (fix_problem(ctx, PR_0_CLEAR_TESTFS_FLAG, &pctx)) {
- fs->super->s_flags &= ~EXT2_FLAGS_TEST_FILESYS;
- ext2fs_mark_super_dirty(fs);
- fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
- }
- }
-
- /*
- * For the Hurd, check to see if the filetype option is set,
- * since it doesn't support it.
- */
- if (!(ctx->options & E2F_OPT_READONLY) &&
- fs->super->s_creator_os == EXT2_OS_HURD &&
- (fs->super->s_feature_incompat &
- EXT2_FEATURE_INCOMPAT_FILETYPE)) {
- if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
- fs->super->s_feature_incompat &=
- ~EXT2_FEATURE_INCOMPAT_FILETYPE;
- ext2fs_mark_super_dirty(fs);
- fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
- }
- }
-
- /*
- * If we have any of the compatibility flags set, we need to have a
- * revision 1 filesystem. Most kernels will not check the flags on
- * a rev 0 filesystem and we may have corruption issues because of
- * the incompatible changes to the filesystem.
- */
- if (!(ctx->options & E2F_OPT_READONLY) &&
- fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
- (fs->super->s_feature_compat ||
- fs->super->s_feature_ro_compat ||
- fs->super->s_feature_incompat) &&
- fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
- ext2fs_update_dynamic_rev(fs);
- ext2fs_mark_super_dirty(fs);
- fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
- }
-
- /*
- * Clean up any orphan inodes, if present.
- */
- if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
- fs->super->s_state &= ~EXT2_VALID_FS;
- ext2fs_mark_super_dirty(fs);
- }
-
- /*
- * Unfortunately, due to Windows' unfortunate design decision
- * to configure the hardware clock to tick localtime, instead
- * of the more proper and less error-prone UTC time, many
- * users end up in the situation where the system clock is
- * incorrectly set at the time when e2fsck is run.
- *
- * Historically this was usually due to some distributions
- * having buggy init scripts and/or installers that didn't
- * correctly detect this case and take appropriate
- * countermeasures. However, it's still possible, despite the
- * best efforts of init script and installer authors to not be
- * able to detect this misconfiguration, usually due to a
- * buggy or misconfigured virtualization manager or the
- * installer not having access to a network time server during
- * the installation process. So by default, we allow the
- * superblock times to be fudged by up to 24 hours. This can
- * be disabled by setting options.accept_time_fudge to the
- * boolean value of false in e2fsck.conf. We also support
- * options.buggy_init_scripts for backwards compatibility.
- */
- profile_get_boolean(ctx->profile, "options", "accept_time_fudge",
- 0, 1, &accept_time_fudge);
- profile_get_boolean(ctx->profile, "options", "buggy_init_scripts",
- 0, accept_time_fudge, &accept_time_fudge);
- ctx->time_fudge = accept_time_fudge ? 86400 : 0;
-
- profile_get_boolean(ctx->profile, "options", "broken_system_clock",
- 0, 0, &broken_system_clock);
-
- /*
- * Check to see if the superblock last mount time or last
- * write time is in the future.
- */
- if (!broken_system_clock &&
- EXT4_XTIME_FUTURE(ctx, fs->super, fs->super->s_mtime, 0)) {
- pctx.num = fs->super->s_mtime;
- problem = PR_0_FUTURE_SB_LAST_MOUNT;
- if (fs->super->s_mtime <= (__u32) ctx->now + ctx->time_fudge)
- problem = PR_0_FUTURE_SB_LAST_MOUNT_FUDGED;
- if (fix_problem(ctx, problem, &pctx)) {
- fs->super->s_mtime = ctx->now;
- ext2fs_mark_super_dirty(fs);
- }
- }
- if (!broken_system_clock &&
- EXT4_XTIME_FUTURE(ctx, fs->super, fs->super->s_wtime, 0)) {
- pctx.num = fs->super->s_wtime;
- problem = PR_0_FUTURE_SB_LAST_WRITE;
- if (fs->super->s_wtime <= (__u32) ctx->now + ctx->time_fudge)
- problem = PR_0_FUTURE_SB_LAST_WRITE_FUDGED;
- if (fix_problem(ctx, problem, &pctx)) {
- fs->super->s_wtime = ctx->now;
- ext2fs_mark_super_dirty(fs);
- }
- }
-
- /*
- * Move the ext3 journal file, if necessary.
- */
- e2fsck_move_ext3_journal(ctx);
-
- /*
- * Fix journal hint, if necessary
- */
- e2fsck_fix_ext3_journal_hint(ctx);
-
- /*
- * Add dirhash hint if necessary
- */
- e2fsck_fix_dirhash_hint(ctx);
-
- return;
-}
-
-/*
- * Check to see if we should backup the master sb to the backup super
- * blocks. Returns non-zero if the sb should be backed up.
- */
-
-/*
- * A few flags are set on the fly by the kernel, but only in the
- * primary superblock. This is actually a bad thing, and we should
- * try to discourage it in the future. In particular, for the newer
- * ext4 files, especially EXT4_FEATURE_RO_COMPAT_DIR_NLINK and
- * EXT3_FEATURE_INCOMPAT_EXTENTS. So some of these may go away in the
- * future. EXT3_FEATURE_INCOMPAT_RECOVER may also get set when
- * copying the primary superblock during online resize.
- *
- * The kernel will set EXT2_FEATURE_COMPAT_EXT_ATTR, but
- * unfortunately, we shouldn't ignore it since if it's not set in the
- * backup, the extended attributes in the filesystem will be stripped
- * away.
- */
-#define FEATURE_RO_COMPAT_IGNORE (EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
- EXT4_FEATURE_RO_COMPAT_DIR_NLINK)
-#define FEATURE_INCOMPAT_IGNORE (EXT3_FEATURE_INCOMPAT_EXTENTS| \
- EXT3_FEATURE_INCOMPAT_RECOVER)
-
-int check_backup_super_block(e2fsck_t ctx)
-{
- ext2_filsys fs = ctx->fs;
- errcode_t retval;
- dgrp_t g;
- blk64_t sb;
- int ret = 0;
- char buf[SUPERBLOCK_SIZE];
- struct ext2_super_block *backup_sb;
-
- /*
- * If we are already writing out the backup blocks, then we
- * don't need to test. Also, if the filesystem is invalid, or
- * the check was aborted or cancelled, we also don't want to
- * do the backup. If the filesystem was opened read-only then
- * we can't do the backup.
- */
- if (((fs->flags & EXT2_FLAG_MASTER_SB_ONLY) == 0) ||
- !ext2fs_test_valid(fs) ||
- (fs->super->s_state & EXT2_ERROR_FS) ||
- (ctx->flags & (E2F_FLAG_ABORT | E2F_FLAG_CANCEL)) ||
- (ctx->options & E2F_OPT_READONLY))
- return 0;
-
- for (g = 1; g < fs->group_desc_count; g++) {
- if (!ext2fs_bg_has_super(fs, g))
- continue;
-
- sb = fs->super->s_first_data_block +
- (g * fs->super->s_blocks_per_group);
-
- retval = io_channel_read_blk(fs->io, sb, -SUPERBLOCK_SIZE,
- buf);
- if (retval)
- continue;
- backup_sb = (struct ext2_super_block *) buf;
-#ifdef WORDS_BIGENDIAN
- ext2fs_swap_super(backup_sb);
-#endif
- if ((backup_sb->s_magic != EXT2_SUPER_MAGIC) ||
- (backup_sb->s_rev_level > EXT2_LIB_CURRENT_REV) ||
- ((backup_sb->s_log_block_size + EXT2_MIN_BLOCK_LOG_SIZE) >
- EXT2_MAX_BLOCK_LOG_SIZE) ||
- (EXT2_INODE_SIZE(backup_sb) < EXT2_GOOD_OLD_INODE_SIZE))
- continue;
-
-#define SUPER_INCOMPAT_DIFFERENT(x) \
- ((fs->super->x & ~FEATURE_INCOMPAT_IGNORE) != \
- (backup_sb->x & ~FEATURE_INCOMPAT_IGNORE))
-#define SUPER_RO_COMPAT_DIFFERENT(x) \
- ((fs->super->x & ~FEATURE_RO_COMPAT_IGNORE) != \
- (backup_sb->x & ~FEATURE_RO_COMPAT_IGNORE))
-#define SUPER_DIFFERENT(x) \
- (fs->super->x != backup_sb->x)
-
- if (SUPER_DIFFERENT(s_feature_compat) ||
- SUPER_INCOMPAT_DIFFERENT(s_feature_incompat) ||
- SUPER_RO_COMPAT_DIFFERENT(s_feature_ro_compat) ||
- SUPER_DIFFERENT(s_blocks_count) ||
- SUPER_DIFFERENT(s_inodes_count) ||
- memcmp(fs->super->s_uuid, backup_sb->s_uuid,
- sizeof(fs->super->s_uuid)))
- ret = 1;
- break;
- }
- return ret;
-}
diff --git a/lib/e2p/feature.c.orig b/lib/e2p/feature.c.orig
deleted file mode 100644
index d3d6423..0000000
--- a/lib/e2p/feature.c.orig
+++ /dev/null
@@ -1,389 +0,0 @@
-/*
- * feature.c --- convert between features and strings
- *
- * Copyright (C) 1999 Theodore Ts'o <tytso at mit.edu>
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU Library
- * General Public License, version 2.
- * %End-Header%
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include "e2p.h"
-#include <ext2fs/ext2fs.h>
-#include <ext2fs/jfs_user.h>
-
-struct feature {
- int compat;
- unsigned int mask;
- const char *string;
-};
-
-static struct feature feature_list[] = {
- { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_PREALLOC,
- "dir_prealloc" },
- { E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL,
- "has_journal" },
- { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_IMAGIC_INODES,
- "imagic_inodes" },
- { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_EXT_ATTR,
- "ext_attr" },
- { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_INDEX,
- "dir_index" },
- { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_RESIZE_INODE,
- "resize_inode" },
- { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_LAZY_BG,
- "lazy_bg" },
-
- { E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER,
- "sparse_super" },
- { E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_LARGE_FILE,
- "large_file" },
- { E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_HUGE_FILE,
- "huge_file" },
- { E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_GDT_CSUM,
- "uninit_bg" },
- { E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_GDT_CSUM,
- "uninit_groups" },
- { E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_DIR_NLINK,
- "dir_nlink" },
- { E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE,
- "extra_isize" },
-
- { E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_COMPRESSION,
- "compression" },
- { E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_FILETYPE,
- "filetype" },
- { E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_RECOVER,
- "needs_recovery" },
- { E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_JOURNAL_DEV,
- "journal_dev" },
- { E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_EXTENTS,
- "extent" },
- { E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_EXTENTS,
- "extents" },
- { E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_META_BG,
- "meta_bg" },
- { E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_64BIT,
- "64bit" },
- { E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_MMP,
- "mmp" },
- { E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_FLEX_BG,
- "flex_bg"},
- { E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_EA_INODE,
- "large_xattr" },
- { 0, 0, 0 },
-};
-
-static struct feature jrnl_feature_list[] = {
- { E2P_FEATURE_COMPAT, JFS_FEATURE_COMPAT_CHECKSUM,
- "journal_checksum" },
-
- { E2P_FEATURE_INCOMPAT, JFS_FEATURE_INCOMPAT_REVOKE,
- "journal_incompat_revoke" },
- { E2P_FEATURE_INCOMPAT, JFS_FEATURE_INCOMPAT_ASYNC_COMMIT,
- "journal_async_commit" },
- { 0, 0, 0 },
-};
-
-const char *e2p_feature2string(int compat, unsigned int mask)
-{
- struct feature *f;
- static char buf[20];
- char fchar;
- int fnum;
-
- for (f = feature_list; f->string; f++) {
- if ((compat == f->compat) &&
- (mask == f->mask))
- return f->string;
- }
- switch (compat) {
- case E2P_FEATURE_COMPAT:
- fchar = 'C';
- break;
- case E2P_FEATURE_INCOMPAT:
- fchar = 'I';
- break;
- case E2P_FEATURE_RO_INCOMPAT:
- fchar = 'R';
- break;
- default:
- fchar = '?';
- break;
- }
- for (fnum = 0; mask >>= 1; fnum++);
- sprintf(buf, "FEATURE_%c%d", fchar, fnum);
- return buf;
-}
-
-int e2p_string2feature(char *string, int *compat_type, unsigned int *mask)
-{
- struct feature *f;
- char *eptr;
- int num;
-
- for (f = feature_list; f->string; f++) {
- if (!strcasecmp(string, f->string)) {
- *compat_type = f->compat;
- *mask = f->mask;
- return 0;
- }
- }
- if (strncasecmp(string, "FEATURE_", 8))
- return 1;
-
- switch (string[8]) {
- case 'c':
- case 'C':
- *compat_type = E2P_FEATURE_COMPAT;
- break;
- case 'i':
- case 'I':
- *compat_type = E2P_FEATURE_INCOMPAT;
- break;
- case 'r':
- case 'R':
- *compat_type = E2P_FEATURE_RO_INCOMPAT;
- break;
- default:
- return 1;
- }
- if (string[9] == 0)
- return 1;
- num = strtol(string+9, &eptr, 10);
- if (num > 32 || num < 0)
- return 1;
- if (*eptr)
- return 1;
- *mask = 1 << num;
- return 0;
-}
-
-const char *e2p_jrnl_feature2string(int compat, unsigned int mask)
-{
- struct feature *f;
- static char buf[20];
- char fchar;
- int fnum;
-
- for (f = jrnl_feature_list; f->string; f++) {
- if ((compat == f->compat) &&
- (mask == f->mask))
- return f->string;
- }
- switch (compat) {
- case E2P_FEATURE_COMPAT:
- fchar = 'C';
- break;
- case E2P_FEATURE_INCOMPAT:
- fchar = 'I';
- break;
- case E2P_FEATURE_RO_INCOMPAT:
- fchar = 'R';
- break;
- default:
- fchar = '?';
- break;
- }
- for (fnum = 0; mask >>= 1; fnum++);
- sprintf(buf, "FEATURE_%c%d", fchar, fnum);
- return buf;
-}
-
-int e2p_jrnl_string2feature(char *string, int *compat_type, unsigned int *mask)
-{
- struct feature *f;
- char *eptr;
- int num;
-
- for (f = jrnl_feature_list; f->string; f++) {
- if (!strcasecmp(string, f->string)) {
- *compat_type = f->compat;
- *mask = f->mask;
- return 0;
- }
- }
- if (strncasecmp(string, "FEATURE_", 8))
- return 1;
-
- switch (string[8]) {
- case 'c':
- case 'C':
- *compat_type = E2P_FEATURE_COMPAT;
- break;
- case 'i':
- case 'I':
- *compat_type = E2P_FEATURE_INCOMPAT;
- break;
- case 'r':
- case 'R':
- *compat_type = E2P_FEATURE_RO_INCOMPAT;
- break;
- default:
- return 1;
- }
- if (string[9] == 0)
- return 1;
- num = strtol(string+9, &eptr, 10);
- if (num > 32 || num < 0)
- return 1;
- if (*eptr)
- return 1;
- *mask = 1 << num;
- return 0;
-}
-static char *skip_over_blanks(char *cp)
-{
- while (*cp && isspace(*cp))
- cp++;
- return cp;
-}
-
-static char *skip_over_word(char *cp)
-{
- while (*cp && !isspace(*cp) && *cp != ',')
- cp++;
- return cp;
-}
-
-/*
- * Edit a feature set array as requested by the user. The ok_array,
- * if set, allows the application to limit what features the user is
- * allowed to set or clear using this function. If clear_ok_array is set,
- * then use it tell whether or not it is OK to clear a filesystem feature.
- */
-int e2p_edit_feature2(const char *str, __u32 *compat_array, __u32 *ok_array,
- __u32 *clear_ok_array, int *type_err,
- unsigned int *mask_err)
-{
- char *cp, *buf, *next;
- int neg;
- unsigned int mask;
- int compat_type;
- int rc = 0;
-
- if (!clear_ok_array)
- clear_ok_array = ok_array;
-
- if (type_err)
- *type_err = 0;
- if (mask_err)
- *mask_err = 0;
-
- buf = malloc(strlen(str)+1);
- if (!buf)
- return 1;
- strcpy(buf, str);
- for (cp = buf; cp && *cp; cp = next ? next+1 : 0) {
- neg = 0;
- cp = skip_over_blanks(cp);
- next = skip_over_word(cp);
-
- if (*next == 0)
- next = 0;
- else
- *next = 0;
-
- if ((strcasecmp(cp, "none") == 0) ||
- (strcasecmp(cp, "clear") == 0)) {
- compat_array[0] = 0;
- compat_array[1] = 0;
- compat_array[2] = 0;
- continue;
- }
-
- switch (*cp) {
- case '-':
- case '^':
- neg++;
- case '+':
- cp++;
- break;
- }
- if (e2p_string2feature(cp, &compat_type, &mask)) {
- rc = 1;
- break;
- }
- if (neg) {
- if (clear_ok_array &&
- !(clear_ok_array[compat_type] & mask)) {
- rc = 1;
- if (type_err)
- *type_err = (compat_type |
- E2P_FEATURE_NEGATE_FLAG);
- if (mask_err)
- *mask_err = mask;
- break;
- }
- compat_array[compat_type] &= ~mask;
- } else {
- if (ok_array && !(ok_array[compat_type] & mask)) {
- rc = 1;
- if (type_err)
- *type_err = compat_type;
- if (mask_err)
- *mask_err = mask;
- break;
- }
- compat_array[compat_type] |= mask;
- }
- }
- free(buf);
- return rc;
-}
-
-int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array)
-{
- return e2p_edit_feature2(str, compat_array, ok_array, 0, 0, 0);
-}
-
-#ifdef TEST_PROGRAM
-int main(int argc, char **argv)
-{
- int compat, compat2, i;
- unsigned int mask, mask2;
- const char *str;
- struct feature *f;
-
- for (i = 0; i < 2; i++) {
- if (i == 0) {
- f = feature_list;
- printf("Feature list:\n");
- } else {
- printf("\nJournal feature list:\n");
- f = jrnl_feature_list;
- }
- for (; f->string; f++) {
- if (i == 0) {
- e2p_string2feature((char *)f->string, &compat,
- &mask);
- str = e2p_feature2string(compat, mask);
- } else {
- e2p_jrnl_string2feature((char *)f->string,
- &compat, &mask);
- str = e2p_jrnl_feature2string(compat, mask);
- }
-
- printf("\tCompat = %d, Mask = %u, %s\n",
- compat, mask, f->string);
- if (strcmp(f->string, str)) {
- if (e2p_string2feature((char *) str, &compat2,
- &mask2) ||
- (compat2 != compat) ||
- (mask2 != mask)) {
- fprintf(stderr, "Failure!\n");
- exit(1);
- }
- }
- }
- }
- exit(0);
-}
-#endif
diff --git a/lib/et/error_message.c.orig b/lib/et/error_message.c.orig
deleted file mode 100644
index 1b08c16..0000000
--- a/lib/et/error_message.c.orig
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * $Header$
- * $Source$
- * $Locker$
- *
- * Copyright 1987 by the Student Information Processing Board
- * of the Massachusetts Institute of Technology
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose is hereby granted, provided that
- * the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
- * advertising or publicity pertaining to distribution of the software
- * without specific, written prior permission. M.I.T. and the
- * M.I.T. S.I.P.B. make no representations about the suitability of
- * this software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#ifdef HAVE_SYS_PRCTL_H
-#include <sys/prctl.h>
-#else
-#define PR_GET_DUMPABLE 3
-#endif
-#if (!defined(HAVE_PRCTL) && defined(linux))
-#include <sys/syscall.h>
-#endif
-#ifdef HAVE_SEMAPHORE_H
-#include <semaphore.h>
-#endif
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <fcntl.h>
-#if HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#include "com_err.h"
-#include "error_table.h"
-#include "internal.h"
-
-#ifdef TLS
-#define THREAD_LOCAL static TLS
-#else
-#define THREAD_LOCAL static
-#endif
-
-THREAD_LOCAL char buffer[25];
-
-struct et_list * _et_list = (struct et_list *) NULL;
-struct et_list * _et_dynamic_list = (struct et_list *) NULL;
-
-#ifdef __GNUC__
-#define COMERR_ATTR(x) __attribute__(x)
-#else
-#define COMERR_ATTR(x)
-#endif
-
-#ifdef HAVE_SEM_INIT
-static sem_t _et_lock;
-static int _et_lock_initialized;
-
-static void COMERR_ATTR((constructor)) setup_et_lock(void)
-{
- sem_init(&_et_lock, 0, 1);
- _et_lock_initialized = 1;
-}
-
-static void COMERR_ATTR((destructor)) fini_et_lock(void)
-{
- sem_destroy(&_et_lock);
- _et_lock_initialized = 0;
-}
-#endif
-
-
-int et_list_lock(void)
-{
-#ifdef HAVE_SEM_INIT
- if (!_et_lock_initialized)
- setup_et_lock();
- return sem_wait(&_et_lock);
-#else
- return 0;
-#endif
-}
-
-int et_list_unlock(void)
-{
-#ifdef HAVE_SEM_INIT
- if (_et_lock_initialized)
- return sem_post(&_et_lock);
-#endif
- return 0;
-}
-
-const char * error_message (errcode_t code)
-{
- int offset;
- struct et_list *et;
- errcode_t table_num;
- int started = 0;
- char *cp;
-
- offset = (int) (code & ((1<<ERRCODE_RANGE)-1));
- table_num = code - offset;
- if (!table_num) {
-#ifdef HAS_SYS_ERRLIST
- if (offset < sys_nerr)
- return(sys_errlist[offset]);
- else
- goto oops;
-#else
- cp = strerror(offset);
- if (cp)
- return(cp);
- else
- goto oops;
-#endif
- }
- et_list_lock();
- for (et = _et_list; et; et = et->next) {
- if ((et->table->base & 0xffffffL) == (table_num & 0xffffffL)) {
- /* This is the right table */
- if (et->table->n_msgs <= offset) {
- break;
- } else {
- const char *msg = et->table->msgs[offset];
- et_list_unlock();
- return msg;
- }
- }
- }
- for (et = _et_dynamic_list; et; et = et->next) {
- if ((et->table->base & 0xffffffL) == (table_num & 0xffffffL)) {
- /* This is the right table */
- if (et->table->n_msgs <= offset) {
- break;
- } else {
- const char *msg = et->table->msgs[offset];
- et_list_unlock();
- return msg;
- }
- }
- }
- et_list_unlock();
-oops:
- strcpy (buffer, "Unknown code ");
- if (table_num) {
- strcat (buffer, error_table_name (table_num));
- strcat (buffer, " ");
- }
- for (cp = buffer; *cp; cp++)
- ;
- if (offset >= 100) {
- *cp++ = '0' + offset / 100;
- offset %= 100;
- started++;
- }
- if (started || offset >= 10) {
- *cp++ = '0' + offset / 10;
- offset %= 10;
- }
- *cp++ = '0' + offset;
- *cp = '\0';
- return(buffer);
-}
-
-/*
- * This routine will only return a value if the we are not running as
- * a privileged process.
- */
-static char *safe_getenv(const char *arg)
-{
- if ((getuid() != geteuid()) || (getgid() != getegid()))
- return NULL;
-#if HAVE_PRCTL
- if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
- return NULL;
-#else
-#if (defined(linux) && defined(SYS_prctl))
- if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
- return NULL;
-#endif
-#endif
-
-#ifdef HAVE___SECURE_GETENV
- return __secure_getenv(arg);
-#else
- return getenv(arg);
-#endif
-}
-
-#define DEBUG_INIT 0x8000
-#define DEBUG_ADDREMOVE 0x0001
-
-static int debug_mask = 0;
-static FILE *debug_f = 0;
-
-static void init_debug(void)
-{
- char *dstr, *fn, *tmp;
- int fd, flags;
-
- if (debug_mask & DEBUG_INIT)
- return;
-
- dstr = getenv("COMERR_DEBUG");
- if (dstr) {
- debug_mask = strtoul(dstr, &tmp, 0);
- if (*tmp || errno)
- debug_mask = 0;
- }
-
- debug_mask |= DEBUG_INIT;
- if (debug_mask == DEBUG_INIT)
- return;
-
- fn = safe_getenv("COMERR_DEBUG_FILE");
- if (fn)
- debug_f = fopen(fn, "a");
- if (!debug_f)
- debug_f = fopen("/dev/tty", "a");
- if (debug_f) {
- fd = fileno(debug_f);
- if (fd >= 0) {
- flags = fcntl(fd, F_GETFD);
- if (flags >= 0)
- fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
- }
- } else
- debug_mask = DEBUG_INIT;
-
-}
-
-/*
- * New interface provided by krb5's com_err library
- */
-errcode_t add_error_table(const struct error_table * et)
-{
- struct et_list *el;
-
- if (!(el = (struct et_list *) malloc(sizeof(struct et_list))))
- return ENOMEM;
-
- if (et_list_lock() != 0) {
- free(el);
- return errno;
- }
-
- el->table = et;
- el->next = _et_dynamic_list;
- _et_dynamic_list = el;
-
- init_debug();
- if (debug_mask & DEBUG_ADDREMOVE)
- fprintf(debug_f, "add_error_table: %s (0x%p)\n",
- error_table_name(et->base),
- (const void *) et);
-
- et_list_unlock();
- return 0;
-}
-
-/*
- * New interface provided by krb5's com_err library
- */
-errcode_t remove_error_table(const struct error_table * et)
-{
- struct et_list *el;
- struct et_list *el2 = 0;
-
- if (et_list_lock() != 0)
- return ENOENT;
-
- el = _et_dynamic_list;
- init_debug();
- while (el) {
- if (el->table->base == et->base) {
- if (el2) /* Not the beginning of the list */
- el2->next = el->next;
- else
- _et_dynamic_list = el->next;
- (void) free(el);
- if (debug_mask & DEBUG_ADDREMOVE)
- fprintf(debug_f,
- "remove_error_table: %s (0x%p)\n",
- error_table_name(et->base),
- (const void *) et);
- et_list_unlock();
- return 0;
- }
- el2 = el;
- el = el->next;
- }
- if (debug_mask & DEBUG_ADDREMOVE)
- fprintf(debug_f, "remove_error_table FAILED: %s (0x%p)\n",
- error_table_name(et->base),
- (const void *) et);
- et_list_unlock();
- return ENOENT;
-}
-
-/*
- * Variant of the interface provided by Heimdal's com_err library
- */
-void
-add_to_error_table(struct et_list *new_table)
-{
- add_error_table(new_table->table);
-}
diff --git a/lib/ext2fs/ext2_fs.h.orig b/lib/ext2fs/ext2_fs.h.orig
deleted file mode 100644
index 9241605..0000000
--- a/lib/ext2fs/ext2_fs.h.orig
+++ /dev/null
@@ -1,820 +0,0 @@
-/*
- * linux/include/linux/ext2_fs.h
- *
- * Copyright (C) 1992, 1993, 1994, 1995
- * Remy Card (card at masi.ibp.fr)
- * Laboratoire MASI - Institut Blaise Pascal
- * Universite Pierre et Marie Curie (Paris VI)
- *
- * from
- *
- * linux/include/linux/minix_fs.h
- *
- * Copyright (C) 1991, 1992 Linus Torvalds
- */
-
-#ifndef _LINUX_EXT2_FS_H
-#define _LINUX_EXT2_FS_H
-
-#include <ext2fs/ext2_types.h> /* Changed from linux/types.h */
-
-/*
- * The second extended filesystem constants/structures
- */
-
-/*
- * Define EXT2FS_DEBUG to produce debug messages
- */
-#undef EXT2FS_DEBUG
-
-/*
- * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files
- */
-#define EXT2_PREALLOCATE
-#define EXT2_DEFAULT_PREALLOC_BLOCKS 8
-
-/*
- * The second extended file system version
- */
-#define EXT2FS_DATE "95/08/09"
-#define EXT2FS_VERSION "0.5b"
-
-/*
- * Special inode numbers
- */
-#define EXT2_BAD_INO 1 /* Bad blocks inode */
-#define EXT2_ROOT_INO 2 /* Root inode */
-#define EXT2_ACL_IDX_INO 3 /* ACL inode */
-#define EXT2_ACL_DATA_INO 4 /* ACL inode */
-#define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */
-#define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */
-#define EXT2_RESIZE_INO 7 /* Reserved group descriptors inode */
-#define EXT2_JOURNAL_INO 8 /* Journal inode */
-#define EXT2_EXCLUDE_INO 9 /* The "exclude" inode, for snapshots */
-
-/* First non-reserved inode for old ext2 filesystems */
-#define EXT2_GOOD_OLD_FIRST_INO 11
-
-/*
- * The second extended file system magic number
- */
-#define EXT2_SUPER_MAGIC 0xEF53
-
-#ifdef __KERNEL__
-#define EXT2_SB(sb) (&((sb)->u.ext2_sb))
-#else
-/* Assume that user mode programs are passing in an ext2fs superblock, not
- * a kernel struct super_block. This will allow us to call the feature-test
- * macros from user land. */
-#define EXT2_SB(sb) (sb)
-#endif
-
-/*
- * Maximal count of links to a file
- */
-#define EXT2_LINK_MAX 65000
-
-/*
- * Macro-instructions used to manage several block sizes
- */
-#define EXT2_MIN_BLOCK_LOG_SIZE 10 /* 1024 */
-#define EXT2_MAX_BLOCK_LOG_SIZE 16 /* 65536 */
-#define EXT2_MIN_BLOCK_SIZE (1 << EXT2_MIN_BLOCK_LOG_SIZE)
-#define EXT2_MAX_BLOCK_SIZE (1 << EXT2_MAX_BLOCK_LOG_SIZE)
-#ifdef __KERNEL__
-#define EXT2_BLOCK_SIZE(s) ((s)->s_blocksize)
-#define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits)
-#define EXT2_ADDR_PER_BLOCK_BITS(s) (EXT2_SB(s)->addr_per_block_bits)
-#define EXT2_INODE_SIZE(s) (EXT2_SB(s)->s_inode_size)
-#define EXT2_FIRST_INO(s) (EXT2_SB(s)->s_first_ino)
-#else
-#define EXT2_BLOCK_SIZE(s) (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
-#define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10)
-#define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
- EXT2_GOOD_OLD_INODE_SIZE : (s)->s_inode_size)
-#define EXT2_FIRST_INO(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
- EXT2_GOOD_OLD_FIRST_INO : (s)->s_first_ino)
-#endif
-#define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof(__u32))
-
-/*
- * Macro-instructions used to manage fragments
- */
-#define EXT2_MIN_FRAG_SIZE EXT2_MIN_BLOCK_SIZE
-#define EXT2_MAX_FRAG_SIZE EXT2_MAX_BLOCK_SIZE
-#define EXT2_MIN_FRAG_LOG_SIZE EXT2_MIN_BLOCK_LOG_SIZE
-#ifdef __KERNEL__
-# define EXT2_FRAG_SIZE(s) (EXT2_SB(s)->s_frag_size)
-# define EXT2_FRAGS_PER_BLOCK(s) (EXT2_SB(s)->s_frags_per_block)
-#else
-# define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
-# define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
-#endif
-
-/*
- * ACL structures
- */
-struct ext2_acl_header /* Header of Access Control Lists */
-{
- __u32 aclh_size;
- __u32 aclh_file_count;
- __u32 aclh_acle_count;
- __u32 aclh_first_acle;
-};
-
-struct ext2_acl_entry /* Access Control List Entry */
-{
- __u32 acle_size;
- __u16 acle_perms; /* Access permissions */
- __u16 acle_type; /* Type of entry */
- __u16 acle_tag; /* User or group identity */
- __u16 acle_pad1;
- __u32 acle_next; /* Pointer on next entry for the */
- /* same inode or on next free entry */
-};
-
-/*
- * Structure of a blocks group descriptor
- */
-struct ext2_group_desc
-{
- __u32 bg_block_bitmap; /* Blocks bitmap block */
- __u32 bg_inode_bitmap; /* Inodes bitmap block */
- __u32 bg_inode_table; /* Inodes table block */
- __u16 bg_free_blocks_count; /* Free blocks count */
- __u16 bg_free_inodes_count; /* Free inodes count */
- __u16 bg_used_dirs_count; /* Directories count */
- __u16 bg_flags;
- __u32 bg_reserved[2];
- __u16 bg_itable_unused; /* Unused inodes count */
- __u16 bg_checksum; /* crc16(s_uuid+grouo_num+group_desc)*/
-};
-
-/*
- * Structure of a blocks group descriptor
- */
-struct ext4_group_desc
-{
- __u32 bg_block_bitmap; /* Blocks bitmap block */
- __u32 bg_inode_bitmap; /* Inodes bitmap block */
- __u32 bg_inode_table; /* Inodes table block */
- __u16 bg_free_blocks_count; /* Free blocks count */
- __u16 bg_free_inodes_count; /* Free inodes count */
- __u16 bg_used_dirs_count; /* Directories count */
- __u16 bg_flags; /* EXT4_BG_flags (INODE_UNINIT, etc) */
- __u32 bg_reserved[2]; /* Likely block/inode bitmap checksum */
- __u16 bg_itable_unused; /* Unused inodes count */
- __u16 bg_checksum; /* crc16(sb_uuid+group+desc) */
- __u32 bg_block_bitmap_hi; /* Blocks bitmap block MSB */
- __u32 bg_inode_bitmap_hi; /* Inodes bitmap block MSB */
- __u32 bg_inode_table_hi; /* Inodes table block MSB */
- __u16 bg_free_blocks_count_hi;/* Free blocks count MSB */
- __u16 bg_free_inodes_count_hi;/* Free inodes count MSB */
- __u16 bg_used_dirs_count_hi; /* Directories count MSB */
- __u16 bg_itable_unused_hi; /* Unused inodes count MSB */
- __u32 bg_reserved2[3];
-};
-
-#define EXT2_BG_INODE_UNINIT 0x0001 /* Inode table/bitmap not initialized */
-#define EXT2_BG_BLOCK_UNINIT 0x0002 /* Block bitmap not initialized */
-#define EXT2_BG_INODE_ZEROED 0x0004 /* On-disk itable initialized to zero */
-
-/*
- * Data structures used by the directory indexing feature
- *
- * Note: all of the multibyte integer fields are little endian.
- */
-
-/*
- * Note: dx_root_info is laid out so that if it should somehow get
- * overlaid by a dirent the two low bits of the hash version will be
- * zero. Therefore, the hash version mod 4 should never be 0.
- * Sincerely, the paranoia department.
- */
-struct ext2_dx_root_info {
- __u32 reserved_zero;
- __u8 hash_version; /* 0 now, 1 at release */
- __u8 info_length; /* 8 */
- __u8 indirect_levels;
- __u8 unused_flags;
-};
-
-#define EXT2_HASH_LEGACY 0
-#define EXT2_HASH_HALF_MD4 1
-#define EXT2_HASH_TEA 2
-#define EXT2_HASH_LEGACY_UNSIGNED 3 /* reserved for userspace lib */
-#define EXT2_HASH_HALF_MD4_UNSIGNED 4 /* reserved for userspace lib */
-#define EXT2_HASH_TEA_UNSIGNED 5 /* reserved for userspace lib */
-
-#define EXT2_HASH_FLAG_INCOMPAT 0x1
-
-struct ext2_dx_entry {
- __u32 hash;
- __u32 block;
-};
-
-struct ext2_dx_countlimit {
- __u16 limit;
- __u16 count;
-};
-
-
-/*
- * Macro-instructions used to manage group descriptors
- */
-#define EXT2_MIN_DESC_SIZE 32
-#define EXT2_MIN_DESC_SIZE_64BIT 64
-#define EXT2_MAX_DESC_SIZE EXT2_MIN_BLOCK_SIZE
-#define EXT2_DESC_SIZE(s) \
- ((EXT2_SB(s)->s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT) ? \
- (s)->s_desc_size : EXT2_MIN_DESC_SIZE)
-
-#define EXT2_BLOCKS_PER_GROUP(s) (EXT2_SB(s)->s_blocks_per_group)
-#define EXT2_INODES_PER_GROUP(s) (EXT2_SB(s)->s_inodes_per_group)
-#define EXT2_INODES_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
-/* limits imposed by 16-bit value gd_free_{blocks,inode}_count */
-#define EXT2_MAX_BLOCKS_PER_GROUP(s) ((1 << 16) - 8)
-#define EXT2_MAX_INODES_PER_GROUP(s) ((1 << 16) - EXT2_INODES_PER_BLOCK(s))
-#ifdef __KERNEL__
-#define EXT2_DESC_PER_BLOCK(s) (EXT2_SB(s)->s_desc_per_block)
-#define EXT2_DESC_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_desc_per_block_bits)
-#else
-#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_DESC_SIZE(s))
-#endif
-
-/*
- * Constants relative to the data blocks
- */
-#define EXT2_NDIR_BLOCKS 12
-#define EXT2_IND_BLOCK EXT2_NDIR_BLOCKS
-#define EXT2_DIND_BLOCK (EXT2_IND_BLOCK + 1)
-#define EXT2_TIND_BLOCK (EXT2_DIND_BLOCK + 1)
-#define EXT2_N_BLOCKS (EXT2_TIND_BLOCK + 1)
-
-/*
- * Inode flags
- */
-#define EXT2_SECRM_FL 0x00000001 /* Secure deletion */
-#define EXT2_UNRM_FL 0x00000002 /* Undelete */
-#define EXT2_COMPR_FL 0x00000004 /* Compress file */
-#define EXT2_SYNC_FL 0x00000008 /* Synchronous updates */
-#define EXT2_IMMUTABLE_FL 0x00000010 /* Immutable file */
-#define EXT2_APPEND_FL 0x00000020 /* writes to file may only append */
-#define EXT2_NODUMP_FL 0x00000040 /* do not dump file */
-#define EXT2_NOATIME_FL 0x00000080 /* do not update atime */
-/* Reserved for compression usage... */
-#define EXT2_DIRTY_FL 0x00000100
-#define EXT2_COMPRBLK_FL 0x00000200 /* One or more compressed clusters */
-#define EXT2_NOCOMPR_FL 0x00000400 /* Access raw compressed data */
-#define EXT2_ECOMPR_FL 0x00000800 /* Compression error */
-/* End compression flags --- maybe not all used */
-#define EXT2_BTREE_FL 0x00001000 /* btree format dir */
-#define EXT2_INDEX_FL 0x00001000 /* hash-indexed directory */
-#define EXT2_IMAGIC_FL 0x00002000
-#define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */
-#define EXT2_NOTAIL_FL 0x00008000 /* file tail should not be merged */
-#define EXT2_DIRSYNC_FL 0x00010000 /* Synchronous directory modifications */
-#define EXT2_TOPDIR_FL 0x00020000 /* Top of directory hierarchies*/
-#define EXT4_HUGE_FILE_FL 0x00040000 /* Set to each huge file */
-#define EXT4_EXTENTS_FL 0x00080000 /* Inode uses extents */
-#define EXT4_EA_INODE_FL 0x00200000 /* Inode used for large EA */
-#define EXT4_EOFBLOCKS_FL 0x00400000 /* Blocks allocated beyond EOF */
-#define EXT4_SNAPFILE_FL 0x01000000 /* Inode is a snapshot */
-#define EXT4_SNAPFILE_DELETED_FL 0x04000000 /* Snapshot is being deleted */
-#define EXT4_SNAPFILE_SHRUNK_FL 0x08000000 /* Snapshot shrink has completed */
-#define EXT2_RESERVED_FL 0x80000000 /* reserved for ext2 lib */
-
-#define EXT2_FL_USER_VISIBLE 0x004BDFFF /* User visible flags */
-#define EXT2_FL_USER_MODIFIABLE 0x004B80FF /* User modifiable flags */
-
-/*
- * ioctl commands
- */
-
-/* Used for online resize */
-struct ext2_new_group_input {
- __u32 group; /* Group number for this data */
- __u32 block_bitmap; /* Absolute block number of block bitmap */
- __u32 inode_bitmap; /* Absolute block number of inode bitmap */
- __u32 inode_table; /* Absolute block number of inode table start */
- __u32 blocks_count; /* Total number of blocks in this group */
- __u16 reserved_blocks; /* Number of reserved blocks in this group */
- __u16 unused; /* Number of reserved GDT blocks in group */
-};
-
-struct ext4_new_group_input {
- __u32 group; /* Group number for this data */
- __u64 block_bitmap; /* Absolute block number of block bitmap */
- __u64 inode_bitmap; /* Absolute block number of inode bitmap */
- __u64 inode_table; /* Absolute block number of inode table start */
- __u32 blocks_count; /* Total number of blocks in this group */
- __u16 reserved_blocks; /* Number of reserved blocks in this group */
- __u16 unused;
-};
-
-#ifdef __GNU__ /* Needed for the Hurd */
-#define _IOT_ext2_new_group_input _IOT (_IOTS(__u32), 5, _IOTS(__u16), 2, 0, 0)
-#endif
-
-#define EXT2_IOC_GETFLAGS _IOR('f', 1, long)
-#define EXT2_IOC_SETFLAGS _IOW('f', 2, long)
-#define EXT2_IOC_GETVERSION _IOR('v', 1, long)
-#define EXT2_IOC_SETVERSION _IOW('v', 2, long)
-#define EXT2_IOC_GETVERSION_NEW _IOR('f', 3, long)
-#define EXT2_IOC_SETVERSION_NEW _IOW('f', 4, long)
-#define EXT2_IOC_GROUP_EXTEND _IOW('f', 7, unsigned long)
-#define EXT2_IOC_GROUP_ADD _IOW('f', 8,struct ext2_new_group_input)
-#define EXT4_IOC_GROUP_ADD _IOW('f', 8,struct ext4_new_group_input)
-
-/*
- * Structure of an inode on the disk
- */
-struct ext2_inode {
- __u16 i_mode; /* File mode */
- __u16 i_uid; /* Low 16 bits of Owner Uid */
- __u32 i_size; /* Size in bytes */
- __u32 i_atime; /* Access time */
- __u32 i_ctime; /* Inode change time */
- __u32 i_mtime; /* Modification time */
- __u32 i_dtime; /* Deletion Time */
- __u16 i_gid; /* Low 16 bits of Group Id */
- __u16 i_links_count; /* Links count */
- __u32 i_blocks; /* Blocks count */
- __u32 i_flags; /* File flags */
- union {
- struct {
- __u32 l_i_version; /* was l_i_reserved1 */
- } linux1;
- struct {
- __u32 h_i_translator;
- } hurd1;
- } osd1; /* OS dependent 1 */
- __u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
- __u32 i_generation; /* File version (for NFS) */
- __u32 i_file_acl; /* File ACL */
- __u32 i_size_high; /* Formerly i_dir_acl, directory ACL */
- __u32 i_faddr; /* Fragment address */
- union {
- struct {
- __u16 l_i_blocks_hi;
- __u16 l_i_file_acl_high;
- __u16 l_i_uid_high; /* these 2 fields */
- __u16 l_i_gid_high; /* were reserved2[0] */
- __u32 l_i_reserved2;
- } linux2;
- struct {
- __u8 h_i_frag; /* Fragment number */
- __u8 h_i_fsize; /* Fragment size */
- __u16 h_i_mode_high;
- __u16 h_i_uid_high;
- __u16 h_i_gid_high;
- __u32 h_i_author;
- } hurd2;
- } osd2; /* OS dependent 2 */
-};
-
-/*
- * Permanent part of an large inode on the disk
- */
-struct ext2_inode_large {
- __u16 i_mode; /* File mode */
- __u16 i_uid; /* Low 16 bits of Owner Uid */
- __u32 i_size; /* Size in bytes */
- __u32 i_atime; /* Access time */
- __u32 i_ctime; /* Inode Change time */
- __u32 i_mtime; /* Modification time */
- __u32 i_dtime; /* Deletion Time */
- __u16 i_gid; /* Low 16 bits of Group Id */
- __u16 i_links_count; /* Links count */
- __u32 i_blocks; /* Blocks count */
- __u32 i_flags; /* File flags */
- union {
- struct {
- __u32 l_i_version; /* was l_i_reserved1 */
- } linux1;
- struct {
- __u32 h_i_translator;
- } hurd1;
- } osd1; /* OS dependent 1 */
- __u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
- __u32 i_generation; /* File version (for NFS) */
- __u32 i_file_acl; /* File ACL */
- __u32 i_size_high; /* Formerly i_dir_acl, directory ACL */
- __u32 i_faddr; /* Fragment address */
- union {
- struct {
- __u16 l_i_blocks_hi;
- __u16 l_i_file_acl_high;
- __u16 l_i_uid_high; /* these 2 fields */
- __u16 l_i_gid_high; /* were reserved2[0] */
- __u32 l_i_reserved2;
- } linux2;
- struct {
- __u8 h_i_frag; /* Fragment number */
- __u8 h_i_fsize; /* Fragment size */
- __u16 h_i_mode_high;
- __u16 h_i_uid_high;
- __u16 h_i_gid_high;
- __u32 h_i_author;
- } hurd2;
- } osd2; /* OS dependent 2 */
- __u16 i_extra_isize;
- __u16 i_pad1;
- __u32 i_ctime_extra; /* extra Change time (nsec << 2 | epoch) */
- __u32 i_mtime_extra; /* extra Modification time (nsec << 2 | epoch) */
- __u32 i_atime_extra; /* extra Access time (nsec << 2 | epoch) */
- __u32 i_crtime; /* File creation time */
- __u32 i_crtime_extra; /* extra File creation time (nsec << 2 | epoch)*/
- __u32 i_version_hi; /* high 32 bits for 64-bit version */
-};
-
-#define i_dir_acl i_size_high
-
-#define EXT2_FITS_IN_INODE(inode, field) \
- ((offsetof(struct ext2_inode_large, field) + \
- sizeof((inode)->field)) <= \
- (EXT2_GOOD_OLD_INODE_SIZE + \
- (inode)->i_extra_isize)) \
-
-#if defined(__KERNEL__) || defined(__linux__)
-#define i_reserved1 osd1.linux1.l_i_reserved1
-#define i_frag osd2.linux2.l_i_frag
-#define i_fsize osd2.linux2.l_i_fsize
-#define i_uid_low i_uid
-#define i_gid_low i_gid
-#define i_uid_high osd2.linux2.l_i_uid_high
-#define i_gid_high osd2.linux2.l_i_gid_high
-#define i_reserved2 osd2.linux2.l_i_reserved2
-#else
-#if defined(__GNU__)
-
-#define i_translator osd1.hurd1.h_i_translator
-#define i_frag osd2.hurd2.h_i_frag;
-#define i_fsize osd2.hurd2.h_i_fsize;
-#define i_uid_high osd2.hurd2.h_i_uid_high
-#define i_gid_high osd2.hurd2.h_i_gid_high
-#define i_author osd2.hurd2.h_i_author
-
-#endif /* __GNU__ */
-#endif /* defined(__KERNEL__) || defined(__linux__) */
-
-#define inode_uid(inode) ((inode).i_uid | (inode).osd2.linux2.l_i_uid_high << 16)
-#define inode_gid(inode) ((inode).i_gid | (inode).osd2.linux2.l_i_gid_high << 16)
-#define ext2fs_set_i_uid_high(inode,x) ((inode).osd2.linux2.l_i_uid_high = (x))
-#define ext2fs_set_i_gid_high(inode,x) ((inode).osd2.linux2.l_i_gid_high = (x))
-
-/*
- * File system states
- */
-#define EXT2_VALID_FS 0x0001 /* Unmounted cleanly */
-#define EXT2_ERROR_FS 0x0002 /* Errors detected */
-#define EXT3_ORPHAN_FS 0x0004 /* Orphans being recovered */
-
-/*
- * Misc. filesystem flags
- */
-#define EXT2_FLAGS_SIGNED_HASH 0x0001 /* Signed dirhash in use */
-#define EXT2_FLAGS_UNSIGNED_HASH 0x0002 /* Unsigned dirhash in use */
-#define EXT2_FLAGS_TEST_FILESYS 0x0004 /* OK for use on development code */
-#define EXT2_FLAGS_IS_SNAPSHOT 0x0010 /* This is a snapshot image */
-#define EXT2_FLAGS_FIX_SNAPSHOT 0x0020 /* Snapshot inodes corrupted */
-#define EXT2_FLAGS_FIX_EXCLUDE 0x0040 /* Exclude bitmaps corrupted */
-
-/*
- * Mount flags
- */
-#define EXT2_MOUNT_CHECK 0x0001 /* Do mount-time checks */
-#define EXT2_MOUNT_GRPID 0x0004 /* Create files with directory's group */
-#define EXT2_MOUNT_DEBUG 0x0008 /* Some debugging messages */
-#define EXT2_MOUNT_ERRORS_CONT 0x0010 /* Continue on errors */
-#define EXT2_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */
-#define EXT2_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */
-#define EXT2_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */
-#define EXT2_MOUNT_NO_UID32 0x0200 /* Disable 32-bit UIDs */
-
-#define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt
-#define set_opt(o, opt) o |= EXT2_MOUNT_##opt
-#define test_opt(sb, opt) (EXT2_SB(sb)->s_mount_opt & \
- EXT2_MOUNT_##opt)
-/*
- * Maximal mount counts between two filesystem checks
- */
-#define EXT2_DFL_MAX_MNT_COUNT 20 /* Allow 20 mounts */
-#define EXT2_DFL_CHECKINTERVAL 0 /* Don't use interval check */
-
-/*
- * Behaviour when detecting errors
- */
-#define EXT2_ERRORS_CONTINUE 1 /* Continue execution */
-#define EXT2_ERRORS_RO 2 /* Remount fs read-only */
-#define EXT2_ERRORS_PANIC 3 /* Panic */
-#define EXT2_ERRORS_DEFAULT EXT2_ERRORS_CONTINUE
-
-#if (__GNUC__ >= 4)
-#define ext4_offsetof(TYPE,MEMBER) __builtin_offsetof(TYPE,MEMBER)
-#else
-#define ext4_offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
-#endif
-
-/*
- * Structure of the super block
- */
-struct ext2_super_block {
- __u32 s_inodes_count; /* Inodes count */
- __u32 s_blocks_count; /* Blocks count */
- __u32 s_r_blocks_count; /* Reserved blocks count */
- __u32 s_free_blocks_count; /* Free blocks count */
- __u32 s_free_inodes_count; /* Free inodes count */
- __u32 s_first_data_block; /* First Data Block */
- __u32 s_log_block_size; /* Block size */
- __s32 s_log_frag_size; /* Fragment size */
- __u32 s_blocks_per_group; /* # Blocks per group */
- __u32 s_frags_per_group; /* # Fragments per group */
- __u32 s_inodes_per_group; /* # Inodes per group */
- __u32 s_mtime; /* Mount time */
- __u32 s_wtime; /* Write time */
- __u16 s_mnt_count; /* Mount count */
- __s16 s_max_mnt_count; /* Maximal mount count */
- __u16 s_magic; /* Magic signature */
- __u16 s_state; /* File system state */
- __u16 s_errors; /* Behaviour when detecting errors */
- __u16 s_minor_rev_level; /* minor revision level */
- __u32 s_lastcheck; /* time of last check */
- __u32 s_checkinterval; /* max. time between checks */
- __u32 s_creator_os; /* OS */
- __u32 s_rev_level; /* Revision level */
- __u16 s_def_resuid; /* Default uid for reserved blocks */
- __u16 s_def_resgid; /* Default gid for reserved blocks */
- /*
- * These fields are for EXT2_DYNAMIC_REV superblocks only.
- *
- * Note: the difference between the compatible feature set and
- * the incompatible feature set is that if there is a bit set
- * in the incompatible feature set that the kernel doesn't
- * know about, it should refuse to mount the filesystem.
- *
- * e2fsck's requirements are more strict; if it doesn't know
- * about a feature in either the compatible or incompatible
- * feature set, it must abort and not try to meddle with
- * things it doesn't understand...
- */
- __u32 s_first_ino; /* First non-reserved inode */
- __u16 s_inode_size; /* size of inode structure */
- __u16 s_block_group_nr; /* block group # of this superblock */
- __u32 s_feature_compat; /* compatible feature set */
- __u32 s_feature_incompat; /* incompatible feature set */
- __u32 s_feature_ro_compat; /* readonly-compatible feature set */
- __u8 s_uuid[16]; /* 128-bit uuid for volume */
- char s_volume_name[16]; /* volume name */
- char s_last_mounted[64]; /* directory where last mounted */
- __u32 s_algorithm_usage_bitmap; /* For compression */
- /*
- * Performance hints. Directory preallocation should only
- * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
- */
- __u8 s_prealloc_blocks; /* Nr of blocks to try to preallocate*/
- __u8 s_prealloc_dir_blocks; /* Nr to preallocate for dirs */
- __u16 s_reserved_gdt_blocks; /* Per group table for online growth */
- /*
- * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
- */
- __u8 s_journal_uuid[16]; /* uuid of journal superblock */
- __u32 s_journal_inum; /* inode number of journal file */
- __u32 s_journal_dev; /* device number of journal file */
- __u32 s_last_orphan; /* start of list of inodes to delete */
- __u32 s_hash_seed[4]; /* HTREE hash seed */
- __u8 s_def_hash_version; /* Default hash version to use */
- __u8 s_jnl_backup_type; /* Default type of journal backup */
- __u16 s_desc_size; /* Group desc. size: INCOMPAT_64BIT */
- __u32 s_default_mount_opts;
- __u32 s_first_meta_bg; /* First metablock group */
- __u32 s_mkfs_time; /* When the filesystem was created */
- __u32 s_jnl_blocks[17]; /* Backup of the journal inode */
- __u32 s_blocks_count_hi; /* Blocks count high 32bits */
- __u32 s_r_blocks_count_hi; /* Reserved blocks count high 32 bits*/
- __u32 s_free_blocks_hi; /* Free blocks count */
- __u16 s_min_extra_isize; /* All inodes have at least # bytes */
- __u16 s_want_extra_isize; /* New inodes should reserve # bytes */
- __u32 s_flags; /* Miscellaneous flags */
- __u16 s_raid_stride; /* RAID stride */
- __u16 s_mmp_update_interval; /* # seconds to wait in MMP checking */
- __u64 s_mmp_block; /* Block for multi-mount protection */
- __u32 s_raid_stripe_width; /* blocks on all data disks (N*stride)*/
- __u8 s_log_groups_per_flex; /* FLEX_BG group size */
- __u8 s_reserved_char_pad;
- __u16 s_reserved_pad; /* Padding to next 32bits */
- __u64 s_kbytes_written; /* nr of lifetime kilobytes written */
- __u32 s_snapshot_inum; /* Inode number of active snapshot */
- __u32 s_snapshot_id; /* sequential ID of active snapshot */
- __u64 s_snapshot_r_blocks_count; /* reserved blocks for active
- snapshot's future use */
- __u32 s_snapshot_list; /* inode number of the head of the on-disk snapshot list */
-#define EXT4_S_ERR_START ext4_offsetof(struct ext2_super_block, s_error_count)
- __u32 s_error_count; /* number of fs errors */
- __u32 s_first_error_time; /* first time an error happened */
- __u32 s_first_error_ino; /* inode involved in first error */
- __u64 s_first_error_block; /* block involved of first error */
- __u8 s_first_error_func[32]; /* function where the error happened */
- __u32 s_first_error_line; /* line number where error happened */
- __u32 s_last_error_time; /* most recent time of an error */
- __u32 s_last_error_ino; /* inode involved in last error */
- __u32 s_last_error_line; /* line number where error happened */
- __u64 s_last_error_block; /* block involved of last error */
- __u8 s_last_error_func[32]; /* function where the error happened */
-#define EXT4_S_ERR_END ext4_offsetof(struct ext2_super_block, s_mount_opts)
- __u8 s_mount_opts[64];
- __u32 s_reserved[112]; /* Padding to the end of the block */
-};
-
-#define EXT4_S_ERR_LEN (EXT4_S_ERR_END - EXT4_S_ERR_START)
-
-/*
- * Codes for operating systems
- */
-#define EXT2_OS_LINUX 0
-#define EXT2_OS_HURD 1
-#define EXT2_OBSO_OS_MASIX 2
-#define EXT2_OS_FREEBSD 3
-#define EXT2_OS_LITES 4
-
-/*
- * Revision levels
- */
-#define EXT2_GOOD_OLD_REV 0 /* The good old (original) format */
-#define EXT2_DYNAMIC_REV 1 /* V2 format w/ dynamic inode sizes */
-
-#define EXT2_CURRENT_REV EXT2_GOOD_OLD_REV
-#define EXT2_MAX_SUPP_REV EXT2_DYNAMIC_REV
-
-#define EXT2_GOOD_OLD_INODE_SIZE 128
-
-/*
- * Journal inode backup types
- */
-#define EXT3_JNL_BACKUP_BLOCKS 1
-
-/*
- * Feature set definitions
- */
-
-#define EXT2_HAS_COMPAT_FEATURE(sb,mask) \
- ( EXT2_SB(sb)->s_feature_compat & (mask) )
-#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask) \
- ( EXT2_SB(sb)->s_feature_ro_compat & (mask) )
-#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \
- ( EXT2_SB(sb)->s_feature_incompat & (mask) )
-
-#define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001
-#define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002
-#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004
-#define EXT2_FEATURE_COMPAT_EXT_ATTR 0x0008
-#define EXT2_FEATURE_COMPAT_RESIZE_INODE 0x0010
-#define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020
-#define EXT2_FEATURE_COMPAT_LAZY_BG 0x0040
-#define EXT2_FEATURE_COMPAT_EXCLUDE_INODE 0x0080
-
-#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001
-#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002
-/* #define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 not used */
-#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008
-#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010
-#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020
-#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040
-#define EXT4_FEATURE_RO_COMPAT_HAS_SNAPSHOT 0x0080
-
-#define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001
-#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
-#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */
-#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */
-#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010
-#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040
-#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080
-#define EXT4_FEATURE_INCOMPAT_MMP 0x0100
-#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200
-#define EXT4_FEATURE_INCOMPAT_EA_INODE 0x0400
-#define EXT4_FEATURE_INCOMPAT_DIRDATA 0x1000
-
-
-#define EXT2_FEATURE_COMPAT_SUPP 0
-#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \
- EXT4_FEATURE_INCOMPAT_MMP|\
- EXT4_FEATURE_INCOMPAT_EA_INODE)
-#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
- EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
- EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE| \
- EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
-
-/*
- * Default values for user and/or group using reserved blocks
- */
-#define EXT2_DEF_RESUID 0
-#define EXT2_DEF_RESGID 0
-
-/*
- * Default mount options
- */
-#define EXT2_DEFM_DEBUG 0x0001
-#define EXT2_DEFM_BSDGROUPS 0x0002
-#define EXT2_DEFM_XATTR_USER 0x0004
-#define EXT2_DEFM_ACL 0x0008
-#define EXT2_DEFM_UID16 0x0010
-#define EXT3_DEFM_JMODE 0x0060
-#define EXT3_DEFM_JMODE_DATA 0x0020
-#define EXT3_DEFM_JMODE_ORDERED 0x0040
-#define EXT3_DEFM_JMODE_WBACK 0x0060
-#define EXT4_DEFM_NOBARRIER 0x0100
-#define EXT4_DEFM_BLOCK_VALIDITY 0x0200
-#define EXT4_DEFM_DISCARD 0x0400
-#define EXT4_DEFM_NODELALLOC 0x0800
-
-/*
- * Structure of a directory entry
- */
-#define EXT2_NAME_LEN 255
-
-struct ext2_dir_entry {
- __u32 inode; /* Inode number */
- __u16 rec_len; /* Directory entry length */
- __u16 name_len; /* Name length */
- char name[EXT2_NAME_LEN]; /* File name */
-};
-
-/*
- * The new version of the directory entry. Since EXT2 structures are
- * stored in intel byte order, and the name_len field could never be
- * bigger than 255 chars, it's safe to reclaim the extra byte for the
- * file_type field.
- */
-struct ext2_dir_entry_2 {
- __u32 inode; /* Inode number */
- __u16 rec_len; /* Directory entry length */
- __u8 name_len; /* Name length */
- __u8 file_type;
- char name[EXT2_NAME_LEN]; /* File name */
-};
-
-/*
- * Ext2 directory file types. Only the low 3 bits are used. The
- * other bits are reserved for now.
- */
-#define EXT2_FT_UNKNOWN 0
-#define EXT2_FT_REG_FILE 1
-#define EXT2_FT_DIR 2
-#define EXT2_FT_CHRDEV 3
-#define EXT2_FT_BLKDEV 4
-#define EXT2_FT_FIFO 5
-#define EXT2_FT_SOCK 6
-#define EXT2_FT_SYMLINK 7
-
-#define EXT2_FT_MAX 8
-
-/*
- * EXT2_DIR_PAD defines the directory entries boundaries
- *
- * NOTE: It must be a multiple of 4
- */
-#define EXT2_DIR_PAD 4
-#define EXT2_DIR_ROUND (EXT2_DIR_PAD - 1)
-#define EXT2_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT2_DIR_ROUND) & \
- ~EXT2_DIR_ROUND)
-
-/*
- * This structure will be used for multiple mount protection. It will be
- * written into the block number saved in the s_mmp_block field in the
- * superblock. Programs that check MMP should assume that if SEQ_FSCK
- * (or any unknown code above SEQ_MAX) is present then it is NOT safe
- * to use the filesystem, regardless of how old the timestamp is.
- *
- * Note: Only the mmp_seq value is used to determine whether the MMP block
- * is being updated. The mmp_time, mmp_nodename, and mmp_bdevname
- * fields can only be for informational purposes for the administrator,
- * due to clock skew between nodes and hostname HA service takeover.
- */
-#define EXT2_MMP_MAGIC 0x004D4D50U /* ASCII for MMP */
-#define EXT2_MMP_SEQ_CLEAN 0xFF4D4D50U /* mmp_seq value for clean unmount */
-#define EXT2_MMP_SEQ_FSCK 0xE24D4D50U /* mmp_seq value when being fscked */
-#define EXT2_MMP_SEQ_MAX 0xE24D4D4FU /* maximum valid mmp_seq value */
-
-struct mmp_struct {
- __u32 mmp_magic; /* Magic number for MMP */
- __u32 mmp_seq; /* Sequence no. updated periodically */
- __u64 mmp_time; /* Time last updated */
- char mmp_nodename[64]; /* Node which last updated MMP block */
- char mmp_bdevname[32]; /* Bdev which last updated MMP block */
- __u16 mmp_check_interval; /* Changed mmp_check_interval */
- __u16 mmp_pad1;
- __u32 mmp_pad2[227];
-};
-
-/*
- * Default interval in seconds to update the MMP sequence number.
- */
-#define EXT2_MMP_UPDATE_INTERVAL 5
-
-/*
- * Minimum interval for MMP checking in seconds.
- */
-#define EXT2_MMP_MIN_CHECK_INTERVAL 5
-
-#endif /* _LINUX_EXT2_FS_H */
diff --git a/lib/ext2fs/ext2fs.h.orig b/lib/ext2fs/ext2fs.h.orig
deleted file mode 100644
index 7c2ffa1..0000000
--- a/lib/ext2fs/ext2fs.h.orig
+++ /dev/null
@@ -1,1650 +0,0 @@
-/*
- * ext2fs.h --- ext2fs
- *
- * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU Library
- * General Public License, version 2.
- * %End-Header%
- */
-
-#ifndef _EXT2FS_EXT2FS_H
-#define _EXT2FS_EXT2FS_H
-
-#ifdef __GNUC__
-#define EXT2FS_ATTR(x) __attribute__(x)
-#else
-#define EXT2FS_ATTR(x)
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * Non-GNU C compilers won't necessarily understand inline
- */
-#if (!defined(__GNUC__) && !defined(__WATCOMC__))
-#define NO_INLINE_FUNCS
-#endif
-
-#ifndef _XOPEN_SOURCE
-#define _XOPEN_SOURCE 600 /* for posix_memalign() */
-#endif
-
-/*
- * Where the master copy of the superblock is located, and how big
- * superblocks are supposed to be. We define SUPERBLOCK_SIZE because
- * the size of the superblock structure is not necessarily trustworthy
- * (some versions have the padding set up so that the superblock is
- * 1032 bytes long).
- */
-#define SUPERBLOCK_OFFSET 1024
-#define SUPERBLOCK_SIZE 1024
-
-/*
- * The last ext2fs revision level that this version of the library is
- * able to support.
- */
-#define EXT2_LIB_CURRENT_REV EXT2_DYNAMIC_REV
-
-#ifdef HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-
-#if EXT2_FLAT_INCLUDES
-#include "e2_types.h"
-#include "ext2_fs.h"
-#include "ext3_extents.h"
-#else
-#include <ext2fs/ext2_types.h>
-#include <ext2fs/ext2_fs.h>
-#include <ext2fs/ext3_extents.h>
-#endif /* EXT2_FLAT_INCLUDES */
-
-typedef __u32 ext2_ino_t;
-typedef __u32 blk_t;
-typedef __u64 blk64_t;
-typedef __u32 dgrp_t;
-typedef __u32 ext2_off_t;
-typedef __u64 ext2_off64_t;
-typedef __s64 e2_blkcnt_t;
-typedef __u32 ext2_dirhash_t;
-
-#if EXT2_FLAT_INCLUDES
-#include "com_err.h"
-#include "ext2_io.h"
-#include "ext2_err.h"
-#include "ext2_ext_attr.h"
-#else
-#include <et/com_err.h>
-#include <ext2fs/ext2_io.h>
-#include <ext2fs/ext2_err.h>
-#include <ext2fs/ext2_ext_attr.h>
-#endif
-
-/*
- * Portability help for Microsoft Visual C++
- */
-#ifdef _MSC_VER
-#define EXT2_QSORT_TYPE int __cdecl
-#else
-#define EXT2_QSORT_TYPE int
-#endif
-
-typedef struct struct_ext2_filsys *ext2_filsys;
-
-#define EXT2FS_MARK_ERROR 0
-#define EXT2FS_UNMARK_ERROR 1
-#define EXT2FS_TEST_ERROR 2
-
-typedef struct ext2fs_struct_generic_bitmap *ext2fs_generic_bitmap;
-typedef struct ext2fs_struct_generic_bitmap *ext2fs_inode_bitmap;
-typedef struct ext2fs_struct_generic_bitmap *ext2fs_block_bitmap;
-
-#define EXT2_FIRST_INODE(s) EXT2_FIRST_INO(s)
-
-
-/*
- * Badblocks list definitions
- */
-
-typedef struct ext2_struct_u32_list *ext2_badblocks_list;
-typedef struct ext2_struct_u32_iterate *ext2_badblocks_iterate;
-
-typedef struct ext2_struct_u32_list *ext2_u32_list;
-typedef struct ext2_struct_u32_iterate *ext2_u32_iterate;
-
-/* old */
-typedef struct ext2_struct_u32_list *badblocks_list;
-typedef struct ext2_struct_u32_iterate *badblocks_iterate;
-
-#define BADBLOCKS_FLAG_DIRTY 1
-
-/*
- * ext2_dblist structure and abstractions (see dblist.c)
- */
-struct ext2_db_entry2 {
- ext2_ino_t ino;
- blk64_t blk;
- e2_blkcnt_t blockcnt;
-};
-
-/* Ye Olde 32-bit version */
-struct ext2_db_entry {
- ext2_ino_t ino;
- blk_t blk;
- int blockcnt;
-};
-
-typedef struct ext2_struct_dblist *ext2_dblist;
-
-#define DBLIST_ABORT 1
-
-/*
- * ext2_fileio definitions
- */
-
-#define EXT2_FILE_WRITE 0x0001
-#define EXT2_FILE_CREATE 0x0002
-
-#define EXT2_FILE_MASK 0x00FF
-
-#define EXT2_FILE_BUF_DIRTY 0x4000
-#define EXT2_FILE_BUF_VALID 0x2000
-
-typedef struct ext2_file *ext2_file_t;
-
-#define EXT2_SEEK_SET 0
-#define EXT2_SEEK_CUR 1
-#define EXT2_SEEK_END 2
-
-/*
- * Flags for the ext2_filsys structure and for ext2fs_open()
- */
-#define EXT2_FLAG_RW 0x01
-#define EXT2_FLAG_CHANGED 0x02
-#define EXT2_FLAG_DIRTY 0x04
-#define EXT2_FLAG_VALID 0x08
-#define EXT2_FLAG_IB_DIRTY 0x10
-#define EXT2_FLAG_BB_DIRTY 0x20
-#define EXT2_FLAG_SWAP_BYTES 0x40
-#define EXT2_FLAG_SWAP_BYTES_READ 0x80
-#define EXT2_FLAG_SWAP_BYTES_WRITE 0x100
-#define EXT2_FLAG_MASTER_SB_ONLY 0x200
-#define EXT2_FLAG_FORCE 0x400
-#define EXT2_FLAG_SUPER_ONLY 0x800
-#define EXT2_FLAG_JOURNAL_DEV_OK 0x1000
-#define EXT2_FLAG_IMAGE_FILE 0x2000
-#define EXT2_FLAG_EXCLUSIVE 0x4000
-#define EXT2_FLAG_SOFTSUPP_FEATURES 0x8000
-#define EXT2_FLAG_NOFREE_ON_ERROR 0x10000
-#define EXT2_FLAG_64BITS 0x20000
-#define EXT2_FLAG_PRINT_PROGRESS 0x40000
-#define EXT2_FLAG_DIRECT_IO 0x80000
-#define EXT2_FLAG_SKIP_MMP 0x100000
-
-/*
- * Special flag in the ext2 inode i_flag field that means that this is
- * a new inode. (So that ext2_write_inode() can clear extra fields.)
- */
-#define EXT2_NEW_INODE_FL 0x80000000
-
-/*
- * Flags for mkjournal
- */
-#define EXT2_MKJOURNAL_V1_SUPER 0x0000001 /* create V1 superblock (deprecated) */
-#define EXT2_MKJOURNAL_LAZYINIT 0x0000002 /* don't zero journal inode before use*/
-
-struct opaque_ext2_group_desc;
-
-/*
- * The timestamp in the MMP structure will be updated by e2fsck at some
- * arbitary intervals (start of passes, after every EXT2_MMP_INODE_INTERVAL
- * inodes in pass1 and pass1b). There is no guarantee that e2fsck is updating
- * the MMP block in a timely manner, and the updates it does are purely for
- * the convenience of the sysadmin and not for automatic validation.
- */
-#define EXT2_MMP_INODE_INTERVAL 20000
-
-struct struct_ext2_filsys {
- errcode_t magic;
- io_channel io;
- int flags;
- char * device_name;
- struct ext2_super_block * super;
- unsigned int blocksize;
- int fragsize;
- dgrp_t group_desc_count;
- unsigned long desc_blocks;
- struct opaque_ext2_group_desc * group_desc;
- int inode_blocks_per_group;
- ext2fs_inode_bitmap inode_map;
- ext2fs_block_bitmap block_map;
- /* XXX FIXME-64: not 64-bit safe, but not used? */
- errcode_t (*get_blocks)(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
- errcode_t (*check_directory)(ext2_filsys fs, ext2_ino_t ino);
- errcode_t (*write_bitmaps)(ext2_filsys fs);
- errcode_t (*read_inode)(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode *inode);
- errcode_t (*write_inode)(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode *inode);
- ext2_badblocks_list badblocks;
- ext2_dblist dblist;
- __u32 stride; /* for mke2fs */
- struct ext2_super_block * orig_super;
- struct ext2_image_hdr * image_header;
- __u32 umask;
- time_t now;
- /*
- * Reserved for future expansion
- */
- __u32 reserved[7];
-
- /*
- * Reserved for the use of the calling application.
- */
- void * priv_data;
-
- /*
- * Inode cache
- */
- struct ext2_inode_cache *icache;
- io_channel image_io;
-
- /*
- * Buffers for Multiple mount protection(MMP) block.
- */
- void *mmp_buf;
- void *mmp_cmp;
- int mmp_fd;
-
- /*
- * Time at which e2fsck last updated the MMP block.
- */
- long mmp_last_written;
-
- /*
- * More callback functions
- */
- errcode_t (*get_alloc_block)(ext2_filsys fs, blk64_t goal,
- blk64_t *ret);
- void (*block_alloc_stats)(ext2_filsys fs, blk64_t blk, int inuse);
-};
-
-#if EXT2_FLAT_INCLUDES
-#include "e2_bitops.h"
-#else
-#include <ext2fs/bitops.h>
-#endif
-
-/*
- * Return flags for the block iterator functions
- */
-#define BLOCK_CHANGED 1
-#define BLOCK_ABORT 2
-#define BLOCK_ERROR 4
-
-/*
- * Block interate flags
- *
- * BLOCK_FLAG_APPEND, or BLOCK_FLAG_HOLE, indicates that the interator
- * function should be called on blocks where the block number is zero.
- * This is used by ext2fs_expand_dir() to be able to add a new block
- * to an inode. It can also be used for programs that want to be able
- * to deal with files that contain "holes".
- *
- * BLOCK_FLAG_DEPTH_TRAVERSE indicates that the iterator function for
- * the indirect, doubly indirect, etc. blocks should be called after
- * all of the blocks containined in the indirect blocks are processed.
- * This is useful if you are going to be deallocating blocks from an
- * inode.
- *
- * BLOCK_FLAG_DATA_ONLY indicates that the iterator function should be
- * called for data blocks only.
- *
- * BLOCK_FLAG_READ_ONLY is a promise by the caller that it will not
- * modify returned block number.
- *
- * BLOCK_FLAG_NO_LARGE is for internal use only. It informs
- * ext2fs_block_iterate2 that large files won't be accepted.
- */
-#define BLOCK_FLAG_APPEND 1
-#define BLOCK_FLAG_HOLE 1
-#define BLOCK_FLAG_DEPTH_TRAVERSE 2
-#define BLOCK_FLAG_DATA_ONLY 4
-#define BLOCK_FLAG_READ_ONLY 8
-
-#define BLOCK_FLAG_NO_LARGE 0x1000
-
-/*
- * Magic "block count" return values for the block iterator function.
- */
-#define BLOCK_COUNT_IND (-1)
-#define BLOCK_COUNT_DIND (-2)
-#define BLOCK_COUNT_TIND (-3)
-#define BLOCK_COUNT_TRANSLATOR (-4)
-
-#if 0
-/*
- * Flags for ext2fs_move_blocks
- */
-#define EXT2_BMOVE_GET_DBLIST 0x0001
-#define EXT2_BMOVE_DEBUG 0x0002
-#endif
-
-/*
- * Generic (non-filesystem layout specific) extents structure
- */
-
-#define EXT2_EXTENT_FLAGS_LEAF 0x0001
-#define EXT2_EXTENT_FLAGS_UNINIT 0x0002
-#define EXT2_EXTENT_FLAGS_SECOND_VISIT 0x0004
-
-struct ext2fs_extent {
- blk64_t e_pblk; /* first physical block */
- blk64_t e_lblk; /* first logical block extent covers */
- __u32 e_len; /* number of blocks covered by extent */
- __u32 e_flags; /* extent flags */
-};
-
-typedef struct ext2_extent_handle *ext2_extent_handle_t;
-typedef struct ext2_extent_path *ext2_extent_path_t;
-
-/*
- * Flags used by ext2fs_extent_get()
- */
-#define EXT2_EXTENT_CURRENT 0x0000
-#define EXT2_EXTENT_MOVE_MASK 0x000F
-#define EXT2_EXTENT_ROOT 0x0001
-#define EXT2_EXTENT_LAST_LEAF 0x0002
-#define EXT2_EXTENT_FIRST_SIB 0x0003
-#define EXT2_EXTENT_LAST_SIB 0x0004
-#define EXT2_EXTENT_NEXT_SIB 0x0005
-#define EXT2_EXTENT_PREV_SIB 0x0006
-#define EXT2_EXTENT_NEXT_LEAF 0x0007
-#define EXT2_EXTENT_PREV_LEAF 0x0008
-#define EXT2_EXTENT_NEXT 0x0009
-#define EXT2_EXTENT_PREV 0x000A
-#define EXT2_EXTENT_UP 0x000B
-#define EXT2_EXTENT_DOWN 0x000C
-#define EXT2_EXTENT_DOWN_AND_LAST 0x000D
-
-/*
- * Flags used by ext2fs_extent_insert()
- */
-#define EXT2_EXTENT_INSERT_AFTER 0x0001 /* insert after handle loc'n */
-#define EXT2_EXTENT_INSERT_NOSPLIT 0x0002 /* insert may not cause split */
-
-/*
- * Flags used by ext2fs_extent_delete()
- */
-#define EXT2_EXTENT_DELETE_KEEP_EMPTY 0x001 /* keep node if last extnt gone */
-
-/*
- * Flags used by ext2fs_extent_set_bmap()
- */
-#define EXT2_EXTENT_SET_BMAP_UNINIT 0x0001
-
-/*
- * Data structure returned by ext2fs_extent_get_info()
- */
-struct ext2_extent_info {
- int curr_entry;
- int curr_level;
- int num_entries;
- int max_entries;
- int max_depth;
- int bytes_avail;
- blk64_t max_lblk;
- blk64_t max_pblk;
- __u32 max_len;
- __u32 max_uninit_len;
-};
-
-/*
- * Flags for directory block reading and writing functions
- */
-#define EXT2_DIRBLOCK_V2_STRUCT 0x0001
-
-/*
- * Return flags for the directory iterator functions
- */
-#define DIRENT_CHANGED 1
-#define DIRENT_ABORT 2
-#define DIRENT_ERROR 3
-
-/*
- * Directory iterator flags
- */
-
-#define DIRENT_FLAG_INCLUDE_EMPTY 1
-#define DIRENT_FLAG_INCLUDE_REMOVED 2
-
-#define DIRENT_DOT_FILE 1
-#define DIRENT_DOT_DOT_FILE 2
-#define DIRENT_OTHER_FILE 3
-#define DIRENT_DELETED_FILE 4
-
-/*
- * Inode scan definitions
- */
-typedef struct ext2_struct_inode_scan *ext2_inode_scan;
-
-/*
- * ext2fs_scan flags
- */
-#define EXT2_SF_CHK_BADBLOCKS 0x0001
-#define EXT2_SF_BAD_INODE_BLK 0x0002
-#define EXT2_SF_BAD_EXTRA_BYTES 0x0004
-#define EXT2_SF_SKIP_MISSING_ITABLE 0x0008
-#define EXT2_SF_DO_LAZY 0x0010
-
-/*
- * ext2fs_check_if_mounted flags
- */
-#define EXT2_MF_MOUNTED 1
-#define EXT2_MF_ISROOT 2
-#define EXT2_MF_READONLY 4
-#define EXT2_MF_SWAP 8
-#define EXT2_MF_BUSY 16
-
-/*
- * Ext2/linux mode flags. We define them here so that we don't need
- * to depend on the OS's sys/stat.h, since we may be compiling on a
- * non-Linux system.
- */
-#define LINUX_S_IFMT 00170000
-#define LINUX_S_IFSOCK 0140000
-#define LINUX_S_IFLNK 0120000
-#define LINUX_S_IFREG 0100000
-#define LINUX_S_IFBLK 0060000
-#define LINUX_S_IFDIR 0040000
-#define LINUX_S_IFCHR 0020000
-#define LINUX_S_IFIFO 0010000
-#define LINUX_S_ISUID 0004000
-#define LINUX_S_ISGID 0002000
-#define LINUX_S_ISVTX 0001000
-
-#define LINUX_S_IRWXU 00700
-#define LINUX_S_IRUSR 00400
-#define LINUX_S_IWUSR 00200
-#define LINUX_S_IXUSR 00100
-
-#define LINUX_S_IRWXG 00070
-#define LINUX_S_IRGRP 00040
-#define LINUX_S_IWGRP 00020
-#define LINUX_S_IXGRP 00010
-
-#define LINUX_S_IRWXO 00007
-#define LINUX_S_IROTH 00004
-#define LINUX_S_IWOTH 00002
-#define LINUX_S_IXOTH 00001
-
-#define LINUX_S_ISLNK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFLNK)
-#define LINUX_S_ISREG(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFREG)
-#define LINUX_S_ISDIR(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFDIR)
-#define LINUX_S_ISCHR(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFCHR)
-#define LINUX_S_ISBLK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFBLK)
-#define LINUX_S_ISFIFO(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFIFO)
-#define LINUX_S_ISSOCK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFSOCK)
-
-/*
- * ext2 size of an inode
- */
-#define EXT2_I_SIZE(i) ((i)->i_size | ((__u64) (i)->i_size_high << 32))
-
-/*
- * ext2_icount_t abstraction
- */
-#define EXT2_ICOUNT_OPT_INCREMENT 0x01
-
-typedef struct ext2_icount *ext2_icount_t;
-
-/*
- * Flags for ext2fs_bmap
- */
-#define BMAP_ALLOC 0x0001
-#define BMAP_SET 0x0002
-
-/*
- * Returned flags from ext2fs_bmap
- */
-#define BMAP_RET_UNINIT 0x0001
-
-/*
- * Flags for imager.c functions
- */
-#define IMAGER_FLAG_INODEMAP 1
-#define IMAGER_FLAG_SPARSEWRITE 2
-
-/*
- * For checking structure magic numbers...
- */
-
-#define EXT2_CHECK_MAGIC(struct, code) \
- if ((struct)->magic != (code)) return (code)
-
-/*
- * Flags for returning status of ext2fs_expand_extra_isize()
- */
-#define EXT2_EXPAND_EISIZE_UNSAFE 0x0001
-#define EXT2_EXPAND_EISIZE_NEW_BLOCK 0x0002
-#define EXT2_EXPAND_EISIZE_NOSPC 0x0004
-
-/*
- * For ext2 compression support
- */
-#define EXT2FS_COMPRESSED_BLKADDR ((blk_t) -1)
-#define HOLE_BLKADDR(_b) ((_b) == 0 || (_b) == EXT2FS_COMPRESSED_BLKADDR)
-
-/*
- * Features supported by this version of the library
- */
-#define EXT2_LIB_FEATURE_COMPAT_SUPP (EXT2_FEATURE_COMPAT_DIR_PREALLOC|\
- EXT2_FEATURE_COMPAT_IMAGIC_INODES|\
- EXT3_FEATURE_COMPAT_HAS_JOURNAL|\
- EXT2_FEATURE_COMPAT_RESIZE_INODE|\
- EXT2_FEATURE_COMPAT_DIR_INDEX|\
- EXT2_FEATURE_COMPAT_EXT_ATTR)
-
-/* This #ifdef is temporary until compression is fully supported */
-#ifdef ENABLE_COMPRESSION
-#ifndef I_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL
-/* If the below warning bugs you, then have
- `CPPFLAGS=-DI_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL' in your
- environment at configure time. */
- #warning "Compression support is experimental"
-#endif
-#define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\
- EXT2_FEATURE_INCOMPAT_COMPRESSION|\
- EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
- EXT2_FEATURE_INCOMPAT_META_BG|\
- EXT3_FEATURE_INCOMPAT_RECOVER|\
- EXT3_FEATURE_INCOMPAT_EXTENTS|\
- EXT4_FEATURE_INCOMPAT_FLEX_BG|\
- EXT4_FEATURE_INCOMPAT_MMP|\
- EXT4_FEATURE_INCOMPAT_EA_INODE|\
- EXT4_FEATURE_INCOMPAT_64BIT)
-#else
-#define EXT2_LIB_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE|\
- EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
- EXT2_FEATURE_INCOMPAT_META_BG|\
- EXT3_FEATURE_INCOMPAT_RECOVER|\
- EXT3_FEATURE_INCOMPAT_EXTENTS|\
- EXT4_FEATURE_INCOMPAT_FLEX_BG|\
- EXT4_FEATURE_INCOMPAT_MMP|\
- EXT4_FEATURE_INCOMPAT_EA_INODE|\
- EXT4_FEATURE_INCOMPAT_64BIT)
-#endif
-#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
- EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE|\
- EXT4_FEATURE_RO_COMPAT_DIR_NLINK|\
- EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|\
- EXT4_FEATURE_RO_COMPAT_GDT_CSUM)
-
-/*
- * These features are only allowed if EXT2_FLAG_SOFTSUPP_FEATURES is passed
- * to ext2fs_openfs()
- */
-#define EXT2_LIB_SOFTSUPP_INCOMPAT (0)
-#define EXT2_LIB_SOFTSUPP_RO_COMPAT (0)
-
-/*
- * function prototypes
- */
-
-/* alloc.c */
-extern errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, int mode,
- ext2fs_inode_bitmap map, ext2_ino_t *ret);
-extern errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
- ext2fs_block_bitmap map, blk_t *ret);
-extern errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal,
- ext2fs_block_bitmap map, blk64_t *ret);
-extern errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start,
- blk_t finish, int num,
- ext2fs_block_bitmap map,
- blk_t *ret);
-extern errcode_t ext2fs_get_free_blocks2(ext2_filsys fs, blk64_t start,
- blk64_t finish, int num,
- ext2fs_block_bitmap map,
- blk64_t *ret);
-extern errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
- char *block_buf, blk_t *ret);
-extern errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal,
- char *block_buf, blk64_t *ret);
-extern void ext2fs_set_alloc_block_callback(ext2_filsys fs,
- errcode_t (*func)(ext2_filsys fs,
- blk64_t goal,
- blk64_t *ret),
- errcode_t (**old)(ext2_filsys fs,
- blk64_t goal,
- blk64_t *ret));
-
-/* alloc_sb.c */
-extern int ext2fs_reserve_super_and_bgd(ext2_filsys fs,
- dgrp_t group,
- ext2fs_block_bitmap bmap);
-extern void ext2fs_set_block_alloc_stats_callback(ext2_filsys fs,
- void (*func)(ext2_filsys fs,
- blk64_t blk,
- int inuse),
- void (**old)(ext2_filsys fs,
- blk64_t blk,
- int inuse));
-
-/* alloc_stats.c */
-void ext2fs_inode_alloc_stats(ext2_filsys fs, ext2_ino_t ino, int inuse);
-void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino,
- int inuse, int isdir);
-void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse);
-void ext2fs_block_alloc_stats2(ext2_filsys fs, blk64_t blk, int inuse);
-
-/* alloc_tables.c */
-extern errcode_t ext2fs_allocate_tables(ext2_filsys fs);
-extern errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
- ext2fs_block_bitmap bmap);
-
-/* badblocks.c */
-extern errcode_t ext2fs_u32_list_create(ext2_u32_list *ret, int size);
-extern errcode_t ext2fs_u32_list_add(ext2_u32_list bb, __u32 blk);
-extern int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk);
-extern int ext2fs_u32_list_test(ext2_u32_list bb, blk_t blk);
-extern errcode_t ext2fs_u32_list_iterate_begin(ext2_u32_list bb,
- ext2_u32_iterate *ret);
-extern int ext2fs_u32_list_iterate(ext2_u32_iterate iter, blk_t *blk);
-extern void ext2fs_u32_list_iterate_end(ext2_u32_iterate iter);
-extern errcode_t ext2fs_u32_copy(ext2_u32_list src, ext2_u32_list *dest);
-extern int ext2fs_u32_list_equal(ext2_u32_list bb1, ext2_u32_list bb2);
-
-extern errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret,
- int size);
-extern errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb,
- blk_t blk);
-extern int ext2fs_badblocks_list_test(ext2_badblocks_list bb,
- blk_t blk);
-extern int ext2fs_u32_list_del(ext2_u32_list bb, __u32 blk);
-extern void ext2fs_badblocks_list_del(ext2_u32_list bb, __u32 blk);
-extern errcode_t
- ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
- ext2_badblocks_iterate *ret);
-extern int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter,
- blk_t *blk);
-extern void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter);
-extern errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
- ext2_badblocks_list *dest);
-extern int ext2fs_badblocks_equal(ext2_badblocks_list bb1,
- ext2_badblocks_list bb2);
-extern int ext2fs_u32_list_count(ext2_u32_list bb);
-
-/* bb_compat */
-extern errcode_t badblocks_list_create(badblocks_list *ret, int size);
-extern errcode_t badblocks_list_add(badblocks_list bb, blk_t blk);
-extern int badblocks_list_test(badblocks_list bb, blk_t blk);
-extern errcode_t badblocks_list_iterate_begin(badblocks_list bb,
- badblocks_iterate *ret);
-extern int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk);
-extern void badblocks_list_iterate_end(badblocks_iterate iter);
-extern void badblocks_list_free(badblocks_list bb);
-
-/* bb_inode.c */
-extern errcode_t ext2fs_update_bb_inode(ext2_filsys fs,
- ext2_badblocks_list bb_list);
-
-/* bitmaps.c */
-extern void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap);
-extern void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap);
-extern errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
- ext2fs_generic_bitmap *dest);
-extern errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs);
-extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
-extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
-extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
-extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
- const char *descr,
- ext2fs_block_bitmap *ret);
-extern errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
- const char *descr,
- ext2fs_inode_bitmap *ret);
-extern errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
- ext2_ino_t end, ext2_ino_t *oend);
-extern errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
- blk_t end, blk_t *oend);
-extern errcode_t ext2fs_fudge_block_bitmap_end2(ext2fs_block_bitmap bitmap,
- blk64_t end, blk64_t *oend);
-extern void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap);
-extern void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap);
-extern errcode_t ext2fs_read_bitmaps(ext2_filsys fs);
-extern errcode_t ext2fs_write_bitmaps(ext2_filsys fs);
-extern errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
- ext2fs_inode_bitmap bmap);
-extern errcode_t ext2fs_resize_inode_bitmap2(__u64 new_end,
- __u64 new_real_end,
- ext2fs_inode_bitmap bmap);
-extern errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
- ext2fs_block_bitmap bmap);
-extern errcode_t ext2fs_resize_block_bitmap2(__u64 new_end,
- __u64 new_real_end,
- ext2fs_block_bitmap bmap);
-extern errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
- ext2fs_block_bitmap bm2);
-extern errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
- ext2fs_inode_bitmap bm2);
-extern errcode_t ext2fs_set_inode_bitmap_range(ext2fs_inode_bitmap bmap,
- ext2_ino_t start, unsigned int num,
- void *in);
-extern errcode_t ext2fs_set_inode_bitmap_range2(ext2fs_inode_bitmap bmap,
- __u64 start, size_t num,
- void *in);
-extern errcode_t ext2fs_get_inode_bitmap_range(ext2fs_inode_bitmap bmap,
- ext2_ino_t start, unsigned int num,
- void *out);
-extern errcode_t ext2fs_get_inode_bitmap_range2(ext2fs_inode_bitmap bmap,
- __u64 start, size_t num,
- void *out);
-extern errcode_t ext2fs_set_block_bitmap_range(ext2fs_block_bitmap bmap,
- blk_t start, unsigned int num,
- void *in);
-extern errcode_t ext2fs_set_block_bitmap_range2(ext2fs_block_bitmap bmap,
- blk64_t start, size_t num,
- void *in);
-extern errcode_t ext2fs_get_block_bitmap_range(ext2fs_block_bitmap bmap,
- blk_t start, unsigned int num,
- void *out);
-extern errcode_t ext2fs_get_block_bitmap_range2(ext2fs_block_bitmap bmap,
- blk64_t start, size_t num,
- void *out);
-
-/* blknum.c */
-extern dgrp_t ext2fs_group_of_blk2(ext2_filsys fs, blk64_t);
-extern blk64_t ext2fs_group_first_block2(ext2_filsys fs, dgrp_t group);
-extern blk64_t ext2fs_group_last_block2(ext2_filsys fs, dgrp_t group);
-extern blk64_t ext2fs_inode_data_blocks2(ext2_filsys fs,
- struct ext2_inode *inode);
-extern blk64_t ext2fs_inode_i_blocks(ext2_filsys fs,
- struct ext2_inode *inode);
-extern blk64_t ext2fs_blocks_count(struct ext2_super_block *super);
-extern void ext2fs_blocks_count_set(struct ext2_super_block *super,
- blk64_t blk);
-extern void ext2fs_blocks_count_add(struct ext2_super_block *super,
- blk64_t blk);
-extern blk64_t ext2fs_r_blocks_count(struct ext2_super_block *super);
-extern void ext2fs_r_blocks_count_set(struct ext2_super_block *super,
- blk64_t blk);
-extern void ext2fs_r_blocks_count_add(struct ext2_super_block *super,
- blk64_t blk);
-extern blk64_t ext2fs_free_blocks_count(struct ext2_super_block *super);
-extern void ext2fs_free_blocks_count_set(struct ext2_super_block *super,
- blk64_t blk);
-extern void ext2fs_free_blocks_count_add(struct ext2_super_block *super,
- blk64_t blk);
-/* Block group descriptor accessor functions */
-extern struct ext2_group_desc *ext2fs_group_desc(ext2_filsys fs,
- struct opaque_ext2_group_desc *gdp,
- dgrp_t group);
-extern blk64_t ext2fs_block_bitmap_loc(ext2_filsys fs, dgrp_t group);
-extern void ext2fs_block_bitmap_loc_set(ext2_filsys fs, dgrp_t group,
- blk64_t blk);
-extern blk64_t ext2fs_inode_bitmap_loc(ext2_filsys fs, dgrp_t group);
-extern void ext2fs_inode_bitmap_loc_set(ext2_filsys fs, dgrp_t group,
- blk64_t blk);
-extern blk64_t ext2fs_inode_table_loc(ext2_filsys fs, dgrp_t group);
-extern void ext2fs_inode_table_loc_set(ext2_filsys fs, dgrp_t group,
- blk64_t blk);
-extern __u32 ext2fs_bg_free_blocks_count(ext2_filsys fs, dgrp_t group);
-extern void ext2fs_bg_free_blocks_count_set(ext2_filsys fs, dgrp_t group,
- __u32 n);
-extern __u32 ext2fs_bg_free_inodes_count(ext2_filsys fs, dgrp_t group);
-extern void ext2fs_bg_free_inodes_count_set(ext2_filsys fs, dgrp_t group,
- __u32 n);
-extern __u32 ext2fs_bg_used_dirs_count(ext2_filsys fs, dgrp_t group);
-extern void ext2fs_bg_used_dirs_count_set(ext2_filsys fs, dgrp_t group,
- __u32 n);
-extern __u32 ext2fs_bg_itable_unused(ext2_filsys fs, dgrp_t group);
-extern void ext2fs_bg_itable_unused_set(ext2_filsys fs, dgrp_t group,
- __u32 n);
-extern __u16 ext2fs_bg_flags(ext2_filsys fs, dgrp_t group);
-extern void ext2fs_bg_flags_zap(ext2_filsys fs, dgrp_t group);
-extern int ext2fs_bg_flags_test(ext2_filsys fs, dgrp_t group, __u16 bg_flag);
-extern void ext2fs_bg_flags_set(ext2_filsys fs, dgrp_t group, __u16 bg_flags);
-extern void ext2fs_bg_flags_clear(ext2_filsys fs, dgrp_t group, __u16 bg_flags);
-extern __u16 ext2fs_bg_checksum(ext2_filsys fs, dgrp_t group);
-extern void ext2fs_bg_checksum_set(ext2_filsys fs, dgrp_t group, __u16 checksum);
-extern blk64_t ext2fs_file_acl_block(const struct ext2_inode *inode);
-extern void ext2fs_file_acl_block_set(struct ext2_inode *inode, blk64_t blk);
-
-/* block.c */
-extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
- ext2_ino_t ino,
- int flags,
- char *block_buf,
- int (*func)(ext2_filsys fs,
- blk_t *blocknr,
- int blockcnt,
- void *priv_data),
- void *priv_data);
-errcode_t ext2fs_block_iterate2(ext2_filsys fs,
- ext2_ino_t ino,
- int flags,
- char *block_buf,
- int (*func)(ext2_filsys fs,
- blk_t *blocknr,
- e2_blkcnt_t blockcnt,
- blk_t ref_blk,
- int ref_offset,
- void *priv_data),
- void *priv_data);
-errcode_t ext2fs_block_iterate3(ext2_filsys fs,
- ext2_ino_t ino,
- int flags,
- char *block_buf,
- int (*func)(ext2_filsys fs,
- blk64_t *blocknr,
- e2_blkcnt_t blockcnt,
- blk64_t ref_blk,
- int ref_offset,
- void *priv_data),
- void *priv_data);
-
-/* bmap.c */
-extern errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode *inode,
- char *block_buf, int bmap_flags,
- blk_t block, blk_t *phys_blk);
-extern errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode *inode,
- char *block_buf, int bmap_flags, blk64_t block,
- int *ret_flags, blk64_t *phys_blk);
-
-#if 0
-/* bmove.c */
-extern errcode_t ext2fs_move_blocks(ext2_filsys fs,
- ext2fs_block_bitmap reserve,
- ext2fs_block_bitmap alloc_map,
- int flags);
-#endif
-
-/* check_desc.c */
-extern errcode_t ext2fs_check_desc(ext2_filsys fs);
-
-/* closefs.c */
-extern errcode_t ext2fs_close(ext2_filsys fs);
-extern errcode_t ext2fs_flush(ext2_filsys fs);
-extern int ext2fs_bg_has_super(ext2_filsys fs, int group_block);
-extern errcode_t ext2fs_super_and_bgd_loc2(ext2_filsys fs,
- dgrp_t group,
- blk64_t *ret_super_blk,
- blk64_t *ret_old_desc_blk,
- blk64_t *ret_new_desc_blk,
- blk_t *ret_used_blks);
-extern int ext2fs_super_and_bgd_loc(ext2_filsys fs,
- dgrp_t group,
- blk_t *ret_super_blk,
- blk_t *ret_old_desc_blk,
- blk_t *ret_new_desc_blk,
- int *ret_meta_bg);
-extern void ext2fs_update_dynamic_rev(ext2_filsys fs);
-
-/* csum.c */
-extern void ext2fs_group_desc_csum_set(ext2_filsys fs, dgrp_t group);
-extern int ext2fs_group_desc_csum_verify(ext2_filsys fs, dgrp_t group);
-extern errcode_t ext2fs_set_gdt_csum(ext2_filsys fs);
-
-/* dblist.c */
-
-extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs);
-extern errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist);
-extern errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino,
- blk_t blk, int blockcnt);
-extern errcode_t ext2fs_add_dir_block2(ext2_dblist dblist, ext2_ino_t ino,
- blk64_t blk, e2_blkcnt_t blockcnt);
-extern void ext2fs_dblist_sort(ext2_dblist dblist,
- EXT2_QSORT_TYPE (*sortfunc)(const void *,
- const void *));
-extern void ext2fs_dblist_sort2(ext2_dblist dblist,
- EXT2_QSORT_TYPE (*sortfunc)(const void *,
- const void *));
-extern errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
- int (*func)(ext2_filsys fs, struct ext2_db_entry *db_info,
- void *priv_data),
- void *priv_data);
-extern errcode_t ext2fs_dblist_iterate2(ext2_dblist dblist,
- int (*func)(ext2_filsys fs, struct ext2_db_entry2 *db_info,
- void *priv_data),
- void *priv_data);
-extern errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino,
- blk_t blk, int blockcnt);
-extern errcode_t ext2fs_set_dir_block2(ext2_dblist dblist, ext2_ino_t ino,
- blk64_t blk, e2_blkcnt_t blockcnt);
-extern errcode_t ext2fs_copy_dblist(ext2_dblist src,
- ext2_dblist *dest);
-extern int ext2fs_dblist_count(ext2_dblist dblist);
-extern blk64_t ext2fs_dblist_count2(ext2_dblist dblist);
-extern errcode_t ext2fs_dblist_get_last(ext2_dblist dblist,
- struct ext2_db_entry **entry);
-extern errcode_t ext2fs_dblist_get_last2(ext2_dblist dblist,
- struct ext2_db_entry2 **entry);
-extern errcode_t ext2fs_dblist_drop_last(ext2_dblist dblist);
-
-/* dblist_dir.c */
-extern errcode_t
- ext2fs_dblist_dir_iterate(ext2_dblist dblist,
- int flags,
- char *block_buf,
- int (*func)(ext2_ino_t dir,
- int entry,
- struct ext2_dir_entry *dirent,
- int offset,
- int blocksize,
- char *buf,
- void *priv_data),
- void *priv_data);
-
-/* dirblock.c */
-extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
- void *buf);
-extern errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block,
- void *buf, int flags);
-extern errcode_t ext2fs_read_dir_block3(ext2_filsys fs, blk64_t block,
- void *buf, int flags);
-extern errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
- void *buf);
-extern errcode_t ext2fs_write_dir_block2(ext2_filsys fs, blk_t block,
- void *buf, int flags);
-extern errcode_t ext2fs_write_dir_block3(ext2_filsys fs, blk64_t block,
- void *buf, int flags);
-
-/* dirhash.c */
-extern errcode_t ext2fs_dirhash(int version, const char *name, int len,
- const __u32 *seed,
- ext2_dirhash_t *ret_hash,
- ext2_dirhash_t *ret_minor_hash);
-
-
-/* dir_iterate.c */
-extern errcode_t ext2fs_get_rec_len(ext2_filsys fs,
- struct ext2_dir_entry *dirent,
- unsigned int *rec_len);
-extern errcode_t ext2fs_set_rec_len(ext2_filsys fs,
- unsigned int len,
- struct ext2_dir_entry *dirent);
-extern errcode_t ext2fs_dir_iterate(ext2_filsys fs,
- ext2_ino_t dir,
- int flags,
- char *block_buf,
- int (*func)(struct ext2_dir_entry *dirent,
- int offset,
- int blocksize,
- char *buf,
- void *priv_data),
- void *priv_data);
-extern errcode_t ext2fs_dir_iterate2(ext2_filsys fs,
- ext2_ino_t dir,
- int flags,
- char *block_buf,
- int (*func)(ext2_ino_t dir,
- int entry,
- struct ext2_dir_entry *dirent,
- int offset,
- int blocksize,
- char *buf,
- void *priv_data),
- void *priv_data);
-
-/* dupfs.c */
-extern errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest);
-
-/* expanddir.c */
-extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir);
-
-/* ext_attr.c */
-extern errcode_t ext2fs_attr_get(ext2_filsys fs, struct ext2_inode *inode,
- int name_index, const char *name, char *buffer,
- size_t buffer_size, int *easize);
-
-extern __u32 ext2fs_ext_attr_hash_entry(struct ext2_ext_attr_entry *entry,
- void *data);
-int ext2fs_attr_get_next_attr(struct ext2_ext_attr_entry *entry, int name_index,
- char *buffer, int buffer_size, int start);
-errcode_t ext2fs_attr_set(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode *inode,
- int name_index, const char *name, const char *value,
- int value_len, int flags);
-extern errcode_t ext2fs_expand_extra_isize(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode_large *inode,
- int new_extra_isize, int *ret,
- int *needed_size);
-extern errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf);
-extern errcode_t ext2fs_read_ext_attr2(ext2_filsys fs, blk64_t block,
- void *buf);
-extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block,
- void *buf);
-extern errcode_t ext2fs_write_ext_attr2(ext2_filsys fs, blk64_t block,
- void *buf);
-extern errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
- char *block_buf,
- int adjust, __u32 *newcount);
-extern errcode_t ext2fs_adjust_ea_refcount2(ext2_filsys fs, blk64_t blk,
- char *block_buf,
- int adjust, __u32 *newcount);
-
-/* extent.c */
-extern errcode_t ext2fs_extent_header_verify(void *ptr, int size);
-extern errcode_t ext2fs_extent_open(ext2_filsys fs, ext2_ino_t ino,
- ext2_extent_handle_t *handle);
-extern errcode_t ext2fs_extent_open2(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode *inode,
- ext2_extent_handle_t *ret_handle);
-extern void ext2fs_extent_free(ext2_extent_handle_t handle);
-extern errcode_t ext2fs_extent_get(ext2_extent_handle_t handle,
- int flags, struct ext2fs_extent *extent);
-extern errcode_t ext2fs_extent_replace(ext2_extent_handle_t handle, int flags,
- struct ext2fs_extent *extent);
-extern errcode_t ext2fs_extent_insert(ext2_extent_handle_t handle, int flags,
- struct ext2fs_extent *extent);
-extern errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
- blk64_t logical, blk64_t physical,
- int flags);
-extern errcode_t ext2fs_extent_delete(ext2_extent_handle_t handle, int flags);
-extern errcode_t ext2fs_extent_get_info(ext2_extent_handle_t handle,
- struct ext2_extent_info *info);
-extern errcode_t ext2fs_extent_goto(ext2_extent_handle_t handle,
- blk64_t blk);
-
-/* fileio.c */
-extern errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode *inode,
- int flags, ext2_file_t *ret);
-extern errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino,
- int flags, ext2_file_t *ret);
-extern ext2_filsys ext2fs_file_get_fs(ext2_file_t file);
-struct ext2_inode *ext2fs_file_get_inode(ext2_file_t file);
-extern errcode_t ext2fs_file_close(ext2_file_t file);
-extern errcode_t ext2fs_file_flush(ext2_file_t file);
-extern errcode_t ext2fs_file_read(ext2_file_t file, void *buf,
- unsigned int wanted, unsigned int *got);
-extern errcode_t ext2fs_file_write(ext2_file_t file, const void *buf,
- unsigned int nbytes, unsigned int *written);
-extern errcode_t ext2fs_file_llseek(ext2_file_t file, __u64 offset,
- int whence, __u64 *ret_pos);
-extern errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
- int whence, ext2_off_t *ret_pos);
-errcode_t ext2fs_file_get_lsize(ext2_file_t file, __u64 *ret_size);
-extern ext2_off_t ext2fs_file_get_size(ext2_file_t file);
-extern errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size);
-extern errcode_t ext2fs_file_set_size2(ext2_file_t file, ext2_off64_t size);
-
-/* finddev.c */
-extern char *ext2fs_find_block_device(dev_t device);
-
-/* flushb.c */
-extern errcode_t ext2fs_sync_device(int fd, int flushb);
-
-/* freefs.c */
-extern void ext2fs_free(ext2_filsys fs);
-extern void ext2fs_free_dblist(ext2_dblist dblist);
-extern void ext2fs_badblocks_list_free(ext2_badblocks_list bb);
-extern void ext2fs_u32_list_free(ext2_u32_list bb);
-
-/* gen_bitmap.c */
-extern void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap);
-extern errcode_t ext2fs_make_generic_bitmap(errcode_t magic, ext2_filsys fs,
- __u32 start, __u32 end,
- __u32 real_end,
- const char *descr, char *init_map,
- ext2fs_generic_bitmap *ret);
-extern errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
- __u32 end,
- __u32 real_end,
- const char *descr,
- ext2fs_generic_bitmap *ret);
-extern errcode_t ext2fs_copy_generic_bitmap(ext2fs_generic_bitmap src,
- ext2fs_generic_bitmap *dest);
-extern void ext2fs_clear_generic_bitmap(ext2fs_generic_bitmap bitmap);
-extern errcode_t ext2fs_fudge_generic_bitmap_end(ext2fs_inode_bitmap bitmap,
- errcode_t magic,
- errcode_t neq,
- ext2_ino_t end,
- ext2_ino_t *oend);
-extern void ext2fs_set_generic_bitmap_padding(ext2fs_generic_bitmap map);
-extern errcode_t ext2fs_resize_generic_bitmap(errcode_t magic,
- __u32 new_end,
- __u32 new_real_end,
- ext2fs_generic_bitmap bmap);
-extern errcode_t ext2fs_compare_generic_bitmap(errcode_t magic, errcode_t neq,
- ext2fs_generic_bitmap bm1,
- ext2fs_generic_bitmap bm2);
-extern errcode_t ext2fs_get_generic_bitmap_range(ext2fs_generic_bitmap bmap,
- errcode_t magic,
- __u32 start, __u32 num,
- void *out);
-extern errcode_t ext2fs_set_generic_bitmap_range(ext2fs_generic_bitmap bmap,
- errcode_t magic,
- __u32 start, __u32 num,
- void *in);
-
-/* gen_bitmap64.c */
-void ext2fs_free_generic_bmap(ext2fs_generic_bitmap bmap);
-errcode_t ext2fs_alloc_generic_bmap(ext2_filsys fs, errcode_t magic,
- int type, __u64 start, __u64 end,
- __u64 real_end,
- const char *descr,
- ext2fs_generic_bitmap *ret);
-errcode_t ext2fs_copy_generic_bmap(ext2fs_generic_bitmap src,
- ext2fs_generic_bitmap *dest);
-void ext2fs_clear_generic_bmap(ext2fs_generic_bitmap bitmap);
-errcode_t ext2fs_fudge_generic_bmap_end(ext2fs_generic_bitmap bitmap,
- errcode_t neq,
- __u64 end, __u64 *oend);
-void ext2fs_set_generic_bmap_padding(ext2fs_generic_bitmap bmap);
-errcode_t ext2fs_resize_generic_bmap(ext2fs_generic_bitmap bmap,
- __u64 new_end,
- __u64 new_real_end);
-errcode_t ext2fs_compare_generic_bmap(errcode_t neq,
- ext2fs_generic_bitmap bm1,
- ext2fs_generic_bitmap bm2);
-errcode_t ext2fs_get_generic_bmap_range(ext2fs_generic_bitmap bmap,
- __u64 start, unsigned int num,
- void *out);
-errcode_t ext2fs_set_generic_bmap_range(ext2fs_generic_bitmap bmap,
- __u64 start, unsigned int num,
- void *in);
-
-/* getsize.c */
-extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
- blk_t *retblocks);
-extern errcode_t ext2fs_get_device_size2(const char *file, int blocksize,
- blk64_t *retblocks);
-
-/* getsectsize.c */
-errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize);
-errcode_t ext2fs_get_device_phys_sectsize(const char *file, int *sectsize);
-
-/* i_block.c */
-errcode_t ext2fs_iblk_add_blocks(ext2_filsys fs, struct ext2_inode *inode,
- blk64_t num_blocks);
-errcode_t ext2fs_iblk_sub_blocks(ext2_filsys fs, struct ext2_inode *inode,
- blk64_t num_blocks);
-errcode_t ext2fs_iblk_set(ext2_filsys fs, struct ext2_inode *inode, blk64_t b);
-
-/* imager.c */
-extern errcode_t ext2fs_image_inode_write(ext2_filsys fs, int fd, int flags);
-extern errcode_t ext2fs_image_inode_read(ext2_filsys fs, int fd, int flags);
-extern errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd, int flags);
-extern errcode_t ext2fs_image_super_read(ext2_filsys fs, int fd, int flags);
-extern errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags);
-extern errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags);
-
-/* ind_block.c */
-errcode_t ext2fs_read_ind_block(ext2_filsys fs, blk_t blk, void *buf);
-errcode_t ext2fs_write_ind_block(ext2_filsys fs, blk_t blk, void *buf);
-
-/* initialize.c */
-extern errcode_t ext2fs_initialize(const char *name, int flags,
- struct ext2_super_block *param,
- io_manager manager, ext2_filsys *ret_fs);
-
-/* icount.c */
-extern void ext2fs_free_icount(ext2_icount_t icount);
-extern int ext2fs_icount_is_set(ext2_icount_t icount, ext2_ino_t ino);
-extern errcode_t ext2fs_create_icount_tdb(ext2_filsys fs, char *tdb_dir,
- int flags, ext2_icount_t *ret);
-extern errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags,
- unsigned int size,
- ext2_icount_t hint, ext2_icount_t *ret);
-extern errcode_t ext2fs_create_icount(ext2_filsys fs, int flags,
- unsigned int size,
- ext2_icount_t *ret);
-extern errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino,
- __u16 *ret);
-extern errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
- __u16 *ret);
-extern errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
- __u16 *ret);
-extern errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
- __u16 count);
-extern ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount);
-errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *);
-
-/* inode.c */
-extern errcode_t ext2fs_flush_icache(ext2_filsys fs);
-extern errcode_t ext2fs_get_next_inode_full(ext2_inode_scan scan,
- ext2_ino_t *ino,
- struct ext2_inode *inode,
- int bufsize);
-extern errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
- ext2_inode_scan *ret_scan);
-extern void ext2fs_close_inode_scan(ext2_inode_scan scan);
-extern errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,
- struct ext2_inode *inode);
-extern errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan,
- int group);
-extern void ext2fs_set_inode_callback
- (ext2_inode_scan scan,
- errcode_t (*done_group)(ext2_filsys fs,
- ext2_inode_scan scan,
- dgrp_t group,
- void * priv_data),
- void *done_group_data);
-extern int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
- int clear_flags);
-extern errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode * inode,
- int bufsize);
-extern errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode * inode);
-extern errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode * inode,
- int bufsize);
-extern errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode * inode);
-extern errcode_t ext2fs_write_new_inode(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode * inode);
-extern errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
-extern errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino);
-
-/* inode_io.c */
-extern io_manager inode_io_manager;
-extern errcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino,
- char **name);
-extern errcode_t ext2fs_inode_io_intern2(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode *inode,
- char **name);
-
-/* ismounted.c */
-extern errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags);
-extern errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
- char *mtpt, int mtlen);
-
-/* punch.c */
-extern errcode_t ext2fs_punch(ext2_filsys fs, ext2_ino_t ino,
- struct ext2_inode *inode,
- char *block_buf, blk64_t start,
- blk64_t end);
-
-/* namei.c */
-extern errcode_t ext2fs_lookup(ext2_filsys fs, ext2_ino_t dir, const char *name,
- int namelen, char *buf, ext2_ino_t *inode);
-extern errcode_t ext2fs_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
- const char *name, ext2_ino_t *inode);
-errcode_t ext2fs_namei_follow(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
- const char *name, ext2_ino_t *inode);
-extern errcode_t ext2fs_follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
- ext2_ino_t inode, ext2_ino_t *res_inode);
-
-/* native.c */
-int ext2fs_native_flag(void);
-
-/* newdir.c */
-extern errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
- ext2_ino_t parent_ino, char **block);
-
-/* mkdir.c */
-extern errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
- const char *name);
-
-/* mkjournal.c */
-extern errcode_t ext2fs_zero_blocks(ext2_filsys fs, blk_t blk, int num,
- blk_t *ret_blk, int *ret_count);
-extern errcode_t ext2fs_zero_blocks2(ext2_filsys fs, blk64_t blk, int num,
- blk64_t *ret_blk, int *ret_count);
-extern errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
- __u32 blocks, int flags,
- char **ret_jsb);
-extern errcode_t ext2fs_add_journal_device(ext2_filsys fs,
- ext2_filsys journal_dev);
-extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t blocks,
- int flags);
-extern int ext2fs_default_journal_size(__u64 blocks);
-
-/* openfs.c */
-extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
- unsigned int block_size, io_manager manager,
- ext2_filsys *ret_fs);
-extern errcode_t ext2fs_open2(const char *name, const char *io_options,
- int flags, int superblock,
- unsigned int block_size, io_manager manager,
- ext2_filsys *ret_fs);
-extern blk64_t ext2fs_descriptor_block_loc2(ext2_filsys fs,
- blk64_t group_block, dgrp_t i);
-extern blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block,
- dgrp_t i);
-errcode_t ext2fs_get_data_io(ext2_filsys fs, io_channel *old_io);
-errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io);
-errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io);
-
-/* get_pathname.c */
-extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
- char **name);
-
-/* link.c */
-errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
- ext2_ino_t ino, int flags);
-errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, const char *name,
- ext2_ino_t ino, int flags);
-
-/* mmp.c */
-errcode_t ext2fs_mmp_read(ext2_filsys fs, blk64_t mmp_blk, void *buf);
-errcode_t ext2fs_mmp_write(ext2_filsys fs, blk64_t mmp_blk, void *buf);
-errcode_t ext2fs_mmp_clear(ext2_filsys fs);
-errcode_t ext2fs_mmp_init(ext2_filsys fs);
-errcode_t ext2fs_mmp_start(ext2_filsys fs);
-errcode_t ext2fs_mmp_update(ext2_filsys fs);
-errcode_t ext2fs_mmp_stop(ext2_filsys fs);
-unsigned ext2fs_mmp_new_seq();
-
-/* read_bb.c */
-extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs,
- ext2_badblocks_list *bb_list);
-
-/* read_bb_file.c */
-extern errcode_t ext2fs_read_bb_FILE2(ext2_filsys fs, FILE *f,
- ext2_badblocks_list *bb_list,
- void *priv_data,
- void (*invalid)(ext2_filsys fs,
- blk_t blk,
- char *badstr,
- void *priv_data));
-extern errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
- ext2_badblocks_list *bb_list,
- void (*invalid)(ext2_filsys fs,
- blk_t blk));
-
-/* res_gdt.c */
-extern errcode_t ext2fs_create_resize_inode(ext2_filsys fs);
-
-/* swapfs.c */
-extern void ext2fs_swap_ext_attr(char *to, char *from, int bufsize,
- int has_header);
-extern void ext2fs_swap_ext_attr_header(struct ext2_ext_attr_header *to_header,
- struct ext2_ext_attr_header *from_hdr);
-extern void ext2fs_swap_ext_attr_entry(struct ext2_ext_attr_entry *to_entry,
- struct ext2_ext_attr_entry *from_entry);
-extern void ext2fs_swap_super(struct ext2_super_block * super);
-extern void ext2fs_swap_group_desc(struct ext2_group_desc *gdp);
-extern void ext2fs_swap_group_desc2(ext2_filsys, struct ext2_group_desc *gdp);
-extern void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
- struct ext2_inode_large *f, int hostorder,
- int bufsize);
-extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t,
- struct ext2_inode *f, int hostorder);
-extern void ext2fs_swap_mmp(struct mmp_struct *mmp);
-
-/* valid_blk.c */
-extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode);
-
-/* version.c */
-extern int ext2fs_parse_version_string(const char *ver_string);
-extern int ext2fs_get_library_version(const char **ver_string,
- const char **date_string);
-
-/* write_bb_file.c */
-extern errcode_t ext2fs_write_bb_FILE(ext2_badblocks_list bb_list,
- unsigned int flags,
- FILE *f);
-
-
-/* inline functions */
-extern errcode_t ext2fs_get_mem(unsigned long size, void *ptr);
-extern errcode_t ext2fs_get_memalign(unsigned long size,
- unsigned long align, void *ptr);
-extern errcode_t ext2fs_free_mem(void *ptr);
-extern errcode_t ext2fs_resize_mem(unsigned long old_size,
- unsigned long size, void *ptr);
-extern void ext2fs_mark_super_dirty(ext2_filsys fs);
-extern void ext2fs_mark_changed(ext2_filsys fs);
-extern int ext2fs_test_changed(ext2_filsys fs);
-extern void ext2fs_mark_valid(ext2_filsys fs);
-extern void ext2fs_unmark_valid(ext2_filsys fs);
-extern int ext2fs_test_valid(ext2_filsys fs);
-extern void ext2fs_mark_ib_dirty(ext2_filsys fs);
-extern void ext2fs_mark_bb_dirty(ext2_filsys fs);
-extern int ext2fs_test_ib_dirty(ext2_filsys fs);
-extern int ext2fs_test_bb_dirty(ext2_filsys fs);
-extern int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk);
-extern int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino);
-extern blk_t ext2fs_group_first_block(ext2_filsys fs, dgrp_t group);
-extern blk_t ext2fs_group_last_block(ext2_filsys fs, dgrp_t group);
-extern blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
- struct ext2_inode *inode);
-extern unsigned int ext2fs_div_ceil(unsigned int a, unsigned int b);
-extern __u64 ext2fs_div64_ceil(__u64 a, __u64 b);
-
-/*
- * The actual inlined functions definitions themselves...
- *
- * If NO_INLINE_FUNCS is defined, then we won't try to do inline
- * functions at all!
- */
-#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
-#ifdef INCLUDE_INLINE_FUNCS
-#define _INLINE_ extern
-#else
-#ifdef __GNUC__
-#define _INLINE_ extern __inline__
-#else /* For Watcom C */
-#define _INLINE_ extern inline
-#endif
-#endif
-
-#ifndef EXT2_CUSTOM_MEMORY_ROUTINES
-#include <string.h>
-/*
- * Allocate memory
- */
-_INLINE_ errcode_t ext2fs_get_mem(unsigned long size, void *ptr)
-{
- void *pp;
-
- pp = malloc(size);
- if (!pp)
- return EXT2_ET_NO_MEMORY;
- memcpy(ptr, &pp, sizeof (pp));
- return 0;
-}
-
-_INLINE_ errcode_t ext2fs_get_memalign(unsigned long size,
- unsigned long align, void *ptr)
-{
- errcode_t retval;
-
- if (align == 0)
- align = 8;
- retval = posix_memalign((void **)ptr, align, size);
- if (retval != 0) {
- if (retval == ENOMEM)
- return EXT2_ET_NO_MEMORY;
- return retval;
- }
- return 0;
-}
-
-_INLINE_ errcode_t ext2fs_get_array(unsigned long count, unsigned long size, void *ptr)
-{
- if (count && (-1UL)/count<size)
- return EXT2_ET_NO_MEMORY; //maybe define EXT2_ET_OVERFLOW ?
- return ext2fs_get_mem(count*size, ptr);
-}
-
-/*
- * Free memory
- */
-_INLINE_ errcode_t ext2fs_free_mem(void *ptr)
-{
- void *p;
-
- memcpy(&p, ptr, sizeof(p));
- free(p);
- p = 0;
- memcpy(ptr, &p, sizeof(p));
- return 0;
-}
-
-/*
- * Resize memory
- */
-_INLINE_ errcode_t ext2fs_resize_mem(unsigned long EXT2FS_ATTR((unused)) old_size,
- unsigned long size, void *ptr)
-{
- void *p;
-
- /* Use "memcpy" for pointer assignments here to avoid problems
- * with C99 strict type aliasing rules. */
- memcpy(&p, ptr, sizeof(p));
- p = realloc(p, size);
- if (!p)
- return EXT2_ET_NO_MEMORY;
- memcpy(ptr, &p, sizeof(p));
- return 0;
-}
-#endif /* Custom memory routines */
-
-/*
- * Mark a filesystem superblock as dirty
- */
-_INLINE_ void ext2fs_mark_super_dirty(ext2_filsys fs)
-{
- fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_CHANGED;
-}
-
-/*
- * Mark a filesystem as changed
- */
-_INLINE_ void ext2fs_mark_changed(ext2_filsys fs)
-{
- fs->flags |= EXT2_FLAG_CHANGED;
-}
-
-/*
- * Check to see if a filesystem has changed
- */
-_INLINE_ int ext2fs_test_changed(ext2_filsys fs)
-{
- return (fs->flags & EXT2_FLAG_CHANGED);
-}
-
-/*
- * Mark a filesystem as valid
- */
-_INLINE_ void ext2fs_mark_valid(ext2_filsys fs)
-{
- fs->flags |= EXT2_FLAG_VALID;
-}
-
-/*
- * Mark a filesystem as NOT valid
- */
-_INLINE_ void ext2fs_unmark_valid(ext2_filsys fs)
-{
- fs->flags &= ~EXT2_FLAG_VALID;
-}
-
-/*
- * Check to see if a filesystem is valid
- */
-_INLINE_ int ext2fs_test_valid(ext2_filsys fs)
-{
- return (fs->flags & EXT2_FLAG_VALID);
-}
-
-/*
- * Mark the inode bitmap as dirty
- */
-_INLINE_ void ext2fs_mark_ib_dirty(ext2_filsys fs)
-{
- fs->flags |= EXT2_FLAG_IB_DIRTY | EXT2_FLAG_CHANGED;
-}
-
-/*
- * Mark the block bitmap as dirty
- */
-_INLINE_ void ext2fs_mark_bb_dirty(ext2_filsys fs)
-{
- fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_CHANGED;
-}
-
-/*
- * Check to see if a filesystem's inode bitmap is dirty
- */
-_INLINE_ int ext2fs_test_ib_dirty(ext2_filsys fs)
-{
- return (fs->flags & EXT2_FLAG_IB_DIRTY);
-}
-
-/*
- * Check to see if a filesystem's block bitmap is dirty
- */
-_INLINE_ int ext2fs_test_bb_dirty(ext2_filsys fs)
-{
- return (fs->flags & EXT2_FLAG_BB_DIRTY);
-}
-
-/*
- * Return the group # of a block
- */
-_INLINE_ int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk)
-{
- return ext2fs_group_of_blk2(fs, blk);
-}
-/*
- * Return the group # of an inode number
- */
-_INLINE_ int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino)
-{
- return (ino - 1) / fs->super->s_inodes_per_group;
-}
-
-/*
- * Return the first block (inclusive) in a group
- */
-_INLINE_ blk_t ext2fs_group_first_block(ext2_filsys fs, dgrp_t group)
-{
- return ext2fs_group_first_block2(fs, group);
-}
-
-/*
- * Return the last block (inclusive) in a group
- */
-_INLINE_ blk_t ext2fs_group_last_block(ext2_filsys fs, dgrp_t group)
-{
- return ext2fs_group_last_block2(fs, group);
-}
-
-_INLINE_ blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
- struct ext2_inode *inode)
-{
- return ext2fs_inode_data_blocks2(fs, inode);
-}
-
-/*
- * This is an efficient, overflow safe way of calculating ceil((1.0 * a) / b)
- */
-_INLINE_ unsigned int ext2fs_div_ceil(unsigned int a, unsigned int b)
-{
- if (!a)
- return 0;
- return ((a - 1) / b) + 1;
-}
-
-_INLINE_ __u64 ext2fs_div64_ceil(__u64 a, __u64 b)
-{
- if (!a)
- return 0;
- return ((a - 1) / b) + 1;
-}
-
-#undef _INLINE_
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _EXT2FS_EXT2FS_H */
diff --git a/lib/ext2fs/finddev.c.orig b/lib/ext2fs/finddev.c.orig
deleted file mode 100644
index cc2029f..0000000
--- a/lib/ext2fs/finddev.c.orig
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * finddev.c -- this routine attempts to find a particular device in
- * /dev
- *
- * Copyright (C) 2000 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU Library
- * General Public License, version 2.
- * %End-Header%
- */
-
-#include <stdio.h>
-#include <string.h>
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <stdlib.h>
-#include <string.h>
-#if HAVE_SYS_TYPES_H
-#include <sys/types.h>
-#endif
-#if HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#include <dirent.h>
-#if HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#if HAVE_SYS_MKDEV_H
-#include <sys/mkdev.h>
-#endif
-
-#include "ext2_fs.h"
-#include "ext2fs.h"
-
-struct dir_list {
- char *name;
- struct dir_list *next;
-};
-
-/*
- * This function adds an entry to the directory list
- */
-static void add_to_dirlist(const char *name, struct dir_list **list)
-{
- struct dir_list *dp;
-
- dp = malloc(sizeof(struct dir_list));
- if (!dp)
- return;
- dp->name = malloc(strlen(name)+1);
- if (!dp->name) {
- free(dp);
- return;
- }
- strcpy(dp->name, name);
- dp->next = *list;
- *list = dp;
-}
-
-/*
- * This function frees a directory list
- */
-static void free_dirlist(struct dir_list **list)
-{
- struct dir_list *dp, *next;
-
- for (dp = *list; dp; dp = next) {
- next = dp->next;
- free(dp->name);
- free(dp);
- }
- *list = 0;
-}
-
-static int scan_dir(char *dirname, dev_t device, struct dir_list **list,
- char **ret_path)
-{
- DIR *dir;
- struct dirent *dp;
- char path[1024], *cp;
- int dirlen;
- struct stat st;
-
- dirlen = strlen(dirname);
- if ((dir = opendir(dirname)) == NULL)
- return errno;
- dp = readdir(dir);
- while (dp) {
- if (dirlen + strlen(dp->d_name) + 2 >= sizeof(path))
- goto skip_to_next;
- if (dp->d_name[0] == '.' &&
- ((dp->d_name[1] == 0) ||
- ((dp->d_name[1] == '.') && (dp->d_name[2] == 0))))
- goto skip_to_next;
- sprintf(path, "%s/%s", dirname, dp->d_name);
- if (stat(path, &st) < 0)
- goto skip_to_next;
- if (S_ISDIR(st.st_mode))
- add_to_dirlist(path, list);
- if (S_ISBLK(st.st_mode) && st.st_rdev == device) {
- cp = malloc(strlen(path)+1);
- if (!cp) {
- closedir(dir);
- return ENOMEM;
- }
- strcpy(cp, path);
- *ret_path = cp;
- goto success;
- }
- skip_to_next:
- dp = readdir(dir);
- }
-success:
- closedir(dir);
- return 0;
-}
-
-/*
- * This function finds the pathname to a block device with a given
- * device number. It returns a pointer to allocated memory to the
- * pathname on success, and NULL on failure.
- */
-char *ext2fs_find_block_device(dev_t device)
-{
- struct dir_list *list = 0, *new_list = 0;
- struct dir_list *current;
- char *ret_path = 0;
-
- /*
- * Add the starting directories to search...
- */
- add_to_dirlist("/devices", &list);
- add_to_dirlist("/devfs", &list);
- add_to_dirlist("/dev", &list);
-
- while (list) {
- current = list;
- list = list->next;
-#ifdef DEBUG
- printf("Scanning directory %s\n", current->name);
-#endif
- scan_dir(current->name, device, &new_list, &ret_path);
- free(current->name);
- free(current);
- if (ret_path)
- break;
- /*
- * If we're done checking at this level, descend to
- * the next level of subdirectories. (breadth-first)
- */
- if (list == 0) {
- list = new_list;
- new_list = 0;
- }
- }
- free_dirlist(&list);
- free_dirlist(&new_list);
- return ret_path;
-}
-
-
-#ifdef DEBUG
-int main(int argc, char** argv)
-{
- char *devname, *tmp;
- int major, minor;
- dev_t device;
- const char *errmsg = "Couldn't parse %s: %s\n";
-
- if ((argc != 2) && (argc != 3)) {
- fprintf(stderr, "Usage: %s device_number\n", argv[0]);
- fprintf(stderr, "\t: %s major minor\n", argv[0]);
- exit(1);
- }
- if (argc == 2) {
- device = strtoul(argv[1], &tmp, 0);
- if (*tmp) {
- fprintf(stderr, errmsg, "device number", argv[1]);
- exit(1);
- }
- } else {
- major = strtoul(argv[1], &tmp, 0);
- if (*tmp) {
- fprintf(stderr, errmsg, "major number", argv[1]);
- exit(1);
- }
- minor = strtoul(argv[2], &tmp, 0);
- if (*tmp) {
- fprintf(stderr, errmsg, "minor number", argv[2]);
- exit(1);
- }
- device = makedev(major, minor);
- printf("Looking for device 0x%04x (%d:%d)\n", device,
- major, minor);
- }
- devname = ext2fs_find_block_device(device);
- if (devname) {
- printf("Found device! %s\n", devname);
- free(devname);
- } else {
- printf("Couldn't find device.\n");
- }
- return 0;
-}
-
-#endif
diff --git a/lib/ext2fs/namei.c.orig b/lib/ext2fs/namei.c.orig
deleted file mode 100644
index bc0ae61..0000000
--- a/lib/ext2fs/namei.c.orig
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * namei.c --- ext2fs directory lookup operations
- *
- * Copyright (C) 1993, 1994, 1994, 1995 Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU Library
- * General Public License, version 2.
- * %End-Header%
- */
-
-#include <stdio.h>
-#include <string.h>
-#if HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-/* #define NAMEI_DEBUG */
-
-#include "ext2_fs.h"
-#include "ext2fs.h"
-
-static errcode_t open_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t base,
- const char *pathname, size_t pathlen, int follow,
- int link_count, char *buf, ext2_ino_t *res_inode);
-
-static errcode_t follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t dir,
- ext2_ino_t inode, int link_count,
- char *buf, ext2_ino_t *res_inode)
-{
- char *pathname;
- char *buffer = 0;
- errcode_t retval;
- struct ext2_inode ei;
-
-#ifdef NAMEI_DEBUG
- printf("follow_link: root=%lu, dir=%lu, inode=%lu, lc=%d\n",
- root, dir, inode, link_count);
-
-#endif
- retval = ext2fs_read_inode (fs, inode, &ei);
- if (retval) return retval;
- if (!LINUX_S_ISLNK (ei.i_mode)) {
- *res_inode = inode;
- return 0;
- }
- if (link_count++ > 5) {
- return EXT2_ET_SYMLINK_LOOP;
- }
- /* FIXME-64: Actually, this is FIXME EXTENTS */
- if (ext2fs_inode_data_blocks(fs,&ei)) {
- retval = ext2fs_get_mem(fs->blocksize, &buffer);
- if (retval)
- return retval;
- retval = io_channel_read_blk(fs->io, ei.i_block[0], 1, buffer);
- if (retval) {
- ext2fs_free_mem(&buffer);
- return retval;
- }
- pathname = buffer;
- } else
- pathname = (char *)&(ei.i_block[0]);
- retval = open_namei(fs, root, dir, pathname, ei.i_size, 1,
- link_count, buf, res_inode);
- if (buffer)
- ext2fs_free_mem(&buffer);
- return retval;
-}
-
-/*
- * This routine interprets a pathname in the context of the current
- * directory and the root directory, and returns the inode of the
- * containing directory, and a pointer to the filename of the file
- * (pointing into the pathname) and the length of the filename.
- */
-static errcode_t dir_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t dir,
- const char *pathname, int pathlen,
- int link_count, char *buf,
- const char **name, int *namelen,
- ext2_ino_t *res_inode)
-{
- char c;
- const char *thisname;
- int len;
- ext2_ino_t inode;
- errcode_t retval;
-
- if ((c = *pathname) == '/') {
- dir = root;
- pathname++;
- pathlen--;
- }
- while (1) {
- thisname = pathname;
- for (len=0; --pathlen >= 0;len++) {
- c = *(pathname++);
- if (c == '/')
- break;
- }
- if (pathlen < 0)
- break;
- retval = ext2fs_lookup (fs, dir, thisname, len, buf, &inode);
- if (retval) return retval;
- retval = follow_link (fs, root, dir, inode,
- link_count, buf, &dir);
- if (retval) return retval;
- }
- *name = thisname;
- *namelen = len;
- *res_inode = dir;
- return 0;
-}
-
-static errcode_t open_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t base,
- const char *pathname, size_t pathlen, int follow,
- int link_count, char *buf, ext2_ino_t *res_inode)
-{
- const char *base_name;
- int namelen;
- ext2_ino_t dir, inode;
- errcode_t retval;
-
-#ifdef NAMEI_DEBUG
- printf("open_namei: root=%lu, dir=%lu, path=%*s, lc=%d\n",
- root, base, pathlen, pathname, link_count);
-#endif
- retval = dir_namei(fs, root, base, pathname, pathlen,
- link_count, buf, &base_name, &namelen, &dir);
- if (retval) return retval;
- if (!namelen) { /* special case: '/usr/' etc */
- *res_inode=dir;
- return 0;
- }
- retval = ext2fs_lookup (fs, dir, base_name, namelen, buf, &inode);
- if (retval)
- return retval;
- if (follow) {
- retval = follow_link(fs, root, dir, inode, link_count,
- buf, &inode);
- if (retval)
- return retval;
- }
-#ifdef NAMEI_DEBUG
- printf("open_namei: (link_count=%d) returns %lu\n",
- link_count, inode);
-#endif
- *res_inode = inode;
- return 0;
-}
-
-errcode_t ext2fs_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
- const char *name, ext2_ino_t *inode)
-{
- char *buf;
- errcode_t retval;
-
- EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-
- retval = ext2fs_get_mem(fs->blocksize, &buf);
- if (retval)
- return retval;
-
- retval = open_namei(fs, root, cwd, name, strlen(name), 0, 0,
- buf, inode);
-
- ext2fs_free_mem(&buf);
- return retval;
-}
-
-errcode_t ext2fs_namei_follow(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
- const char *name, ext2_ino_t *inode)
-{
- char *buf;
- errcode_t retval;
-
- EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-
- retval = ext2fs_get_mem(fs->blocksize, &buf);
- if (retval)
- return retval;
-
- retval = open_namei(fs, root, cwd, name, strlen(name), 1, 0,
- buf, inode);
-
- ext2fs_free_mem(&buf);
- return retval;
-}
-
-errcode_t ext2fs_follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
- ext2_ino_t inode, ext2_ino_t *res_inode)
-{
- char *buf;
- errcode_t retval;
-
- EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-
- retval = ext2fs_get_mem(fs->blocksize, &buf);
- if (retval)
- return retval;
-
- retval = follow_link(fs, root, cwd, inode, 0, buf, res_inode);
-
- ext2fs_free_mem(&buf);
- return retval;
-}
-
diff --git a/misc/mke2fs.c.orig b/misc/mke2fs.c.orig
deleted file mode 100644
index 92dc4b3..0000000
--- a/misc/mke2fs.c.orig
+++ /dev/null
@@ -1,2410 +0,0 @@
-/*
- * mke2fs.c - Make a ext2fs filesystem.
- *
- * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- * 2003, 2004, 2005 by Theodore Ts'o.
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU Public
- * License.
- * %End-Header%
- */
-
-/* Usage: mke2fs [options] device
- *
- * The device may be a block device or a image of one, but this isn't
- * enforced (but it's not much fun on a character device :-).
- */
-
-#define _XOPEN_SOURCE 600 /* for inclusion of PATH_MAX in Solaris */
-
-#include <stdio.h>
-#include <string.h>
-#include <strings.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <time.h>
-#ifdef __linux__
-#include <sys/utsname.h>
-#endif
-#ifdef HAVE_GETOPT_H
-#include <getopt.h>
-#else
-extern char *optarg;
-extern int optind;
-#endif
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#ifdef HAVE_STDLIB_H
-#include <stdlib.h>
-#endif
-#ifdef HAVE_ERRNO_H
-#include <errno.h>
-#endif
-#ifdef HAVE_MNTENT_H
-#include <mntent.h>
-#endif
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <libgen.h>
-#include <limits.h>
-#include <blkid/blkid.h>
-
-#include "ext2fs/ext2_fs.h"
-#include "ext2fs/ext2fsP.h"
-#include "et/com_err.h"
-#include "uuid/uuid.h"
-#include "e2p/e2p.h"
-#include "ext2fs/ext2fs.h"
-#include "util.h"
-#include "profile.h"
-#include "prof_err.h"
-#include "../version.h"
-#include "nls-enable.h"
-
-#define STRIDE_LENGTH 8
-
-#define MAX_32_NUM ((((unsigned long long) 1) << 32) - 1)
-
-#ifndef __sparc__
-#define ZAP_BOOTBLOCK
-#endif
-
-#define DISCARD_STEP_MB (2048)
-
-extern int isatty(int);
-extern FILE *fpopen(const char *cmd, const char *mode);
-
-const char * program_name = "mke2fs";
-const char * device_name /* = NULL */;
-
-/* Command line options */
-int cflag;
-int verbose;
-int quiet;
-int super_only;
-int discard = 1; /* attempt to discard device before fs creation */
-int force;
-int noaction;
-int journal_size;
-int journal_flags;
-int lazy_itable_init;
-char *bad_blocks_filename;
-__u32 fs_stride;
-
-struct ext2_super_block fs_param;
-char *fs_uuid = NULL;
-char *creator_os;
-char *volume_label;
-char *mount_dir;
-char *journal_device;
-int sync_kludge; /* Set using the MKE2FS_SYNC env. option */
-char **fs_types;
-
-profile_t profile;
-
-int sys_page_size = 4096;
-int linux_version_code = 0;
-
-static void usage(void)
-{
- fprintf(stderr, _("Usage: %s [-c|-l filename] [-b block-size] "
- "[-f fragment-size]\n\t[-i bytes-per-inode] [-I inode-size] "
- "[-J journal-options]\n"
- "\t[-G meta group size] [-N number-of-inodes]\n"
- "\t[-m reserved-blocks-percentage] [-o creator-os]\n"
- "\t[-g blocks-per-group] [-L volume-label] "
- "[-M last-mounted-directory]\n\t[-O feature[,...]] "
- "[-r fs-revision] [-E extended-option[,...]]\n"
- "\t[-T fs-type] [-U UUID] [-jnqvFKSV] device [blocks-count]\n"),
- program_name);
- exit(1);
-}
-
-static int int_log2(unsigned long long arg)
-{
- int l = 0;
-
- arg >>= 1;
- while (arg) {
- l++;
- arg >>= 1;
- }
- return l;
-}
-
-static int int_log10(unsigned long long arg)
-{
- int l;
-
- for (l=0; arg ; l++)
- arg = arg / 10;
- return l;
-}
-
-static int parse_version_number(const char *s)
-{
- int major, minor, rev;
- char *endptr;
- const char *cp = s;
-
- if (!s)
- return 0;
- major = strtol(cp, &endptr, 10);
- if (cp == endptr || *endptr != '.')
- return 0;
- cp = endptr + 1;
- minor = strtol(cp, &endptr, 10);
- if (cp == endptr || *endptr != '.')
- return 0;
- cp = endptr + 1;
- rev = strtol(cp, &endptr, 10);
- if (cp == endptr)
- return 0;
- return ((((major * 256) + minor) * 256) + rev);
-}
-
-/*
- * Helper function for read_bb_file and test_disk
- */
-static void invalid_block(ext2_filsys fs EXT2FS_ATTR((unused)), blk_t blk)
-{
- fprintf(stderr, _("Bad block %u out of range; ignored.\n"), blk);
- return;
-}
-
-/*
- * Reads the bad blocks list from a file
- */
-static void read_bb_file(ext2_filsys fs, badblocks_list *bb_list,
- const char *bad_blocks_file)
-{
- FILE *f;
- errcode_t retval;
-
- f = fopen(bad_blocks_file, "r");
- if (!f) {
- com_err("read_bad_blocks_file", errno,
- _("while trying to open %s"), bad_blocks_file);
- exit(1);
- }
- retval = ext2fs_read_bb_FILE(fs, f, bb_list, invalid_block);
- fclose (f);
- if (retval) {
- com_err("ext2fs_read_bb_FILE", retval,
- _("while reading in list of bad blocks from file"));
- exit(1);
- }
-}
-
-/*
- * Runs the badblocks program to test the disk
- */
-static void test_disk(ext2_filsys fs, badblocks_list *bb_list)
-{
- FILE *f;
- errcode_t retval;
- char buf[1024];
-
- sprintf(buf, "badblocks -b %d -X %s%s%s %llu", fs->blocksize,
- quiet ? "" : "-s ", (cflag > 1) ? "-w " : "",
- fs->device_name, ext2fs_blocks_count(fs->super)-1);
- if (verbose)
- printf(_("Running command: %s\n"), buf);
- f = popen(buf, "r");
- if (!f) {
- com_err("popen", errno,
- _("while trying to run '%s'"), buf);
- exit(1);
- }
- retval = ext2fs_read_bb_FILE(fs, f, bb_list, invalid_block);
- pclose(f);
- if (retval) {
- com_err("ext2fs_read_bb_FILE", retval,
- _("while processing list of bad blocks from program"));
- exit(1);
- }
-}
-
-static void handle_bad_blocks(ext2_filsys fs, badblocks_list bb_list)
-{
- dgrp_t i;
- blk_t j;
- unsigned must_be_good;
- blk_t blk;
- badblocks_iterate bb_iter;
- errcode_t retval;
- blk_t group_block;
- int group;
- int group_bad;
-
- if (!bb_list)
- return;
-
- /*
- * The primary superblock and group descriptors *must* be
- * good; if not, abort.
- */
- must_be_good = fs->super->s_first_data_block + 1 + fs->desc_blocks;
- for (i = fs->super->s_first_data_block; i <= must_be_good; i++) {
- if (ext2fs_badblocks_list_test(bb_list, i)) {
- fprintf(stderr, _("Block %d in primary "
- "superblock/group descriptor area bad.\n"), i);
- fprintf(stderr, _("Blocks %u through %u must be good "
- "in order to build a filesystem.\n"),
- fs->super->s_first_data_block, must_be_good);
- fputs(_("Aborting....\n"), stderr);
- exit(1);
- }
- }
-
- /*
- * See if any of the bad blocks are showing up in the backup
- * superblocks and/or group descriptors. If so, issue a
- * warning and adjust the block counts appropriately.
- */
- group_block = fs->super->s_first_data_block +
- fs->super->s_blocks_per_group;
-
- for (i = 1; i < fs->group_desc_count; i++) {
- group_bad = 0;
- for (j=0; j < fs->desc_blocks+1; j++) {
- if (ext2fs_badblocks_list_test(bb_list,
- group_block + j)) {
- if (!group_bad)
- fprintf(stderr,
-_("Warning: the backup superblock/group descriptors at block %u contain\n"
-" bad blocks.\n\n"),
- group_block);
- group_bad++;
- group = ext2fs_group_of_blk2(fs, group_block+j);
- ext2fs_bg_free_blocks_count_set(fs, group, ext2fs_bg_free_blocks_count(fs, group) + 1);
- ext2fs_group_desc_csum_set(fs, group);
- ext2fs_free_blocks_count_add(fs->super, 1);
- }
- /* The kernel doesn't need to zero the itable blocks */
- ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_ZEROED |
- ext2fs_bg_flags(fs, i));
- }
- group_block += fs->super->s_blocks_per_group;
- }
-
- /*
- * Mark all the bad blocks as used...
- */
- retval = ext2fs_badblocks_list_iterate_begin(bb_list, &bb_iter);
- if (retval) {
- com_err("ext2fs_badblocks_list_iterate_begin", retval,
- _("while marking bad blocks as used"));
- exit(1);
- }
- while (ext2fs_badblocks_list_iterate(bb_iter, &blk))
- ext2fs_mark_block_bitmap2(fs->block_map, blk);
- ext2fs_badblocks_list_iterate_end(bb_iter);
-}
-
-static void write_inode_tables(ext2_filsys fs, int lazy_flag, int itable_zeroed)
-{
- errcode_t retval;
- blk64_t blk;
- dgrp_t i;
- int num;
- struct ext2fs_numeric_progress_struct progress;
-
- ext2fs_numeric_progress_init(fs, &progress,
- _("Writing inode tables: "),
- fs->group_desc_count);
-
- for (i = 0; i < fs->group_desc_count; i++) {
- ext2fs_numeric_progress_update(fs, &progress, i);
-
- blk = ext2fs_inode_table_loc(fs, i);
- num = fs->inode_blocks_per_group;
-
- if (lazy_flag)
- num = ext2fs_div_ceil((fs->super->s_inodes_per_group -
- ext2fs_bg_itable_unused(fs, i)) *
- EXT2_INODE_SIZE(fs->super),
- EXT2_BLOCK_SIZE(fs->super));
- if (!lazy_flag || itable_zeroed) {
- /* The kernel doesn't need to zero the itable blocks */
- ext2fs_bg_flags_set(fs, i, EXT2_BG_INODE_ZEROED);
- ext2fs_group_desc_csum_set(fs, i);
- }
- retval = ext2fs_zero_blocks2(fs, blk, num, &blk, &num);
- if (retval) {
- fprintf(stderr, _("\nCould not write %d "
- "blocks in inode table starting at %llu: %s\n"),
- num, blk, error_message(retval));
- exit(1);
- }
- if (sync_kludge) {
- if (sync_kludge == 1)
- sync();
- else if ((i % sync_kludge) == 0)
- sync();
- }
- }
- ext2fs_zero_blocks2(0, 0, 0, 0, 0);
- ext2fs_numeric_progress_close(fs, &progress,
- _("done \n"));
-}
-
-static void create_root_dir(ext2_filsys fs)
-{
- errcode_t retval;
- struct ext2_inode inode;
- __u32 uid, gid;
-
- retval = ext2fs_mkdir(fs, EXT2_ROOT_INO, EXT2_ROOT_INO, 0);
- if (retval) {
- com_err("ext2fs_mkdir", retval, _("while creating root dir"));
- exit(1);
- }
- if (geteuid()) {
- retval = ext2fs_read_inode(fs, EXT2_ROOT_INO, &inode);
- if (retval) {
- com_err("ext2fs_read_inode", retval,
- _("while reading root inode"));
- exit(1);
- }
- uid = getuid();
- inode.i_uid = uid;
- ext2fs_set_i_uid_high(inode, uid >> 16);
- if (uid) {
- gid = getgid();
- inode.i_gid = gid;
- ext2fs_set_i_gid_high(inode, gid >> 16);
- }
- retval = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
- if (retval) {
- com_err("ext2fs_write_inode", retval,
- _("while setting root inode ownership"));
- exit(1);
- }
- }
-}
-
-static void create_lost_and_found(ext2_filsys fs)
-{
- unsigned int lpf_size = 0;
- errcode_t retval;
- ext2_ino_t ino;
- const char *name = "lost+found";
- int i;
-
- fs->umask = 077;
- retval = ext2fs_mkdir(fs, EXT2_ROOT_INO, 0, name);
- if (retval) {
- com_err("ext2fs_mkdir", retval,
- _("while creating /lost+found"));
- exit(1);
- }
-
- retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name, strlen(name), 0, &ino);
- if (retval) {
- com_err("ext2_lookup", retval,
- _("while looking up /lost+found"));
- exit(1);
- }
-
- for (i=1; i < EXT2_NDIR_BLOCKS; i++) {
- /* Ensure that lost+found is at least 2 blocks, so we always
- * test large empty blocks for big-block filesystems. */
- if ((lpf_size += fs->blocksize) >= 16*1024 &&
- lpf_size >= 2 * fs->blocksize)
- break;
- retval = ext2fs_expand_dir(fs, ino);
- if (retval) {
- com_err("ext2fs_expand_dir", retval,
- _("while expanding /lost+found"));
- exit(1);
- }
- }
-}
-
-static void create_bad_block_inode(ext2_filsys fs, badblocks_list bb_list)
-{
- errcode_t retval;
-
- ext2fs_mark_inode_bitmap2(fs->inode_map, EXT2_BAD_INO);
- ext2fs_inode_alloc_stats2(fs, EXT2_BAD_INO, +1, 0);
- retval = ext2fs_update_bb_inode(fs, bb_list);
- if (retval) {
- com_err("ext2fs_update_bb_inode", retval,
- _("while setting bad block inode"));
- exit(1);
- }
-
-}
-
-static void reserve_inodes(ext2_filsys fs)
-{
- ext2_ino_t i;
-
- for (i = EXT2_ROOT_INO + 1; i < EXT2_FIRST_INODE(fs->super); i++)
- ext2fs_inode_alloc_stats2(fs, i, +1, 0);
- ext2fs_mark_ib_dirty(fs);
-}
-
-#define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */
-#define BSD_MAGICDISK (0x57455682UL) /* The disk magic number reversed */
-#define BSD_LABEL_OFFSET 64
-
-static void zap_sector(ext2_filsys fs, int sect, int nsect)
-{
- char *buf;
- int retval;
- unsigned int *magic;
-
- buf = malloc(512*nsect);
- if (!buf) {
- printf(_("Out of memory erasing sectors %d-%d\n"),
- sect, sect + nsect - 1);
- exit(1);
- }
-
- if (sect == 0) {
- /* Check for a BSD disklabel, and don't erase it if so */
- retval = io_channel_read_blk64(fs->io, 0, -512, buf);
- if (retval)
- fprintf(stderr,
- _("Warning: could not read block 0: %s\n"),
- error_message(retval));
- else {
- magic = (unsigned int *) (buf + BSD_LABEL_OFFSET);
- if ((*magic == BSD_DISKMAGIC) ||
- (*magic == BSD_MAGICDISK))
- return;
- }
- }
-
- memset(buf, 0, 512*nsect);
- io_channel_set_blksize(fs->io, 512);
- retval = io_channel_write_blk64(fs->io, sect, -512*nsect, buf);
- io_channel_set_blksize(fs->io, fs->blocksize);
- free(buf);
- if (retval)
- fprintf(stderr, _("Warning: could not erase sector %d: %s\n"),
- sect, error_message(retval));
-}
-
-static void create_journal_dev(ext2_filsys fs)
-{
- struct ext2fs_numeric_progress_struct progress;
- errcode_t retval;
- char *buf;
- blk64_t blk, err_blk;
- int c, count, err_count;
-
- retval = ext2fs_create_journal_superblock(fs,
- ext2fs_blocks_count(fs->super), 0, &buf);
- if (retval) {
- com_err("create_journal_dev", retval,
- _("while initializing journal superblock"));
- exit(1);
- }
-
- if (journal_flags & EXT2_MKJOURNAL_LAZYINIT)
- goto write_superblock;
-
- ext2fs_numeric_progress_init(fs, &progress,
- _("Zeroing journal device: "),
- ext2fs_blocks_count(fs->super));
- blk = 0;
- count = ext2fs_blocks_count(fs->super);
- while (count > 0) {
- if (count > 1024)
- c = 1024;
- else
- c = count;
- retval = ext2fs_zero_blocks2(fs, blk, c, &err_blk, &err_count);
- if (retval) {
- com_err("create_journal_dev", retval,
- _("while zeroing journal device "
- "(block %llu, count %d)"),
- err_blk, err_count);
- exit(1);
- }
- blk += c;
- count -= c;
- ext2fs_numeric_progress_update(fs, &progress, blk);
- }
- ext2fs_zero_blocks2(0, 0, 0, 0, 0);
-
- ext2fs_numeric_progress_close(fs, &progress, NULL);
-write_superblock:
- retval = io_channel_write_blk64(fs->io,
- fs->super->s_first_data_block+1,
- 1, buf);
- if (retval) {
- com_err("create_journal_dev", retval,
- _("while writing journal superblock"));
- exit(1);
- }
-}
-
-static void show_stats(ext2_filsys fs)
-{
- struct ext2_super_block *s = fs->super;
- char buf[80];
- char *os;
- blk64_t group_block;
- dgrp_t i;
- int need, col_left;
-
- if (ext2fs_blocks_count(&fs_param) != ext2fs_blocks_count(s))
- fprintf(stderr, _("warning: %llu blocks unused.\n\n"),
- ext2fs_blocks_count(&fs_param) - ext2fs_blocks_count(s));
-
- memset(buf, 0, sizeof(buf));
- strncpy(buf, s->s_volume_name, sizeof(s->s_volume_name));
- printf(_("Filesystem label=%s\n"), buf);
- os = e2p_os2string(fs->super->s_creator_os);
- if (os)
- printf(_("OS type: %s\n"), os);
- free(os);
- printf(_("Block size=%u (log=%u)\n"), fs->blocksize,
- s->s_log_block_size);
- printf(_("Fragment size=%u (log=%u)\n"), fs->fragsize,
- s->s_log_frag_size);
- printf(_("Stride=%u blocks, Stripe width=%u blocks\n"),
- s->s_raid_stride, s->s_raid_stripe_width);
- printf(_("%u inodes, %llu blocks\n"), s->s_inodes_count,
- ext2fs_blocks_count(s));
- printf(_("%llu blocks (%2.2f%%) reserved for the super user\n"),
- ext2fs_r_blocks_count(s),
- 100.0 * ext2fs_r_blocks_count(s) / ext2fs_blocks_count(s));
- printf(_("First data block=%u\n"), s->s_first_data_block);
- if (s->s_reserved_gdt_blocks)
- printf(_("Maximum filesystem blocks=%lu\n"),
- (s->s_reserved_gdt_blocks + fs->desc_blocks) *
- EXT2_DESC_PER_BLOCK(s) * s->s_blocks_per_group);
- if (fs->group_desc_count > 1)
- printf(_("%u block groups\n"), fs->group_desc_count);
- else
- printf(_("%u block group\n"), fs->group_desc_count);
- printf(_("%u blocks per group, %u fragments per group\n"),
- s->s_blocks_per_group, s->s_frags_per_group);
- printf(_("%u inodes per group\n"), s->s_inodes_per_group);
-
- if (fs->group_desc_count == 1) {
- printf("\n");
- return;
- }
-
- printf(_("Superblock backups stored on blocks: "));
- group_block = s->s_first_data_block;
- col_left = 0;
- for (i = 1; i < fs->group_desc_count; i++) {
- group_block += s->s_blocks_per_group;
- if (!ext2fs_bg_has_super(fs, i))
- continue;
- if (i != 1)
- printf(", ");
- need = int_log10(group_block) + 2;
- if (need > col_left) {
- printf("\n\t");
- col_left = 72;
- }
- col_left -= need;
- printf("%llu", group_block);
- }
- printf("\n\n");
-}
-
-/*
- * Set the S_CREATOR_OS field. Return true if OS is known,
- * otherwise, 0.
- */
-static int set_os(struct ext2_super_block *sb, char *os)
-{
- if (isdigit (*os))
- sb->s_creator_os = atoi (os);
- else if (strcasecmp(os, "linux") == 0)
- sb->s_creator_os = EXT2_OS_LINUX;
- else if (strcasecmp(os, "GNU") == 0 || strcasecmp(os, "hurd") == 0)
- sb->s_creator_os = EXT2_OS_HURD;
- else if (strcasecmp(os, "freebsd") == 0)
- sb->s_creator_os = EXT2_OS_FREEBSD;
- else if (strcasecmp(os, "lites") == 0)
- sb->s_creator_os = EXT2_OS_LITES;
- else
- return 0;
- return 1;
-}
-
-#define PATH_SET "PATH=/sbin"
-
-static void parse_extended_opts(struct ext2_super_block *param,
- const char *opts)
-{
- char *buf, *token, *next, *p, *arg, *badopt = 0;
- int len;
- int r_usage = 0;
-
- len = strlen(opts);
- buf = malloc(len+1);
- if (!buf) {
- fprintf(stderr,
- _("Couldn't allocate memory to parse options!\n"));
- exit(1);
- }
- strcpy(buf, opts);
- for (token = buf; token && *token; token = next) {
- p = strchr(token, ',');
- next = 0;
- if (p) {
- *p = 0;
- next = p+1;
- }
- arg = strchr(token, '=');
- if (arg) {
- *arg = 0;
- arg++;
- }
- if (strcmp(token, "stride") == 0) {
- if (!arg) {
- r_usage++;
- badopt = token;
- continue;
- }
- param->s_raid_stride = strtoul(arg, &p, 0);
- if (*p || (param->s_raid_stride == 0)) {
- fprintf(stderr,
- _("Invalid stride parameter: %s\n"),
- arg);
- r_usage++;
- continue;
- }
- } else if (strcmp(token, "stripe-width") == 0 ||
- strcmp(token, "stripe_width") == 0) {
- if (!arg) {
- r_usage++;
- badopt = token;
- continue;
- }
- param->s_raid_stripe_width = strtoul(arg, &p, 0);
- if (*p || (param->s_raid_stripe_width == 0)) {
- fprintf(stderr,
- _("Invalid stripe-width parameter: %s\n"),
- arg);
- r_usage++;
- continue;
- }
- } else if (!strcmp(token, "resize")) {
- blk64_t resize;
- unsigned long bpg, rsv_groups;
- unsigned long group_desc_count, desc_blocks;
- unsigned int gdpb, blocksize;
- int rsv_gdb;
-
- if (!arg) {
- r_usage++;
- badopt = token;
- continue;
- }
-
- resize = parse_num_blocks2(arg,
- param->s_log_block_size);
-
- if (resize == 0) {
- fprintf(stderr,
- _("Invalid resize parameter: %s\n"),
- arg);
- r_usage++;
- continue;
- }
- if (resize <= ext2fs_blocks_count(param)) {
- fprintf(stderr,
- _("The resize maximum must be greater "
- "than the filesystem size.\n"));
- r_usage++;
- continue;
- }
-
- blocksize = EXT2_BLOCK_SIZE(param);
- bpg = param->s_blocks_per_group;
- if (!bpg)
- bpg = blocksize * 8;
- gdpb = EXT2_DESC_PER_BLOCK(param);
- group_desc_count = (__u32) ext2fs_div64_ceil(
- ext2fs_blocks_count(param), bpg);
- desc_blocks = (group_desc_count +
- gdpb - 1) / gdpb;
- rsv_groups = ext2fs_div64_ceil(resize, bpg);
- rsv_gdb = ext2fs_div_ceil(rsv_groups, gdpb) -
- desc_blocks;
- if (rsv_gdb > (int) EXT2_ADDR_PER_BLOCK(param))
- rsv_gdb = EXT2_ADDR_PER_BLOCK(param);
-
- if (rsv_gdb > 0) {
- if (param->s_rev_level == EXT2_GOOD_OLD_REV) {
- fprintf(stderr,
- _("On-line resizing not supported with revision 0 filesystems\n"));
- free(buf);
- exit(1);
- }
- param->s_feature_compat |=
- EXT2_FEATURE_COMPAT_RESIZE_INODE;
-
- param->s_reserved_gdt_blocks = rsv_gdb;
- }
- } else if (!strcmp(token, "test_fs")) {
- param->s_flags |= EXT2_FLAGS_TEST_FILESYS;
- } else if (!strcmp(token, "lazy_journal_init")) {
- if (arg)
- journal_flags |= strtoul(arg, &p, 0) ?
- EXT2_MKJOURNAL_LAZYINIT : 0;
- else
- journal_flags |= EXT2_MKJOURNAL_LAZYINIT;
- } else if (!strcmp(token, "lazy_itable_init")) {
- if (arg)
- lazy_itable_init = strtoul(arg, &p, 0);
- else
- lazy_itable_init = 1;
- } else if (!strcmp(token, "discard")) {
- discard = 1;
- } else if (!strcmp(token, "nodiscard")) {
- discard = 0;
- } else {
- r_usage++;
- badopt = token;
- }
- }
- if (r_usage) {
- fprintf(stderr, _("\nBad option(s) specified: %s\n\n"
- "Extended options are separated by commas, "
- "and may take an argument which\n"
- "\tis set off by an equals ('=') sign.\n\n"
- "Valid extended options are:\n"
- "\tstride=<RAID per-disk data chunk in blocks>\n"
- "\tstripe-width=<RAID stride * data disks in blocks>\n"
- "\tresize=<resize maximum size in blocks>\n"
- "\tlazy_itable_init=<0 to disable, 1 to enable>\n"
- "\tlazy_journal_init=<0 to disable, 1 to enable>\n"
- "\ttest_fs\n"
- "\tdiscard\n"
- "\tnodiscard\n\n"),
- badopt ? badopt : "");
- free(buf);
- exit(1);
- }
- if (param->s_raid_stride &&
- (param->s_raid_stripe_width % param->s_raid_stride) != 0)
- fprintf(stderr, _("\nWarning: RAID stripe-width %u not an even "
- "multiple of stride %u.\n\n"),
- param->s_raid_stripe_width, param->s_raid_stride);
-
- free(buf);
-}
-
-static __u32 ok_features[3] = {
- /* Compat */
- EXT3_FEATURE_COMPAT_HAS_JOURNAL |
- EXT2_FEATURE_COMPAT_RESIZE_INODE |
- EXT2_FEATURE_COMPAT_DIR_INDEX |
- EXT2_FEATURE_COMPAT_EXT_ATTR,
- /* Incompat */
- EXT2_FEATURE_INCOMPAT_FILETYPE|
- EXT3_FEATURE_INCOMPAT_EXTENTS|
- EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|
- EXT2_FEATURE_INCOMPAT_META_BG|
- EXT4_FEATURE_INCOMPAT_FLEX_BG|
- EXT4_FEATURE_INCOMPAT_64BIT,
- /* R/O compat */
- EXT2_FEATURE_RO_COMPAT_LARGE_FILE|
- EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
- EXT4_FEATURE_RO_COMPAT_DIR_NLINK|
- EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE|
- EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|
- EXT4_FEATURE_RO_COMPAT_GDT_CSUM
-};
-
-
-static void syntax_err_report(const char *filename, long err, int line_num)
-{
- fprintf(stderr,
- _("Syntax error in mke2fs config file (%s, line #%d)\n\t%s\n"),
- filename, line_num, error_message(err));
- exit(1);
-}
-
-static const char *config_fn[] = { ROOT_SYSCONFDIR "/mke2fs.conf", 0 };
-
-static void edit_feature(const char *str, __u32 *compat_array)
-{
- if (!str)
- return;
-
- if (e2p_edit_feature(str, compat_array, ok_features)) {
- fprintf(stderr, _("Invalid filesystem option set: %s\n"),
- str);
- exit(1);
- }
-}
-
-static void edit_mntopts(const char *str, __u32 *mntopts)
-{
- if (!str)
- return;
-
- if (e2p_edit_mntopts(str, mntopts, ~0)) {
- fprintf(stderr, _("Invalid mount option set: %s\n"),
- str);
- exit(1);
- }
-}
-
-struct str_list {
- char **list;
- int num;
- int max;
-};
-
-static errcode_t init_list(struct str_list *sl)
-{
- sl->num = 0;
- sl->max = 0;
- sl->list = malloc((sl->max+1) * sizeof(char *));
- if (!sl->list)
- return ENOMEM;
- sl->list[0] = 0;
- return 0;
-}
-
-static errcode_t push_string(struct str_list *sl, const char *str)
-{
- char **new_list;
-
- if (sl->num >= sl->max) {
- sl->max += 2;
- new_list = realloc(sl->list, (sl->max+1) * sizeof(char *));
- if (!new_list)
- return ENOMEM;
- sl->list = new_list;
- }
- sl->list[sl->num] = malloc(strlen(str)+1);
- if (sl->list[sl->num] == 0)
- return ENOMEM;
- strcpy(sl->list[sl->num], str);
- sl->num++;
- sl->list[sl->num] = 0;
- return 0;
-}
-
-static void print_str_list(char **list)
-{
- char **cpp;
-
- for (cpp = list; *cpp; cpp++) {
- printf("'%s'", *cpp);
- if (cpp[1])
- fputs(", ", stdout);
- }
- fputc('\n', stdout);
-}
-
-/*
- * Return TRUE if the profile has the given subsection
- */
-static int profile_has_subsection(profile_t profile, const char *section,
- const char *subsection)
-{
- void *state;
- const char *names[4];
- char *name;
- int ret = 0;
-
- names[0] = section;
- names[1] = subsection;
- names[2] = 0;
-
- if (profile_iterator_create(profile, names,
- PROFILE_ITER_LIST_SECTION |
- PROFILE_ITER_RELATIONS_ONLY, &state))
- return 0;
-
- if ((profile_iterator(&state, &name, 0) == 0) && name) {
- free(name);
- ret = 1;
- }
-
- profile_iterator_free(&state);
- return ret;
-}
-
-static char **parse_fs_type(const char *fs_type,
- const char *usage_types,
- struct ext2_super_block *fs_param,
- blk64_t fs_blocks_count,
- char *progname)
-{
- const char *ext_type = 0;
- char *parse_str;
- char *profile_type = 0;
- char *cp, *t;
- const char *size_type;
- struct str_list list;
- unsigned long long meg;
- int is_hurd = 0;
-
- if (init_list(&list))
- return 0;
-
- if (creator_os && (!strcasecmp(creator_os, "GNU") ||
- !strcasecmp(creator_os, "hurd")))
- is_hurd = 1;
-
- if (fs_type)
- ext_type = fs_type;
- else if (is_hurd)
- ext_type = "ext2";
- else if (!strcmp(program_name, "mke3fs"))
- ext_type = "ext3";
- else if (progname) {
- ext_type = strrchr(progname, '/');
- if (ext_type)
- ext_type++;
- else
- ext_type = progname;
-
- if (!strncmp(ext_type, "mkfs.", 5)) {
- ext_type += 5;
- if (ext_type[0] == 0)
- ext_type = 0;
- } else
- ext_type = 0;
- }
-
- if (!ext_type) {
- profile_get_string(profile, "defaults", "fs_type", 0,
- "ext2", &profile_type);
- ext_type = profile_type;
- if (!strcmp(ext_type, "ext2") && (journal_size != 0))
- ext_type = "ext3";
- }
-
-
- if (!profile_has_subsection(profile, "fs_types", ext_type) &&
- strcmp(ext_type, "ext2")) {
- printf(_("\nYour mke2fs.conf file does not define the "
- "%s filesystem type.\n"), ext_type);
- if (!strcmp(ext_type, "ext3") || !strcmp(ext_type, "ext4") ||
- !strcmp(ext_type, "ext4dev")) {
- printf(_("You probably need to install an updated "
- "mke2fs.conf file.\n\n"));
- }
- if (!force) {
- printf(_("Aborting...\n"));
- exit(1);
- }
- }
-
- meg = (1024 * 1024) / EXT2_BLOCK_SIZE(fs_param);
- if (fs_blocks_count < 3 * meg)
- size_type = "floppy";
- else if (fs_blocks_count < 512 * meg)
- size_type = "small";
- else if (fs_blocks_count < 4 * 1024 * 1024 * meg)
- size_type = "default";
- else if (fs_blocks_count < 16 * 1024 * 1024 * meg)
- size_type = "big";
- else
- size_type = "huge";
-
- if (!usage_types)
- usage_types = size_type;
-
- parse_str = malloc(usage_types ? strlen(usage_types)+1 : 1);
- if (!parse_str) {
- free(list.list);
- return 0;
- }
- if (usage_types)
- strcpy(parse_str, usage_types);
- else
- *parse_str = '\0';
-
- if (ext_type)
- push_string(&list, ext_type);
- cp = parse_str;
- while (1) {
- t = strchr(cp, ',');
- if (t)
- *t = '\0';
-
- if (*cp) {
- if (profile_has_subsection(profile, "fs_types", cp))
- push_string(&list, cp);
- else if (strcmp(cp, "default") != 0)
- fprintf(stderr,
- _("\nWarning: the fs_type %s is not "
- "defined in mke2fs.conf\n\n"),
- cp);
- }
- if (t)
- cp = t+1;
- else {
- cp = "";
- break;
- }
- }
- free(parse_str);
- free(profile_type);
- if (is_hurd)
- push_string(&list, "hurd");
- return (list.list);
-}
-
-static char *get_string_from_profile(char **fs_types, const char *opt,
- const char *def_val)
-{
- char *ret = 0;
- int i;
-
- for (i=0; fs_types[i]; i++);
- for (i-=1; i >=0 ; i--) {
- profile_get_string(profile, "fs_types", fs_types[i],
- opt, 0, &ret);
- if (ret)
- return ret;
- }
- profile_get_string(profile, "defaults", opt, 0, def_val, &ret);
- return (ret);
-}
-
-static int get_int_from_profile(char **fs_types, const char *opt, int def_val)
-{
- int ret;
- char **cpp;
-
- profile_get_integer(profile, "defaults", opt, 0, def_val, &ret);
- for (cpp = fs_types; *cpp; cpp++)
- profile_get_integer(profile, "fs_types", *cpp, opt, ret, &ret);
- return ret;
-}
-
-static int get_bool_from_profile(char **fs_types, const char *opt, int def_val)
-{
- int ret;
- char **cpp;
-
- profile_get_boolean(profile, "defaults", opt, 0, def_val, &ret);
- for (cpp = fs_types; *cpp; cpp++)
- profile_get_boolean(profile, "fs_types", *cpp, opt, ret, &ret);
- return ret;
-}
-
-extern const char *mke2fs_default_profile;
-static const char *default_files[] = { "<default>", 0 };
-
-#ifdef HAVE_BLKID_PROBE_GET_TOPOLOGY
-/*
- * Sets the geometry of a device (stripe/stride), and returns the
- * device's alignment offset, if any, or a negative error.
- */
-static int get_device_geometry(const char *file,
- struct ext2_super_block *fs_param,
- int psector_size)
-{
- int rc = -1;
- int blocksize;
- blkid_probe pr;
- blkid_topology tp;
- unsigned long min_io;
- unsigned long opt_io;
- struct stat statbuf;
-
- /* Nothing to do for a regular file */
- if (!stat(file, &statbuf) && S_ISREG(statbuf.st_mode))
- return 0;
-
- pr = blkid_new_probe_from_filename(file);
- if (!pr)
- goto out;
-
- tp = blkid_probe_get_topology(pr);
- if (!tp)
- goto out;
-
- min_io = blkid_topology_get_minimum_io_size(tp);
- opt_io = blkid_topology_get_optimal_io_size(tp);
- blocksize = EXT2_BLOCK_SIZE(fs_param);
- if ((min_io == 0) && (psector_size > blocksize))
- min_io = psector_size;
- if ((opt_io == 0) && min_io)
- opt_io = min_io;
- if ((opt_io == 0) && (psector_size > blocksize))
- opt_io = psector_size;
-
- /* setting stripe/stride to blocksize is pointless */
- if (min_io > blocksize)
- fs_param->s_raid_stride = min_io / blocksize;
- if (opt_io > blocksize)
- fs_param->s_raid_stripe_width = opt_io / blocksize;
-
- rc = blkid_topology_get_alignment_offset(tp);
-out:
- blkid_free_probe(pr);
- return rc;
-}
-#endif
-
-static void PRS(int argc, char *argv[])
-{
- int b, c;
- int size;
- char *tmp, **cpp;
- int blocksize = 0;
- int inode_ratio = 0;
- int inode_size = 0;
- unsigned long flex_bg_size = 0;
- double reserved_ratio = 5.0;
- int lsector_size = 0, psector_size = 0;
- int show_version_only = 0;
- unsigned long long num_inodes = 0; /* unsigned long long to catch too-large input */
- errcode_t retval;
- char * oldpath = getenv("PATH");
- char * extended_opts = 0;
- const char * fs_type = 0;
- const char * usage_types = 0;
- blk64_t dev_size;
- blk64_t fs_blocks_count = 0;
-#ifdef __linux__
- struct utsname ut;
-#endif
- long sysval;
- int s_opt = -1, r_opt = -1;
- char *fs_features = 0;
- int use_bsize;
- char *newpath;
- int pathlen = sizeof(PATH_SET) + 1;
-
- if (oldpath)
- pathlen += strlen(oldpath);
- newpath = malloc(pathlen);
- if (!newpath) {
- fprintf(stderr, _("Couldn't allocate memory for new PATH.\n"));
- exit(1);
- }
- strcpy(newpath, PATH_SET);
-
- /* Update our PATH to include /sbin */
- if (oldpath) {
- strcat (newpath, ":");
- strcat (newpath, oldpath);
- }
- putenv (newpath);
-
- tmp = getenv("MKE2FS_SYNC");
- if (tmp)
- sync_kludge = atoi(tmp);
-
- /* Determine the system page size if possible */
-#ifdef HAVE_SYSCONF
-#if (!defined(_SC_PAGESIZE) && defined(_SC_PAGE_SIZE))
-#define _SC_PAGESIZE _SC_PAGE_SIZE
-#endif
-#ifdef _SC_PAGESIZE
- sysval = sysconf(_SC_PAGESIZE);
- if (sysval > 0)
- sys_page_size = sysval;
-#endif /* _SC_PAGESIZE */
-#endif /* HAVE_SYSCONF */
-
- if ((tmp = getenv("MKE2FS_CONFIG")) != NULL)
- config_fn[0] = tmp;
- profile_set_syntax_err_cb(syntax_err_report);
- retval = profile_init(config_fn, &profile);
- if (retval == ENOENT) {
- retval = profile_init(default_files, &profile);
- if (retval)
- goto profile_error;
- retval = profile_set_default(profile, mke2fs_default_profile);
- if (retval)
- goto profile_error;
- } else if (retval) {
-profile_error:
- fprintf(stderr, _("Couldn't init profile successfully"
- " (error: %ld).\n"), retval);
- exit(1);
- }
-
- setbuf(stdout, NULL);
- setbuf(stderr, NULL);
- add_error_table(&et_ext2_error_table);
- add_error_table(&et_prof_error_table);
- memset(&fs_param, 0, sizeof(struct ext2_super_block));
- fs_param.s_rev_level = 1; /* Create revision 1 filesystems now */
-
-#ifdef __linux__
- if (uname(&ut)) {
- perror("uname");
- exit(1);
- }
- linux_version_code = parse_version_number(ut.release);
- if (linux_version_code && linux_version_code < (2*65536 + 2*256))
- fs_param.s_rev_level = 0;
-#endif
-
- if (argc && *argv) {
- program_name = get_progname(*argv);
-
- /* If called as mkfs.ext3, create a journal inode */
- if (!strcmp(program_name, "mkfs.ext3") ||
- !strcmp(program_name, "mke3fs"))
- journal_size = -1;
- }
-
- while ((c = getopt (argc, argv,
- "b:cf:g:G:i:jl:m:no:qr:s:t:vE:FI:J:KL:M:N:O:R:ST:U:V")) != EOF) {
- switch (c) {
- case 'b':
- blocksize = strtol(optarg, &tmp, 0);
- b = (blocksize > 0) ? blocksize : -blocksize;
- if (b < EXT2_MIN_BLOCK_SIZE ||
- b > EXT2_MAX_BLOCK_SIZE || *tmp) {
- com_err(program_name, 0,
- _("invalid block size - %s"), optarg);
- exit(1);
- }
- if (blocksize > 4096)
- fprintf(stderr, _("Warning: blocksize %d not "
- "usable on most systems.\n"),
- blocksize);
- if (blocksize > 0)
- fs_param.s_log_block_size =
- int_log2(blocksize >>
- EXT2_MIN_BLOCK_LOG_SIZE);
- break;
- case 'c': /* Check for bad blocks */
- cflag++;
- break;
- case 'f':
- size = strtoul(optarg, &tmp, 0);
- if (size < EXT2_MIN_BLOCK_SIZE ||
- size > EXT2_MAX_BLOCK_SIZE || *tmp) {
- com_err(program_name, 0,
- _("invalid fragment size - %s"),
- optarg);
- exit(1);
- }
- fs_param.s_log_frag_size =
- int_log2(size >> EXT2_MIN_BLOCK_LOG_SIZE);
- fprintf(stderr, _("Warning: fragments not supported. "
- "Ignoring -f option\n"));
- break;
- case 'g':
- fs_param.s_blocks_per_group = strtoul(optarg, &tmp, 0);
- if (*tmp) {
- com_err(program_name, 0,
- _("Illegal number for blocks per group"));
- exit(1);
- }
- if ((fs_param.s_blocks_per_group % 8) != 0) {
- com_err(program_name, 0,
- _("blocks per group must be multiple of 8"));
- exit(1);
- }
- break;
- case 'G':
- flex_bg_size = strtoul(optarg, &tmp, 0);
- if (*tmp) {
- com_err(program_name, 0,
- _("Illegal number for flex_bg size"));
- exit(1);
- }
- if (flex_bg_size < 1 ||
- (flex_bg_size & (flex_bg_size-1)) != 0) {
- com_err(program_name, 0,
- _("flex_bg size must be a power of 2"));
- exit(1);
- }
- break;
- case 'i':
- inode_ratio = strtoul(optarg, &tmp, 0);
- if (inode_ratio < EXT2_MIN_BLOCK_SIZE ||
- inode_ratio > EXT2_MAX_BLOCK_SIZE * 1024 ||
- *tmp) {
- com_err(program_name, 0,
- _("invalid inode ratio %s (min %d/max %d)"),
- optarg, EXT2_MIN_BLOCK_SIZE,
- EXT2_MAX_BLOCK_SIZE * 1024);
- exit(1);
- }
- break;
- case 'J':
- parse_journal_opts(optarg);
- break;
- case 'K':
- fprintf(stderr, _("Warning: -K option is deprecated and "
- "should not be used anymore. Use "
- "\'-E nodiscard\' extended option "
- "instead!\n"));
- discard = 0;
- break;
- case 'j':
- if (!journal_size)
- journal_size = -1;
- break;
- case 'l':
- bad_blocks_filename = malloc(strlen(optarg)+1);
- if (!bad_blocks_filename) {
- com_err(program_name, ENOMEM,
- _("in malloc for bad_blocks_filename"));
- exit(1);
- }
- strcpy(bad_blocks_filename, optarg);
- break;
- case 'm':
- reserved_ratio = strtod(optarg, &tmp);
- if ( *tmp || reserved_ratio > 50 ||
- reserved_ratio < 0) {
- com_err(program_name, 0,
- _("invalid reserved blocks percent - %s"),
- optarg);
- exit(1);
- }
- break;
- case 'n':
- noaction++;
- break;
- case 'o':
- creator_os = optarg;
- break;
- case 'q':
- quiet = 1;
- break;
- case 'r':
- r_opt = strtoul(optarg, &tmp, 0);
- if (*tmp) {
- com_err(program_name, 0,
- _("bad revision level - %s"), optarg);
- exit(1);
- }
- fs_param.s_rev_level = r_opt;
- break;
- case 's': /* deprecated */
- s_opt = atoi(optarg);
- break;
- case 'I':
- inode_size = strtoul(optarg, &tmp, 0);
- if (*tmp) {
- com_err(program_name, 0,
- _("invalid inode size - %s"), optarg);
- exit(1);
- }
- break;
- case 'v':
- verbose = 1;
- break;
- case 'F':
- force++;
- break;
- case 'L':
- volume_label = optarg;
- break;
- case 'M':
- mount_dir = optarg;
- break;
- case 'N':
- num_inodes = strtoul(optarg, &tmp, 0);
- if (*tmp) {
- com_err(program_name, 0,
- _("bad num inodes - %s"), optarg);
- exit(1);
- }
- break;
- case 'O':
- fs_features = optarg;
- break;
- case 'E':
- case 'R':
- extended_opts = optarg;
- break;
- case 'S':
- super_only = 1;
- break;
- case 't':
- fs_type = optarg;
- break;
- case 'T':
- usage_types = optarg;
- break;
- case 'U':
- fs_uuid = optarg;
- break;
- case 'V':
- /* Print version number and exit */
- show_version_only++;
- break;
- default:
- usage();
- }
- }
- if ((optind == argc) && !show_version_only)
- usage();
- device_name = argv[optind++];
-
- if (!quiet || show_version_only)
- fprintf (stderr, "mke2fs %s (%s)\n", E2FSPROGS_VERSION,
- E2FSPROGS_DATE);
-
- if (show_version_only) {
- fprintf(stderr, _("\tUsing %s\n"),
- error_message(EXT2_ET_BASE));
- exit(0);
- }
-
- /*
- * If there's no blocksize specified and there is a journal
- * device, use it to figure out the blocksize
- */
- if (blocksize <= 0 && journal_device) {
- ext2_filsys jfs;
- io_manager io_ptr;
-
-#ifdef CONFIG_TESTIO_DEBUG
- if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
- io_ptr = test_io_manager;
- test_io_backing_manager = unix_io_manager;
- } else
-#endif
- io_ptr = unix_io_manager;
- retval = ext2fs_open(journal_device,
- EXT2_FLAG_JOURNAL_DEV_OK, 0,
- 0, io_ptr, &jfs);
- if (retval) {
- com_err(program_name, retval,
- _("while trying to open journal device %s\n"),
- journal_device);
- exit(1);
- }
- if ((blocksize < 0) && (jfs->blocksize < (unsigned) (-blocksize))) {
- com_err(program_name, 0,
- _("Journal dev blocksize (%d) smaller than "
- "minimum blocksize %d\n"), jfs->blocksize,
- -blocksize);
- exit(1);
- }
- blocksize = jfs->blocksize;
- printf(_("Using journal device's blocksize: %d\n"), blocksize);
- fs_param.s_log_block_size =
- int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE);
- ext2fs_close(jfs);
- }
-
- if (blocksize > sys_page_size) {
- if (!force) {
- com_err(program_name, 0,
- _("%d-byte blocks too big for system (max %d)"),
- blocksize, sys_page_size);
- proceed_question();
- }
- fprintf(stderr, _("Warning: %d-byte blocks too big for system "
- "(max %d), forced to continue\n"),
- blocksize, sys_page_size);
- }
- if (optind < argc) {
- fs_blocks_count = parse_num_blocks2(argv[optind++],
- fs_param.s_log_block_size);
- if (!fs_blocks_count) {
- com_err(program_name, 0,
- _("invalid blocks '%s' on device '%s'"),
- argv[optind - 1], device_name);
- exit(1);
- }
- }
- if (optind < argc)
- usage();
-
- if (!force)
- check_plausibility(device_name);
- check_mount(device_name, force, _("filesystem"));
-
- fs_param.s_log_frag_size = fs_param.s_log_block_size;
-
- /* Determine the size of the device (if possible) */
- if (noaction && fs_blocks_count) {
- dev_size = fs_blocks_count;
- retval = 0;
- } else
- retval = ext2fs_get_device_size2(device_name,
- EXT2_BLOCK_SIZE(&fs_param),
- &dev_size);
-
- if (retval && (retval != EXT2_ET_UNIMPLEMENTED)) {
- com_err(program_name, retval,
- _("while trying to determine filesystem size"));
- exit(1);
- }
- if (!fs_blocks_count) {
- if (retval == EXT2_ET_UNIMPLEMENTED) {
- com_err(program_name, 0,
- _("Couldn't determine device size; you "
- "must specify\nthe size of the "
- "filesystem\n"));
- exit(1);
- } else {
- if (dev_size == 0) {
- com_err(program_name, 0,
- _("Device size reported to be zero. "
- "Invalid partition specified, or\n\t"
- "partition table wasn't reread "
- "after running fdisk, due to\n\t"
- "a modified partition being busy "
- "and in use. You may need to reboot\n\t"
- "to re-read your partition table.\n"
- ));
- exit(1);
- }
- fs_blocks_count = dev_size;
- if (sys_page_size > EXT2_BLOCK_SIZE(&fs_param))
- fs_blocks_count &= ~((blk64_t) ((sys_page_size /
- EXT2_BLOCK_SIZE(&fs_param))-1));
- }
- } else if (!force && (fs_blocks_count > dev_size)) {
- com_err(program_name, 0,
- _("Filesystem larger than apparent device size."));
- proceed_question();
- }
-
- /*
- * We have the file system (or device) size, so we can now
- * determine the appropriate file system types so the fs can
- * be appropriately configured.
- */
- fs_types = parse_fs_type(fs_type, usage_types, &fs_param,
- fs_blocks_count ? fs_blocks_count : dev_size,
- argv[0]);
- if (!fs_types) {
- fprintf(stderr, _("Failed to parse fs types list\n"));
- exit(1);
- }
-
- /* Figure out what features should be enabled */
-
- tmp = NULL;
- if (fs_param.s_rev_level != EXT2_GOOD_OLD_REV) {
- tmp = get_string_from_profile(fs_types, "base_features",
- "sparse_super,filetype,resize_inode,dir_index");
- edit_feature(tmp, &fs_param.s_feature_compat);
- free(tmp);
-
- /* And which mount options as well */
- tmp = get_string_from_profile(fs_types, "default_mntopts",
- "acl,user_xattr");
- edit_mntopts(tmp, &fs_param.s_default_mount_opts);
- if (tmp)
- free(tmp);
-
- for (cpp = fs_types; *cpp; cpp++) {
- tmp = NULL;
- profile_get_string(profile, "fs_types", *cpp,
- "features", "", &tmp);
- if (tmp && *tmp)
- edit_feature(tmp, &fs_param.s_feature_compat);
- if (tmp)
- free(tmp);
- }
- tmp = get_string_from_profile(fs_types, "default_features",
- "");
- }
- edit_feature(fs_features ? fs_features : tmp,
- &fs_param.s_feature_compat);
- if (tmp)
- free(tmp);
-
- /*
- * We now need to do a sanity check of fs_blocks_count for
- * 32-bit vs 64-bit block number support.
- */
- if ((fs_blocks_count > MAX_32_NUM) && (blocksize == 0)) {
- fs_blocks_count /= 4; /* Try using a 4k blocksize */
- blocksize = 4096;
- fs_param.s_log_block_size = 2;
- }
- if ((fs_blocks_count > MAX_32_NUM) &&
- !(fs_param.s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT) &&
- get_bool_from_profile(fs_types, "auto_64-bit_support", 0)) {
- fs_param.s_feature_incompat |= EXT4_FEATURE_INCOMPAT_64BIT;
- fs_param.s_feature_compat &= ~EXT2_FEATURE_COMPAT_RESIZE_INODE;
- }
- if ((fs_blocks_count > MAX_32_NUM) &&
- !(fs_param.s_feature_incompat & EXT4_FEATURE_INCOMPAT_64BIT)) {
- fprintf(stderr, _("%s: Size of device (0x%llx blocks) %s "
- "too big to be expressed\n\t"
- "in 32 bits using a blocksize of %d.\n"),
- program_name, fs_blocks_count, device_name,
- EXT2_BLOCK_SIZE(&fs_param));
- exit(1);
- }
-
- ext2fs_blocks_count_set(&fs_param, fs_blocks_count);
-
- if (fs_param.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
- fs_types[0] = strdup("journal");
- fs_types[1] = 0;
- }
-
- if (verbose) {
- fputs(_("fs_types for mke2fs.conf resolution: "), stdout);
- print_str_list(fs_types);
- }
-
- if (r_opt == EXT2_GOOD_OLD_REV &&
- (fs_param.s_feature_compat || fs_param.s_feature_incompat ||
- fs_param.s_feature_ro_compat)) {
- fprintf(stderr, _("Filesystem features not supported "
- "with revision 0 filesystems\n"));
- exit(1);
- }
-
- if (s_opt > 0) {
- if (r_opt == EXT2_GOOD_OLD_REV) {
- fprintf(stderr, _("Sparse superblocks not supported "
- "with revision 0 filesystems\n"));
- exit(1);
- }
- fs_param.s_feature_ro_compat |=
- EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
- } else if (s_opt == 0)
- fs_param.s_feature_ro_compat &=
- ~EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER;
-
- if (journal_size != 0) {
- if (r_opt == EXT2_GOOD_OLD_REV) {
- fprintf(stderr, _("Journals not supported "
- "with revision 0 filesystems\n"));
- exit(1);
- }
- fs_param.s_feature_compat |=
- EXT3_FEATURE_COMPAT_HAS_JOURNAL;
- }
-
- if (fs_param.s_feature_incompat &
- EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
- reserved_ratio = 0;
- fs_param.s_feature_incompat = EXT3_FEATURE_INCOMPAT_JOURNAL_DEV;
- fs_param.s_feature_compat = 0;
- fs_param.s_feature_ro_compat = 0;
- }
-
- if ((fs_param.s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) &&
- (fs_param.s_feature_compat & EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
- fprintf(stderr, _("The resize_inode and meta_bg features "
- "are not compatible.\n"
- "They can not be both enabled "
- "simultaneously.\n"));
- exit(1);
- }
-
- /* Set first meta blockgroup via an environment variable */
- /* (this is mostly for debugging purposes) */
- if ((fs_param.s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) &&
- ((tmp = getenv("MKE2FS_FIRST_META_BG"))))
- fs_param.s_first_meta_bg = atoi(tmp);
-
- /* Get the hardware sector sizes, if available */
- retval = ext2fs_get_device_sectsize(device_name, &lsector_size);
- if (retval) {
- com_err(program_name, retval,
- _("while trying to determine hardware sector size"));
- exit(1);
- }
- retval = ext2fs_get_device_phys_sectsize(device_name, &psector_size);
- if (retval) {
- com_err(program_name, retval,
- _("while trying to determine physical sector size"));
- exit(1);
- }
-
- if ((tmp = getenv("MKE2FS_DEVICE_SECTSIZE")) != NULL)
- lsector_size = atoi(tmp);
- if ((tmp = getenv("MKE2FS_DEVICE_PHYS_SECTSIZE")) != NULL)
- psector_size = atoi(tmp);
-
- /* Older kernels may not have physical/logical distinction */
- if (!psector_size)
- psector_size = lsector_size;
-
- if (blocksize <= 0) {
- use_bsize = get_int_from_profile(fs_types, "blocksize", 4096);
-
- if (use_bsize == -1) {
- use_bsize = sys_page_size;
- if ((linux_version_code < (2*65536 + 6*256)) &&
- (use_bsize > 4096))
- use_bsize = 4096;
- }
- if (lsector_size && use_bsize < lsector_size)
- use_bsize = lsector_size;
- if ((blocksize < 0) && (use_bsize < (-blocksize)))
- use_bsize = -blocksize;
- blocksize = use_bsize;
- ext2fs_blocks_count_set(&fs_param,
- ext2fs_blocks_count(&fs_param) /
- (blocksize / 1024));
- } else {
- if (blocksize < lsector_size) { /* Impossible */
- com_err(program_name, EINVAL,
- _("while setting blocksize; too small "
- "for device\n"));
- exit(1);
- } else if ((blocksize < psector_size) &&
- (psector_size <= sys_page_size)) { /* Suboptimal */
- fprintf(stderr, _("Warning: specified blocksize %d is "
- "less than device physical sectorsize %d\n"),
- blocksize, psector_size);
- }
- }
-
- if (inode_ratio == 0) {
- inode_ratio = get_int_from_profile(fs_types, "inode_ratio",
- 8192);
- if (inode_ratio < blocksize)
- inode_ratio = blocksize;
- }
-
- fs_param.s_log_frag_size = fs_param.s_log_block_size =
- int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE);
-
-#ifdef HAVE_BLKID_PROBE_GET_TOPOLOGY
- retval = get_device_geometry(device_name, &fs_param, psector_size);
- if (retval < 0) {
- fprintf(stderr,
- _("warning: Unable to get device geometry for %s\n"),
- device_name);
- } else if (retval) {
- printf(_("%s alignment is offset by %lu bytes.\n"),
- device_name, retval);
- printf(_("This may result in very poor performance, "
- "(re)-partitioning suggested.\n"));
- }
-#endif
-
- blocksize = EXT2_BLOCK_SIZE(&fs_param);
-
- lazy_itable_init = 0;
- if (access("/sys/fs/ext4/features/lazy_itable_init", R_OK) == 0)
- lazy_itable_init = 1;
-
- lazy_itable_init = get_bool_from_profile(fs_types,
- "lazy_itable_init",
- lazy_itable_init);
- discard = get_bool_from_profile(fs_types, "discard" , discard);
- journal_flags |= get_bool_from_profile(fs_types,
- "lazy_journal_init", 0) ?
- EXT2_MKJOURNAL_LAZYINIT : 0;
-
- /* Get options from profile */
- for (cpp = fs_types; *cpp; cpp++) {
- tmp = NULL;
- profile_get_string(profile, "fs_types", *cpp, "options", "", &tmp);
- if (tmp && *tmp)
- parse_extended_opts(&fs_param, tmp);
- free(tmp);
- }
-
- if (extended_opts)
- parse_extended_opts(&fs_param, extended_opts);
-
- /* Since sparse_super is the default, we would only have a problem
- * here if it was explicitly disabled.
- */
- if ((fs_param.s_feature_compat & EXT2_FEATURE_COMPAT_RESIZE_INODE) &&
- !(fs_param.s_feature_ro_compat&EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
- com_err(program_name, 0,
- _("reserved online resize blocks not supported "
- "on non-sparse filesystem"));
- exit(1);
- }
-
- if (fs_param.s_blocks_per_group) {
- if (fs_param.s_blocks_per_group < 256 ||
- fs_param.s_blocks_per_group > 8 * (unsigned) blocksize) {
- com_err(program_name, 0,
- _("blocks per group count out of range"));
- exit(1);
- }
- }
-
- if (inode_size == 0)
- inode_size = get_int_from_profile(fs_types, "inode_size", 0);
- if (!flex_bg_size && (fs_param.s_feature_incompat &
- EXT4_FEATURE_INCOMPAT_FLEX_BG))
- flex_bg_size = get_int_from_profile(fs_types,
- "flex_bg_size", 16);
- if (flex_bg_size) {
- if (!(fs_param.s_feature_incompat &
- EXT4_FEATURE_INCOMPAT_FLEX_BG)) {
- com_err(program_name, 0,
- _("Flex_bg feature not enabled, so "
- "flex_bg size may not be specified"));
- exit(1);
- }
- fs_param.s_log_groups_per_flex = int_log2(flex_bg_size);
- }
-
- if (inode_size && fs_param.s_rev_level >= EXT2_DYNAMIC_REV) {
- if (inode_size < EXT2_GOOD_OLD_INODE_SIZE ||
- inode_size > EXT2_BLOCK_SIZE(&fs_param) ||
- inode_size & (inode_size - 1)) {
- com_err(program_name, 0,
- _("invalid inode size %d (min %d/max %d)"),
- inode_size, EXT2_GOOD_OLD_INODE_SIZE,
- blocksize);
- exit(1);
- }
- fs_param.s_inode_size = inode_size;
- }
-
- /* Make sure number of inodes specified will fit in 32 bits */
- if (num_inodes == 0) {
- unsigned long long n;
- n = ext2fs_blocks_count(&fs_param) * blocksize / inode_ratio;
- if (n > MAX_32_NUM) {
- if (fs_param.s_feature_incompat &
- EXT4_FEATURE_INCOMPAT_64BIT)
- num_inodes = MAX_32_NUM;
- else {
- com_err(program_name, 0,
- _("too many inodes (%llu), raise"
- "inode ratio?"), n);
- exit(1);
- }
- }
- } else if (num_inodes > MAX_32_NUM) {
- com_err(program_name, 0,
- _("too many inodes (%llu), specify < 2^32 inodes"),
- num_inodes);
- exit(1);
- }
- /*
- * Calculate number of inodes based on the inode ratio
- */
- fs_param.s_inodes_count = num_inodes ? num_inodes :
- (ext2fs_blocks_count(&fs_param) * blocksize) / inode_ratio;
-
- if ((((long long)fs_param.s_inodes_count) *
- (inode_size ? inode_size : EXT2_GOOD_OLD_INODE_SIZE)) >=
- ((ext2fs_blocks_count(&fs_param)) *
- EXT2_BLOCK_SIZE(&fs_param))) {
- com_err(program_name, 0, _("inode_size (%u) * inodes_count "
- "(%u) too big for a\n\t"
- "filesystem with %llu blocks, "
- "specify higher inode_ratio (-i)\n\t"
- "or lower inode count (-N).\n"),
- inode_size ? inode_size : EXT2_GOOD_OLD_INODE_SIZE,
- fs_param.s_inodes_count,
- (unsigned long long) ext2fs_blocks_count(&fs_param));
- exit(1);
- }
-
- /*
- * Calculate number of blocks to reserve
- */
- ext2fs_r_blocks_count_set(&fs_param, reserved_ratio *
- ext2fs_blocks_count(&fs_param) / 100.0);
-}
-
-static int should_do_undo(const char *name)
-{
- errcode_t retval;
- io_channel channel;
- __u16 s_magic;
- struct ext2_super_block super;
- io_manager manager = unix_io_manager;
- int csum_flag, force_undo;
-
- csum_flag = EXT2_HAS_RO_COMPAT_FEATURE(&fs_param,
- EXT4_FEATURE_RO_COMPAT_GDT_CSUM);
- force_undo = get_int_from_profile(fs_types, "force_undo", 0);
- if (!force_undo && (!csum_flag || !lazy_itable_init))
- return 0;
-
- retval = manager->open(name, IO_FLAG_EXCLUSIVE, &channel);
- if (retval) {
- /*
- * We don't handle error cases instead we
- * declare that the file system doesn't exist
- * and let the rest of mke2fs take care of
- * error
- */
- retval = 0;
- goto open_err_out;
- }
-
- io_channel_set_blksize(channel, SUPERBLOCK_OFFSET);
- retval = io_channel_read_blk64(channel, 1, -SUPERBLOCK_SIZE, &super);
- if (retval) {
- retval = 0;
- goto err_out;
- }
-
-#if defined(WORDS_BIGENDIAN)
- s_magic = ext2fs_swab16(super.s_magic);
-#else
- s_magic = super.s_magic;
-#endif
-
- if (s_magic == EXT2_SUPER_MAGIC)
- retval = 1;
-
-err_out:
- io_channel_close(channel);
-
-open_err_out:
-
- return retval;
-}
-
-static int mke2fs_setup_tdb(const char *name, io_manager *io_ptr)
-{
- errcode_t retval = ENOMEM;
- char *tdb_dir, *tdb_file = NULL;
- char *device_name, *tmp_name;
-
- /*
- * Configuration via a conf file would be
- * nice
- */
- tdb_dir = getenv("E2FSPROGS_UNDO_DIR");
- if (!tdb_dir)
- profile_get_string(profile, "defaults",
- "undo_dir", 0, "/var/lib/e2fsprogs",
- &tdb_dir);
-
- if (!strcmp(tdb_dir, "none") || (tdb_dir[0] == 0) ||
- access(tdb_dir, W_OK))
- return 0;
-
- tmp_name = strdup(name);
- if (!tmp_name)
- goto errout;
- device_name = basename(tmp_name);
- tdb_file = malloc(strlen(tdb_dir) + 8 + strlen(device_name) + 7 + 1);
- if (!tdb_file) {
- free(tmp_name);
- goto errout;
- }
- sprintf(tdb_file, "%s/mke2fs-%s.e2undo", tdb_dir, device_name);
- free(tmp_name);
-
- if (!access(tdb_file, F_OK)) {
- if (unlink(tdb_file) < 0) {
- retval = errno;
- goto errout;
- }
- }
-
- set_undo_io_backing_manager(*io_ptr);
- *io_ptr = undo_io_manager;
- retval = set_undo_io_backup_file(tdb_file);
- if (retval)
- goto errout;
- printf(_("Overwriting existing filesystem; this can be undone "
- "using the command:\n"
- " e2undo %s %s\n\n"), tdb_file, name);
-
- free(tdb_file);
- return 0;
-
-errout:
- free(tdb_file);
- com_err(program_name, retval,
- _("while trying to setup undo file\n"));
- return retval;
-}
-
-static int mke2fs_discard_device(ext2_filsys fs)
-{
- struct ext2fs_numeric_progress_struct progress;
- blk64_t blocks = ext2fs_blocks_count(fs->super);
- blk64_t count = DISCARD_STEP_MB;
- blk64_t cur = 0;
- int retval = 0;
-
- count *= (1024 * 1024);
- count /= fs->blocksize;
-
- while (cur < blocks) {
- if (cur + count > blocks)
- count = blocks - cur;
-
- retval = io_channel_discard(fs->io, cur, count);
- if (cur == 0) {
- /* If discard is unimplemented skip the progress bar */
- if (retval == EXT2_ET_UNIMPLEMENTED)
- return retval;
-
- ext2fs_numeric_progress_init(fs, &progress,
- _("Discarding device blocks: "),
- blocks);
- }
-
- ext2fs_numeric_progress_update(fs, &progress, cur);
-
- if (retval)
- break;
-
- cur += count;
- }
-
- if (retval) {
- ext2fs_numeric_progress_close(fs, &progress, _("failed - "));
- if (!quiet)
- printf("%s\n",error_message(retval));
- } else {
- ext2fs_numeric_progress_close(fs, &progress,
- _("done \n"));
- }
-
- return retval;
-}
-
-int main (int argc, char *argv[])
-{
- errcode_t retval = 0;
- ext2_filsys fs;
- badblocks_list bb_list = 0;
- unsigned int journal_blocks;
- unsigned int i;
- int val, hash_alg;
- int flags;
- int old_bitmaps;
- io_manager io_ptr;
- char tdb_string[40];
- char *hash_alg_str;
- int itable_zeroed = 0;
-
-#ifdef ENABLE_NLS
- setlocale(LC_MESSAGES, "");
- setlocale(LC_CTYPE, "");
- bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
- textdomain(NLS_CAT_NAME);
-#endif
- PRS(argc, argv);
-
-#ifdef CONFIG_TESTIO_DEBUG
- if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
- io_ptr = test_io_manager;
- test_io_backing_manager = unix_io_manager;
- } else
-#endif
- io_ptr = unix_io_manager;
-
- if (should_do_undo(device_name)) {
- retval = mke2fs_setup_tdb(device_name, &io_ptr);
- if (retval)
- exit(1);
- }
-
- /*
- * Initialize the superblock....
- */
- flags = EXT2_FLAG_EXCLUSIVE;
- profile_get_boolean(profile, "options", "old_bitmaps", 0, 0,
- &old_bitmaps);
- if (!old_bitmaps)
- flags |= EXT2_FLAG_64BITS;
- /*
- * By default, we print how many inode tables or block groups
- * or whatever we've written so far. The quiet flag disables
- * this, along with a lot of other output.
- */
- if (!quiet)
- flags |= EXT2_FLAG_PRINT_PROGRESS;
- retval = ext2fs_initialize(device_name, flags, &fs_param, io_ptr, &fs);
- if (retval) {
- com_err(device_name, retval, _("while setting up superblock"));
- exit(1);
- }
-
- /* Can't undo discard ... */
- if (!noaction && discard && (io_ptr != undo_io_manager)) {
- retval = mke2fs_discard_device(fs);
- if (!retval && io_channel_discard_zeroes_data(fs->io)) {
- if (verbose)
- printf(_("Discard succeeded and will return 0s "
- " - skipping inode table wipe\n"));
- lazy_itable_init = 1;
- itable_zeroed = 1;
- }
- }
-
- sprintf(tdb_string, "tdb_data_size=%d", fs->blocksize <= 4096 ?
- 32768 : fs->blocksize * 8);
- io_channel_set_options(fs->io, tdb_string);
-
- if (fs_param.s_flags & EXT2_FLAGS_TEST_FILESYS)
- fs->super->s_flags |= EXT2_FLAGS_TEST_FILESYS;
-
- if ((fs_param.s_feature_incompat &
- (EXT3_FEATURE_INCOMPAT_EXTENTS|EXT4_FEATURE_INCOMPAT_FLEX_BG)) ||
- (fs_param.s_feature_ro_compat &
- (EXT4_FEATURE_RO_COMPAT_HUGE_FILE|EXT4_FEATURE_RO_COMPAT_GDT_CSUM|
- EXT4_FEATURE_RO_COMPAT_DIR_NLINK|
- EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE)))
- fs->super->s_kbytes_written = 1;
-
- /*
- * Wipe out the old on-disk superblock
- */
- if (!noaction)
- zap_sector(fs, 2, 6);
-
- /*
- * Parse or generate a UUID for the filesystem
- */
- if (fs_uuid) {
- if (uuid_parse(fs_uuid, fs->super->s_uuid) !=0) {
- com_err(device_name, 0, "could not parse UUID: %s\n",
- fs_uuid);
- exit(1);
- }
- } else
- uuid_generate(fs->super->s_uuid);
-
- /*
- * Initialize the directory index variables
- */
- hash_alg_str = get_string_from_profile(fs_types, "hash_alg",
- "half_md4");
- hash_alg = e2p_string2hash(hash_alg_str);
- free(hash_alg_str);
- fs->super->s_def_hash_version = (hash_alg >= 0) ? hash_alg :
- EXT2_HASH_HALF_MD4;
- uuid_generate((unsigned char *) fs->super->s_hash_seed);
-
- /*
- * Periodic checks can be enabled/disabled via config file.
- * Note we override the kernel include file's idea of what the default
- * check interval (never) should be. It's a good idea to check at
- * least *occasionally*, specially since servers will never rarely get
- * to reboot, since Linux is so robust these days. :-)
- *
- * 180 days (six months) seems like a good value.
- */
-#ifdef EXT2_DFL_CHECKINTERVAL
-#undef EXT2_DFL_CHECKINTERVAL
-#endif
-#define EXT2_DFL_CHECKINTERVAL (86400L * 180L)
-
- if (get_bool_from_profile(fs_types, "enable_periodic_fsck", 0)) {
- fs->super->s_checkinterval = EXT2_DFL_CHECKINTERVAL;
- fs->super->s_max_mnt_count = EXT2_DFL_MAX_MNT_COUNT;
- /*
- * Add "jitter" to the superblock's check interval so that we
- * don't check all the filesystems at the same time. We use a
- * kludgy hack of using the UUID to derive a random jitter value
- */
- for (i = 0, val = 0 ; i < sizeof(fs->super->s_uuid); i++)
- val += fs->super->s_uuid[i];
- fs->super->s_max_mnt_count += val % EXT2_DFL_MAX_MNT_COUNT;
- }
-
- /*
- * Override the creator OS, if applicable
- */
- if (creator_os && !set_os(fs->super, creator_os)) {
- com_err (program_name, 0, _("unknown os - %s"), creator_os);
- exit(1);
- }
-
- /*
- * For the Hurd, we will turn off filetype since it doesn't
- * support it.
- */
- if (fs->super->s_creator_os == EXT2_OS_HURD)
- fs->super->s_feature_incompat &=
- ~EXT2_FEATURE_INCOMPAT_FILETYPE;
-
- /*
- * Set the volume label...
- */
- if (volume_label) {
- memset(fs->super->s_volume_name, 0,
- sizeof(fs->super->s_volume_name));
- strncpy(fs->super->s_volume_name, volume_label,
- sizeof(fs->super->s_volume_name));
- }
-
- /*
- * Set the last mount directory
- */
- if (mount_dir) {
- memset(fs->super->s_last_mounted, 0,
- sizeof(fs->super->s_last_mounted));
- strncpy(fs->super->s_last_mounted, mount_dir,
- sizeof(fs->super->s_last_mounted));
- }
-
- if (!quiet || noaction)
- show_stats(fs);
-
- if (noaction)
- exit(0);
-
- if (fs->super->s_feature_incompat &
- EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
- create_journal_dev(fs);
- exit(ext2fs_close(fs) ? 1 : 0);
- }
-
- if (bad_blocks_filename)
- read_bb_file(fs, &bb_list, bad_blocks_filename);
- if (cflag)
- test_disk(fs, &bb_list);
-
- handle_bad_blocks(fs, bb_list);
- fs->stride = fs_stride = fs->super->s_raid_stride;
- if (!quiet)
- printf(_("Allocating group tables: "));
- retval = ext2fs_allocate_tables(fs);
- if (retval) {
- com_err(program_name, retval,
- _("while trying to allocate filesystem tables"));
- exit(1);
- }
- if (!quiet)
- printf(_("done \n"));
- if (super_only) {
- fs->super->s_state |= EXT2_ERROR_FS;
- fs->flags &= ~(EXT2_FLAG_IB_DIRTY|EXT2_FLAG_BB_DIRTY);
- } else {
- /* rsv must be a power of two (64kB is MD RAID sb alignment) */
- blk64_t rsv = 65536 / fs->blocksize;
- blk64_t blocks = ext2fs_blocks_count(fs->super);
- blk64_t start;
- blk64_t ret_blk;
-
-#ifdef ZAP_BOOTBLOCK
- zap_sector(fs, 0, 2);
-#endif
-
- /*
- * Wipe out any old MD RAID (or other) metadata at the end
- * of the device. This will also verify that the device is
- * as large as we think. Be careful with very small devices.
- */
- start = (blocks & ~(rsv - 1));
- if (start > rsv)
- start -= rsv;
- if (start > 0)
- retval = ext2fs_zero_blocks2(fs, start, blocks - start,
- &ret_blk, NULL);
-
- if (retval) {
- com_err(program_name, retval,
- _("while zeroing block %llu at end of filesystem"),
- ret_blk);
- }
- write_inode_tables(fs, lazy_itable_init, itable_zeroed);
- create_root_dir(fs);
- create_lost_and_found(fs);
- reserve_inodes(fs);
- create_bad_block_inode(fs, bb_list);
- if (fs->super->s_feature_compat &
- EXT2_FEATURE_COMPAT_RESIZE_INODE) {
- retval = ext2fs_create_resize_inode(fs);
- if (retval) {
- com_err("ext2fs_create_resize_inode", retval,
- _("while reserving blocks for online resize"));
- exit(1);
- }
- }
- }
-
- if (journal_device) {
- ext2_filsys jfs;
-
- if (!force)
- check_plausibility(journal_device);
- check_mount(journal_device, force, _("journal"));
-
- retval = ext2fs_open(journal_device, EXT2_FLAG_RW|
- EXT2_FLAG_JOURNAL_DEV_OK, 0,
- fs->blocksize, unix_io_manager, &jfs);
- if (retval) {
- com_err(program_name, retval,
- _("while trying to open journal device %s\n"),
- journal_device);
- exit(1);
- }
- if (!quiet) {
- printf(_("Adding journal to device %s: "),
- journal_device);
- fflush(stdout);
- }
- retval = ext2fs_add_journal_device(fs, jfs);
- if(retval) {
- com_err (program_name, retval,
- _("\n\twhile trying to add journal to device %s"),
- journal_device);
- exit(1);
- }
- if (!quiet)
- printf(_("done\n"));
- ext2fs_close(jfs);
- free(journal_device);
- } else if ((journal_size) ||
- (fs_param.s_feature_compat &
- EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
- journal_blocks = figure_journal_size(journal_size, fs);
-
- if (super_only) {
- printf(_("Skipping journal creation in super-only mode\n"));
- fs->super->s_journal_inum = EXT2_JOURNAL_INO;
- goto no_journal;
- }
-
- if (!journal_blocks) {
- fs->super->s_feature_compat &=
- ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
- goto no_journal;
- }
- if (!quiet) {
- printf(_("Creating journal (%u blocks): "),
- journal_blocks);
- fflush(stdout);
- }
- retval = ext2fs_add_journal_inode(fs, journal_blocks,
- journal_flags);
- if (retval) {
- com_err (program_name, retval,
- _("\n\twhile trying to create journal"));
- exit(1);
- }
- if (!quiet)
- printf(_("done\n"));
- }
-no_journal:
-
- if (!super_only)
- ext2fs_set_gdt_csum(fs);
- if (!quiet)
- printf(_("Writing superblocks and "
- "filesystem accounting information: "));
- retval = ext2fs_flush(fs);
- if (retval) {
- fprintf(stderr,
- _("\nWarning, had trouble writing out superblocks."));
- }
- if (!quiet) {
- printf(_("done\n\n"));
- if (!getenv("MKE2FS_SKIP_CHECK_MSG"))
- print_check_message(fs);
- }
- val = ext2fs_close(fs);
- remove_error_table(&et_ext2_error_table);
- remove_error_table(&et_prof_error_table);
- profile_release(profile);
- for (i=0; fs_types[i]; i++)
- free(fs_types[i]);
- free(fs_types);
- return (retval || val) ? 1 : 0;
-}
--
Repository for maintaining lidskfsprogs
More information about the Pkg-lustre-svn-commit
mailing list