[syslinux:elflink] xfs: Flush cache of directory blocks once done with readdir()

syslinux-bot for Paulo Alcantara pcacjr at zytor.com
Thu Jan 24 09:45:08 PST 2013


Commit-ID:  8656549bab437d880ab4a485b40b6f806182efbd
Gitweb:     http://www.syslinux.org/commit/8656549bab437d880ab4a485b40b6f806182efbd
Author:     Paulo Alcantara <pcacjr at zytor.com>
AuthorDate: Tue, 22 Jan 2013 02:13:47 -0200
Committer:  Paulo Alcantara <pcacjr at zytor.com>
CommitDate: Tue, 22 Jan 2013 02:13:47 -0200

xfs: Flush cache of directory blocks once done with readdir()

Signed-off-by: Paulo Alcantara <pcacjr at zytor.com>

---
 core/fs/xfs/xfs_dir2.c    | 12 ++++++++++++
 core/fs/xfs/xfs_dir2.h    |  3 +++
 core/fs/xfs/xfs_readdir.c | 22 ++++++++++++++++++----
 3 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/core/fs/xfs/xfs_dir2.c b/core/fs/xfs/xfs_dir2.c
index 39a586b..de37ef7 100644
--- a/core/fs/xfs/xfs_dir2.c
+++ b/core/fs/xfs/xfs_dir2.c
@@ -156,6 +156,18 @@ const void *xfs_dir2_dirblks_get_cached(struct fs_info *fs, block_t startblock,
     return NULL;
 }
 
+void xfs_dir2_dirblks_flush_cache(void)
+{
+    unsigned char i;
+
+    for (i = 0; i < dirblks_cached_count; i++) {
+	free(dirblks_cache[i].dc_area);
+	memset(&dirblks_cache[i], 0, sizeof(dirblks_cache[i]));
+    }
+
+    dirblks_cached_count = 0;
+}
+
 struct inode *xfs_dir2_local_find_entry(const char *dname, struct inode *parent,
 					xfs_dinode_t *core)
 {
diff --git a/core/fs/xfs/xfs_dir2.h b/core/fs/xfs/xfs_dir2.h
index 9c2785f..158cf44 100644
--- a/core/fs/xfs/xfs_dir2.h
+++ b/core/fs/xfs/xfs_dir2.h
@@ -25,7 +25,10 @@
 
 const 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);
+
 block_t xfs_dir2_get_right_blk(struct fs_info *fs, xfs_dinode_t *core,
 			       block_t fsblkno, int *error);
 
diff --git a/core/fs/xfs/xfs_readdir.c b/core/fs/xfs/xfs_readdir.c
index 952f33b..86c8a77 100644
--- a/core/fs/xfs/xfs_readdir.c
+++ b/core/fs/xfs/xfs_readdir.c
@@ -78,7 +78,7 @@ int xfs_readdir_dir2_local(struct file *file, struct dirent *dirent,
     xfs_debug("count %hhu i8count %hhu", sf->hdr.count, sf->hdr.i8count);
 
     if (file->offset + 1 > count)
-	return -1;
+	goto out;
 
     file->offset++;
 
@@ -112,6 +112,11 @@ int xfs_readdir_dir2_local(struct file *file, struct dirent *dirent,
 	xfs_error("Failed to fill in dirent structure");
 
     return retval;
+
+out:
+    xfs_dir2_dirblks_flush_cache();
+
+    return -1;
 }
 
 int xfs_readdir_dir2_block(struct file *file, struct dirent *dirent,
@@ -142,13 +147,13 @@ int xfs_readdir_dir2_block(struct file *file, struct dirent *dirent,
     if (be32_to_cpu(hdr->magic) != XFS_DIR2_BLOCK_MAGIC) {
         xfs_error("Block directory header's magic number does not match!");
         xfs_debug("hdr->magic: 0x%lx", be32_to_cpu(hdr->magic));
-	return -1;
+	goto out;
     }
 
     btp = xfs_dir2_block_tail_p(XFS_INFO(fs), hdr);
 
     if (file->offset + 1 > be32_to_cpu(btp->count))
-	return -1;
+	goto out;
 
     file->offset++;
 
@@ -182,6 +187,11 @@ int xfs_readdir_dir2_block(struct file *file, struct dirent *dirent,
 	xfs_error("Failed to fill in dirent structure");
 
     return retval;
+
+out:
+    xfs_dir2_dirblks_flush_cache();
+
+    return -1;
 }
 
 int xfs_readdir_dir2_leaf(struct file *file, struct dirent *dirent,
@@ -258,6 +268,8 @@ int xfs_readdir_dir2_leaf(struct file *file, struct dirent *dirent,
     return retval;
 
 out:
+    xfs_dir2_dirblks_flush_cache();
+
     return -1;
 }
 
@@ -300,7 +312,7 @@ int xfs_readdir_dir2_node(struct file *file, struct dirent *dirent,
 try_next_btree:
     if (!node->hdr.count ||
 	XFS_PVT(inode)->i_btree_offset >= be16_to_cpu(node->hdr.count))
-        goto out;
+	goto out;
 
     fsblkno = be32_to_cpu(node->btree[XFS_PVT(inode)->i_btree_offset].before);
     fsblkno = xfs_dir2_get_right_blk(fs, core, fsblkno, &error);
@@ -367,6 +379,8 @@ try_next_btree:
     return retval;
 
 out:
+    xfs_dir2_dirblks_flush_cache();
+
     XFS_PVT(inode)->i_btree_offset = 0;
     XFS_PVT(inode)->i_leaf_ent_offset = 0;
 


More information about the Syslinux-commits mailing list