diff --git a/src/fdcache.cpp b/src/fdcache.cpp index cd56603..d57c1d1 100644 --- a/src/fdcache.cpp +++ b/src/fdcache.cpp @@ -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){ diff --git a/src/fdcache.h b/src/fdcache.h index d96a020..0296550 100644 --- a/src/fdcache.h +++ b/src/fdcache.h @@ -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);