summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorPaulo Alcantara <pcacjr@gmail.com>2011-08-29 05:49:32 +0000
committerPaulo Alcantara <pcacjr@gmail.com>2011-09-11 04:09:59 +0000
commit8edf44b7fb1a4f29029b93c63285c4431358bbe1 (patch)
treefafa9b1d8620e202986d1b13692de879ede2ef3d /core
parentc65a32b86a09f997cf443149c0dc9acfb6d20186 (diff)
downloadsyslinux-8edf44b7fb1a4f29029b93c63285c4431358bbe1.tar.gz
ntfs: don't start lookup from the same block in ntfs_mft_record_lookup()
ntfs_mft_record_lookup() always started its lookup from the same block, which was though a mistake. So the lookup became very slow. Now determine its starting block number from the calculated MFT record's LCN number. Signed-off-by: Paulo Alcantara <pcacjr@gmail.com>
Diffstat (limited to 'core')
-rw-r--r--core/fs/ntfs/ntfs.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/core/fs/ntfs/ntfs.c b/core/fs/ntfs/ntfs.c
index 51557eef..14c275b9 100644
--- a/core/fs/ntfs/ntfs.c
+++ b/core/fs/ntfs/ntfs.c
@@ -167,10 +167,13 @@ static MFT_RECORD *ntfs_mft_record_lookup(struct fs_info *fs, uint32_t file, blo
{
const uint64_t mft_record_size = NTFS_SB(fs)->mft_record_size;
uint8_t *buf;
+ const block_t mft_blk = NTFS_SB(fs)->mft_blk;
block_t cur_blk;
block_t right_blk;
uint64_t offset = 0;
uint64_t next_offset;
+ const unsigned mft_record_shift = ilog2(mft_record_size);
+ const unsigned clust_byte_shift = NTFS_SB(fs)->clust_byte_shift;
uint64_t lcn = NTFS_SB(fs)->mft_lcn;
int err;
MFT_RECORD *mrec;
@@ -179,9 +182,11 @@ static MFT_RECORD *ntfs_mft_record_lookup(struct fs_info *fs, uint32_t file, blo
if (!buf)
malloc_error("uint8_t *");
- cur_blk = blk ? *blk : 0;
+ /* determine MFT record's LCN and block number */
+ lcn = NTFS_SB(fs)->mft_lcn + (file << mft_record_shift >> clust_byte_shift);
+ cur_blk = (lcn << clust_byte_shift >> BLOCK_SHIFT(fs)) - mft_blk - 1;
for (;;) {
- right_blk = cur_blk + NTFS_SB(fs)->mft_blk;
+ right_blk = cur_blk + mft_blk;
err = ntfs_read(fs, buf, mft_record_size, mft_record_size, &right_blk,
&offset, &next_offset, &lcn);
if (err) {
@@ -202,10 +207,10 @@ static MFT_RECORD *ntfs_mft_record_lookup(struct fs_info *fs, uint32_t file, blo
if (next_offset >= BLOCK_SIZE(fs)) {
/* try the next FS block */
offset = 0;
- cur_blk = right_blk - NTFS_SB(fs)->mft_blk + 1;
+ cur_blk = right_blk - mft_blk + 1;
} else {
/* there's still content to fetch in the current block */
- cur_blk = right_blk - NTFS_SB(fs)->mft_blk;
+ cur_blk = right_blk - mft_blk;
offset = next_offset; /* update FS block offset */
}
}
@@ -751,7 +756,6 @@ static uint32_t ntfs_getfssec(struct file *file, char *buf, int sectors,
free(mrec);
}
-
return ret;
out: