[Ocfs2-tools-devel] [RFC 3/8] dx_dirs v4: dx_root and dx_leaf read/write in libocfs2

Coly Li coly.li at suse.de
Wed Jan 20 07:23:51 PST 2010


This patch provide the read/write functions for dx_root and dx_leaf structure.

Signed-off-by: Coly Li <coly.li at suse.de>
---
 dirblock.c |  158 +++++++++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 134 insertions(+), 24 deletions(-)

diff --git a/libocfs2/dirblock.c b/libocfs2/dirblock.c
index 06a1b64..b7d72cb 100644
--- a/libocfs2/dirblock.c
+++ b/libocfs2/dirblock.c
@@ -33,7 +33,6 @@
 #include "ocfs2/byteorder.h"
 #include "ocfs2/ocfs2.h"

-
 unsigned int ocfs2_dir_trailer_blk_off(ocfs2_filesys *fs)
 {
 	return fs->fs_blocksize - sizeof(struct ocfs2_dir_block_trailer);
@@ -105,9 +104,9 @@ static void ocfs2_swap_dir_entry(struct ocfs2_dir_entry *dirent)
 static errcode_t ocfs2_swap_dir_entries_direction(void *buf, uint64_t bytes,
 						  int to_cpu)
 {
-	char		*p, *end;
+	char *p, *end;
 	struct ocfs2_dir_entry *dirent;
-	unsigned int	name_len, rec_len;
+	unsigned int name_len, rec_len;
 	errcode_t retval = 0;

 	p = (char *) buf;
@@ -160,8 +159,8 @@ void ocfs2_swap_dir_trailer(struct ocfs2_dir_block_trailer *trailer)
 errcode_t ocfs2_read_dir_block(ocfs2_filesys *fs, struct ocfs2_dinode *di,
 			       uint64_t block, void *buf)
 {
-	errcode_t	retval;
-	int		end = fs->fs_blocksize;
+	errcode_t retval;
+	int end = fs->fs_blocksize;
 	struct ocfs2_dir_block_trailer *trailer = NULL;

 	retval = ocfs2_read_blocks(fs, block, 1, buf);
@@ -197,9 +196,9 @@ out:
 errcode_t ocfs2_write_dir_block(ocfs2_filesys *fs, struct ocfs2_dinode *di,
 				uint64_t block, void *inbuf)
 {
-	errcode_t	retval;
-	char		*buf = NULL;
-	int		end = fs->fs_blocksize;
+	errcode_t retval;
+	char *buf = NULL;
+	int end = fs->fs_blocksize;
 	struct ocfs2_dir_block_trailer *trailer = NULL;

 	retval = ocfs2_malloc_block(fs->fs_io, &buf);
@@ -230,28 +229,36 @@ out:
 	return retval;
 }

-static void ocfs2_swap_dx_entry_to_cpu(struct ocfs2_dx_entry *dx_entry)
+static void ocfs2_swap_dx_entry(struct ocfs2_dx_entry *dx_entry)
 {
-	if (cpu_is_little_endian)
-		return;
-
 	dx_entry->dx_major_hash		= bswap_32(dx_entry->dx_major_hash);
 	dx_entry->dx_minor_hash		= bswap_32(dx_entry->dx_minor_hash);
 	dx_entry->dx_dirent_blk		= bswap_64(dx_entry->dx_dirent_blk);
 }

-static void ocfs2_swap_dx_entry_list_to_cpu(struct ocfs2_dx_entry_list *dl_list)
+static void ocfs2_swap_dx_entry_list(struct ocfs2_dx_entry_list *dl_list)
 {
 	int i;

-	if (cpu_is_little_endian)
-		return;
-
 	dl_list->de_count	= bswap_16(dl_list->de_count);
 	dl_list->de_num_used	= bswap_16(dl_list->de_num_used);

 	for (i = 0; i < dl_list->de_count; i++)
-		ocfs2_swap_dx_entry_to_cpu(&dl_list->de_entries[i]);
+		ocfs2_swap_dx_entry(&dl_list->de_entries[i]);
+}
+
+static void ocfs2_swap_dx_entry_list_to_cpu(struct ocfs2_dx_entry_list *dl_list)
+{
+	if (cpu_is_little_endian)
+		return;
+	ocfs2_swap_dx_entry_list(dl_list);
+}
+
+static void ocfs2_swap_dx_entry_list_from_cpu(struct ocfs2_dx_entry_list *dl_list)
+{
+	if (cpu_is_little_endian)
+		return;
+	ocfs2_swap_dx_entry_list(dl_list);
 }

 static void ocfs2_swap_dx_root_to_cpu(ocfs2_filesys *fs,
@@ -276,10 +283,32 @@ static void ocfs2_swap_dx_root_to_cpu(ocfs2_filesys *fs,
 		ocfs2_swap_extent_list_to_cpu(fs, dx_root, &dx_root->dr_list);
 }

+static void ocfs2_swap_dx_root_from_cpu(ocfs2_filesys *fs,
+				struct ocfs2_dx_root_block *dx_root)
+{
+	if (cpu_is_little_endian)
+		return;
+
+	dx_root->dr_suballoc_slot	= bswap_16(dx_root->dr_suballoc_slot);
+	dx_root->dr_suballoc_bit	= bswap_16(dx_root->dr_suballoc_bit);
+	dx_root->dr_fs_generation	= bswap_32(dx_root->dr_fs_generation);
+	dx_root->dr_blkno		= bswap_64(dx_root->dr_blkno);
+	dx_root->dr_last_eb_blk		= bswap_64(dx_root->dr_last_eb_blk);
+	dx_root->dr_clusters		= bswap_32(dx_root->dr_clusters);
+	dx_root->dr_dir_blkno		= bswap_64(dx_root->dr_dir_blkno);
+	dx_root->dr_num_entries		= bswap_32(dx_root->dr_num_entries);
+	dx_root->dr_free_blk		= bswap_64(dx_root->dr_free_blk);
+
+	if (dx_root->dr_flags & OCFS2_DX_FLAG_INLINE)
+		ocfs2_swap_dx_entry_list_from_cpu(&dx_root->dr_entries);
+	else
+		ocfs2_swap_extent_list_from_cpu(fs, dx_root, &dx_root->dr_list);
+}
+
 errcode_t ocfs2_read_dx_root(ocfs2_filesys *fs, uint64_t block,
 			     void *buf)
 {
-	errcode_t	ret;
+	errcode_t ret;
 	struct ocfs2_dx_root_block *dx_root;

 	ret = ocfs2_read_blocks(fs, block, 1, buf);
@@ -300,21 +329,66 @@ errcode_t ocfs2_read_dx_root(ocfs2_filesys *fs, uint64_t block,
 	return 0;
 }

-static void ocfs2_swap_dx_leaf_to_cpu(struct ocfs2_dx_leaf *dx_leaf)
+errcode_t ocfs2_write_dx_root(ocfs2_filesys *fs, uint64_t block,
+				char *buf)
 {
-	if (cpu_is_little_endian)
-		return;
+	errcode_t ret;
+	char *dx_root_buf = NULL;
+	struct ocfs2_dx_root_block *dx_root;
+
+	if (!(fs->fs_flags & OCFS2_FLAG_RW))
+		return OCFS2_ET_RO_FILESYS;
+
+	if ((block < OCFS2_SUPER_BLOCK_BLKNO) ||
+	    (block > fs->fs_blocks))
+		return OCFS2_ET_BAD_BLKNO;
+
+	ret = ocfs2_malloc_block(fs->fs_io, &dx_root_buf);
+	if (ret)
+		goto out;

+	memcpy(dx_root_buf, buf, fs->fs_blocksize);
+
+	dx_root = (struct ocfs2_dx_root_block *)dx_root_buf;
+	ocfs2_swap_dx_root_from_cpu(fs, dx_root);
+
+	ocfs2_compute_meta_ecc(fs, buf, &dx_root->dr_check);
+	ret = io_write_block(fs->fs_io, block, 1, dx_root_buf);
+	if (!ret)
+		fs->fs_flags |= OCFS2_FLAG_CHANGED;
+
+out:
+	if (dx_root_buf)
+		ocfs2_free(&dx_root_buf);
+	return ret;
+}
+
+static void ocfs2_swap_dx_leaf(struct ocfs2_dx_leaf *dx_leaf)
+{
 	dx_leaf->dl_blkno = bswap_64(dx_leaf->dl_blkno);
 	dx_leaf->dl_fs_generation = bswap_64(dx_leaf->dl_fs_generation);

-	ocfs2_swap_dx_entry_list_to_cpu(&dx_leaf->dl_list);
+	ocfs2_swap_dx_entry_list(&dx_leaf->dl_list);
+}
+
+static void ocfs2_swap_dx_leaf_to_cpu(struct ocfs2_dx_leaf *dx_leaf)
+{
+	if (cpu_is_little_endian)
+		return;
+	ocfs2_swap_dx_leaf(dx_leaf);
+}
+
+static void ocfs2_swap_dx_leaf_from_cpu(struct ocfs2_dx_leaf *dx_leaf)
+{
+	if (cpu_is_little_endian)
+		return;
+	ocfs2_swap_dx_leaf(dx_leaf);
 }

 errcode_t ocfs2_read_dx_leaf(ocfs2_filesys *fs, uint64_t block,
 			     void *buf)
 {
-	errcode_t	ret;
+	errcode_t ret;
 	struct ocfs2_dx_leaf *dx_leaf;

 	ret = ocfs2_read_blocks(fs, block, 1, buf);
@@ -335,6 +409,42 @@ errcode_t ocfs2_read_dx_leaf(ocfs2_filesys *fs, uint64_t block,
 	return 0;
 }

+errcode_t ocfs2_write_dx_leaf(ocfs2_filesys *fs, uint64_t block,
+				void *buf)
+{
+	errcode_t ret;
+	char *dx_leaf_buf = NULL;
+	struct ocfs2_dx_leaf *dx_leaf;
+
+	if (!(fs->fs_flags & OCFS2_FLAG_RW))
+		return OCFS2_ET_RO_FILESYS;
+
+	if ((block < OCFS2_SUPER_BLOCK_BLKNO) ||
+	    (block > fs->fs_blocks))
+		return OCFS2_ET_BAD_BLKNO;
+
+	ret = ocfs2_malloc_block(fs->fs_io, &dx_leaf_buf);
+	if (ret)
+		goto out;
+
+	memcpy(buf, dx_leaf_buf, fs->fs_blocksize);
+	dx_leaf = (struct ocfs2_dx_leaf *)dx_leaf_buf;
+	ocfs2_swap_dx_leaf_from_cpu(dx_leaf);
+
+	ocfs2_compute_meta_ecc(fs, dx_leaf_buf, &dx_leaf->dl_check);
+	ret = io_write_block(fs->fs_io, block, 1, dx_leaf_buf);
+
+	if (ret)
+		goto out;
+
+	fs->fs_flags |= OCFS2_FLAG_CHANGED;
+
+out:
+	if (dx_leaf_buf)
+		ocfs2_free(&dx_leaf_buf);
+	return ret;
+}
+
 int ocfs2_dir_indexed(struct ocfs2_dinode *di)
 {
 	if (di->i_dyn_features & OCFS2_INDEXED_DIR_FL)
@@ -345,7 +455,7 @@ int ocfs2_dir_indexed(struct ocfs2_dinode *di)
 /*
  * Only use this when we already know the directory is indexed.
  */
-int __ocfs2_is_dir_trailer(ocfs2_filesys *fs, unsigned long de_off)
+static int __ocfs2_is_dir_trailer(ocfs2_filesys *fs, unsigned long de_off)
 {
 	if (de_off == ocfs2_dir_trailer_blk_off(fs))
 		return 1;
-- 
Coly Li
SuSE Labs



More information about the Ocfs2-tools-devel mailing list