All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <djwong@us.ibm.com>
To: Andreas Dilger <adilger.kernel@dilger.ca>,
	Theodore Tso <tytso@mit.edu>,
	"Darrick J. Wong" <djwong@us.ibm.com>
Cc: Sunil Mushran <sunil.mushran@oracle.com>,
	Amir Goldstein <amir73il@gmail.com>,
	Andi Kleen <andi@firstfloor.org>, Mingming Cao <cmm@us.ibm.com>,
	Joel Becker <jlbec@evilplan.org>,
	linux-ext4@vger.kernel.org, Coly Li <colyli@gmail.com>
Subject: [PATCH 24/51] libext2fs: Introduce dir_entry_tail to provide checksums for directory leaf nodes
Date: Tue, 13 Dec 2011 17:15:58 -0800	[thread overview]
Message-ID: <20111214011557.20947.36828.stgit@elm3c44.beaverton.ibm.com> (raw)
In-Reply-To: <20111214011316.20947.13706.stgit@elm3c44.beaverton.ibm.com>

Introduce small structures for recording directory tree checksums, and some API
changes to support writing out directory blocks with checksums.

Signed-off-by: Darrick J. Wong <djwong@us.ibm.com>
---
 debugfs/htree.c           |    9 ++-
 e2fsck/pass1.c            |    2 -
 e2fsck/pass2.c            |   14 +++-
 e2fsck/pass3.c            |   10 ++-
 e2fsck/rehash.c           |   37 +++++++++---
 lib/ext2fs/csum.c         |  143 +++++++++++++++++++++++++++++++++++++++++++++
 lib/ext2fs/dir_iterate.c  |   14 +++-
 lib/ext2fs/dirblock.c     |   98 +++++++++++++------------------
 lib/ext2fs/expanddir.c    |    5 +-
 lib/ext2fs/ext2_err.et.in |    3 +
 lib/ext2fs/ext2fs.h       |   18 ++++++
 lib/ext2fs/link.c         |    6 ++
 lib/ext2fs/mkdir.c        |    2 -
 lib/ext2fs/newdir.c       |   15 ++++-
 lib/ext2fs/swapfs.c       |   62 ++++++++++++++++++++
 15 files changed, 356 insertions(+), 82 deletions(-)


