aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaulo Alcantara <pcacjr@zytor.com>2013-01-22 02:13:47 -0200
committerPaulo Alcantara <pcacjr@zytor.com>2013-01-22 02:13:47 -0200
commit8656549bab437d880ab4a485b40b6f806182efbd (patch)
treebf849c90750e2650eef19a7a2e1d7cca8d4a5300
parent2be24375ed6af881405d23483aebe81ce3dcb3b7 (diff)
downloadsyslinux-8656549bab437d880ab4a485b40b6f806182efbd.tar.gz
syslinux-8656549bab437d880ab4a485b40b6f806182efbd.tar.xz
syslinux-8656549bab437d880ab4a485b40b6f806182efbd.zip
xfs: Flush cache of directory blocks once done with readdir()
Signed-off-by: Paulo Alcantara <pcacjr@zytor.com>
-rw-r--r--core/fs/xfs/xfs_dir2.c12
-rw-r--r--core/fs/xfs/xfs_dir2.h3
-rw-r--r--core/fs/xfs/xfs_readdir.c22
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;