aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@linux.intel.com>2010-05-13 14:38:04 -0700
committerH. Peter Anvin <hpa@linux.intel.com>2010-05-13 14:38:04 -0700
commit4ade7735e6607f3db51df50d4e79e636ba6a0121 (patch)
tree77b487df25ca96007c92fd49c99943e03c977039
parentae197a98b905a7da7872eef29dcbb0f822fa81de (diff)
downloadsyslinux-4ade7735e6607f3db51df50d4e79e636ba6a0121.tar.gz
syslinux-4ade7735e6607f3db51df50d4e79e636ba6a0121.tar.xz
syslinux-4ade7735e6607f3db51df50d4e79e636ba6a0121.zip
fat: fix confusion between byte and sector counts
clust_shift is in units of sectors, not in bytes; this was mixed up in the extent finder. Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
-rw-r--r--core/fs/fat/fat.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/core/fs/fat/fat.c b/core/fs/fat/fat.c
index 029c2d4a..e2fcc14c 100644
--- a/core/fs/fat/fat.c
+++ b/core/fs/fat/fat.c
@@ -93,13 +93,17 @@ static int fat_next_extent(struct inode *inode, uint32_t lstart)
uint32_t lcluster;
uint32_t pcluster;
uint32_t tcluster;
- uint32_t cluster_size = UINT32_C(1) << sbi->clust_shift;
+ const uint32_t cluster_bytes = UINT32_C(1) << sbi->clust_byte_shift;
+ const uint32_t cluster_secs = UINT32_C(1) << sbi->clust_shift;
sector_t data_area = sbi->data;
- tcluster = (inode->size + cluster_size - 1) >> sbi->clust_shift;
+ tcluster = (inode->size + cluster_bytes - 1) >> sbi->clust_byte_shift;
if (mcluster >= tcluster)
goto err; /* Requested cluster beyond end of file */
+ dprintf("Getting next cluster, inode = %p, lstart = %u, mcluster = %u, tcluster = %u\n",
+ inode, lstart, mcluster, tcluster);
+
if (inode->next_extent.len) {
if (inode->next_extent.pstart < data_area)
goto err; /* Root directory has only one extent */
@@ -132,7 +136,7 @@ static int fat_next_extent(struct inode *inode, uint32_t lstart)
inode->next_extent.pstart =
((sector_t)(pcluster-2) << sbi->clust_shift) + data_area;
- inode->next_extent.len = cluster_size;
+ inode->next_extent.len = cluster_secs;
lcluster++;
while (lcluster < tcluster) {
@@ -141,7 +145,7 @@ static int fat_next_extent(struct inode *inode, uint32_t lstart)
if (xcluster != pcluster+1)
break; /* Not contiguous */
pcluster = xcluster;
- inode->next_extent.len += cluster_size;
+ inode->next_extent.len += cluster_secs;
lcluster++;
}
return 0;
@@ -183,12 +187,9 @@ static sector_t get_next_sector(struct fs_info* fs, uint32_t sector)
}
/*
- * Here comes the place I don't like VFAT fs most; if we need seek
- * the file to the right place, we need get the right sector address
- * from begining everytime! Since it's a kind a signle link list, we
- * need to traver from the head-node to find the right node in that list.
- *
- * What a waste of time!
+ * The FAT is a single-linked list. We remember the last place we
+ * were, so for a forward seek we can move forward from there, but
+ * for a reverse seek we have to start over...
*/
static sector_t get_the_right_sector(struct file *file)
{