Blob Blame History Raw
From 5fef457767fa876e29a5277e6c7428aa36c9ac61 Mon Sep 17 00:00:00 2001
From: Theodore Ts'o <tytso@mit.edu>
Date: Thu, 13 Dec 2018 00:51:51 -0500
Subject: [PATCH 1/4] libext2fs: add ext2fs_{read,write}_inode2()

Add new library interface which allows the caller to control whether
the inode checksum should be checked on inode read, or set on inode
write.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
---
 lib/ext2fs/ext2fs.h | 18 +++++++++++++++-
 lib/ext2fs/inode.c  | 50 +++++++++++++++++++++++++++++----------------
 2 files changed, 49 insertions(+), 19 deletions(-)

diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h
index c86596a6..96735c8e 100644
--- a/lib/ext2fs/ext2fs.h
+++ b/lib/ext2fs/ext2fs.h
@@ -570,6 +570,16 @@ typedef struct ext2_icount *ext2_icount_t;
  */
 #define BMAP_RET_UNINIT	0x0001
 
+/*
+ * Flags for ext2fs_read_inode2
+ */
+#define READ_INODE_NOCSUM	0x0001
+
+/*
+ * Flags for ext2fs_write_inode2
+ */
+#define WRITE_INODE_NOCSUM	0x0001
+
 /*
  * Flags for imager.c functions
  */
@@ -1514,13 +1524,19 @@ extern int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_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,
+extern errcode_t ext2fs_read_inode(ext2_filsys fs, ext2_ino_t ino,
 			    struct ext2_inode * inode);
+extern errcode_t ext2fs_read_inode2(ext2_filsys fs, ext2_ino_t ino,
+				    struct ext2_inode * inode,
+				    int bufsize, int flags);
 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_inode2(ext2_filsys fs, ext2_ino_t ino,
+				     struct ext2_inode * inode,
+				     int bufsize, int flags);
 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);
diff --git a/lib/ext2fs/inode.c b/lib/ext2fs/inode.c
index 013c658e..2a4be739 100644
--- a/lib/ext2fs/inode.c
+++ b/lib/ext2fs/inode.c
@@ -740,8 +740,9 @@ errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,
 /*
  * Functions to read and write a single inode.
  */
-errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
-				 struct ext2_inode * inode, int bufsize)
+errcode_t ext2fs_read_inode2(ext2_filsys fs, ext2_ino_t ino,
+			     struct ext2_inode * inode, int bufsize,
+			     int flags)
 {
 	blk64_t		block_nr;
 	dgrp_t		group;
@@ -850,21 +851,29 @@ errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
 	}
 	memcpy(inode, iptr, (bufsize > length) ? length : bufsize);
 
-	if (!(fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) && fail_csum)
+	if (!(fs->flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) &&
+	    !(flags & READ_INODE_NOCSUM) && fail_csum)
 		return EXT2_ET_INODE_CSUM_INVALID;
 
 	return 0;
 }
 
+errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
+				 struct ext2_inode * inode, int bufsize)
+{
+	return ext2fs_read_inode2(fs, ino, inode, bufsize, 0);
+}
+
 errcode_t ext2fs_read_inode(ext2_filsys fs, ext2_ino_t ino,
 			    struct ext2_inode * inode)
 {
-	return ext2fs_read_inode_full(fs, ino, inode,
-					sizeof(struct ext2_inode));
+	return ext2fs_read_inode2(fs, ino, inode,
+				  sizeof(struct ext2_inode), 0);
 }
 
-errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
-				  struct ext2_inode * inode, int bufsize)
+errcode_t ext2fs_write_inode2(ext2_filsys fs, ext2_ino_t ino,
+			      struct ext2_inode * inode, int bufsize,
+			      int flags)
 {
 	blk64_t block_nr;
 	dgrp_t group;
@@ -895,12 +904,9 @@ errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
 
 	if (bufsize < length) {
 		int old_flags = fs->flags;
-		fs->flags |= EXT2_FLAG_IGNORE_CSUM_ERRORS;
-		retval = ext2fs_read_inode_full(fs, ino,
-						(struct ext2_inode *)w_inode,
-						length);
-		fs->flags = (old_flags & EXT2_FLAG_IGNORE_CSUM_ERRORS) |
-			    (fs->flags & ~EXT2_FLAG_IGNORE_CSUM_ERRORS);
+		retval = ext2fs_read_inode2(fs, ino,
+					    (struct ext2_inode *)w_inode,
+					    length, READ_INODE_NOCSUM);
 		if (retval)
 			goto errout;
 	}
@@ -930,9 +936,11 @@ errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
 	ext2fs_swap_inode_full(fs, w_inode, w_inode, 1, length);
 #endif
 
-	retval = ext2fs_inode_csum_set(fs, ino, w_inode);
-	if (retval)
-		goto errout;
+	if ((flags & WRITE_INODE_NOCSUM) == 0) {
+		retval = ext2fs_inode_csum_set(fs, ino, w_inode);
+		if (retval)
+			goto errout;
+	}
 
 	group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
 	offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
@@ -989,11 +997,17 @@ errout:
 	return retval;
 }
 
+errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
+				  struct ext2_inode * inode, int bufsize)
+{
+	return ext2fs_write_inode2(fs, ino, inode, bufsize, 0);
+}
+
 errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
 			     struct ext2_inode *inode)
 {
-	return ext2fs_write_inode_full(fs, ino, inode,
-				       sizeof(struct ext2_inode));
+	return ext2fs_write_inode2(fs, ino, inode,
+				   sizeof(struct ext2_inode), 0);
 }
 
 /*
-- 
2.20.1