linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/5 bigalloc] e2fsprogs: change unit of extent's ee_block and ee_len from block to cluster for bigalloc
@ 2011-11-18 10:55 Robin Dong
  2011-11-18 10:55 ` [PATCH 1/5 bigalloc] e2fsprogs: add tool e2wreck to corrupt fs for e2fsck testing Robin Dong
                   ` (4 more replies)
  0 siblings, 5 replies; 7+ messages in thread
From: Robin Dong @ 2011-11-18 10:55 UTC (permalink / raw)
  To: linux-ext4; +Cc: Robin Dong

From: Robin Dong <sanbai@taobao.com>

Hi,

After the kernel patch series which change ee_block and ee_len (of extent) 's unit from "block" to "cluster",
We need e2fsprogs to support this too.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/5 bigalloc] e2fsprogs: add tool e2wreck to corrupt fs for e2fsck testing
  2011-11-18 10:55 [PATCH 0/5 bigalloc] e2fsprogs: change unit of extent's ee_block and ee_len from block to cluster for bigalloc Robin Dong
@ 2011-11-18 10:55 ` Robin Dong
  2011-11-19  3:31   ` Ted Ts'o
  2011-11-18 10:55 ` [PATCH 2/5 bigalloc] debugfs: support cluster unit of ee_block and ee_len Robin Dong
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 7+ messages in thread
From: Robin Dong @ 2011-11-18 10:55 UTC (permalink / raw)
  To: linux-ext4; +Cc: Robin Dong

From: Robin Dong <sanbai@taobao.com>

We need a tool to wreck filesystem to test e2fsck

Signed-off-by: Robin Dong <sanbai@taobao.com>
---
 misc/Makefile.in |   10 +-
 misc/e2wreck.c   |  549 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 611 insertions(+), 2 deletions(-)
 create mode 100644 misc/e2wreck.c

diff --git a/misc/Makefile.in b/misc/Makefile.in
index cb3c6d9..c5597b4 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -26,7 +26,7 @@ INSTALL = @INSTALL@
 @BLKID_CMT@FINDFS_LINK= findfs
 @BLKID_CMT@FINDFS_MAN= findfs.8
 
-SPROGS=		mke2fs badblocks tune2fs dumpe2fs $(BLKID_PROG) logsave \
+SPROGS=		mke2fs badblocks tune2fs dumpe2fs e2wreck $(BLKID_PROG) logsave \
 			$(E2IMAGE_PROG) @FSCK_PROG@ e2undo
 USPROGS=	mklost+found filefrag e2freefrag $(UUIDD_PROG) $(E4DEFRAG_PROG)
 SMANPAGES=	tune2fs.8 mklost+found.8 mke2fs.8 dumpe2fs.8 badblocks.8 \
@@ -50,6 +50,7 @@ UUIDD_OBJS=	uuidd.o
 DUMPE2FS_OBJS=	dumpe2fs.o
 BADBLOCKS_OBJS=	badblocks.o
 E2IMAGE_OBJS=	e2image.o
+E2WRECK_OBJS=	e2wreck.o
 FSCK_OBJS=	fsck.o base_device.o ismounted.o
 BLKID_OBJS=	blkid.o
 FILEFRAG_OBJS=	filefrag.o
@@ -68,6 +69,7 @@ PROFILED_UUIDD_OBJS=	profiled/uuidd.o
 PROFILED_DUMPE2FS_OBJS=	profiled/dumpe2fs.o
 PROFILED_BADBLOCKS_OBJS=	profiled/badblocks.o
 PROFILED_E2IMAGE_OBJS=	profiled/e2image.o
+PROFILED_E2WRECK_OBJS=	profiled/e2wreck.o
 PROFILED_FSCK_OBJS=	profiled/fsck.o profiled/base_device.o \
 			profiled/ismounted.o
 PROFILED_BLKID_OBJS=	profiled/blkid.o
@@ -191,6 +193,10 @@ e2image.profiled: $(PROFILED_E2IMAGE_OBJS) $(PROFILED_DEPLIBS)
 	$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o e2image.profiled \
 		$(PROFILED_E2IMAGE_OBJS) $(PROFILED_LIBS) $(LIBINTL)
 
+e2wreck: $(E2WRECK_OBJS) $(DEPLIBS)
+	$(E) "	LD $@"
+	$(Q) $(CC) $(ALL_LDFLAGS) -o e2wreck $(E2WRECK_OBJS) $(LIBS) $(LIBINTL)
+
 e2undo: $(E2UNDO_OBJS) $(DEPLIBS)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -o e2undo $(E2UNDO_OBJS) $(LIBS) $(LIBINTL)
@@ -556,7 +562,7 @@ clean:
 		$(FMANPAGES) profile.h \
 		base_device base_device.out mke2fs.static filefrag e2freefrag \
 		e2initrd_helper partinfo prof_err.[ch] default_profile.c \
-		uuidd e2image tune2fs.static tst_ismounted fsck.profiled \
+		uuidd e2image e2wreck tune2fs.static tst_ismounted fsck.profiled \
 		blkid.profiled tune2fs.profiled e2image.profiled \
 		e2undo.profiled mke2fs.profiled dumpe2fs.profiled \
 		logsave.profiled filefrag.profiled uuidgen.profiled \
diff --git a/misc/e2wreck.c b/misc/e2wreck.c
new file mode 100644
index 0000000..2d7194b
--- /dev/null
+++ b/misc/e2wreck.c
@@ -0,0 +1,549 @@
+/*
+ * e2wreck.c --- Program which writes an image file backing up
+ * critical metadata for the filesystem.
+ *
+ * Copyright 2000, 2001 by Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#define _LARGEFILE_SOURCE
+#define _LARGEFILE64_SOURCE
+
+#include <fcntl.h>
+#include <grp.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#else
+#endif
+#include <pwd.h>
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <assert.h>
+
+#include "ext2fs/ext2_fs.h"
+#include "ext2fs/ext2fs.h"
+#include "et/com_err.h"
+#include "uuid/uuid.h"
+#include "e2p/e2p.h"
+
+#include "../version.h"
+#include "nls-enable.h"
+
+#define QCOW_OFLAG_COPIED     (1LL << 63)
+
+const char *program_name = "e2wreck";
+
+static void wreck_file_block_bitmap(ext2_filsys fs, const char *name, int flag);
+static void wreck_dirent(ext2_filsys fs, const char *name, int flag);
+static void wreck_zero_inode(ext2_filsys fs, const char *name, int flag);
+static void wreck_inode_field(ext2_filsys fs, const char *name, int flag);
+
+#define DIRENT_ZERO_DIR		1
+#define DIRENT_DUP_DOT		2
+#define DIRENT_INVALID_DOTDOT	3
+#define DIRENT_INVALID_RECLEN	4
+
+#define INODE_GENERATION	1
+#define INODE_MODE		2
+#define INODE_LINKS		3
+#define INODE_DTIME		4
+#define INODE_BLOCK		5
+#define INODE_BLOCKS		6
+#define INODE_SIZE		7
+#define EXTENT_BLOCK		8
+#define EXTENT_LEN		9
+
+struct command {
+	char name[256];
+	void (*func) (ext2_filsys fs, const char *name, int flag);
+	int flag;
+};
+
+struct command cmd_table[] = { {
+		.name = "ZERO_INODE",
+		.func = wreck_zero_inode,
+		.flag = 0,
+	}, {
+		.name = "CLEAR_BITMAP",
+		.func = wreck_file_block_bitmap,
+		.flag = 0,
+	}, {
+		.name = "INODE_GENERATION",
+		.func = wreck_inode_field,
+		.flag = INODE_GENERATION,
+	}, {
+		.name = "INODE_MODE",
+		.func = wreck_inode_field,
+		.flag = INODE_MODE,
+	}, {
+		.name = "INODE_SIZE",
+		.func = wreck_inode_field,
+		.flag = INODE_SIZE,
+	}, {
+		.name = "INODE_LINKS",
+		.func = wreck_inode_field,
+		.flag = INODE_LINKS,
+	}, {
+		.name = "INODE_DTIME",
+		.func = wreck_inode_field,
+		.flag = INODE_DTIME,
+	}, {
+		.name = "INODE_BLOCK",
+		.func = wreck_inode_field,
+		.flag = INODE_BLOCK,
+	}, {
+		.name = "INODE_BLOCKS",
+		.func = wreck_inode_field,
+		.flag = INODE_BLOCKS,
+	}, {
+		.name = "EXTENT_BLOCK",
+		.func = wreck_inode_field,
+		.flag = EXTENT_BLOCK,
+	}, {
+		.name = "EXTENT_LEN",
+		.func = wreck_inode_field,
+		.flag = EXTENT_LEN,
+	}, {
+		.name = "DIRENT_ZERO_DIR",
+		.func = wreck_dirent,
+		.flag = DIRENT_ZERO_DIR,
+	}, {
+		.name = "DIRENT_DUP_DOT",
+		.func = wreck_dirent,
+		.flag = DIRENT_DUP_DOT,
+	}, {
+		.name = "DIRENT_INVALID_DOTDOT",
+		.func = wreck_dirent,
+		.flag = DIRENT_INVALID_DOTDOT,
+	}, {
+		.name = "DIRENT_INVALID_RECLEN",
+		.func = wreck_dirent,
+		.flag = DIRENT_INVALID_RECLEN,
+	}
+};
+
+struct link_struct  {
+	const char	*name;
+	int		namelen;
+	ext2_ino_t	inode;
+	int		flags;
+	struct ext2_dir_entry *prev;
+	int		done;
+};
+
+static void usage(void)
+{
+	int i;
+	fprintf(stderr, _("Usage: %s OPTION file_name device_name\n"),
+		program_name);
+	fprintf(stderr, _("	option:\n"));
+	for (i = 0; i < sizeof(cmd_table) / sizeof(struct command); i++)
+		fprintf(stderr, _("\t%s\n"), cmd_table[i].name);
+	exit(1);
+}
+
+/*
+ * This routine is used whenever a command needs to turn a string into
+ * an inode.
+ */
+static ext2_ino_t string_to_inode(ext2_filsys fs, const char *str)
+{
+	ext2_ino_t	ino;
+	int		len = strlen(str);
+	char		*end;
+	int		retval;
+
+	/*
+	 * If the string is of the form <ino>, then treat it as an
+	 * inode number.
+	 */
+	if ((len > 2) && (str[0] == '<') && (str[len-1] == '>')) {
+		ino = strtoul(str+1, &end, 0);
+		if (*end == '>')
+			return ino;
+	}
+
+	retval = ext2fs_namei(fs, 2, 2, str, &ino);
+	if (retval) {
+		com_err(str, retval, 0);
+		return 0;
+	}
+	return ino;
+}
+
+#define DUMP_LEAF_EXTENTS	0x01
+#define DUMP_NODE_EXTENTS	0x02
+#define DUMP_EXTENT_TABLE	0x04
+
+static void dump_extents(ext2_filsys fs, 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;
+	errcode_t		errcode;
+	blk64_t			i;
+
+	errcode = ext2fs_extent_open(fs, ino, &handle);
+	if (errcode)
+		return;
+
+	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;
+
+			continue;
+		}
+
+		if (extent.e_len == 0)
+			continue;
+
+		for (i = extent.e_lblk; i < extent.e_lblk + extent.e_len; i++) {
+			blk64_t b;
+			b = extent.e_pblk + i;
+			ext2fs_unmark_block_bitmap2(fs->block_map, b);
+		}
+	}
+}
+
+static void wreck_file_block_bitmap(ext2_filsys fs, const char *name, int flag)
+{
+	ext2_ino_t ino;
+	struct ext2_inode *inode_buf;
+	__u32 inode_size = EXT2_INODE_SIZE(fs->super);
+
+	inode_buf = (struct ext2_inode *) malloc(inode_size);
+	if (!inode_buf) {
+		printf("malloc inode_buf fail\n");
+		return;
+	}
+
+	ino = string_to_inode(fs, name);
+	if (!ino) {
+		printf("fetch inode fail\n");
+		return;
+	}
+
+	if (ext2fs_read_inode_full(fs, ino, inode_buf, inode_size)) {
+		printf("read inode fail\n");
+		goto out;
+	}
+
+	if (ext2fs_read_bitmaps(fs)) {
+		printf("read bitmap fail\n");
+		return;
+	}
+
+	dump_extents(fs, stdout, "{", ino, DUMP_LEAF_EXTENTS, 0, 0);
+	ext2fs_mark_bb_dirty(fs);
+
+	if (ext2fs_write_bitmaps(fs))
+		printf("write bitmap fail\n");
+
+out:
+	free(inode_buf);
+}
+
+static int clear_proc(struct ext2_dir_entry *dirent,
+		     int	offset,
+		     int	blocksize EXT2FS_ATTR((unused)),
+		     char	*buf EXT2FS_ATTR((unused)),
+		     void	*priv_data)
+{
+	dirent->inode = 0;
+
+	return DIRENT_CHANGED;
+}
+
+static int dup_proc(struct ext2_dir_entry *dirent,
+		     int	offset,
+		     int	blocksize EXT2FS_ATTR((unused)),
+		     char	*buf EXT2FS_ATTR((unused)),
+		     void	*priv_data)
+{
+	struct link_struct *ls = (struct link_struct *) priv_data;
+	struct ext2_dir_entry *prev;
+
+	prev = ls->prev;
+	ls->prev = dirent;
+
+	if ((dirent->name_len & 0xFF) == 2 &&
+			dirent->name[0] == '.' &&
+			dirent->name[1] == '.') {
+		dirent->name_len = 1;
+		return DIRENT_ABORT|DIRENT_CHANGED;
+	}
+	return 0;
+}
+
+static int invalid_dotdot_proc(struct ext2_dir_entry *dirent,
+		     int	offset,
+		     int	blocksize EXT2FS_ATTR((unused)),
+		     char	*buf EXT2FS_ATTR((unused)),
+		     void	*priv_data)
+{
+	struct link_struct *ls = (struct link_struct *) priv_data;
+	struct ext2_dir_entry *prev;
+
+	prev = ls->prev;
+	ls->prev = dirent;
+
+	if ((dirent->name_len & 0xFF) == 2 &&
+			dirent->name[0] == '.' &&
+			dirent->name[1] == '.') {
+		dirent->name[0] = 'a';
+		dirent->name[1] = 'b';
+		return DIRENT_ABORT|DIRENT_CHANGED;
+	}
+	return 0;
+}
+
+static int invalid_reclen_proc(struct ext2_dir_entry *dirent,
+		     int	offset,
+		     int	blocksize EXT2FS_ATTR((unused)),
+		     char	*buf EXT2FS_ATTR((unused)),
+		     void	*priv_data)
+{
+	struct link_struct *ls = (struct link_struct *) priv_data;
+	struct ext2_dir_entry *prev;
+
+	prev = ls->prev;
+	ls->prev = dirent;
+
+	if ((dirent->name_len & 0xFF) == 2 &&
+			dirent->name[0] == '1' &&
+			dirent->name[1] == '9') {
+		dirent->rec_len = 25;
+		return DIRENT_ABORT|DIRENT_CHANGED;
+	}
+	return 0;
+}
+
+static void wreck_dirent(ext2_filsys fs, const char *name, int flag)
+{
+	ext2_ino_t ino;
+	__u32 inode_size = EXT2_INODE_SIZE(fs->super);
+	struct link_struct ls;
+	int retval;
+
+	ino = string_to_inode(fs, name);
+	if (!ino) {
+		printf("fetch inode fail\n");
+		goto out;
+	}
+
+	switch (flag) {
+	case DIRENT_ZERO_DIR:
+		retval = ext2fs_dir_iterate(fs, ino,
+			DIRENT_FLAG_INCLUDE_EMPTY, 0, clear_proc, &ls);
+	case DIRENT_DUP_DOT:
+		retval = ext2fs_dir_iterate(fs, ino,
+			DIRENT_FLAG_INCLUDE_EMPTY, 0, dup_proc, &ls);
+		break;
+	case DIRENT_INVALID_DOTDOT:
+		retval = ext2fs_dir_iterate(fs, ino,
+			DIRENT_FLAG_INCLUDE_EMPTY, 0,
+			invalid_dotdot_proc, &ls);
+		break;
+	case DIRENT_INVALID_RECLEN:
+		retval = ext2fs_dir_iterate(fs, ino,
+			DIRENT_FLAG_INCLUDE_EMPTY, 0,
+			invalid_reclen_proc, &ls);
+		break;
+	default:
+		goto out;
+	}
+
+	if (retval) {
+		printf("iterate dir fail\n");
+		goto out;
+	}
+
+out:
+	return;
+}
+
+static void wreck_zero_inode(ext2_filsys fs, const char *name, int flag)
+{
+	ext2_ino_t ino;
+	struct ext2_inode *inode_buf;
+	__u32 inode_size = EXT2_INODE_SIZE(fs->super);
+
+	inode_buf = (struct ext2_inode *) malloc(inode_size);
+	if (!inode_buf) {
+		printf("malloc inode_buf fail\n");
+		return;
+	}
+
+	ino = string_to_inode(fs, name);
+	if (!ino) {
+		printf("fetch inode fail\n");
+		return;
+	}
+
+	memset(inode_buf, 0, inode_size);
+	if (ext2fs_write_inode_full(fs, ino, inode_buf, inode_size)) {
+		printf("write inode fail\n");
+		goto out;
+	}
+out:
+	free(inode_buf);
+}
+
+static void wreck_inode_field(ext2_filsys fs, const char *name, int field)
+{
+	ext2_ino_t ino;
+	struct ext2_inode *inode_buf;
+	struct ext3_extent *ex;
+	struct ext3_extent_header *eh;
+	__u32 inode_size = EXT2_INODE_SIZE(fs->super);
+	int i;
+
+	inode_buf = (struct ext2_inode *) malloc(inode_size);
+	if (!inode_buf) {
+		printf("malloc inode_buf fail\n");
+		return;
+	}
+
+	ino = string_to_inode(fs, name);
+	if (!ino) {
+		printf("fetch inode fail\n");
+		return;
+	}
+
+	if (ext2fs_read_inode_full(fs, ino, inode_buf,
+				sizeof(struct ext2_inode))) {
+		printf("read inode fail\n");
+		goto out;
+	}
+
+	switch (field) {
+	case INODE_GENERATION:
+		inode_buf->i_generation = 0;
+		break;
+	case INODE_MODE:
+		inode_buf->i_mode = 0;
+		break;
+	case INODE_LINKS:
+		inode_buf->i_links_count = 0;
+		break;
+	case INODE_DTIME:
+		inode_buf->i_dtime = 0;
+		break;
+	case INODE_BLOCK:
+		for (i = 0; i < EXT2_N_BLOCKS; i++)
+			inode_buf->i_block[i] = 0;
+		break;
+	case INODE_BLOCKS:
+		inode_buf->i_blocks = 0;
+		break;
+	case INODE_SIZE:
+		inode_buf->i_size = 0;
+		break;
+	case EXTENT_BLOCK:
+		eh = (struct ext3_extent_header *)(inode_buf->i_block);
+		ex = EXT_FIRST_EXTENT(eh);
+		ex->ee_block = 60;
+		break;
+	case EXTENT_LEN:
+		eh = (struct ext3_extent_header *)(inode_buf->i_block);
+		ex = EXT_FIRST_EXTENT(eh);
+		ex->ee_len = 60;
+		break;
+	default:
+		goto out;
+	}
+
+	if (ext2fs_write_inode_full(fs, ino, inode_buf, inode_size)) {
+		printf("write inode fail\n");
+		goto out;
+	}
+out:
+	free(inode_buf);
+}
+
+int main(int argc, char **argv)
+{
+	errcode_t retval;
+	ext2_filsys fs;
+	int open_flag = EXT2_FLAG_64BITS | EXT2_FLAG_RW | EXT2_FLAG_BB_DIRTY;
+	int ret = 0;
+	unsigned int i;
+
+#ifdef ENABLE_NLS
+	setlocale(LC_MESSAGES, "");
+	setlocale(LC_CTYPE, "");
+	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
+	textdomain(NLS_CAT_NAME);
+#endif
+	fprintf(stderr, "e2wreck %s (%s)\n", E2FSPROGS_VERSION,
+		 E2FSPROGS_DATE);
+	if (argc < 4) {
+		usage();
+		goto out;
+	}
+
+	if (argc && *argv)
+		program_name = *argv;
+
+	add_error_table(&et_ext2_error_table);
+
+	device_name = argv[3];
+
+	retval = ext2fs_open(device_name, open_flag, 0, 0,
+			      unix_io_manager, &fs);
+	if (retval) {
+		com_err(program_name, retval, _("while trying to open %s"),
+			 device_name);
+		fputs(_("Couldn't find valid filesystem superblock.\n"),
+				stdout);
+		exit(1);
+	}
+
+	for (i = 0; i < sizeof(cmd_table) / sizeof(struct command); i++)
+		if (!strcmp(cmd_table[i].name, argv[1]))
+			cmd_table[i].func(fs, argv[2], cmd_table[i].flag);
+
+	ext2fs_close(fs);
+out:
+	remove_error_table(&et_ext2_error_table);
+	return ret;
+}
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/5 bigalloc] debugfs: support cluster unit of ee_block and ee_len
  2011-11-18 10:55 [PATCH 0/5 bigalloc] e2fsprogs: change unit of extent's ee_block and ee_len from block to cluster for bigalloc Robin Dong
  2011-11-18 10:55 ` [PATCH 1/5 bigalloc] e2fsprogs: add tool e2wreck to corrupt fs for e2fsck testing Robin Dong
