[Ocfs2-tools-devel] [PATCH 9/9] dx_dirs: fix ocfs2_swap_dx_entry_list() for big endian

Coly Li coly.li at suse.de
Tue Apr 27 00:54:58 PDT 2010



On 04/27/2010 02:54 PM, Tao Ma Wrote:
> yeah, actually most of current code don't have a 'to_cpu' paramter.
> The reason why ocfs2_swap_dir_entries_direction I guess is that it is
> very complicated.  But your codes isn't the case.
> You can check the swap of extent_block, inode etc for reference.

Hi Tao,

Here is the modified patch, how about it ?
(I don't test it yet, just pass compiling)

>From d3b7deb6cc813fdb6382e7d426b4d578c7deb252 Mon Sep 17 00:00:00 2001
From: Coly Li <coly.li at suse.de>
Date: Tue, 27 Apr 2010 15:39:40 +0800
Subject: [PATCH 9/9] dx_dirs: fix ocfs2_swap_dx_entry_list() for big endian

As Tao Ma suggested, current ocfs2_swap_dx_entry_list() is
buggy for big endian hardware, because after dl_list->de_count
swapped, it is referenced in the following loop.

This patch fixes this bug with adding an 'int to_cpu' argument, also
modifies other routines who call ocfs2_swap_dx_entry_list().

Signed-off-by: Coly Li <coly.li at suse.de>
Cc: Mark Fasheh <mfasheh at suse.com>
Cc: Tao Ma <tao.ma at oracle.com>
---
diff --git a/libocfs2/dirblock.c b/libocfs2/dirblock.c
index c22d843..bd65119 100644
--- a/libocfs2/dirblock.c
+++ b/libocfs2/dirblock.c
@@ -245,29 +245,32 @@ static void ocfs2_swap_dx_entry(struct ocfs2_dx_entry *dx_entry)
 	dx_entry->dx_dirent_blk		= bswap_64(dx_entry->dx_dirent_blk);
 }

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

-	dl_list->de_count	= bswap_16(dl_list->de_count);
-	dl_list->de_num_used	= bswap_16(dl_list->de_num_used);
+	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(&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)
 {
+	int i;
+
 	if (cpu_is_little_endian)
 		return;
-	ocfs2_swap_dx_entry_list(dl_list);
+
+	for (i = 0; i < dl_list->de_count; i++)
+		ocfs2_swap_dx_entry(&dl_list->de_entries[i]);
+
+	dl_list->de_count = bswap_16(dl_list->de_count);
+	dl_list->de_num_used = bswap_16(dl_list->de_num_used);
 }

 static void ocfs2_swap_dx_root_to_cpu(ocfs2_filesys *fs,
@@ -384,26 +387,22 @@ out:
 	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(&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);
+	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);
 }

 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);
+	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_from_cpu(&dx_leaf->dl_list);
 }

 errcode_t ocfs2_read_dx_leaf(ocfs2_filesys *fs, uint64_t block,
-- 
Coly Li
SuSE Labs



More information about the Ocfs2-tools-devel mailing list