Merge pull request #1081 from gaul/write-blocks-readdir

Break FdEntity locks into data and metadata
This commit is contained in:
Takeshi Nakatani 2019-07-11 03:40:26 +09:00 committed by GitHub
commit 50d13255e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 12 deletions

View File

@ -623,14 +623,16 @@ int FdEntity::FillFile(int fd, unsigned char byte, off_t size, off_t start)
// FdEntity methods
//------------------------------------------------
FdEntity::FdEntity(const char* tpath, const char* cpath)
: is_lock_init(false), refcnt(0), path(SAFESTRPTR(tpath)), cachepath(SAFESTRPTR(cpath)), mirrorpath(""),
fd(-1), pfile(NULL), is_modify(false), size_orgmeta(0), upload_id(""), mp_start(0), mp_size(0)
: is_lock_init(false), refcnt(0), path(SAFESTRPTR(tpath)),
fd(-1), pfile(NULL), size_orgmeta(0), upload_id(""), mp_start(0), mp_size(0), is_modify(false),
cachepath(SAFESTRPTR(cpath)), mirrorpath("")
{
try{
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, S3FS_MUTEX_RECURSIVE); // recursive mutex
pthread_mutex_init(&fdent_lock, &attr);
pthread_mutex_init(&fdent_data_lock, &attr);
is_lock_init = true;
}catch(exception& e){
S3FS_PRN_CRIT("failed to init mutex");
@ -643,6 +645,7 @@ FdEntity::~FdEntity()
if(is_lock_init){
try{
pthread_mutex_destroy(&fdent_data_lock);
pthread_mutex_destroy(&fdent_lock);
}catch(exception& e){
S3FS_PRN_CRIT("failed to destroy mutex");
@ -654,6 +657,7 @@ FdEntity::~FdEntity()
void FdEntity::Clear()
{
AutoLock auto_lock(&fdent_lock);
AutoLock auto_data_lock(&fdent_data_lock);
if(-1 != fd){
if(!cachepath.empty()){
@ -696,6 +700,7 @@ void FdEntity::Close()
abort();
}
if(0 == refcnt){
AutoLock auto_data_lock(&fdent_data_lock);
if(!cachepath.empty()){
CacheFileStat cfstat(path.c_str());
if(!pagelist.Serialize(cfstat, true)){
@ -796,6 +801,7 @@ int FdEntity::Open(headers_t* pmeta, off_t size, time_t time, bool no_fd_lock_wa
return -EIO;
}
AutoLock auto_data_lock(&fdent_data_lock);
if(-1 != fd){
// already opened, needs to increment refcnt.
Dup();
@ -993,7 +999,7 @@ bool FdEntity::OpenAndLoadAll(headers_t* pmeta, off_t* size, bool force_load)
return false;
}
}
AutoLock auto_lock(&fdent_lock);
AutoLock auto_lock(&fdent_data_lock);
if(force_load){
SetAllStatusUnloaded();
@ -1172,7 +1178,7 @@ int FdEntity::Load(off_t start, off_t size)
if(-1 == fd){
return -EBADF;
}
AutoLock auto_lock(&fdent_lock);
AutoLock auto_lock(&fdent_data_lock);
int result = 0;
@ -1474,7 +1480,7 @@ int FdEntity::RowFlush(const char* tpath, bool force_sync)
if(-1 == fd){
return -EBADF;
}
AutoLock auto_lock(&fdent_lock);
AutoLock auto_lock(&fdent_data_lock);
if(!force_sync && !is_modify){
// nothing to update.
@ -1628,7 +1634,7 @@ ssize_t FdEntity::Read(char* bytes, off_t start, size_t size, bool force_load)
if(-1 == fd){
return -EBADF;
}
AutoLock auto_lock(&fdent_lock);
AutoLock auto_lock(&fdent_data_lock);
if(force_load){
pagelist.SetPageLoadedStatus(start, size, false);
@ -1691,7 +1697,7 @@ ssize_t FdEntity::Write(const char* bytes, off_t start, size_t size)
if(FdManager::IsCacheDir() && !FdManager::IsSafeDiskSpace(NULL, size)){
FdManager::get()->CleanupCacheDir();
}
AutoLock auto_lock(&fdent_lock);
AutoLock auto_lock(&fdent_data_lock);
// check file size
if(pagelist.Size() < start){

View File

@ -112,22 +112,23 @@ class FdEntity
private:
pthread_mutex_t fdent_lock;
bool is_lock_init;
PageList pagelist;
int refcnt; // reference count
std::string path; // object path
std::string cachepath; // local cache file path
// (if this is empty, does not load/save pagelist.)
std::string mirrorpath; // mirror file path to local cache file path
int fd; // file descriptor(tmp file or cache file)
FILE* pfile; // file pointer(tmp file or cache file)
bool is_modify; // if file is changed, this flag is true
headers_t orgmeta; // original headers at opening
off_t size_orgmeta; // original file size in original headers
pthread_mutex_t fdent_data_lock;// protects the following members
PageList pagelist;
std::string upload_id; // for no cached multipart uploading when no disk space
etaglist_t etaglist; // for no cached multipart uploading when no disk space
off_t mp_start; // start position for no cached multipart(write method only)
off_t mp_size; // size for no cached multipart(write method only)
bool is_modify; // if file is changed, this flag is true
std::string cachepath; // local cache file path
// (if this is empty, does not load/save pagelist.)
std::string mirrorpath; // mirror file path to local cache file path
private:
static int FillFile(int fd, unsigned char byte, off_t size, off_t start);