#define NUM_READ_SECTORS 2 ssize_t fat_file_read(struct file_info *fp, void* buf, size_t count) { char *bufp = buf; size_t ncopy; size_t n = 0; int readnumsectors, f_cluster, f_sector, countsectors; struct libfat_fileinfo *fs_desc = (struct libfat_fileinfo*) fp->fs_desc; struct libfat_filesystem *fs = fs_desc->fs; struct libfat_direntry *dentry = &fs_desc->dentry; char buffer[LIBFAT_SECTOR_SIZE * NUM_READ_SECTORS]; ncopy = NUM_READ_SECTORS*LIBFAT_SECTOR_SIZE; f_cluster = read16(&dentry->clustlo) + (read16(&dentry->clusthi) << 16); countsectors = count / ncopy; bytes_left = count - countsectors*LIBFAT_SECTOR_SIZE; f_sector = libfat_clustertosector(fs, f_cluster); while ( countsectors && f_sector > 0 ) { if ( fp->i.offset >= fp->i.length || !fp->i.filedes ) return n; /* As good as it gets... */ status = fs->read(fs->readptr, bufp, f_sector, NUM_READ_SECTORS); if ( status < 0 ) { errno = EIO; return -1; } n += ncopy; bufp += ncopy; countsectors -= NUM_READ_SECTORS; fp->i.offset += ncopy; f_sector = libfat_nextsector(fs, f_sector); } if (bytes_left) { if ( fp->i.offset >= fp->i.length || !fp->i.filedes ) return n; /* As good as it gets... */ status = fs->read(fs->readptr, buffer, f_sector, NUM_READ_SECTORS); if ( status < 0 ) { errno = EIO; return -1; } ncopy = bytes_left; memcpy(bufp, buffer, ncopy); n += ncopy; fp->i.offset += ncopy; } return n; }