summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-02-26 20:40:21 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-02-26 20:40:21 -0800
commitf822d01851e0404e00cd198bdf3d12b76aba53b5 (patch)
tree78da9950b8c09e2e42e30386a2dd12e613b3edc7
parent0458be0391b4a7448e2a1911427c4c1800fe7145 (diff)
downloadsyslinux-f822d01851e0404e00cd198bdf3d12b76aba53b5.tar.gz
core: fix and simplify generic_getfssec()syslinux-4.00-pre29
Both simplify and fix generic_getfssec(). The previous version would occasionally request the same extent twice from the underlying layer. This is not a big deal for ext2fs for example, but is *very* expensive on FAT, where any out-of-order next_extent() call means walking the FAT from the beginning. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--core/fs/getfssec.c25
1 files changed, 9 insertions, 16 deletions
diff --git a/core/fs/getfssec.c b/core/fs/getfssec.c
index 80923c1c..d10bb29c 100644
--- a/core/fs/getfssec.c
+++ b/core/fs/getfssec.c
@@ -134,27 +134,20 @@ uint32_t generic_getfssec(struct file *file, char *buf,
inode->this_extent.pstart,
inode->this_extent.len);
- if (inode->this_extent.len < sectors &&
- (!inode->next_extent.len ||
- inode->next_extent.lstart !=
- inode->this_extent.lstart + inode->this_extent.len)) {
- get_next_extent(inode);
- }
-
while (sectors) {
uint32_t chunk;
size_t len;
- if (!inode->this_extent.len) {
- inode->this_extent = inode->next_extent;
- if (!inode->next_extent.len)
- break; /* Can't read anything more */
- }
-
while (sectors > inode->this_extent.len) {
- get_next_extent(inode);
-
- if (inode->next_extent.len &&
+ if (!inode->next_extent.len ||
+ inode->next_extent.lstart !=
+ inode->this_extent.lstart + inode->this_extent.len)
+ get_next_extent(inode);
+
+ if (!inode->this_extent.len) {
+ /* Doesn't matter if it's contiguous... */
+ inode->this_extent = inode->next_extent;
+ } else if (inode->next_extent.len &&
inode->next_extent.pstart == next_pstart(&inode->this_extent)) {
/* Coalesce extents and loop */
inode->this_extent.len += inode->next_extent.len;