mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2024-11-14 00:14:07 +00:00
Merge pull request #1365 from ggtakec/check_lseek
Dynamically determine whether lseek extended options are supported
This commit is contained in:
commit
a5186c73c2
@ -55,6 +55,19 @@ using namespace std;
|
||||
static const int MAX_MULTIPART_CNT = 10 * 1000; // S3 multipart max count
|
||||
static const int CHECK_CACHEFILE_PART_SIZE = 1024 * 16; // Buffer size in PageList::CheckZeroAreaInFile()
|
||||
|
||||
//
|
||||
// [NOTE]
|
||||
// If the following symbols in lseek whence are undefined, define them.
|
||||
// If it is not supported by lseek, s3fs judges by the processing result of lseek.
|
||||
//
|
||||
#ifndef SEEK_DATA
|
||||
#define SEEK_DATA 3
|
||||
#endif
|
||||
#ifndef SEEK_HOLE
|
||||
#define SEEK_HOLE 4
|
||||
#endif
|
||||
#define TMPFILE_FOR_CHECK_HOLE "/tmp/.s3fs_hole_check.tmp"
|
||||
|
||||
//
|
||||
// For cache directory top path
|
||||
//
|
||||
@ -2719,6 +2732,8 @@ string FdManager::cache_dir;
|
||||
bool FdManager::check_cache_dir_exist(false);
|
||||
off_t FdManager::free_disk_space = 0;
|
||||
std::string FdManager::check_cache_output;
|
||||
bool FdManager::checked_lseek(false);
|
||||
bool FdManager::have_lseek_hole(false);
|
||||
|
||||
//------------------------------------------------
|
||||
// FdManager class methods
|
||||
@ -2928,6 +2943,43 @@ bool FdManager::IsSafeDiskSpace(const char* path, off_t size)
|
||||
return size + FdManager::GetEnsureFreeDiskSpace() <= fsize;
|
||||
}
|
||||
|
||||
bool FdManager::HaveLseekHole(void)
|
||||
{
|
||||
if(FdManager::checked_lseek){
|
||||
return FdManager::have_lseek_hole;
|
||||
}
|
||||
|
||||
// create tempolary file
|
||||
int fd;
|
||||
if(-1 == (fd = open(TMPFILE_FOR_CHECK_HOLE, O_CREAT|O_RDWR, 0600))){
|
||||
S3FS_PRN_ERR("failed to open tempolary file(%s) - errno(%d)", TMPFILE_FOR_CHECK_HOLE, errno);
|
||||
FdManager::checked_lseek = true;
|
||||
FdManager::have_lseek_hole = false;
|
||||
return FdManager::have_lseek_hole;
|
||||
}
|
||||
|
||||
// check SEEK_DATA/SEEK_HOLE options
|
||||
bool result = true;
|
||||
if(-1 == lseek(fd, 0, SEEK_DATA)){
|
||||
if(EINVAL == errno){
|
||||
S3FS_PRN_ERR("lseek does not support SEEK_DATA");
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
if(result && -1 == lseek(fd, 0, SEEK_HOLE)){
|
||||
if(EINVAL == errno){
|
||||
S3FS_PRN_ERR("lseek does not support SEEK_HOLE");
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
unlink(TMPFILE_FOR_CHECK_HOLE);
|
||||
|
||||
FdManager::checked_lseek = true;
|
||||
FdManager::have_lseek_hole = result;
|
||||
return FdManager::have_lseek_hole;
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
// FdManager methods
|
||||
//------------------------------------------------
|
||||
@ -3470,6 +3522,11 @@ bool FdManager::RawCheckAllCache(FILE* fp, const char* cache_stat_top_dir, const
|
||||
|
||||
bool FdManager::CheckAllCache()
|
||||
{
|
||||
if(!FdManager::HaveLseekHole()){
|
||||
S3FS_PRN_ERR("lseek does not support SEEK_DATA/SEEK_HOLE, then could not check cache.");
|
||||
return false;
|
||||
}
|
||||
|
||||
FILE* fp;
|
||||
if(FdManager::check_cache_output.empty()){
|
||||
fp = stdout;
|
||||
|
@ -232,6 +232,8 @@ class FdManager
|
||||
static bool check_cache_dir_exist;
|
||||
static off_t free_disk_space; // limit free disk space
|
||||
static std::string check_cache_output;
|
||||
static bool checked_lseek;
|
||||
static bool have_lseek_hole;
|
||||
|
||||
fdent_map_t fent;
|
||||
|
||||
@ -265,6 +267,7 @@ class FdManager
|
||||
static bool IsSafeDiskSpace(const char* path, off_t size);
|
||||
static void FreeReservedDiskSpace(off_t size);
|
||||
static bool ReserveDiskSpace(off_t size);
|
||||
static bool HaveLseekHole(void);
|
||||
|
||||
// Return FdEntity associated with path, returning NULL on error. This operation increments the reference count; callers must decrement via Close after use.
|
||||
FdEntity* GetFdEntity(const char* path, int existfd = -1);
|
||||
|
@ -93,6 +93,11 @@ void S3fsSignals::HandlerUSR1(int sig)
|
||||
|
||||
bool S3fsSignals::SetUsr1Handler(const char* path)
|
||||
{
|
||||
if(!FdManager::HaveLseekHole()){
|
||||
S3FS_PRN_ERR("Could not set SIGUSR1 for checking cache, because this system does not support SEEK_DATA/SEEK_HOLE in lseek function.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// set output file
|
||||
if(!FdManager::SetCacheCheckOutput(path)){
|
||||
S3FS_PRN_ERR("Could not set output file(%s) for checking cache.", path ? path : "null(stdout)");
|
||||
|
Loading…
Reference in New Issue
Block a user