[syslinux] [PATCH 2/2] xfs: use cache_read() to read contiguous fs blocks
Paulo Alcantara
pcacjr at gmail.com
Sat Jul 18 09:07:24 PDT 2015
Do not reimplement cache_read() logic in get_dirblks().
Signed-off-by: Paulo Alcantara <pcacjr at zytor.com>
---
core/fs/xfs/xfs_dir2.c | 68 ++++++++++++++++++++++++++------------------------
core/fs/xfs/xfs_dir2.h | 6 ++---
2 files changed, 39 insertions(+), 35 deletions(-)
diff --git a/core/fs/xfs/xfs_dir2.c b/core/fs/xfs/xfs_dir2.c
index de37ef7..4ba1f63 100644
--- a/core/fs/xfs/xfs_dir2.c
+++ b/core/fs/xfs/xfs_dir2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013 Paulo Alcantara <pcacjr at zytor.com>
+ * Copyright (c) 2012-2015 Paulo Alcantara <pcacjr at zytor.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -67,30 +67,29 @@ uint32_t xfs_dir2_da_hashname(const uint8_t *name, int namelen)
}
static void *get_dirblks(struct fs_info *fs, block_t startblock,
- xfs_filblks_t c)
+ xfs_filblks_t c)
{
- int count = c << XFS_INFO(fs)->dirblklog;
- uint8_t *p;
- uint8_t *buf;
- off_t offset = 0;
+ const size_t len = c * XFS_INFO(fs)->dirblksize;
+ uint64_t offs = startblock << BLOCK_SHIFT(fs);
+ void *buf;
+ size_t ret;
- buf = malloc(c * XFS_INFO(fs)->dirblksize);
+ buf = malloc(len);
if (!buf)
malloc_error("buffer memory");
+ memset(buf, 0, len);
- memset(buf, 0, XFS_INFO(fs)->dirblksize);
-
- while (count--) {
- p = (uint8_t *)get_cache(fs->fs_dev, startblock++);
- memcpy(buf + offset, p, BLOCK_SIZE(fs));
- offset += BLOCK_SIZE(fs);
+ ret = cache_read(fs, buf, offs, len);
+ if (ret != len) {
+ xfs_error("failed to read directory blocks linearly\n");
+ free(buf);
+ return NULL;
}
-
return buf;
}
-const void *xfs_dir2_dirblks_get_cached(struct fs_info *fs, block_t startblock,
- xfs_filblks_t c)
+void *xfs_dir2_dirblks_get_cached(struct fs_info *fs, block_t startblock,
+ xfs_filblks_t c)
{
unsigned char i;
void *buf;
@@ -100,7 +99,8 @@ const void *xfs_dir2_dirblks_get_cached(struct fs_info *fs, block_t startblock,
if (!dirblks_cached_count) {
buf = get_dirblks(fs, startblock, c);
-
+ if (!buf)
+ return NULL;
dirblks_cache[dirblks_cached_count].dc_startblock = startblock;
dirblks_cache[dirblks_cached_count].dc_blkscount = c;
dirblks_cache[dirblks_cached_count].dc_area = buf;
@@ -144,7 +144,8 @@ const void *xfs_dir2_dirblks_get_cached(struct fs_info *fs, block_t startblock,
}
buf = get_dirblks(fs, startblock, c);
-
+ if (!buf)
+ return NULL;
dirblks_cache[dirblks_cached_count].dc_startblock = startblock;
dirblks_cache[dirblks_cached_count].dc_blkscount = c;
dirblks_cache[dirblks_cached_count].dc_area = buf;
@@ -152,7 +153,6 @@ const void *xfs_dir2_dirblks_get_cached(struct fs_info *fs, block_t startblock,
return dirblks_cache[dirblks_cached_count++].dc_area;
}
}
-
return NULL;
}
@@ -266,6 +266,9 @@ struct inode *xfs_dir2_block_find_entry(const char *dname, struct inode *parent,
dir_blk = fsblock_to_bytes(fs, r.br_startblock) >> BLOCK_SHIFT(fs);
dirblk_buf = xfs_dir2_dirblks_get_cached(fs, dir_blk, r.br_blockcount);
+ if (!dirblk_buf)
+ return NULL;
+
hdr = (xfs_dir2_data_hdr_t *)dirblk_buf;
if (be32_to_cpu(hdr->magic) != XFS_DIR2_BLOCK_MAGIC) {
xfs_error("Block directory header's magic number does not match!");
@@ -358,14 +361,14 @@ struct inode *xfs_dir2_leaf_find_entry(const char *dname, struct inode *parent,
uint32_t hash = 0;
uint32_t hashwant;
uint32_t newdb, curdb = -1;
- xfs_dir2_data_entry_t *dep;
+ xfs_dir2_data_entry_t *dep = NULL;
struct inode *ip;
xfs_dir2_data_hdr_t *data_hdr;
uint8_t *start_name;
uint8_t *end_name;
xfs_intino_t ino;
xfs_dinode_t *ncore;
- const uint8_t *buf = NULL;
+ uint8_t *buf = NULL;
xfs_debug("dname %s parent %p core %p", dname, parent, core);
@@ -374,8 +377,10 @@ struct inode *xfs_dir2_leaf_find_entry(const char *dname, struct inode *parent,
leaf_blk = fsblock_to_bytes(parent->fs, irec.br_startblock) >>
BLOCK_SHIFT(parent->fs);
- leaf = (xfs_dir2_leaf_t *)xfs_dir2_dirblks_get_cached(parent->fs, leaf_blk,
- irec.br_blockcount);
+ leaf = xfs_dir2_dirblks_get_cached(parent->fs, leaf_blk,
+ irec.br_blockcount);
+ if (!leaf)
+ return NULL;
if (be16_to_cpu(leaf->hdr.info.magic) != XFS_DIR2_LEAF1_MAGIC) {
xfs_error("Single leaf block header's magic number does not match!");
goto out;
@@ -432,9 +437,9 @@ struct inode *xfs_dir2_leaf_find_entry(const char *dname, struct inode *parent,
curdb = newdb;
}
- dep = (xfs_dir2_data_entry_t *)((char *)buf +
- xfs_dir2_dataptr_to_off(parent->fs, be32_to_cpu(lep->address)));
-
+ dep = (xfs_dir2_data_entry_t *)(
+ buf + xfs_dir2_dataptr_to_off(parent->fs,
+ be32_to_cpu(lep->address)));
start_name = &dep->name[0];
end_name = start_name + dep->namelen;
@@ -614,7 +619,7 @@ struct inode *xfs_dir2_node_find_entry(const char *dname, struct inode *parent,
uint32_t newdb, curdb = -1;
xfs_intino_t ino;
xfs_dinode_t *ncore;
- const uint8_t *buf = NULL;
+ uint8_t *buf = NULL;
xfs_debug("dname %s parent %p core %p", dname, parent, core);
@@ -680,8 +685,7 @@ struct inode *xfs_dir2_node_find_entry(const char *dname, struct inode *parent,
goto out;
}
- node = (xfs_da_intnode_t *)xfs_dir2_dirblks_get_cached(parent->fs,
- fsblkno, 1);
+ node = xfs_dir2_dirblks_get_cached(parent->fs, fsblkno, 1);
} while(be16_to_cpu(node->hdr.info.magic) == XFS_DA_NODE_MAGIC);
leaf = (xfs_dir2_leaf_t*)node;
@@ -740,9 +744,9 @@ struct inode *xfs_dir2_node_find_entry(const char *dname, struct inode *parent,
curdb = newdb;
}
- dep = (xfs_dir2_data_entry_t *)((char *)buf +
- xfs_dir2_dataptr_to_off(parent->fs, be32_to_cpu(lep->address)));
-
+ dep = (xfs_dir2_data_entry_t *)(
+ buf + xfs_dir2_dataptr_to_off(parent->fs,
+ be32_to_cpu(lep->address)));
start_name = &dep->name[0];
end_name = start_name + dep->namelen;
diff --git a/core/fs/xfs/xfs_dir2.h b/core/fs/xfs/xfs_dir2.h
index 158cf44..8015eba 100644
--- a/core/fs/xfs/xfs_dir2.h
+++ b/core/fs/xfs/xfs_dir2.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012 Paulo Alcantara <pcacjr at zytor.com>
+ * Copyright (c) 2012-2015 Paulo Alcantara <pcacjr at zytor.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@@ -23,8 +23,8 @@
#include "xfs.h"
-const void *xfs_dir2_dirblks_get_cached(struct fs_info *fs, block_t startblock,
- xfs_filblks_t c);
+void *xfs_dir2_dirblks_get_cached(struct fs_info *fs, block_t startblock,
+ xfs_filblks_t c);
void xfs_dir2_dirblks_flush_cache(void);
uint32_t xfs_dir2_da_hashname(const uint8_t *name, int namelen);
--
2.1.0
More information about the Syslinux
mailing list