@ 2011-11-18 10:55 ` Robin Dong
  2011-11-18 10:55 ` [PATCH 3/5 bigalloc] e2fsprogs: make ext2fs_mkdir to support cluster unit of directory Robin Dong
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 7+ messages in thread
From: Robin Dong @ 2011-11-18 10:55 UTC (permalink / raw)
  To: linux-ext4; +Cc: Robin Dong

From: Robin Dong <sanbai@taobao.com>

Signed-off-by: Robin Dong <sanbai@taobao.com>
---
 debugfs/debugfs.c   |    8 +++++---
 lib/ext2fs/block.c  |   15 +++++++++------
 lib/ext2fs/bmap.c   |    8 ++++++--
 lib/ext2fs/extent.c |   13 ++++++++-----
 4 files changed, 28 insertions(+), 16 deletions(-)

diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index 1fb8f44..e9c0510 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -662,7 +662,8 @@ static void dump_extents(FILE *f, const char *prefix, ext2_ino_t ino,
 				physical_width,
 				extent.e_pblk,
 				physical_width,
-				extent.e_pblk + (extent.e_len - 1),
+				extent.e_pblk + ((extent.e_len <<
+					current_fs->cluster_ratio_bits) - 1),
 				extent.e_len,
 				extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT ?
 					"Uninit" : "");
