in src/fdcache_entity.cpp [1760:1864]
ssize_t FdEntity::Read(int fd, char* bytes, off_t start, size_t size, bool force_load)
{
S3FS_PRN_DBG("[path=%s][pseudo_fd=%d][physical_fd=%d][offset=%lld][size=%zu]", path.c_str(), fd, physical_fd, static_cast<long long int>(start), size);
PseudoFdInfo* pseudo_obj = NULL;
if(-1 == physical_fd || NULL == (pseudo_obj = CheckPseudoFdFlags(fd, false))){
S3FS_PRN_DBG("pseudo_fd(%d) to physical_fd(%d) for path(%s) is not opened or not readable", fd, physical_fd, path.c_str());
return -EBADF;
}
AutoLock auto_lock(&fdent_lock);
AutoLock auto_lock2(&fdent_data_lock);
ssize_t rsize = 0;
if(is_direct_read){
if (DirectReader::GetDirectReadLocalFileCacheSize() == 0) {
return pseudo_obj->DirectReadAndPrefetch(bytes, start, size);
}
// mix-direct-read mode
// enter direct-read-and-prefetch when the total_downloaded_size >= the threshold
if (pseudo_obj->GetLoadedSize() >= DirectReader::GetDirectReadLocalFileCacheSize()) {
if (pagelist.IsPageLoaded(start, size)) {
// Reading
if(-1 == (rsize = pread(physical_fd, bytes, size, start))){
S3FS_PRN_ERR("pread failed. errno(%d)", errno);
return -errno;
}
return rsize;
}
S3FS_PRN_DBG("start direct read. total_loaded_size = %lld, offset = %lld", pseudo_obj->GetLoadedSize(), start);
return pseudo_obj->DirectReadAndPrefetch(bytes, start, size);
}
}
CheckAndFreeDiskCacheIfNeeded();
if(force_load){
pagelist.SetPageLoadedStatus(start, size, PageList::PAGE_NOT_LOAD_MODIFIED);
}
int result = 0;
uint64_t downloaded_size = 0;
bool read_from_oss_directly = false;
// check disk space
if(0 < pagelist.GetTotalUnloadedPageSize(start, size)){
// load size(for prefetch)
size_t load_size = size;
if(start + static_cast<ssize_t>(size) < pagelist.Size()){
ssize_t prefetch_max_size = std::max(static_cast<off_t>(size), S3fsCurl::GetMultipartSize() * S3fsCurl::GetMaxParallelCount());
if(start + prefetch_max_size < pagelist.Size()){
load_size = prefetch_max_size;
}else{
load_size = pagelist.Size() - start;
}
}
if(!ReserveDiskSpace(load_size)){
S3FS_PRN_WARN("could not reserve disk space for pre-fetch download");
load_size = size;
if(!ReserveDiskSpace(load_size)){
S3FS_PRN_WARN("could not reserve disk space for pre-fetch download");
read_from_oss_directly = true;
}
}
if(!read_from_oss_directly) {
if(0 < size){
// Loading
result = LoadWithSizeInfo(start, load_size, AutoLock::ALREADY_LOCKED, downloaded_size);
}
FdManager::FreeReservedDiskSpace(load_size);
if(0 != result){
S3FS_PRN_WARN("could not download. start(%lld), size(%zu), errno(%d)", static_cast<long long int>(start), size, result);
read_from_oss_directly = true;
} else {
pseudo_obj->AddLoadedSize(downloaded_size);
}
}
}
if(read_from_oss_directly){
// direct read from oss, but no prefetch
S3FS_PRN_WARN("could not reserve disk space for download, direct read from cloud.");
S3fsCurl s3fscurl;
result = s3fscurl.GetObjectStreamRequest(path.c_str(), bytes, start, size, rsize);
if(0 != result){
S3FS_PRN_ERR("could not download. start(%lld), size(%zu), errno(%d)", static_cast<long long int>(start), size, result);
return result;
}
return rsize;
}
// Reading
if(-1 == (rsize = pread(physical_fd, bytes, size, start))){
S3FS_PRN_ERR("pread failed. errno(%d)", errno);
return -errno;
}
return rsize;
}