[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