[Ocfs2-tools-devel] [PATCH 2/4] Adds o2image library support

Srinivas Eeda srinivas.eeda at oracle.com
Wed Mar 5 19:00:51 PST 2008


This patch modifies libocfs2 routines to recognize and make appropriate calls
when dealing o2image file

Signed-off-by: Srinivas Eeda <srinivas.eeda at oracle.com>
---
 extras/set_random_bits.c |    2 +-
 fsck.ocfs2/journal.c     |    2 +-
 fsck.ocfs2/pass1.c       |    2 +-
 fswreck/dir.c            |    4 +-
 include/ocfs2/ocfs2.h    |   12 +++++++++++
 libocfs2/chain.c         |    2 +-
 libocfs2/dirblock.c      |    2 +-
 libocfs2/extents.c       |    2 +-
 libocfs2/fileio.c        |    8 +++---
 libocfs2/inode.c         |    2 +-
 libocfs2/inode_scan.c    |    6 +---
 libocfs2/mkjournal.c     |    2 +-
 libocfs2/namei.c         |    2 +-
 libocfs2/openfs.c        |   47 ++++++++++++++++++++++++++++++++++++++++++++-
 libocfs2/truncate.c      |    2 +-
 libocfs2/unix_io.c       |    5 ++++
 16 files changed, 80 insertions(+), 22 deletions(-)

