From 8cf3a61039b0bda46d8824e50c3989eae83b9a1a Mon Sep 17 00:00:00 2001 From: Coly Li Date: Mon, 26 Apr 2010 22:38:31 +0800 Subject: [PATCH 30/30] 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 Cc: Mark Fasheh Cc: Tao Ma --- libocfs2/dirblock.c | 23 ++++++++++++++--------- 1 files changed, 14 insertions(+), 9 deletions(-) diff --git a/libocfs2/dirblock.c b/libocfs2/dirblock.c index c22d843..e128d73 100644 --- a/libocfs2/dirblock.c +++ b/libocfs2/dirblock.c @@ -245,29 +245,34 @@ 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) +/* called for big endian */ +static void ocfs2_swap_dx_entry_list(struct ocfs2_dx_entry_list *dl_list, int to_cpu) { 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 (to_cpu) + dl_list->de_count = bswap_16(dl_list->de_count); for (i = 0; i < dl_list->de_count; i++) ocfs2_swap_dx_entry(&dl_list->de_entries[i]); + dl_list->de_num_used = bswap_16(dl_list->de_num_used); + + if (!to_cpu) + dl_list->de_count = bswap_16(dl_list->de_count); } 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); + ocfs2_swap_dx_entry_list(dl_list, 1); } 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); + ocfs2_swap_dx_entry_list(dl_list, 0); } static void ocfs2_swap_dx_root_to_cpu(ocfs2_filesys *fs, @@ -384,26 +389,26 @@ out: return ret; } -static void ocfs2_swap_dx_leaf(struct ocfs2_dx_leaf *dx_leaf) +static void ocfs2_swap_dx_leaf(struct ocfs2_dx_leaf *dx_leaf, int to_cpu) { 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); + ocfs2_swap_dx_entry_list(&dx_leaf->dl_list, to_cpu); } 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); + ocfs2_swap_dx_leaf(dx_leaf, 1); } 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); + ocfs2_swap_dx_leaf(dx_leaf, 0); } errcode_t ocfs2_read_dx_leaf(ocfs2_filesys *fs, uint64_t block, -- 1.7.0.2