diff options
Diffstat (limited to 'contrib/syslinux/latest/core/fs/getfssec.c')
-rw-r--r-- | contrib/syslinux/latest/core/fs/getfssec.c | 194 |
1 files changed, 0 insertions, 194 deletions
diff --git a/contrib/syslinux/latest/core/fs/getfssec.c b/contrib/syslinux/latest/core/fs/getfssec.c deleted file mode 100644 index e099b64..0000000 --- a/contrib/syslinux/latest/core/fs/getfssec.c +++ /dev/null @@ -1,194 +0,0 @@ -/* ----------------------------------------------------------------------- * - * - * Copyright 2010 Intel Corporation; author: H. Peter Anvin - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall - * be included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * ----------------------------------------------------------------------- */ - -/* - * getfssec.c - * - * Generic getfssec implementation for disk-based filesystems, which - * support the next_extent() method. - * - * The expected semantics of next_extent are as follows: - * - * The second argument will contain the initial sector number to be - * mapped. The routine is expected to populate - * inode->next_extent.pstart and inode->next_extent.len (the caller - * will store the initial sector number into inode->next_extent.lstart - * on return.) - * - * If inode->next_extent.len != 0 on entry then the routine is allowed - * to assume inode->next_extent contains valid data from the previous - * usage, which can be used for optimization purposes. - * - * If the filesystem can map the entire file as a single extent - * (e.g. iso9660), then the filesystem can simply insert the extent - * information into inode->next_extent at searchdir/iget time, and leave - * next_extent() as NULL. - * - * Note: the filesystem driver is not required to do extent coalescing, - * if that is difficult to do; this routine will perform extent lookahead - * and coalescing. - */ - -#include <dprintf.h> -#include <minmax.h> -#include "fs.h" - -static inline sector_t next_psector(sector_t psector, uint32_t skip) -{ - if (EXTENT_SPECIAL(psector)) - return psector; - else - return psector + skip; -} - -static inline sector_t next_pstart(const struct extent *e) -{ - return next_psector(e->pstart, e->len); -} - - -static void get_next_extent(struct inode *inode) -{ - /* The logical start address that we care about... */ - uint32_t lstart = inode->this_extent.lstart + inode->this_extent.len; - - if (inode->fs->fs_ops->next_extent(inode, lstart)) - inode->next_extent.len = 0; /* ERROR */ - inode->next_extent.lstart = lstart; - - dprintf("Extent: inode %p @ %u start %llu len %u\n", - inode, inode->next_extent.lstart, - inode->next_extent.pstart, inode->next_extent.len); -} - -uint32_t generic_getfssec(struct file *file, char *buf, - int sectors, bool *have_more) -{ - struct inode *inode = file->inode; - struct fs_info *fs = file->fs; - struct disk *disk = fs->fs_dev->disk; - uint32_t bytes_read = 0; - uint32_t bytes_left = inode->size - file->offset; - uint32_t sectors_left = - (bytes_left + SECTOR_SIZE(fs) - 1) >> SECTOR_SHIFT(fs); - uint32_t lsector; - - if (sectors > sectors_left) - sectors = sectors_left; - - if (!sectors) - return 0; - - lsector = file->offset >> SECTOR_SHIFT(fs); - dprintf("Offset: %u lsector: %u\n", file->offset, lsector); - - if (lsector < inode->this_extent.lstart || - lsector >= inode->this_extent.lstart + inode->this_extent.len) { - /* inode->this_extent unusable, maybe next_extent is... */ - inode->this_extent = inode->next_extent; - } - - if (lsector < inode->this_extent.lstart || - lsector >= inode->this_extent.lstart + inode->this_extent.len) { - /* Still nothing useful... */ - inode->this_extent.lstart = lsector; - inode->this_extent.len = 0; - } else { - /* We have some usable information */ - uint32_t delta = lsector - inode->this_extent.lstart; - inode->this_extent.lstart = lsector; - inode->this_extent.len -= delta; - inode->this_extent.pstart - = next_psector(inode->this_extent.pstart, delta); - } - - dprintf("this_extent: lstart %u pstart %llu len %u\n", - inode->this_extent.lstart, - inode->this_extent.pstart, - inode->this_extent.len); - - while (sectors) { - uint32_t chunk; - size_t len; - - while (sectors > inode->this_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; - if (!inode->next_extent.len) { - sectors = 0; /* Failed to get anything... we're dead */ - break; - } - } 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; - } else { - /* Discontiguous extents */ - break; - } - } - - dprintf("this_extent: lstart %u pstart %llu len %u\n", - inode->this_extent.lstart, - inode->this_extent.pstart, - inode->this_extent.len); - - chunk = min(sectors, inode->this_extent.len); - len = chunk << SECTOR_SHIFT(fs); - - dprintf(" I/O: inode %p @ %u start %llu len %u\n", - inode, inode->this_extent.lstart, - inode->this_extent.pstart, chunk); - - if (inode->this_extent.pstart == EXTENT_ZERO) { - memset(buf, 0, len); - } else { - disk->rdwr_sectors(disk, buf, inode->this_extent.pstart, chunk, 0); - inode->this_extent.pstart += chunk; - } - - buf += len; - sectors -= chunk; - bytes_read += len; - inode->this_extent.lstart += chunk; - inode->this_extent.len -= chunk; - } - - bytes_read = min(bytes_read, bytes_left); - file->offset += bytes_read; - - if (have_more) - *have_more = bytes_read < bytes_left; - - return bytes_read; -} |