diff --git a/extras/set_random_bits.c b/extras/set_random_bits.c
index 96de5e8..dab3827 100644
--- a/extras/set_random_bits.c
+++ b/extras/set_random_bits.c
@@ -76,7 +76,7 @@ static int walk_blocks_func(ocfs2_filesys *fs,
 	int i;
 	uint32_t *up;
 
-	ret = io_read_block(fs->fs_io, blkno, 1, wb->buf);
+	ret = ocfs2_read_blocks(fs, blkno, 1, wb->buf);
 	if (ret) {
 		com_err("walk_blocks_func", ret,
 			"while reading block %"PRIu64, blkno);
diff --git a/fsck.ocfs2/journal.c b/fsck.ocfs2/journal.c
index d9846ba..75f500b 100644
--- a/fsck.ocfs2/journal.c
+++ b/fsck.ocfs2/journal.c
@@ -277,7 +277,7 @@ static errcode_t read_journal_block(ocfs2_filesys *fs,
 	if (err)
 		return err;
 
-	err = io_read_block(fs->fs_io, blkno, 1, buf);
+	err = ocfs2_read_blocks(fs, blkno, 1, buf);
 	if (err)
 		com_err(whoami, err, "while reading block %"PRIu64" of slot "
 			"%d's journal", blkno, ji->ji_slot);
diff --git a/fsck.ocfs2/pass1.c b/fsck.ocfs2/pass1.c
index 6e739ad..5b4e796 100644
--- a/fsck.ocfs2/pass1.c
+++ b/fsck.ocfs2/pass1.c
@@ -584,7 +584,7 @@ static errcode_t process_link_block(struct verifying_blocks *vb,
 		goto out;
 	}
 
-	ret = io_read_block(vb->vb_ost->ost_fs->fs_io, blkno, 1, buf);
+	ret = ocfs2_read_blocks(vb->vb_ost->ost_fs, blkno, 1, buf);
 	if (ret)
 		goto out;
 
diff --git a/fswreck/dir.c b/fswreck/dir.c
index 0be4c70..bb0844a 100644
--- a/fswreck/dir.c
+++ b/fswreck/dir.c
@@ -154,7 +154,7 @@ static void damage_dir_content(ocfs2_filesys *fs, uint64_t dir,
 	if (ret)
 		FSWRK_COM_FATAL(progname, ret);
 
-	ret = io_read_block(fs->fs_io, blkno, 1, buf);	
+	ret = ocfs2_read_blocks(fs, blkno, 1, buf);
 	if (ret)
 		FSWRK_COM_FATAL(progname, ret);
 
@@ -364,7 +364,7 @@ void mess_up_dir_parent_dup(ocfs2_filesys *fs, uint64_t blkno)
 	if (ret)
 		FSWRK_COM_FATAL(progname, ret);
 
-	ret = io_read_block(fs->fs_io, extblk, 1, buf);	
+	ret = ocfs2_read_blocks(fs, extblk, 1, buf);
 	if (ret)
 		FSWRK_COM_FATAL(progname, ret);
 
diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index 36ff02f..adfdaab 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -97,6 +97,7 @@
 						   for revision info */
 #define OCFS2_FLAG_HEARTBEAT_DEV_OK	0x40
 #define OCFS2_FLAG_STRICT_COMPAT_CHECK	0x80
+#define OCFS2_FLAG_O2IMAGE_FILE        0x0100
 
 /* Return flags for the directory iterator functions */
 #define OCFS2_DIRENT_CHANGED	0x01
@@ -169,6 +170,7 @@ struct _ocfs2_filesys {
 	ocfs2_cached_inode *fs_system_eb_alloc;
 
 	struct o2dlm_ctxt *fs_dlm_ctxt;
+	struct o2image_state *ost;
 
 	/* Reserved for the use of the calling application. */
 	void *fs_private;
@@ -220,6 +222,9 @@ errcode_t io_close(io_channel *channel);
 int io_get_error(io_channel *channel);
 errcode_t io_set_blksize(io_channel *channel, int blksize);
 int io_get_blksize(io_channel *channel);
+int io_get_fd(io_channel *channel);
+
+/* use ocfs2_read_blocks if your application might handle o2image file */
 errcode_t io_read_block(io_channel *channel, int64_t blkno, int count,
 			char *data);
 errcode_t io_write_block(io_channel *channel, int64_t blkno, int count,
@@ -230,6 +235,13 @@ void io_destroy_cache(io_channel *channel);
 
 errcode_t ocfs2_read_super(ocfs2_filesys *fs, uint64_t superblock, char *sb);
 errcode_t ocfs2_write_super(ocfs2_filesys *fs);
+
+/*
+ * ocfs2_read_blocks is a wraper around io_read_block. If device is an image-
+ * file it translates disk offset to image offset
+ */
+inline errcode_t ocfs2_read_blocks(ocfs2_filesys *fs, int64_t blkno, int count,
+		char *data);
 int ocfs2_mount_local(ocfs2_filesys *fs);
 errcode_t ocfs2_open(const char *name, int flags,
 		     unsigned int superblock, unsigned int blksize,
diff --git a/libocfs2/chain.c b/libocfs2/chain.c
index c860015..7af61fe 100644
--- a/libocfs2/chain.c
+++ b/libocfs2/chain.c
@@ -61,7 +61,7 @@ errcode_t ocfs2_read_group_desc(ocfs2_filesys *fs, uint64_t blkno,
 	if (ret)
 		return ret;
 
-	ret = io_read_block(fs->fs_io, blkno, 1, blk);
+	ret = ocfs2_read_blocks(fs, blkno, 1, blk);
 	if (ret)
 		goto out;
 
diff --git a/libocfs2/dirblock.c b/libocfs2/dirblock.c
index d8135fc..4684406 100644
--- a/libocfs2/dirblock.c
+++ b/libocfs2/dirblock.c
@@ -89,7 +89,7 @@ errcode_t ocfs2_read_dir_block(ocfs2_filesys *fs, uint64_t block,
 {
 	errcode_t	retval;
 
- 	retval = io_read_block(fs->fs_io, block, 1, buf);
+	retval = ocfs2_read_blocks(fs, block, 1, buf);
 	if (retval)
 		return retval;
 
diff --git a/libocfs2/extents.c b/libocfs2/extents.c
index 654b7e6..7c6afe0 100644
--- a/libocfs2/extents.c
+++ b/libocfs2/extents.c
@@ -118,7 +118,7 @@ errcode_t ocfs2_read_extent_block_nocheck(ocfs2_filesys *fs,
 	if (ret)
 		return ret;
 
-	ret = io_read_block(fs->fs_io, blkno, 1, blk);
+	ret = ocfs2_read_blocks(fs, blkno, 1, blk);
 	if (ret)
 		goto out;
 
diff --git a/libocfs2/fileio.c b/libocfs2/fileio.c
index 3b8aa76..471775f 100644
--- a/libocfs2/fileio.c
+++ b/libocfs2/fileio.c
@@ -54,8 +54,8 @@ static int read_whole_func(ocfs2_filesys *fs,
 		memset(ctx->ptr, 0, fs->fs_blocksize);
 		ctx->errcode = 0;
 	} else
-		ctx->errcode = io_read_block(fs->fs_io, blkno,
-					     1, ctx->ptr);
+		ctx->errcode = ocfs2_read_blocks(fs, blkno, 1, ctx->ptr);
+
 	if (ctx->errcode)
 		return OCFS2_BLOCK_ABORT;
 
@@ -176,8 +176,8 @@ errcode_t ocfs2_file_read(ocfs2_cached_inode *ci, void *buf, uint32_t count,
 			 */
 			memset(ptr, 0, contig_blocks * fs->fs_blocksize);
 		} else {
-			ret = io_read_block(fs->fs_io, p_blkno,
-					    contig_blocks, ptr);
+			ret = ocfs2_read_blocks(fs, p_blkno, contig_blocks,
+					ptr);
 			if (ret)
 				return ret;
 		}
diff --git a/libocfs2/inode.c b/libocfs2/inode.c
index 3cc5815..90f83b2 100644
--- a/libocfs2/inode.c
+++ b/libocfs2/inode.c
@@ -225,7 +225,7 @@ errcode_t ocfs2_read_inode(ocfs2_filesys *fs, uint64_t blkno,
 	if (ret)
 		return ret;
 
-	ret = io_read_block(fs->fs_io, blkno, 1, blk);
+	ret = ocfs2_read_blocks(fs, blkno, 1, blk);
 	if (ret)
 		goto out;
 
diff --git a/libocfs2/inode_scan.c b/libocfs2/inode_scan.c
index 11ba848..483a075 100644
--- a/libocfs2/inode_scan.c
+++ b/libocfs2/inode_scan.c
@@ -175,10 +175,8 @@ static errcode_t fill_group_buffer(ocfs2_inode_scan *scan)
 	if (num_blocks > scan->buffer_blocks)
 		num_blocks = scan->buffer_blocks;
 
-       ret = io_read_block(scan->fs->fs_io,
-			   scan->cur_blkno,
-			   num_blocks,
-			   scan->group_buffer);
+	ret = ocfs2_read_blocks(scan->fs, scan->cur_blkno, num_blocks,
+			scan->group_buffer);
 	if (ret)
 		return ret;
 
diff --git a/libocfs2/mkjournal.c b/libocfs2/mkjournal.c
index afb617c..4e8ccf0 100644
--- a/libocfs2/mkjournal.c
+++ b/libocfs2/mkjournal.c
@@ -150,7 +150,7 @@ errcode_t ocfs2_read_journal_superblock(ocfs2_filesys *fs, uint64_t blkno,
 	if (ret)
 		return ret;
 
-	ret = io_read_block(fs->fs_io, blkno, 1, blk);
+	ret = ocfs2_read_blocks(fs, blkno, 1, blk);
 	if (ret)
 		goto out;
 
diff --git a/libocfs2/namei.c b/libocfs2/namei.c
index aa78937..9241d3b 100644
--- a/libocfs2/namei.c
+++ b/libocfs2/namei.c
@@ -93,7 +93,7 @@ static errcode_t follow_link(ocfs2_filesys *fs, uint64_t root, uint64_t dir,
 	if (ret)
 		goto bail;
 
-	ret = io_read_block(fs->fs_io, blkno, 1, buffer);
+	ret = ocfs2_read_blocks(fs, blkno, 1, buffer);
 	if (ret)
 		goto bail;
 
diff --git a/libocfs2/openfs.c b/libocfs2/openfs.c
index f352add..5cd0998 100644
--- a/libocfs2/openfs.c
+++ b/libocfs2/openfs.c
@@ -30,6 +30,7 @@
 
 #include <string.h>
 #include <inttypes.h>
+#include <errno.h>
 
 /* I hate glibc and gcc */
 #ifndef ULLONG_MAX
@@ -39,7 +40,34 @@
 #include "ocfs2/byteorder.h"
 #include "ocfs2/ocfs2.h"
 #include "ocfs2-kernel/ocfs1_fs_compat.h"
+#include "ocfs2/o2image.h"
 
+/*
+ * if the file is an o2image file, this routine maps the actual blockno to
+ * relative block number in image file and then calls the underlying IO
+ * function. At this point this function returns EIO if image file has any
+ * holes
+ */
+inline errcode_t ocfs2_read_blocks(ocfs2_filesys *fs, int64_t blkno,
+		int count, char *data)
+{
+	int i;
+
+	if (fs->fs_flags & OCFS2_FLAG_O2IMAGE_FILE) {
+		/*
+		 * o2image copies all meta blocks. If a caller asks for
+		 * N contiguous metadata blocks, all N should be in the
+		 * image file. However we check for any holes and
+		 * return -EIO if any.
+		 */
+		for (i = 0; i < count; i++)
+			if (!o2image_test_bit(fs, blkno+i))
+				return -EIO;
+		/* translate the block number */
+		blkno = o2image_get_blockno(fs, blkno);
+	}
+	return io_read_block(fs->fs_io, blkno, count, data);
+}
 
 static errcode_t ocfs2_validate_ocfs1_header(ocfs2_filesys *fs)
 {
@@ -51,7 +79,7 @@ static errcode_t ocfs2_validate_ocfs1_header(ocfs2_filesys *fs)
 	if (ret)
 		return ret;
 
-	ret = io_read_block(fs->fs_io, 0, 1, blk);
+	ret = ocfs2_read_blocks(fs, 0, 1, blk);
 	if (ret)
 		goto out;
 	hdr = (struct ocfs1_vol_disk_hdr *)blk;
@@ -81,7 +109,7 @@ errcode_t ocfs2_read_super(ocfs2_filesys *fs, uint64_t superblock, char *sb)
 	if (ret)
 		return ret;
 
-	ret = io_read_block(fs->fs_io, superblock, 1, blk);
+	ret = ocfs2_read_blocks(fs, superblock, 1, blk);
 	if (ret)
 		goto out_blk;
 	di = (struct ocfs2_dinode *)blk;
@@ -206,6 +234,21 @@ errcode_t ocfs2_open(const char *name, int flags,
 	strcpy(fs->fs_devname, name);
 
 	/*
+	 * If OCFS2_FLAG_O2IMAGE_FILE is specified, it needs to be handled
+	 * differently
+	 */
+	if (flags & OCFS2_FLAG_O2IMAGE_FILE) {
+		ret = o2image_load_bitmap(fs);
+		if (ret)
+			goto out;
+		if (!superblock)
+			superblock = fs->ost->ost_superblocks[0];
+		if (!block_size)
+			block_size = fs->ost->ost_fsblksz;
+	}
+
+
+	/*
 	 * If OCFS2_FLAG_NO_REV_CHECK is specified, fsck (or someone
 	 * like it) is asking to ignore the OCFS vol_header at
 	 * block 0.
diff --git a/libocfs2/truncate.c b/libocfs2/truncate.c
index bc70682..e67f3b7 100644
--- a/libocfs2/truncate.c
+++ b/libocfs2/truncate.c
@@ -167,7 +167,7 @@ static errcode_t ocfs2_zero_tail_for_truncate(ocfs2_cached_inode *ci,
 	if (ret)
 		goto out;
 
-	ret = io_read_block(fs->fs_io, p_blkno, count, buf);
+	ret = ocfs2_read_blocks(fs, p_blkno, count, buf);
 	if (ret)
 		goto out;
 
diff --git a/libocfs2/unix_io.c b/libocfs2/unix_io.c
index 2ba51d4..ae78924 100644
--- a/libocfs2/unix_io.c
+++ b/libocfs2/unix_io.c
@@ -558,6 +558,11 @@ int io_get_blksize(io_channel *channel)
 	return channel->io_blksize;
 }
 
+int io_get_fd(io_channel *channel)
+{
+	return channel->io_fd;
+}
+
 errcode_t io_read_block(io_channel *channel, int64_t blkno, int count,
 			char *data)
 {
-- 
1.5.3.4




More information about the Ocfs2-tools-devel mailing list