diff options
author | H. Peter Anvin <hpa@zytor.com> | 2010-02-26 20:40:21 -0800 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2010-02-26 20:40:21 -0800 |
commit | f822d01851e0404e00cd198bdf3d12b76aba53b5 (patch) | |
tree | 78da9950b8c09e2e42e30386a2dd12e613b3edc7 | |
parent | 0458be0391b4a7448e2a1911427c4c1800fe7145 (diff) | |
download | syslinux-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.c | 25 |
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; |