From e44c7231931688c589e503bc03a0bef5750829ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Fri, 11 Feb 2011 18:13:21 +0000 Subject: [PATCH] Improved DataStream::FindBlock() to return big extents instead of single blocks. This really speeds up the get_file_map operation for big files. Thanks to Stephan for reporting. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@40440 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/file_systems/exfat/DataStream.cpp | 16 ++++++++++++---- .../kernel/file_systems/exfat/DataStream.h | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/add-ons/kernel/file_systems/exfat/DataStream.cpp b/src/add-ons/kernel/file_systems/exfat/DataStream.cpp index 4a2788cc3c..48edf05709 100644 --- a/src/add-ons/kernel/file_systems/exfat/DataStream.cpp +++ b/src/add-ons/kernel/file_systems/exfat/DataStream.cpp @@ -24,6 +24,7 @@ DataStream::DataStream(Volume* volume, Inode* inode, off_t size) : kBlockSize(volume->BlockSize()), + kClusterSize(volume->ClusterSize()), fVolume(volume), fInode(inode), fSize(size) @@ -44,8 +45,8 @@ DataStream::FindBlock(off_t pos, off_t& physical, off_t *_length) TRACE("FindBlock: offset larger than size\n"); return B_ENTRY_NOT_FOUND; } - cluster_t clusterIndex = pos / fVolume->ClusterSize(); - uint32 offset = pos % fVolume->ClusterSize(); + cluster_t clusterIndex = pos / kClusterSize; + uint32 offset = pos % kClusterSize; cluster_t cluster = fInode->StartCluster(); for (uint32 i = 0; i < clusterIndex; i++) @@ -53,9 +54,16 @@ DataStream::FindBlock(off_t pos, off_t& physical, off_t *_length) fsblock_t block; fVolume->ClusterToBlock(cluster, block); physical = block * kBlockSize + offset; - *_length = min_c(kBlockSize, fSize - pos); + for (uint32 i = 0; i < 64; i++) { + cluster_t extentEnd = fInode->NextCluster(cluster); + if (extentEnd == EXFAT_CLUSTER_END || extentEnd == cluster + 1) + break; + cluster = extentEnd; + } + *_length = min_c((cluster - clusterIndex + 1) * kClusterSize - offset, + fSize - pos); TRACE("inode %" B_PRIdINO ": cluster %ld, pos %lld, %lld\n", - fInode->ID(), fInode->StartCluster(), pos, physical); + fInode->ID(), clusterIndex, pos, physical); return B_OK; } diff --git a/src/add-ons/kernel/file_systems/exfat/DataStream.h b/src/add-ons/kernel/file_systems/exfat/DataStream.h index ab43f6ece9..53a706fb54 100644 --- a/src/add-ons/kernel/file_systems/exfat/DataStream.h +++ b/src/add-ons/kernel/file_systems/exfat/DataStream.h @@ -27,6 +27,7 @@ public: off_t *_length = NULL); private: const uint32 kBlockSize; + const uint32 kClusterSize; Volume* fVolume; Inode* fInode; off_t fNumBlocks;