diff --git a/debugfs/htree.c b/debugfs/htree.c
index f79fa05..ddd1539 100644
--- a/debugfs/htree.c
+++ b/debugfs/htree.c
@@ -44,6 +44,11 @@ static void htree_dump_leaf_node(ext2_filsys fs, ext2_ino_t ino,
 	ext2_dirhash_t 	hash, minor_hash;
 	unsigned int	rec_len;
 	int		hash_alg;
+	int		csum_size = 0;
+
+	if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+				       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+		csum_size = sizeof(struct ext2_dir_entry_tail);
 
 	errcode = ext2fs_bmap2(fs, ino, inode, buf, 0, blk, 0, &pblk);
 	if (errcode) {
@@ -53,7 +58,7 @@ static void htree_dump_leaf_node(ext2_filsys fs, ext2_ino_t ino,
 	}
 
 	printf("Reading directory block %llu, phys %llu\n", blk, pblk);
-	errcode = ext2fs_read_dir_block2(current_fs, pblk, buf, 0);
+	errcode = ext2fs_read_dir_block4(current_fs, pblk, buf, 0, ino);
 	if (errcode) {
 		com_err("htree_dump_leaf_node", errcode,
 			"while reading block %llu (%llu)\n",
@@ -65,7 +70,7 @@ static void htree_dump_leaf_node(ext2_filsys fs, ext2_ino_t ino,
 	    (fs->super->s_flags & EXT2_FLAGS_UNSIGNED_HASH))
 		hash_alg += 3;
 
-	while (offset < fs->blocksize) {
+	while (offset < (fs->blocksize - csum_size)) {
 		dirent = (struct ext2_dir_entry *) (buf + offset);
 		errcode = ext2fs_get_rec_len(fs, dirent, &rec_len);
 		if (errcode) {
diff --git a/e2fsck/pass1.c b/e2fsck/pass1.c
index 7cfc739..b2b6596 100644
--- a/e2fsck/pass1.c
+++ b/e2fsck/pass1.c
@@ -473,7 +473,7 @@ static void check_is_really_dir(e2fsck_t ctx, struct problem_context *pctx,
 
 	/* read the first block */
 	ehandler_operation(_("reading directory block"));
-	retval = ext2fs_read_dir_block3(ctx->fs, blk, buf, 0);
+	retval = ext2fs_read_dir_block4(ctx->fs, blk, buf, 0, pctx->ino);
 	ehandler_operation(0);
 	if (retval)
 		return;
diff --git a/e2fsck/pass2.c b/e2fsck/pass2.c
index e11ddbf..cf2079a 100644
--- a/e2fsck/pass2.c
+++ b/e2fsck/pass2.c
@@ -746,6 +746,7 @@ static int check_dir_block(ext2_filsys fs,
 	int	dups_found = 0;
 	int	ret;
 	int	csum_size = 0;
+	int	failed_csum = 0;
 
 	cd = (struct check_dir_struct *) priv_data;
 	buf = cd->buf;
@@ -796,10 +797,14 @@ static int check_dir_block(ext2_filsys fs,
 #endif
 
 	ehandler_operation(_("reading directory block"));
-	cd->pctx.errcode = ext2fs_read_dir_block3(fs, block_nr, buf, 0);
+	cd->pctx.errcode = ext2fs_read_dir_block4(fs, block_nr, buf, 0, ino);
 	ehandler_operation(0);
 	if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
 		cd->pctx.errcode = 0; /* We'll handle this ourselves */
+	else if (cd->pctx.errcode == EXT2_ET_DIR_CSUM_INVALID) {
+		cd->pctx.errcode = 0; /* We'll handle this ourselves */
+		failed_csum = 1;
+	}
 	if (cd->pctx.errcode) {
 		if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
 			ctx->flags |= E2F_FLAG_ABORT;
@@ -1137,7 +1142,7 @@ out_htree:
 		cd->pctx.dir = cd->pctx.ino;
 		if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
 		    (dx_db->type == DX_DIRBLOCK_NODE))
-			parse_int_node(fs, db, cd, dx_dir, buf, 0);
+			parse_int_node(fs, db, cd, dx_dir, buf, failed_csum);
 	}
 #endif /* ENABLE_HTREE */
 	if (offset != fs->blocksize) {
@@ -1148,7 +1153,8 @@ out_htree:
 		}
 	}
 	if (dir_modified) {
-		cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
+		cd->pctx.errcode = ext2fs_write_dir_block4(fs, block_nr, buf,
+							   0, ino);
 		if (cd->pctx.errcode) {
 			if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
 					 &cd->pctx))
@@ -1468,7 +1474,7 @@ static int allocate_dir_block(e2fsck_t ctx,
 		return 1;
 	}
 
-	pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
+	pctx->errcode = ext2fs_write_dir_block4(fs, blk, block, 0, db->ino);
 	ext2fs_free_mem(&block);
 	if (pctx->errcode) {
 		pctx->str = "ext2fs_write_dir_block";
diff --git a/e2fsck/pass3.c b/e2fsck/pass3.c
index 7164aa9..86a509c 100644
--- a/e2fsck/pass3.c
+++ b/e2fsck/pass3.c
@@ -197,7 +197,8 @@ static void check_root(e2fsck_t ctx)
 		return;
 	}
 
-	pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
+	pctx.errcode = ext2fs_write_dir_block4(fs, blk, block, 0,
+					       EXT2_ROOT_INO);
 	if (pctx.errcode) {
 		pctx.str = "ext2fs_write_dir_block";
 		fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
@@ -443,7 +444,7 @@ ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
 		return 0;
 	}
 
-	retval = ext2fs_write_dir_block(fs, blk, block);
+	retval = ext2fs_write_dir_block4(fs, blk, block, 0, ino);
 	ext2fs_free_mem(&block);
 	if (retval) {
 		pctx.errcode = retval;
@@ -684,6 +685,7 @@ struct expand_dir_struct {
 	blk64_t			last_block;
 	errcode_t		err;
 	e2fsck_t		ctx;
+	ext2_ino_t		dir;
 };
 
 static int expand_dir_proc(ext2_filsys fs,
@@ -724,7 +726,8 @@ static int expand_dir_proc(ext2_filsys fs,
 			return BLOCK_ABORT;
 		}
 		es->num--;
-		retval = ext2fs_write_dir_block(fs, new_blk, block);
+		retval = ext2fs_write_dir_block4(fs, new_blk, block, 0,
+						 es->dir);
 	} else {
 		retval = ext2fs_get_mem(fs->blocksize, &block);
 		if (retval) {
@@ -777,6 +780,7 @@ errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
 	es.err = 0;
 	es.newblocks = 0;
 	es.ctx = ctx;
+	es.dir = dir;
 
 	retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_APPEND,
 				       0, expand_dir_proc, &es);
diff --git a/e2fsck/rehash.c b/e2fsck/rehash.c
index a472aad..e80f728 100644
--- a/e2fsck/rehash.c
+++ b/e2fsck/rehash.c
@@ -62,6 +62,7 @@ struct fill_dir_struct {
 	int dir_size;
 	int compress;
 	ino_t parent;
+	ext2_ino_t dir;
 };
 
 struct hash_entry {
@@ -106,7 +107,10 @@ static int fill_dir_block(ext2_filsys fs,
 		dirent = (struct ext2_dir_entry *) dir;
 		(void) ext2fs_set_rec_len(fs, fs->blocksize, dirent);
 	} else {
-		fd->err = ext2fs_read_dir_block3(fs, *block_nr, dir, 0);
+		fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
+		fd->err = ext2fs_read_dir_block4(fs, *block_nr, dir, 0,
+						 fd->dir);
+		fs->flags &= ~EXT2_FLAG_IGNORE_CSUM_ERRORS;
 		if (fd->err)
 			return BLOCK_ABORT;
 	}
@@ -397,7 +401,8 @@ static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
 
 static errcode_t copy_dir_entries(e2fsck_t ctx,
 				  struct fill_dir_struct *fd,
-				  struct out_dir *outdir)
+				  struct out_dir *outdir,
+				  ext2_ino_t ino)
 {
 	ext2_filsys 		fs = ctx->fs;
 	errcode_t		retval;
@@ -408,6 +413,8 @@ static errcode_t copy_dir_entries(e2fsck_t ctx,
 	int			i, left;
 	ext2_dirhash_t		prev_hash;
 	int			offset, slack;
+	int			csum_size = 0;
+	struct			ext2_dir_entry_tail *t;
 
 	if (ctx->htree_slack_percentage == 255) {
 		profile_get_uint(ctx->profile, "options",
@@ -418,6 +425,10 @@ static errcode_t copy_dir_entries(e2fsck_t ctx,
 			ctx->htree_slack_percentage = 20;
 	}
 
+	if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+				       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+		csum_size = sizeof(struct ext2_dir_entry_tail);
+
 	outdir->max = 0;
 	retval = alloc_size_dir(fs, outdir,
 				(fd->dir_size / fs->blocksize) + 2);
@@ -432,9 +443,9 @@ static errcode_t copy_dir_entries(e2fsck_t ctx,
 	dirent = (struct ext2_dir_entry *) block_start;
 	prev_rec_len = 0;
 	rec_len = 0;
-	left = fs->blocksize;
+	left = fs->blocksize - csum_size;
 	slack = fd->compress ? 12 :
-		(fs->blocksize * ctx->htree_slack_percentage)/100;
+		((fs->blocksize - csum_size) * ctx->htree_slack_percentage)/100;
 	if (slack < 12)
 		slack = 12;
 	for (i = 0; i < fd->num_array; i++) {
@@ -449,12 +460,17 @@ static errcode_t copy_dir_entries(e2fsck_t ctx,
 				if (retval)
 					return retval;
 			}
+			if (csum_size) {
+				t = EXT2_DIRENT_TAIL(block_start,
+						     fs->blocksize);
+				ext2fs_initialize_dirent_tail(fs, t);
+			}
 			if ((retval = get_next_block(fs, outdir,
 						      &block_start)))
 				return retval;
 			offset = 0;
 		}
-		left = fs->blocksize - offset;
+		left = (fs->blocksize - csum_size) - offset;
 		dirent = (struct ext2_dir_entry *) (block_start + offset);
 		if (offset == 0) {
 			if (ent->hash == prev_hash)
@@ -483,6 +499,10 @@ static errcode_t copy_dir_entries(e2fsck_t ctx,
 	}
 	if (left)
 		retval = ext2fs_set_rec_len(fs, rec_len + left, dirent);
+	if (csum_size) {
+		t = EXT2_DIRENT_TAIL(block_start, fs->blocksize);
+		ext2fs_initialize_dirent_tail(fs, t);
+	}
 
 	return retval;
 }
@@ -640,6 +660,7 @@ struct write_dir_struct {
 	errcode_t	err;
 	e2fsck_t	ctx;
 	int		cleared;
+	ext2_ino_t	dir;
 };
 
 /*
@@ -671,7 +692,7 @@ static int write_dir_block(ext2_filsys fs,
 		return 0;
 
 	dir = wd->outdir->buf + (blockcnt * fs->blocksize);
-	wd->err = ext2fs_write_dir_block3(fs, *block_nr, dir, 0);
+	wd->err = ext2fs_write_dir_block4(fs, *block_nr, dir, 0, wd->dir);
 	if (wd->err)
 		return BLOCK_ABORT;
 	return 0;
@@ -693,6 +714,7 @@ static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
 	wd.err = 0;
 	wd.ctx = ctx;
 	wd.cleared = 0;
+	wd.dir = ino;
 
 	retval = ext2fs_block_iterate3(fs, ino, 0, 0,
 				       write_dir_block, &wd);
@@ -745,6 +767,7 @@ errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
 	fd.err = 0;
 	fd.dir_size = 0;
 	fd.compress = 0;
+	fd.dir = ino;
 	if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
 	    (inode.i_size / fs->blocksize) < 2)
 		fd.compress = 1;
@@ -804,7 +827,7 @@ resort:
 	 * Copy the directory entries.  In a htree directory these
 	 * will become the leaf nodes.
 	 */
-	retval = copy_dir_entries(ctx, &fd, &outdir);
+	retval = copy_dir_entries(ctx, &fd, &outdir, ino);
 	if (retval)
 		goto errout;
 
diff --git a/lib/ext2fs/csum.c b/lib/ext2fs/csum.c
index 31dc4dc..5a370d6 100644
--- a/lib/ext2fs/csum.c
+++ b/lib/ext2fs/csum.c
@@ -93,6 +93,117 @@ errcode_t ext2fs_get_dx_countlimit(ext2_filsys fs,
 	return __get_dx_countlimit(fs, dirent, cc, offset, 0);
 }
 
+void ext2fs_initialize_dirent_tail(ext2_filsys fs,
+				   struct ext2_dir_entry_tail *t)
+{
+	memset(t, 0, sizeof(struct ext2_dir_entry_tail));
+	ext2fs_set_rec_len(fs, sizeof(struct ext2_dir_entry_tail),
+			   (struct ext2_dir_entry *)t);
+	t->reserved_name_len = EXT2_DIR_NAME_LEN_CSUM;
+}
+
+static errcode_t __get_dirent_tail(ext2_filsys fs,
+				   struct ext2_dir_entry *dirent,
+				   struct ext2_dir_entry_tail **tt,
+				   int need_swab)
+{
+	struct ext2_dir_entry *d;
+	void *top;
+	struct ext2_dir_entry_tail *t;
+	unsigned int rec_len;
+	errcode_t retval = 0;
+	__u16 (*translate)(__u16) = (need_swab ? disk_to_host16 : do_nothing16);
+
+	d = dirent;
+	top = EXT2_DIRENT_TAIL(dirent, fs->blocksize);
+
+	rec_len = translate(d->rec_len);
+	while (rec_len && !(rec_len & 0x3)) {
+		d = (struct ext2_dir_entry *)(((void *)d) + rec_len);
+		if ((void *)d >= top)
+			break;
+		rec_len = translate(d->rec_len);
+	}
+
+	if (d != top)
+		return EXT2_ET_DIR_NO_SPACE_FOR_CSUM;
+
+	t = (struct ext2_dir_entry_tail *)d;
+	if (t->reserved_zero1 ||
+	    translate(t->rec_len) != sizeof(struct ext2_dir_entry_tail) ||
+	    translate(t->reserved_name_len) != EXT2_DIR_NAME_LEN_CSUM)
+		return EXT2_ET_DIR_NO_SPACE_FOR_CSUM;
+
+	if (tt)
+		*tt = t;
+	return retval;
+}
+
+int ext2fs_dirent_has_tail(ext2_filsys fs, struct ext2_dir_entry *dirent)
+{
+	return __get_dirent_tail(fs, dirent, NULL, 0) == 0;
+}
+
+static errcode_t ext2fs_dirent_csum(ext2_filsys fs, ext2_ino_t inum,
+				    struct ext2_dir_entry *dirent, __u32 *crc,
+				    int size)
+{
+	errcode_t retval = 0;
+	char *buf = (char *)dirent;
+	__u32 ncrc;
+
+	inum = ext2fs_cpu_to_le32(inum);
+	ncrc = ext2fs_crc32c_le(~0, fs->super->s_uuid,
+				sizeof(fs->super->s_uuid));
+	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)&inum, sizeof(inum));
+	ncrc = ext2fs_crc32c_le(ncrc, (unsigned char *)buf, size);
+	*crc = ncrc;
+
+	return retval;
+}
+
+int ext2fs_dirent_csum_verify(ext2_filsys fs, ext2_ino_t inum,
+			      struct ext2_dir_entry *dirent)
+{
+	errcode_t retval;
+	__u32 calculated;
+	struct ext2_dir_entry_tail *t;
+
+	retval = __get_dirent_tail(fs, dirent, &t, 1);
+	if (retval)
+		return 1;
+
+	/*
+	 * The checksum field is overlaid with the dirent->name field
+	 * so the swapfs.c functions won't change the endianness.
+	 */
+	retval = ext2fs_dirent_csum(fs, inum, dirent, &calculated,
+				    (void *)t - (void *)dirent);
+	if (retval)
+		return 0;
+	return ext2fs_le32_to_cpu(t->checksum) == calculated;
+}
+
+static errcode_t ext2fs_dirent_csum_set(ext2_filsys fs, ext2_ino_t inum,
+					struct ext2_dir_entry *dirent)
+{
+	errcode_t retval;
+	__u32 crc;
+	struct ext2_dir_entry_tail *t;
+
+	retval = __get_dirent_tail(fs, dirent, &t, 1);
+	if (retval)
+		return retval;
+
+	/* swapfs.c functions don't change the checksum endianness */
+	retval = ext2fs_dirent_csum(fs, inum, dirent, &crc,
+				    (void *)t - (void *)dirent);
+	if (retval)
+		return retval;
+	t->checksum = ext2fs_cpu_to_le32(crc);
+	return 0;
+}
+
 static errcode_t ext2fs_dx_csum(ext2_filsys fs, ext2_ino_t inum,
 				struct ext2_dir_entry *dirent,
 				__u32 *crc, int count_offset, int count,
@@ -175,6 +286,38 @@ static errcode_t ext2fs_dx_csum_set(ext2_filsys fs, ext2_ino_t inum,
 	return retval;
 }
 
+int ext2fs_dir_block_csum_verify(ext2_filsys fs, ext2_ino_t inum,
+				 struct ext2_dir_entry *dirent)
+{
+	if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+					EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+		return 1;
+
+	if (__get_dirent_tail(fs, dirent, NULL, 1) == 0)
+		return ext2fs_dirent_csum_verify(fs, inum, dirent);
+	if (__get_dx_countlimit(fs, dirent, NULL, NULL, 1) == 0)
+		return ext2fs_dx_csum_verify(fs, inum, dirent);
+
+	return 0;
+}
+
+errcode_t ext2fs_dir_block_csum_set(ext2_filsys fs, ext2_ino_t inum,
+				    struct ext2_dir_entry *dirent)
+{
+	if (!EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+					EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+		return 0;
+
+	if (__get_dirent_tail(fs, dirent, NULL, 1) == 0)
+		return ext2fs_dirent_csum_set(fs, inum, dirent);
+	if (__get_dx_countlimit(fs, dirent, NULL, NULL, 1) == 0)
+		return ext2fs_dx_csum_set(fs, inum, dirent);
+
+	if (fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS)
+		return 0;
+	return EXT2_ET_DIR_NO_SPACE_FOR_CSUM;
+}
+
 #define EXT3_EXTENT_TAIL_OFFSET(hdr)	(sizeof(struct ext3_extent_header) + \
 	(sizeof(struct ext3_extent) * ext2fs_le16_to_cpu((hdr)->eh_max)))
 
diff --git a/lib/ext2fs/dir_iterate.c b/lib/ext2fs/dir_iterate.c
index 5125d19..c24015c 100644
--- a/lib/ext2fs/dir_iterate.c
+++ b/lib/ext2fs/dir_iterate.c
@@ -192,17 +192,23 @@ int ext2fs_process_dir_block(ext2_filsys fs,
 	unsigned int	rec_len, size;
 	int		entry;
 	struct ext2_dir_entry *dirent;
+	int		csum_size = 0;
 
 	if (blockcnt < 0)
 		return 0;
 
 	entry = blockcnt ? DIRENT_OTHER_FILE : DIRENT_DOT_FILE;
 
-	ctx->errcode = ext2fs_read_dir_block3(fs, *blocknr, ctx->buf, 0);
+	ctx->errcode = ext2fs_read_dir_block4(fs, *blocknr, ctx->buf, 0,
+					      ctx->dir);
 	if (ctx->errcode)
 		return BLOCK_ABORT;
 
-	while (offset < fs->blocksize) {
+	if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+					EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+		csum_size = sizeof(struct ext2_dir_entry_tail);
+
+	while (offset < (fs->blocksize - csum_size)) {
 		dirent = (struct ext2_dir_entry *) (ctx->buf + offset);
 		if (ext2fs_get_rec_len(fs, dirent, &rec_len))
 			return BLOCK_ABORT;
@@ -259,8 +265,8 @@ next:
 	}
 
 	if (changed) {
-		ctx->errcode = ext2fs_write_dir_block3(fs, *blocknr, ctx->buf,
-						       0);
+		ctx->errcode = ext2fs_write_dir_block4(fs, *blocknr, ctx->buf,
+						       0, ctx->dir);
 		if (ctx->errcode)
 			return BLOCK_ABORT;
 	}
diff --git a/lib/ext2fs/dirblock.c b/lib/ext2fs/dirblock.c
index cb3a104..54b2777 100644
--- a/lib/ext2fs/dirblock.c
+++ b/lib/ext2fs/dirblock.c
@@ -20,45 +20,36 @@
 #include "ext2_fs.h"
 #include "ext2fs.h"
 
-errcode_t ext2fs_read_dir_block3(ext2_filsys fs, blk64_t block,
-				 void *buf, int flags EXT2FS_ATTR((unused)))
+errcode_t ext2fs_read_dir_block4(ext2_filsys fs, blk64_t block,
+				 void *buf, int flags EXT2FS_ATTR((unused)),
+				 ext2_ino_t ino)
 {
 	errcode_t	retval;
-	char		*p, *end;
-	struct ext2_dir_entry *dirent;
-	unsigned int	name_len, rec_len;
-
+	int		corrupt = 0;
 
 	retval = io_channel_read_blk64(fs->io, block, 1, buf);
 	if (retval)
 		return retval;
 
-	p = (char *) buf;
-	end = (char *) buf + fs->blocksize;
-	while (p < end-8) {
-		dirent = (struct ext2_dir_entry *) p;
-#ifdef WORDS_BIGENDIAN
-		dirent->inode = ext2fs_swab32(dirent->inode);
-		dirent->rec_len = ext2fs_swab16(dirent->rec_len);
-		dirent->name_len = ext2fs_swab16(dirent->name_len);
-#endif
-		name_len = dirent->name_len;
+	if (!(fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) &&
+	    !ext2fs_dir_block_csum_verify(fs, ino,
+					  (struct ext2_dir_entry *)buf))
+		corrupt = 1;
+
 #ifdef WORDS_BIGENDIAN
-		if (flags & EXT2_DIRBLOCK_V2_STRUCT)
-			dirent->name_len = ext2fs_swab16(dirent->name_len);
+	retval = ext2fs_dirent_swab_in(fs, buf, flags);
 #endif
-		if ((retval = ext2fs_get_rec_len(fs, dirent, &rec_len)) != 0)
-			return retval;
-		if ((rec_len < 8) || (rec_len % 4)) {
-			rec_len = 8;
-			retval = EXT2_ET_DIR_CORRUPTED;
-		} else if (((name_len & 0xFF) + 8) > rec_len)
-			retval = EXT2_ET_DIR_CORRUPTED;
-		p += rec_len;
-	}
+	if (!retval && corrupt)
+		retval = EXT2_ET_DIR_CSUM_INVALID;
 	return retval;
 }
 
+errcode_t ext2fs_read_dir_block3(ext2_filsys fs, blk64_t block,
+				 void *buf, int flags EXT2FS_ATTR((unused)))
+{
+	return ext2fs_read_dir_block4(fs, block, buf, flags, 0);
+}
+
 errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block,
 				 void *buf, int flags EXT2FS_ATTR((unused)))
 {
@@ -72,45 +63,40 @@ errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
 }
 
 
-errcode_t ext2fs_write_dir_block3(ext2_filsys fs, blk64_t block,
-				  void *inbuf, int flags EXT2FS_ATTR((unused)))
+errcode_t ext2fs_write_dir_block4(ext2_filsys fs, blk64_t block,
+				  void *inbuf, int flags EXT2FS_ATTR((unused)),
+				  ext2_ino_t ino)
 {
-#ifdef WORDS_BIGENDIAN
 	errcode_t	retval;
-	char		*p, *end;
-	char		*buf = 0;
-	unsigned int	rec_len;
-	struct ext2_dir_entry *dirent;
+	char		*buf = inbuf;
 
+#ifdef WORDS_BIGENDIAN
 	retval = ext2fs_get_mem(fs->blocksize, &buf);
 	if (retval)
 		return retval;
 	memcpy(buf, inbuf, fs->blocksize);
-	p = buf;
-	end = buf + fs->blocksize;
-	while (p < end) {
-		dirent = (struct ext2_dir_entry *) p;
-		if ((retval = ext2fs_get_rec_len(fs, dirent, &rec_len)) != 0)
-			return retval;
-		if ((rec_len < 8) ||
-		    (rec_len % 4)) {
-			ext2fs_free_mem(&buf);
-			return (EXT2_ET_DIR_CORRUPTED);
-		}
-		p += rec_len;
-		dirent->inode = ext2fs_swab32(dirent->inode);
-		dirent->rec_len = ext2fs_swab16(dirent->rec_len);
-		dirent->name_len = ext2fs_swab16(dirent->name_len);
-
-		if (flags & EXT2_DIRBLOCK_V2_STRUCT)
-			dirent->name_len = ext2fs_swab16(dirent->name_len);
-	}
+	retval = ext2fs_dirent_swab_out(fs, buf, flags);
+	if (retval)
+		return retval;
+#endif
+	retval = ext2fs_dir_block_csum_set(fs, ino,
+					   (struct ext2_dir_entry *)buf);
+	if (retval)
+		goto out;
+
 	retval = io_channel_write_blk64(fs->io, block, 1, buf);
+
+out:
+#ifdef WORDS_BIGENDIAN
 	ext2fs_free_mem(&buf);
-	return retval;
-#else
-	return io_channel_write_blk64(fs->io, block, 1, (char *) inbuf);
 #endif
+	return retval;
+}
+
+errcode_t ext2fs_write_dir_block3(ext2_filsys fs, blk64_t block,
+				  void *inbuf, int flags EXT2FS_ATTR((unused)))
+{
+	return ext2fs_write_dir_block4(fs, block, inbuf, flags, 0);
 }
 
 errcode_t ext2fs_write_dir_block2(ext2_filsys fs, blk_t block,
diff --git a/lib/ext2fs/expanddir.c b/lib/ext2fs/expanddir.c
index 41c4088..22558d6 100644
--- a/lib/ext2fs/expanddir.c
+++ b/lib/ext2fs/expanddir.c
@@ -24,6 +24,7 @@ struct expand_dir_struct {
 	int		newblocks;
 	blk64_t		goal;
 	errcode_t	err;
+	ext2_ino_t	dir;
 };
 
 static int expand_dir_proc(ext2_filsys	fs,
@@ -62,7 +63,8 @@ static int expand_dir_proc(ext2_filsys	fs,
 			return BLOCK_ABORT;
 		}
 		es->done = 1;
-		retval = ext2fs_write_dir_block(fs, new_blk, block);
+		retval = ext2fs_write_dir_block4(fs, new_blk, block, 0,
+						 es->dir);
 	} else {
 		retval = ext2fs_get_mem(fs->blocksize, &block);
 		if (retval) {
@@ -110,6 +112,7 @@ errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir)
 	es.err = 0;
 	es.goal = 0;
 	es.newblocks = 0;
+	es.dir = dir;
 
 	retval = ext2fs_block_iterate3(fs, dir, BLOCK_FLAG_APPEND,
 				       0, expand_dir_proc, &es);
diff --git a/lib/ext2fs/ext2_err.et.in b/lib/ext2fs/ext2_err.et.in
index 1e51384..ad0cb7a 100644
--- a/lib/ext2fs/ext2_err.et.in
+++ b/lib/ext2fs/ext2_err.et.in
@@ -455,4 +455,7 @@ ec	EXT2_ET_EXTENT_CSUM_INVALID,
 ec	EXT2_ET_DIR_NO_SPACE_FOR_CSUM,
 	"Directory block does not have space for checksum"
 
+ec	EXT2_ET_DIR_CSUM_INVALID,
+	"Directory block checksum does not match directory block"
+
 	end
diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index da598d0..6de2da7 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -940,6 +940,18 @@ extern __u32 ext2fs_crc32c_be(__u32 crc, unsigned char const *p, size_t len);
 extern __u32 ext2fs_crc32c_le(__u32 crc, unsigned char const *p, size_t len);
 
 /* csum.c */
+#define EXT2_DIRENT_TAIL(block, blocksize) \
+	((struct ext2_dir_entry_tail *)(((void *)(block)) + \
+	(blocksize) - sizeof(struct ext2_dir_entry_tail)))
+
+extern void ext2fs_initialize_dirent_tail(ext2_filsys fs,
+					  struct ext2_dir_entry_tail *t);
+extern int ext2fs_dirent_has_tail(ext2_filsys fs,
+				  struct ext2_dir_entry *dirent);
+extern int ext2fs_dir_block_csum_verify(ext2_filsys fs, ext2_ino_t inum,
+					struct ext2_dir_entry *dirent);
+extern errcode_t ext2fs_dir_block_csum_set(ext2_filsys fs, ext2_ino_t inum,
+					   struct ext2_dir_entry *dirent);
 extern errcode_t ext2fs_get_dx_countlimit(ext2_filsys fs,
 					  struct ext2_dir_entry *dirent,
 					  struct ext2_dx_countlimit **cc,
@@ -1023,12 +1035,16 @@ 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_read_dir_block4(ext2_filsys fs, blk64_t block,
+					void *buf, int flags, ext2_ino_t ino);
 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);
+extern errcode_t ext2fs_write_dir_block4(ext2_filsys fs, blk64_t block,
+					 void *buf, int flags, ext2_ino_t ino);
 
 /* dirhash.c */
 extern errcode_t ext2fs_dirhash(int version, const char *name, int len,
@@ -1417,6 +1433,8 @@ extern errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
 extern errcode_t ext2fs_create_resize_inode(ext2_filsys fs);
 
 /* swapfs.c */
+extern errcode_t ext2fs_dirent_swab_in(ext2_filsys fs, char *buf, int flags);
+extern errcode_t ext2fs_dirent_swab_out(ext2_filsys fs, char *buf, int flags);
 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,
diff --git a/lib/ext2fs/link.c b/lib/ext2fs/link.c
index 2d03b57..2dec5dc 100644
--- a/lib/ext2fs/link.c
+++ b/lib/ext2fs/link.c
@@ -41,6 +41,7 @@ static int link_proc(struct ext2_dir_entry *dirent,
 	struct ext2_dir_entry *next;
 	unsigned int rec_len, min_rec_len, curr_rec_len;
 	int ret = 0;
+	int csum_size = 0;
 
 	rec_len = EXT2_DIR_REC_LEN(ls->namelen);
 
@@ -48,12 +49,15 @@ static int link_proc(struct ext2_dir_entry *dirent,
 	if (ls->err)
 		return DIRENT_ABORT;
 
+	if (EXT2_HAS_RO_COMPAT_FEATURE(ls->fs->super,
+				       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+		csum_size = sizeof(struct ext2_dir_entry_tail);
 	/*
 	 * See if the following directory entry (if any) is unused;
 	 * if so, absorb it into this one.
 	 */
 	next = (struct ext2_dir_entry *) (buf + offset + curr_rec_len);
-	if ((offset + (int) curr_rec_len < blocksize - 8) &&
+	if ((offset + (int) curr_rec_len < blocksize - (8 + csum_size)) &&
 	    (next->inode == 0) &&
 	    (offset + (int) curr_rec_len + (int) next->rec_len <= blocksize)) {
 		curr_rec_len += next->rec_len;
diff --git a/lib/ext2fs/mkdir.c b/lib/ext2fs/mkdir.c
index b12bf2d..0d1b7b8 100644
--- a/lib/ext2fs/mkdir.c
+++ b/lib/ext2fs/mkdir.c
@@ -95,7 +95,7 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
 	/*
 	 * Write out the inode and inode data block
 	 */
-	retval = ext2fs_write_dir_block(fs, blk, block);
+	retval = ext2fs_write_dir_block4(fs, blk, block, 0, ino);
 	if (retval)
 		goto cleanup;
 	retval = ext2fs_write_new_inode(fs, ino, &inode);
diff --git a/lib/ext2fs/newdir.c b/lib/ext2fs/newdir.c
index b0a1e47..2cd541d 100644
--- a/lib/ext2fs/newdir.c
+++ b/lib/ext2fs/newdir.c
@@ -34,6 +34,8 @@ errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
 	char			*buf;
 	int			rec_len;
 	int			filetype = 0;
+	struct ext2_dir_entry_tail	*t;
+	int			csum_size = 0;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
@@ -43,7 +45,11 @@ errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
 	memset(buf, 0, fs->blocksize);
 	dir = (struct ext2_dir_entry *) buf;
 
-	retval = ext2fs_set_rec_len(fs, fs->blocksize, dir);
+	if (EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
+				       EXT4_FEATURE_RO_COMPAT_METADATA_CSUM))
+		csum_size = sizeof(struct ext2_dir_entry_tail);
+
+	retval = ext2fs_set_rec_len(fs, fs->blocksize - csum_size, dir);
 	if (retval)
 		return retval;
 
@@ -57,7 +63,7 @@ errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
 		dir->inode = dir_ino;
 		dir->name_len = 1 | filetype;
 		dir->name[0] = '.';
-		rec_len = fs->blocksize - EXT2_DIR_REC_LEN(1);
+		rec_len = (fs->blocksize - csum_size) - EXT2_DIR_REC_LEN(1);
 		dir->rec_len = EXT2_DIR_REC_LEN(1);
 
 		/*
@@ -73,6 +79,11 @@ errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
 		dir->name[1] = '.';
 
 	}
+
+	if (csum_size) {
+		t = EXT2_DIRENT_TAIL(buf, fs->blocksize);
+		ext2fs_initialize_dirent_tail(fs, t);
+	}
 	*block = buf;
 	return 0;
 }
diff --git a/lib/ext2fs/swapfs.c b/lib/ext2fs/swapfs.c
index 7c99373..69916e5 100644
--- a/lib/ext2fs/swapfs.c
+++ b/lib/ext2fs/swapfs.c
@@ -350,4 +350,66 @@ void ext2fs_swap_mmp(struct mmp_struct *mmp)
 	mmp->mmp_check_interval = ext2fs_swab16(mmp->mmp_check_interval);
 }
 
+errcode_t ext2fs_dirent_swab_in(ext2_filsys fs, char *buf, int flags)
+{
+	errcode_t	retval;
+	char		*p, *end;
+	struct ext2_dir_entry *dirent;
+	unsigned int	name_len, rec_len;
+
+	p = (char *) buf;
+	end = (char *) buf + fs->blocksize;
+	while (p < end-8) {
+		dirent = (struct ext2_dir_entry *) p;
+		dirent->inode = ext2fs_swab32(dirent->inode);
+		dirent->rec_len = ext2fs_swab16(dirent->rec_len);
+		dirent->name_len = ext2fs_swab16(dirent->name_len);
+		name_len = dirent->name_len;
+		if (flags & EXT2_DIRBLOCK_V2_STRUCT)
+			dirent->name_len = ext2fs_swab16(dirent->name_len);
+		retval = ext2fs_get_rec_len(fs, dirent, &rec_len);
+		if (retval)
+			return retval;
+		if ((rec_len < 8) || (rec_len % 4)) {
+			rec_len = 8;
+			retval = EXT2_ET_DIR_CORRUPTED;
+		} else if (((name_len & 0xFF) + 8) > rec_len)
+			retval = EXT2_ET_DIR_CORRUPTED;
+		p += rec_len;
+	}
+
+	return 0;
+}
+
+errcode_t ext2fs_dirent_swab_out(ext2_filsys fs, char *buf, int flags)
+{
+	errcode_t	retval;
+	char		*p, *end;
+	unsigned int	rec_len;
+	struct ext2_dir_entry *dirent;
+
+	p = buf;
+	end = buf + fs->blocksize;
+	while (p < end) {
+		dirent = (struct ext2_dir_entry *) p;
+		retval = ext2fs_get_rec_len(fs, dirent, &rec_len);
+		if (retval)
+			return retval;
+		if ((rec_len < 8) ||
+		    (rec_len % 4)) {
+			ext2fs_free_mem(&buf);
+			return EXT2_ET_DIR_CORRUPTED;
+		}
+		p += rec_len;
+		dirent->inode = ext2fs_swab32(dirent->inode);
+		dirent->rec_len = ext2fs_swab16(dirent->rec_len);
+		dirent->name_len = ext2fs_swab16(dirent->name_len);
+
+		if (flags & EXT2_DIRBLOCK_V2_STRUCT)
+			dirent->name_len = ext2fs_swab16(dirent->name_len);
+	}
+
+	return 0;
+}
+
 #endif


  parent reply	other threads:[~2011-12-14  1:16 UTC|newest]

Thread overview: 64+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-12-14  1:13 [PATCH v2.2 00/51] e2fsprogs: Add metadata checksumming Darrick J. Wong
2011-12-14  1:13 ` [PATCH 01/51] libext2fs: Read and write full size inodes Darrick J. Wong
     [not found]   ` <15FBE485-FC42-46A4-A2BE-9931A3B933A5@dilger.ca>
2011-12-19 17:46     ` Darrick J. Wong
2011-12-14  1:13 ` [PATCH 02/51] libext2fs: Change ext4 on-disk layout to support metadata checksumming Darrick J. Wong
     [not found]   ` <BBB7550D-77E9-441D-8ECF-C5A5A3B839C8@dilger.ca>
2011-12-19 20:13     ` Darrick J. Wong
2011-12-14  1:13 ` [PATCH 03/51] debugfs: Optionally ignore bad checksums Darrick J. Wong
2011-12-14  1:13 ` [PATCH 04/51] libext2fs: Add inode checksum support Darrick J. Wong
     [not found]   ` <4CD3617E-A647-4CAF-9C35-DF24656CB440@dilger.ca>
2011-12-19 20:05     ` Darrick J. Wong
2011-12-14  1:13 ` [PATCH 05/51] debugfs: Dump inode checksum when appropriate Darrick J. Wong
2011-12-14  1:13 ` [PATCH 06/51] tune2fs: Add inode checksum support Darrick J. Wong
2011-12-14  1:14 ` [PATCH 07/51] e2fsck: Verify and correct inode checksums Darrick J. Wong
     [not found]   ` <701CAD1A-51A8-4F0F-8323-4B2091BF8F78@dilger.ca>
2011-12-19 20:12     ` Darrick J. Wong
2011-12-14  1:14 ` [PATCH 08/51] mke2fs: Allow metadata checksums to be turned on at mkfs time Darrick J. Wong
     [not found]   ` <76441870-91E6-402F-B1F7-F67C97D0B02B@dilger.ca>
2011-12-19 16:59     ` Darrick J. Wong
2011-12-14  1:14 ` [PATCH 09/51] libext2fs: Create the inode bitmap checksum Darrick J. Wong
     [not found]   ` <8D63B0B0-ED5C-426E-82FE-5122A84DFFEC@gmail.com>
2011-12-19 20:03     ` Darrick J. Wong
2011-12-14  1:14 ` [PATCH 10/51] tune2fs: Rewrite inode bitmap checksums Darrick J. Wong
2011-12-14  1:14 ` [PATCH 11/51] dumpe2fs: Display inode bitmap checksum Darrick J. Wong
2011-12-18 18:09   ` Andreas Dilger
2011-12-14  1:14 ` [PATCH 12/51] e2fsck: Verify " Darrick J. Wong
2011-12-14  1:14 ` [PATCH 13/51] libext2fs: Create the block " Darrick J. Wong
2011-12-14  1:14 ` [PATCH 14/51] dumpe2fs: Display " Darrick J. Wong
     [not found]   ` <32C86905-38C6-4897-8A98-26431DB73118@dilger.ca>
2011-12-19 19:50     ` Darrick J. Wong
2011-12-14  1:14 ` [PATCH 15/51] e2fsck: Verify " Darrick J. Wong
2011-12-14  1:15 ` [PATCH 16/51] e2fsck: Don't verify bitmap checksums Darrick J. Wong
2011-12-14  1:15 ` [PATCH 17/51] tune2fs: Rewrite block " Darrick J. Wong
2011-12-14  1:15 ` [PATCH 18/51] libext2fs: Verify and calculate extent tree block checksums Darrick J. Wong
2011-12-14  1:15 ` [PATCH 19/51] tune2fs: Enable extent tree checksums Darrick J. Wong
2011-12-14  1:15 ` [PATCH 20/51] e2fsck: Verify extent tree blocks and clear the bad ones Darrick J. Wong
2011-12-19  6:50   ` Andreas Dilger
2011-12-19 19:47     ` Darrick J. Wong
2011-12-14  1:15 ` [PATCH 21/51] debugfs: Print htree internal node checksums Darrick J. Wong
2011-12-14  1:15 ` [PATCH 22/51] libext2fs: Add dx_root/dx_node checksum calculation and verification helpers Darrick J. Wong
2011-12-14  1:15 ` [PATCH 23/51] e2fsck: Verify htree root/node checksums Darrick J. Wong
2011-12-19  6:57   ` Andreas Dilger
2011-12-19 19:46     ` Darrick J. Wong
2011-12-14  1:15 ` Darrick J. Wong [this message]
2011-12-14  1:16 ` [PATCH 25/51] e2fsck: Check directory leaf block checksums Darrick J. Wong
2011-12-14  1:16 ` [PATCH 26/51] tune2fs: Rebuild and checksum directories when toggling metadata_csum or changing UUID Darrick J. Wong
2011-12-14  1:16 ` [PATCH 27/51] libext2fs: Verify and calculate extended attribute block checksums Darrick J. Wong
2011-12-14  1:16 ` [PATCH 28/51] e2fsck: Check " Darrick J. Wong
2011-12-14  1:16 ` [PATCH 29/51] tune2fs: Rewrite " Darrick J. Wong
2011-12-14  1:16 ` [PATCH 30/51] libext2fs: Calculate and verify superblock checksums Darrick J. Wong
2011-12-14  1:16 ` [PATCH 31/51] e2fsck: Handle superblock checksum errors gracefully Darrick J. Wong
2011-12-14  1:16 ` [PATCH 32/51] libext2fs: Use i_generation in inode-related metadata checksums Darrick J. Wong
2011-12-14  1:16 ` [PATCH 33/51] libext2fs: Record the checksum algorithm in use in the superblock Darrick J. Wong
2011-12-14  1:17 ` [PATCH 34/51] tune2fs: Store checksum algorithm type in superblock Darrick J. Wong
2011-12-14  1:17 ` [PATCH 35/51] mke2fs: Record the checksum algorithm in use in the superblock Darrick J. Wong
2011-12-14  1:17 ` [PATCH 36/51] libext2fs: Block group checksum should use metadata_csum algorithm (if feature flag set) Darrick J. Wong
2011-12-14  1:17 ` [PATCH 37/51] tune2fs: Rewrite block group checksums when changing bg_use_meta_csum feature Darrick J. Wong
2011-12-14  1:17 ` [PATCH 38/51] mke2fs: Warn if not enabling all the features that metadata_csum wants Darrick J. Wong
2011-12-14  1:17 ` [PATCH 39/51] libext2fs: Add checksum to MMP block Darrick J. Wong
2011-12-14  1:17 ` [PATCH 40/51] e2fsck: Verify and correct MMP checksum problems Darrick J. Wong
2011-12-14  1:17 ` [PATCH 41/51] tune2fs: Force MMP update when changing metadata_csum flag Darrick J. Wong
2011-12-14  1:17 ` [PATCH 42/51] libext2fs: Change on-disk journal layout to support metadata checksumming Darrick J. Wong
2011-12-14  1:18 ` [PATCH 43/51] libext2fs: Dump feature flags for jbd2 v2 checksums Darrick J. Wong
2011-12-14  1:18 ` [PATCH 44/51] e2fsck: Check journal superblock checksum prior to recovery Darrick J. Wong
2011-12-14  1:18 ` [PATCH 45/51] e2fsck: Check revoke block checksum during recovery Darrick J. Wong
2011-12-14  1:18 ` [PATCH 46/51] e2fsck: Check descriptor block checksum when recovering journal Darrick J. Wong
2011-12-14  1:18 ` [PATCH 47/51] e2fsck: Check commit block checksum during recovery Darrick J. Wong
2011-12-14  1:18 ` [PATCH 48/51] e2fsck: Verify data block checksums when recovering journal Darrick J. Wong
2011-12-14  1:18 ` [PATCH 49/51] libext2fs: Enable support for the metadata checksumming feature Darrick J. Wong
2011-12-14  1:18 ` [PATCH 50/51] libext2fs: Bring the CRC32c implementation up to date with the kernel implementation Darrick J. Wong
2011-12-14  1:18 ` [PATCH 51/51] e2fsck: Refactor crc32_be code Darrick J. Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20111214011557.20947.36828.stgit@elm3c44.beaverton.ibm.com \
    --to=djwong@us.ibm.com \
    --cc=adilger.kernel@dilger.ca \
    --cc=amir73il@gmail.com \
    --cc=andi@firstfloor.org \
    --cc=cmm@us.ibm.com \
    --cc=colyli@gmail.com \
    --cc=jlbec@evilplan.org \
    --cc=linux-ext4@vger.kernel.org \
    --cc=sunil.mushran@oracle.com \
    --cc=tytso@mit.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.