@@ -55,6 +55,19 @@ using namespace std;
55
55
static const int MAX_MULTIPART_CNT = 10 * 1000 ; // S3 multipart max count
56
56
static const int CHECK_CACHEFILE_PART_SIZE = 1024 * 16 ; // Buffer size in PageList::CheckZeroAreaInFile()
57
57
58
+ //
59
+ // [NOTE]
60
+ // If the following symbols in lseek whence are undefined, define them.
61
+ // If it is not supported by lseek, s3fs judges by the processing result of lseek.
62
+ //
63
+ #ifndef SEEK_DATA
64
+ #define SEEK_DATA 3
65
+ #endif
66
+ #ifndef SEEK_HOLE
67
+ #define SEEK_HOLE 4
68
+ #endif
69
+ #define TMPFILE_FOR_CHECK_HOLE " /tmp/.s3fs_hole_check.tmp"
70
+
58
71
//
59
72
// For cache directory top path
60
73
//
@@ -2719,6 +2732,8 @@ string FdManager::cache_dir;
2719
2732
bool FdManager::check_cache_dir_exist (false );
2720
2733
off_t FdManager::free_disk_space = 0 ;
2721
2734
std::string FdManager::check_cache_output;
2735
+ bool FdManager::checked_lseek (false );
2736
+ bool FdManager::have_lseek_hole (false );
2722
2737
2723
2738
// ------------------------------------------------
2724
2739
// FdManager class methods
@@ -2928,6 +2943,43 @@ bool FdManager::IsSafeDiskSpace(const char* path, off_t size)
2928
2943
return size + FdManager::GetEnsureFreeDiskSpace () <= fsize;
2929
2944
}
2930
2945
2946
+ bool FdManager::HaveLseekHole (void )
2947
+ {
2948
+ if (FdManager::checked_lseek){
2949
+ return FdManager::have_lseek_hole;
2950
+ }
2951
+
2952
+ // create tempolary file
2953
+ int fd;
2954
+ if (-1 == (fd = open (TMPFILE_FOR_CHECK_HOLE, O_CREAT|O_RDWR, 0600 ))){
2955
+ S3FS_PRN_ERR (" failed to open tempolary file(%s) - errno(%d)" , TMPFILE_FOR_CHECK_HOLE, errno);
2956
+ FdManager::checked_lseek = true ;
2957
+ FdManager::have_lseek_hole = false ;
2958
+ return FdManager::have_lseek_hole;
2959
+ }
2960
+
2961
+ // check SEEK_DATA/SEEK_HOLE options
2962
+ bool result = true ;
2963
+ if (-1 == lseek (fd, 0 , SEEK_DATA)){
2964
+ if (EINVAL == errno){
2965
+ S3FS_PRN_ERR (" lseek does not support SEEK_DATA" );
2966
+ result = false ;
2967
+ }
2968
+ }
2969
+ if (result && -1 == lseek (fd, 0 , SEEK_HOLE)){
2970
+ if (EINVAL == errno){
2971
+ S3FS_PRN_ERR (" lseek does not support SEEK_HOLE" );
2972
+ result = false ;
2973
+ }
2974
+ }
2975
+ close (fd);
2976
+ unlink (TMPFILE_FOR_CHECK_HOLE);
2977
+
2978
+ FdManager::checked_lseek = true ;
2979
+ FdManager::have_lseek_hole = result;
2980
+ return FdManager::have_lseek_hole;
2981
+ }
2982
+
2931
2983
// ------------------------------------------------
2932
2984
// FdManager methods
2933
2985
// ------------------------------------------------
@@ -3470,6 +3522,11 @@ bool FdManager::RawCheckAllCache(FILE* fp, const char* cache_stat_top_dir, const
3470
3522
3471
3523
bool FdManager::CheckAllCache ()
3472
3524
{
3525
+ if (!FdManager::HaveLseekHole ()){
3526
+ S3FS_PRN_ERR (" lseek does not support SEEK_DATA/SEEK_HOLE, then could not check cache." );
3527
+ return false ;
3528
+ }
3529
+
3473
3530
FILE* fp;
3474
3531
if (FdManager::check_cache_output.empty ()){
3475
3532
fp = stdout;
0 commit comments