From: Paulo Alcantara Date: Tue, 22 Jan 2013 04:13:47 +0000 (-0200) Subject: xfs: Flush cache of directory blocks once done with readdir() X-Git-Tag: syslinux-5.01-pre5~3^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8656549bab437d880ab4a485b40b6f806182efbd;p=platform%2Fupstream%2Fsyslinux.git xfs: Flush cache of directory blocks once done with readdir() Signed-off-by: Paulo Alcantara --- 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;