[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