From 8656549bab437d880ab4a485b40b6f806182efbd Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Tue, 22 Jan 2013 02:13:47 -0200 Subject: xfs: Flush cache of directory blocks once done with readdir() Signed-off-by: Paulo Alcantara --- 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 39a586b5..de37ef7c 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 9c2785f3..158cf44f 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 952f33b3..86c8a77b 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; -- cgit 1.2.3-korg