@@ -671,7 +672,7 @@ static void dump_extents(FILE *f, const char *prefix, ext2_ino_t ino,
 
 		if (extent.e_len == 0)
 			continue;
-		else if (extent.e_len == 1)
+		else if (extent.e_len == 1 && current_fs->cluster_ratio_bits == 1)
 			fprintf(f,
 				"%s(%lld%s):%lld",
 				printed ? ", " : "",
@@ -688,7 +689,8 @@ static void dump_extents(FILE *f, const char *prefix, ext2_ino_t ino,
 				extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT ?
 					"[u]" : "",
 				extent.e_pblk,
-				extent.e_pblk + (extent.e_len - 1));
+				extent.e_pblk + ((extent.e_len <<
+					current_fs->cluster_ratio_bits) - 1));
 		printed = 1;
 	}
 	if (printed)
diff --git a/lib/ext2fs/block.c b/lib/ext2fs/block.c
index 6a5c10d..212989d 100644
--- a/lib/ext2fs/block.c
+++ b/lib/ext2fs/block.c
@@ -337,6 +337,7 @@ errcode_t ext2fs_block_iterate3(ext2_filsys fs,
 	struct block_context ctx;
 	int	limit;
 	blk64_t	blk64;
+	blk64_t lblk;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
@@ -459,14 +460,16 @@ errcode_t ext2fs_block_iterate3(ext2_filsys fs,
 			       extent.e_lblk, extent.e_pblk,
 			       extent.e_len, blockcnt);
 #endif
-			if (extent.e_lblk + extent.e_len <= blockcnt)
+			if (((extent.e_lblk + extent.e_len) <<
+					fs->cluster_ratio_bits) <= blockcnt)
 				continue;
-			if (extent.e_lblk > blockcnt)
-				blockcnt = extent.e_lblk;
-			j = blockcnt - extent.e_lblk;
+			lblk = extent.e_lblk << fs->cluster_ratio_bits;
+			if (lblk > blockcnt)
+				blockcnt = lblk;
+			j = blockcnt - lblk;
 			blk += j;
-			for (blockcnt = extent.e_lblk, j = 0;
-			     j < extent.e_len;
+			for (blockcnt = lblk, j = 0;
+			     j < (extent.e_len << fs->cluster_ratio_bits);
 			     blk++, blockcnt++, j++) {
 				new_blk = blk;
 				r = (*ctx.func)(fs, &new_blk, blockcnt,
diff --git a/lib/ext2fs/bmap.c b/lib/ext2fs/bmap.c
index 16d51e0..3e71fdf 100644
--- a/lib/ext2fs/bmap.c
+++ b/lib/ext2fs/bmap.c
@@ -175,6 +175,8 @@ static errcode_t extent_bmap(ext2_filsys fs, ext2_ino_t ino,
 	unsigned int		offset;
 	errcode_t		retval = 0;
 	blk64_t			blk64 = 0;
+	blk64_t			lblk = 0;
+	blk64_t			len = 0;
 	int			alloc = 0;
 
 	if (bmap_flags & BMAP_SET) {
@@ -192,8 +194,10 @@ static errcode_t extent_bmap(ext2_filsys fs, ext2_ino_t ino,
 	retval = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent);
 	if (retval)
 		return retval;
-	offset = block - extent.e_lblk;
-	if (block >= extent.e_lblk && (offset <= extent.e_len)) {
+	lblk = extent.e_lblk << fs->cluster_ratio_bits;
+	len = extent.e_len << fs->cluster_ratio_bits;
+	offset = block - lblk;
+	if (block >= lblk && (offset <= len)) {
 		*phys_blk = extent.e_pblk + offset;
 		if (ret_flags && extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT)
 			*ret_flags |= BMAP_RET_UNINIT;
diff --git a/lib/ext2fs/extent.c b/lib/ext2fs/extent.c
index eb096d6..32eb171 100644
--- a/lib/ext2fs/extent.c
+++ b/lib/ext2fs/extent.c
@@ -636,10 +636,13 @@ static errcode_t extent_goto(ext2_extent_handle_t handle,
 	while (1) {
 		if (handle->max_depth - handle->level == leaf_level) {
 			/* block is in this &extent */
-			if ((blk >= extent.e_lblk) &&
-			    (blk < extent.e_lblk + extent.e_len))
+			if ((blk >= (extent.e_lblk <<
+					handle->fs->cluster_ratio_bits)) &&
+			    (blk < ((extent.e_lblk + extent.e_len) <<
+				    handle->fs->cluster_ratio_bits)))
 				return 0;
-			if (blk < extent.e_lblk) {
+			if (blk < (extent.e_lblk <<
+					handle->fs->cluster_ratio_bits)) {
 				retval = ext2fs_extent_get(handle,
 							   EXT2_EXTENT_PREV_SIB,
 							   &extent);
@@ -665,9 +668,9 @@ static errcode_t extent_goto(ext2_extent_handle_t handle,
 #ifdef DEBUG_GOTO_EXTENTS
 		dbg_print_extent("next", &extent);
 #endif
-		if (blk == extent.e_lblk)
+		if (blk == (extent.e_lblk << handle->fs->cluster_ratio_bits))
 			goto go_down;
-		if (blk > extent.e_lblk)
+		if (blk > (extent.e_lblk << handle->fs->cluster_ratio_bits))
 			continue;
 
 		retval = ext2fs_extent_get(handle, EXT2_EXTENT_PREV_SIB,
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 3/5 bigalloc] e2fsprogs: make ext2fs_mkdir to support cluster unit of directory
  2011-11-18 10:55 [PATCH 0/5 bigalloc] e2fsprogs: change unit of extent's ee_block and ee_len from block to cluster for bigalloc Robin Dong
  2011-11-18 10:55 ` [PATCH 1/5 bigalloc] e2fsprogs: add tool e2wreck to corrupt fs for e2fsck testing Robin Dong
  2011-11-18 10:55 ` [PATCH 2/5 bigalloc] debugfs: support cluster unit of ee_block and ee_len Robin Dong
@ 2011-11-18 10:55 ` Robin Dong
  2011-11-18 10:55 ` [PATCH 4/5 bigalloc] e2fsck: support cluster unit of ee_block and ee_len Robin Dong
  2011-11-18 10:55 ` [PATCH 5/5 bigalloc] e2fsprogs: make ext2fs_extent_set_bmap() to " Robin Dong
  4 siblings, 0 replies; 7+ messages in thread
From: Robin Dong @ 2011-11-18 10:55 UTC (permalink / raw)
  To: linux-ext4; +Cc: Robin Dong

From: Robin Dong <sanbai@taobao.com>

Signed-off-by: Robin Dong <sanbai@taobao.com>
---
 lib/ext2fs/block.c |    3 ++-
 lib/ext2fs/mkdir.c |   19 +++++++++++++++++++
 misc/mke2fs.c      |    8 ++++++++
 3 files changed, 29 insertions(+), 1 deletions(-)

diff --git a/lib/ext2fs/block.c b/lib/ext2fs/block.c
index 212989d..468538a 100644
--- a/lib/ext2fs/block.c
+++ b/lib/ext2fs/block.c
@@ -469,7 +469,8 @@ errcode_t ext2fs_block_iterate3(ext2_filsys fs,
 			j = blockcnt - lblk;
 			blk += j;
 			for (blockcnt = lblk, j = 0;
-			     j < (extent.e_len << fs->cluster_ratio_bits);
+			     j < (extent.e_len << fs->cluster_ratio_bits) &&
+			     ((j * (fs->blocksize)) < (inode.i_size));
 			     blk++, blockcnt++, j++) {
 				new_blk = blk;
 				r = (*ctx.func)(fs, &new_blk, blockcnt,
diff --git a/lib/ext2fs/mkdir.c b/lib/ext2fs/mkdir.c
index b12bf2d..de42107 100644
--- a/lib/ext2fs/mkdir.c
+++ b/lib/ext2fs/mkdir.c
@@ -40,7 +40,9 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
 	ext2_ino_t		ino = inum;
 	ext2_ino_t		scratch_ino;
 	blk64_t			blk;
+	int			i = 0;
 	char			*block = 0;
+	char			*empty_block = 0;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
@@ -69,6 +71,13 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
 		goto cleanup;
 
 	/*
+	 * Create a empty dir block
+	 */
+	retval = ext2fs_new_dir_block(fs, 0, 0, &empty_block);
+	if (retval)
+		goto cleanup;
+
+	/*
 	 * Get the parent's inode, if necessary
 	 */
 	if (parent != ino) {
@@ -98,6 +107,14 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
 	retval = ext2fs_write_dir_block(fs, blk, block);
 	if (retval)
 		goto cleanup;
+	if (fs->cluster_ratio_bits > 0) {
+		for (i = 1; i < (1 << fs->cluster_ratio_bits); i++) {
+			retval = ext2fs_write_dir_block(fs, blk + i,
+					empty_block);
+			if (retval)
+				goto cleanup;
+		}
+	}
 	retval = ext2fs_write_new_inode(fs, ino, &inode);
 	if (retval)
 		goto cleanup;
@@ -149,6 +166,8 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
 cleanup:
 	if (block)
 		ext2fs_free_mem(&block);
+	if (empty_block)
+		ext2fs_free_mem(&empty_block);
 	return retval;
 
 }
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 0ef2531..b0d7025 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -392,6 +392,7 @@ static void create_lost_and_found(ext2_filsys fs)
 	unsigned int		lpf_size = 0;
 	errcode_t		retval;
 	ext2_ino_t		ino;
+	struct ext2_inode	inode;
 	const char		*name = "lost+found";
 	int			i;
 
@@ -410,6 +411,13 @@ static void create_lost_and_found(ext2_filsys fs)
 		exit(1);
 	}
 
+	if (fs->cluster_ratio_bits > 0) {
+		retval = ext2fs_read_inode(fs, ino, &inode);
+		inode.i_size = 16*1024;
+		ext2fs_write_inode(fs, ino, &inode);
+		return;
+	}
+
 	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.  */
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 4/5 bigalloc] e2fsck: support cluster unit of ee_block and ee_len
  2011-11-18 10:55 [PATCH 0/5 bigalloc] e2fsprogs: change unit of extent's ee_block and ee_len from block to cluster for bigalloc Robin Dong
                   ` (2 preceding siblings ...)
  2011-11-18 10:55 ` [PATCH 3/5 bigalloc] e2fsprogs: make ext2fs_mkdir to support cluster unit of directory Robin Dong
@ 2011-11-18 10:55 ` Robin Dong
  2011-11-18 10:55 ` [PATCH 5/5 bigalloc] e2fsprogs: make ext2fs_extent_set_bmap() to " Robin Dong
  4 siblings, 0 replies; 7+ messages in thread
From: Robin Dong @ 2011-11-18 10:55 UTC (permalink / raw)
  To: linux-ext4; +Cc: Robin Dong

From: Robin Dong <sanbai@taobao.com>

Signed-off-by: Robin Dong <sanbai@taobao.com>
---
 e2fsck/pass1.c |   63 +++++++++++++++++++++++++++++++++++++++----------------
 1 files changed, 44 insertions(+), 19 deletions(-)

diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 532e132..70d26df 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -1741,6 +1741,8 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
 {
 	struct ext2fs_extent	extent;
 	blk64_t			blk;
+	blk64_t			elblk;
+	__u32			elen;
 	e2_blkcnt_t		blockcnt;
 	unsigned int		i;
 	int			is_dir, is_leaf;
@@ -1753,6 +1755,8 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
 
 	pctx->errcode = ext2fs_extent_get(ehandle, EXT2_EXTENT_FIRST_SIB,
 					  &extent);
+	elblk = extent.e_lblk << ctx->fs->cluster_ratio_bits;
+	elen = extent.e_len << ctx->fs->cluster_ratio_bits;
 	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);
@@ -1762,18 +1766,18 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
 		    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)
+		else if (elblk < start_block)
 			problem = PR_1_OUT_OF_ORDER_EXTENTS;
 		else if (is_leaf &&
-			 (extent.e_pblk + extent.e_len) >
+			 (extent.e_pblk + elen) >
 			 ext2fs_blocks_count(ctx->fs->super))
 			problem = PR_1_EXTENT_ENDS_BEYOND;
 
 		if (problem) {
 		report_problem:
 			pctx->blk = extent.e_pblk;
-			pctx->blk2 = extent.e_lblk;
-			pctx->num = extent.e_len;
+			pctx->blk2 = elblk;
+			pctx->num = elen;
 			if (fix_problem(ctx, problem, pctx)) {
 				e2fsck_read_bitmaps(ctx);
 				pctx->errcode =
@@ -1785,6 +1789,10 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
 				pctx->errcode = ext2fs_extent_get(ehandle,
 								  EXT2_EXTENT_CURRENT,
 								  &extent);
+				elblk = extent.e_lblk <<
+					ctx->fs->cluster_ratio_bits;
+				elen = extent.e_len <<
+					ctx->fs->cluster_ratio_bits;
 				if (pctx->errcode == EXT2_ET_NO_CURRENT_NODE) {
 					pctx->errcode = 0;
 					break;
@@ -1805,11 +1813,13 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
 					goto report_problem;
 				return;
 			}
-			scan_extent_node(ctx, pctx, pb, extent.e_lblk, ehandle);
+			scan_extent_node(ctx, pctx, pb, elblk, ehandle);
 			if (pctx->errcode)
 				return;
 			pctx->errcode = ext2fs_extent_get(ehandle,
 						  EXT2_EXTENT_UP, &extent);
+			elblk = extent.e_lblk << ctx->fs->cluster_ratio_bits;
+			elen = extent.e_len << ctx->fs->cluster_ratio_bits;
 			if (pctx->errcode) {
 				pctx->str = "EXT2_EXTENT_UP";
 				return;
@@ -1835,12 +1845,12 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
 				       (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);
+				       (unsigned long) elblk,
+				       (unsigned long) elen);
 			}
 			pb->fragmented = 1;
 		}
-		while (is_dir && ++pb->last_db_block < extent.e_lblk) {
+		while (is_dir && ++pb->last_db_block < elblk) {
 			pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist,
 							      pb->ino, 0,
 							      pb->last_db_block);
@@ -1850,8 +1860,7 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
 				goto failed_add_dir_block;
 			}
 		}
-		for (blk = extent.e_pblk, blockcnt = extent.e_lblk, i = 0;
-		     i < extent.e_len;
+		for (blk = extent.e_pblk, blockcnt = elblk, i = 0; i < elen;
 		     blk++, blockcnt++, i++) {
 			if (!(ctx->fs->cluster_ratio_bits &&
 			      pb->previous_block &&
@@ -1865,7 +1874,8 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
 
 			pb->previous_block = blk;
 
-			if (is_dir) {
+			if (is_dir && i < (pctx->inode->i_size /
+						ctx->fs->blocksize)) {
 				pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist, pctx->ino, blk, blockcnt);
 				if (pctx->errcode) {
 					pctx->blk = blk;
@@ -1878,14 +1888,16 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
 				}
 			}
 		}
-		if (is_dir && extent.e_len > 0)
+		if (is_dir && elen > 0)
 			pb->last_db_block = blockcnt - 1;
-		pb->previous_block = extent.e_pblk + extent.e_len - 1;
-		start_block = pb->last_block = extent.e_lblk + extent.e_len - 1;
+		pb->previous_block = extent.e_pblk + elen - 1;
+		start_block = pb->last_block = elblk + elen - 1;
 	next:
 		pctx->errcode = ext2fs_extent_get(ehandle,
 						  EXT2_EXTENT_NEXT_SIB,
 						  &extent);
+		elblk = extent.e_lblk << ctx->fs->cluster_ratio_bits;
+		elen = extent.e_len << ctx->fs->cluster_ratio_bits;
 	}
 	if (pctx->errcode == EXT2_ET_EXTENT_NO_NEXT)
 		pctx->errcode = 0;
@@ -1944,6 +1956,7 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 	int		dirty_inode = 0;
 	int		extent_fs;
 	__u64		size;
+	__u32		last_cluster;
 
 	pb.ino = ino;
 	pb.num_blocks = 0;
@@ -2055,9 +2068,15 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 		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;
+			if (fs->cluster_ratio_bits > 0) {
+				if ((EXT2FS_B2C(fs, pb.last_block) -
+						EXT2FS_B2C(fs, nblock)) > 1)
+					bad_size = 2;
+			} else {
+				if (((pb.last_block + 1) - nblock) >
+				    fs->super->s_prealloc_dir_blocks)
+					bad_size = 2;
+			}
 		}
 	} else {
 		e2_blkcnt_t blkpg = ctx->blocks_per_page;
@@ -2068,8 +2087,14 @@ static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
 		    (size < (__u64)pb.last_block * fs->blocksize) &&
 		    (pb.last_block / blkpg * blkpg != pb.last_block ||
 		     size < (__u64)(pb.last_block & ~(blkpg-1)) *fs->blocksize) &&
-		    !(inode->i_flags & EXT4_EOFBLOCKS_FL))
-			bad_size = 3;
+		    !(inode->i_flags & EXT4_EOFBLOCKS_FL)) {
+			last_cluster = EXT2FS_NUM_B2C(fs, (size + fs->blocksize
+						- 1) / fs->blocksize);
+			if (fs->cluster_ratio_bits <= 0 ||
+					last_cluster < ((pb.last_block + 1) >>
+						fs->cluster_ratio_bits))
+				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 */
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 5/5 bigalloc] e2fsprogs: make ext2fs_extent_set_bmap() to support cluster unit of ee_block and ee_len
  2011-11-18 10:55 [PATCH 0/5 bigalloc] e2fsprogs: change unit of extent's ee_block and ee_len from block to cluster for bigalloc Robin Dong
                   ` (3 preceding siblings ...)
  2011-11-18 10:55 ` [PATCH 4/5 bigalloc] e2fsck: support cluster unit of ee_block and ee_len Robin Dong
@ 2011-11-18 10:55 ` Robin Dong
  4 siblings, 0 replies; 7+ messages in thread
From: Robin Dong @ 2011-11-18 10:55 UTC (permalink / raw)
  To: linux-ext4; +Cc: Robin Dong

From: Robin Dong <sanbai@taobao.com>

Signed-off-by: Robin Dong <sanbai@taobao.com>
---
 lib/ext2fs/extent.c |   76 ++++++++++++++++++++++++++++++---------------------
 1 files changed, 45 insertions(+), 31 deletions(-)

diff --git a/lib/ext2fs/extent.c b/lib/ext2fs/extent.c
index 32eb171..c646604 100644
--- a/lib/ext2fs/extent.c
+++ b/lib/ext2fs/extent.c
@@ -516,7 +516,7 @@ retry:
 			ix++;
 			end_blk = ext2fs_le32_to_cpu(ix->ei_block);
 		} else
-			end_blk = path->end_blk;
+			end_blk = EXT2FS_B2C(handle->fs, path->end_blk);
 
 		extent->e_len = end_blk - extent->e_lblk;
 	}
@@ -854,7 +854,7 @@ static errcode_t extent_node_split(ext2_extent_handle_t handle)
 
 	/* save the position we were originally splitting... */
 	orig_height = info.max_depth - info.curr_level;
-	orig_lblk = extent.e_lblk;
+	orig_lblk = EXT2FS_C2B(handle->fs, extent.e_lblk);
 
 	/* Is there room in the parent for a new entry? */
 	if (handle->level &&
@@ -1000,7 +1000,8 @@ static errcode_t extent_node_split(ext2_extent_handle_t handle)
 
 		extent.e_lblk = new_node_start;
 		extent.e_pblk = new_node_pblk;
-		extent.e_len = handle->path[0].end_blk - extent.e_lblk;
+		extent.e_len = EXT2FS_B2C(handle->fs, handle->path[0].end_blk -
+				EXT2FS_C2B(handle->fs, extent.e_lblk));
 		retval = ext2fs_extent_replace(handle, 0, &extent);
 		if (retval)
 			goto done;
@@ -1157,6 +1158,7 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
 	struct ext2fs_extent	extent, next_extent, prev_extent;
 	struct ext2fs_extent	newextent;
 	struct ext2_extent_info	info;
+	ext2_filsys		fs = handle->fs;
 
 	EXT2_CHECK_MAGIC(handle, EXT2_ET_MAGIC_EXTENT_HANDLE);
 
@@ -1182,7 +1184,7 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
 	if (physical) {
 		newextent.e_len = 1;
 		newextent.e_pblk = physical;
-		newextent.e_lblk = logical;
+		newextent.e_lblk = EXT2FS_B2C(handle->fs, logical);
 		newextent.e_flags = EXT2_EXTENT_FLAGS_LEAF;
 		if (new_uninit)
 			newextent.e_flags |= EXT2_EXTENT_FLAGS_UNINIT;
@@ -1204,7 +1206,7 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
 	if ((retval = ext2fs_extent_get_info(handle, &info)))
 		return retval;
 	orig_height = info.max_depth - info.curr_level;
-	orig_lblk = extent.e_lblk;
+	orig_lblk = EXT2FS_C2B(handle->fs, extent.e_lblk);
 
 	/* go to the logical spot we want to (re/un)map */
 	retval = ext2fs_extent_goto(handle, logical);
@@ -1267,7 +1269,8 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
 
 	/* check if already pointing to the requested physical */
 	if (mapped && (new_uninit == extent_uninit) &&
-	    (extent.e_pblk + (logical - extent.e_lblk) == physical)) {
+	    (extent.e_pblk + (logical - EXT2FS_C2B(handle->fs, extent.e_lblk))
+	     == physical)) {
 #ifdef DEBUG
 		printf("physical block (at %llu) unchanged\n", logical);
 #endif
@@ -1278,25 +1281,30 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
 #ifdef DEBUG
 		printf("mapping unmapped logical block %llu\n", logical);
 #endif
-		if ((logical == extent.e_lblk + extent.e_len) &&
-		    (physical == extent.e_pblk + extent.e_len) &&
+		if ((logical == EXT2FS_C2B(fs, extent.e_lblk + extent.e_len)) &&
+		    (physical == extent.e_pblk +
+		     EXT2FS_C2B(fs, extent.e_len)) &&
 		    (new_uninit == extent_uninit) &&
-		    ((int) extent.e_len < max_len-1)) {
+		    ((int) EXT2FS_C2B(fs, extent.e_len) < max_len - 1)) {
 			extent.e_len++;
 			retval = ext2fs_extent_replace(handle, 0, &extent);
-		} else if ((logical == extent.e_lblk - 1) &&
-			   (physical == extent.e_pblk - 1) &&
+		} else if ((logical == EXT2FS_C2B(fs, extent.e_lblk - 1)) &&
+			   (physical == extent.e_pblk -
+			    EXT2FS_CLUSTER_RATIO(fs)) &&
 			   (new_uninit == extent_uninit) &&
-			   ((int) extent.e_len < max_len - 1)) {
+			   ((int) EXT2FS_C2B(fs, extent.e_len) < max_len - 1)) {
 			extent.e_len++;
 			extent.e_lblk--;
-			extent.e_pblk--;
+			extent.e_pblk -= EXT2FS_CLUSTER_RATIO(fs);
 			retval = ext2fs_extent_replace(handle, 0, &extent);
 		} else if (has_next &&
-			   (logical == next_extent.e_lblk - 1) &&
-			   (physical == next_extent.e_pblk - 1) &&
+			   (logical == EXT2FS_C2B(fs,
+					next_extent.e_lblk - 1)) &&
+			   (physical == next_extent.e_pblk -
+			    EXT2FS_CLUSTER_RATIO(fs)) &&
 			   (new_uninit == next_uninit) &&
-			   ((int) next_extent.e_len < max_len - 1)) {
+			   ((int) EXT2FS_C2B(fs, next_extent.e_len) <
+			    max_len - 1)) {
 			retval = ext2fs_extent_get(handle,
 						   EXT2_EXTENT_NEXT_LEAF,
 						   &next_extent);
@@ -1304,9 +1312,9 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
 				goto done;
 			next_extent.e_len++;
 			next_extent.e_lblk--;
-			next_extent.e_pblk--;
+			next_extent.e_pblk -= EXT2FS_CLUSTER_RATIO(fs);
 			retval = ext2fs_extent_replace(handle, 0, &next_extent);
-		} else if (logical < extent.e_lblk)
+		} else if (logical < EXT2FS_C2B(fs, extent.e_lblk))
 			retval = ext2fs_extent_insert(handle, 0, &newextent);
 		else
 			retval = ext2fs_extent_insert(handle,
@@ -1316,7 +1324,8 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
 		retval = ext2fs_extent_fix_parents(handle);
 		if (retval)
 			goto done;
-	} else if ((logical == extent.e_lblk) && (extent.e_len == 1))  {
+	} else if ((logical == EXT2FS_C2B(fs, extent.e_lblk)) &&
+			(extent.e_len == 1))  {
 #ifdef DEBUG
 		printf("(re/un)mapping only block in extent\n");
 #endif
@@ -1333,23 +1342,27 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
 
 		if (retval)
 			goto done;
-	} else if (logical == extent.e_lblk + extent.e_len - 1)  {
+	} else if (logical == EXT2FS_C2B(fs, extent.e_lblk +
+				extent.e_len - 1))  {
 #ifdef DEBUG
 		printf("(re/un)mapping last block in extent\n");
 #endif
 		if (physical) {
 			if (has_next &&
-			    (logical == (next_extent.e_lblk - 1)) &&
-			    (physical == (next_extent.e_pblk - 1)) &&
+			    (logical == (EXT2FS_C2B(fs,
+					next_extent.e_lblk - 1))) &&
+			    (physical == (next_extent.e_pblk -
+					  EXT2FS_CLUSTER_RATIO(fs))) &&
 			    (new_uninit == next_uninit) &&
-			    ((int) next_extent.e_len < max_len - 1)) {
+			    ((int) EXT2FS_C2B(fs, next_extent.e_len) <
+			     max_len - 1)) {
 				retval = ext2fs_extent_get(handle,
 					EXT2_EXTENT_NEXT_LEAF, &next_extent);
 				if (retval)
 					goto done;
 				next_extent.e_len++;
 				next_extent.e_lblk--;
-				next_extent.e_pblk--;
+				next_extent.e_pblk -= EXT2FS_CLUSTER_RATIO(fs);
 				retval = ext2fs_extent_replace(handle, 0,
 							       &next_extent);
 				if (retval)
@@ -1370,18 +1383,19 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
 		retval = ext2fs_extent_replace(handle, 0, &extent);
 		if (retval)
 			goto done;
-	} else if (logical == extent.e_lblk) {
+	} else if (logical == EXT2FS_C2B(fs, extent.e_lblk)) {
 #ifdef DEBUG
 		printf("(re/un)mapping first block in extent\n");
 #endif
 		if (physical) {
 			if (has_prev &&
-			    (logical == (prev_extent.e_lblk +
+			    (logical == EXT2FS_C2B(fs, prev_extent.e_lblk +
 					 prev_extent.e_len)) &&
 			    (physical == (prev_extent.e_pblk +
-					  prev_extent.e_len)) &&
+					  EXT2FS_C2B(fs, prev_extent.e_len))) &&
 			    (new_uninit == prev_uninit) &&
-			    ((int) prev_extent.e_len < max_len-1)) {
+			    ((int) EXT2FS_C2B(fs, prev_extent.e_len) <
+			     max_len - 1)) {
 				retval = ext2fs_extent_get(handle, 
 					EXT2_EXTENT_PREV_LEAF, &prev_extent);
 				if (retval)
@@ -1400,7 +1414,7 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
 			if (retval)
 				goto done;
 		}
-		extent.e_pblk++;
+		extent.e_pblk += EXT2FS_CLUSTER_RATIO(fs);
 		extent.e_lblk++;
 		extent.e_len--;
 		retval = ext2fs_extent_replace(handle, 0, &extent);
@@ -1417,7 +1431,7 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
 		orig_length = extent.e_len;
 
 		/* shorten pre-split extent */
-		extent.e_len = (logical - extent.e_lblk);
+		extent.e_len = (EXT2FS_B2C(fs, logical) - extent.e_lblk);
 		retval = ext2fs_extent_replace(handle, 0, &extent);
 		if (retval)
 			goto done;
@@ -1430,7 +1444,7 @@ errcode_t ext2fs_extent_set_bmap(ext2_extent_handle_t handle,
 				goto done;
 		}
 		/* add post-split extent */
-		extent.e_pblk += extent.e_len + 1;
+		extent.e_pblk += EXT2FS_C2B(fs, extent.e_len + 1);
 		extent.e_lblk += extent.e_len + 1;
 		extent.e_len = orig_length - extent.e_len - 1;
 		retval = ext2fs_extent_insert(handle,
-- 
1.7.3.2


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/5 bigalloc] e2fsprogs: add tool e2wreck to corrupt fs for e2fsck testing
  2011-11-18 10:55 ` [PATCH 1/5 bigalloc] e2fsprogs: add tool e2wreck to corrupt fs for e2fsck testing Robin Dong
@ 2011-11-19  3:31   ` Ted Ts'o
  0 siblings, 0 replies; 7+ messages in thread
From: Ted Ts'o @ 2011-11-19  3:31 UTC (permalink / raw)
  To: Robin Dong; +Cc: linux-ext4, Robin Dong

On Fri, Nov 18, 2011 at 06:55:26PM +0800, Robin Dong wrote:
> From: Robin Dong <sanbai@taobao.com>
> 
> We need a tool to wreck filesystem to test e2fsck
> 
> Signed-off-by: Robin Dong <sanbai@taobao.com>

I don't understand why you need this tool.  Debugfs is a more general
tool that will do pretty much everything your proposed e2wreck tool
will do.

The one exception to this is low-level extent tree modifications ---
that functionality is there in the tst_extent program, which is a
debugging program I used when developing the extent support for
e2fsck.  Go to the lib/ext2fs directory, and run "make tst_extents".
It's been on my todo list to get a more cleaner support for low-level
extent manipulation to debugfs, but I haven't gotten around to it,
since tst_extents is a serviceable enough, if hacky, substitute.

      		       		   	      	     - Ted

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-11-19  3:31 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-11-18 10:55 [PATCH 0/5 bigalloc] e2fsprogs: change unit of extent's ee_block and ee_len from block to cluster for bigalloc Robin Dong
2011-11-18 10:55 ` [PATCH 1/5 bigalloc] e2fsprogs: add tool e2wreck to corrupt fs for e2fsck testing Robin Dong
2011-11-19  3:31   ` Ted Ts'o
2011-11-18 10:55 ` [PATCH 2/5 bigalloc] debugfs: support cluster unit of ee_block and ee_len Robin Dong
2011-11-18 10:55 ` [PATCH 3/5 bigalloc] e2fsprogs: make ext2fs_mkdir to support cluster unit of directory Robin Dong
2011-11-18 10:55 ` [PATCH 4/5 bigalloc] e2fsck: support cluster unit of ee_block and ee_len Robin Dong
2011-11-18 10:55 ` [PATCH 5/5 bigalloc] e2fsprogs: make ext2fs_extent_set_bmap() to " Robin Dong

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).