mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2024-12-23 09:18:55 +00:00
Fix data races caused by incorrect locking (#1668)
Found via Threadsanitizer. Fixes #1471.
This commit is contained in:
parent
9bf525ee7a
commit
84174c560d
@ -512,7 +512,7 @@ FdEntity* FdManager::Open(const char* path, headers_t* pmeta, off_t size, time_t
|
|||||||
}
|
}
|
||||||
|
|
||||||
// open
|
// open
|
||||||
if(0 != ent->Open(pmeta, size, time, no_fd_lock_wait)){
|
if(0 != ent->Open(pmeta, size, time, no_fd_lock_wait ? AutoLock::NO_WAIT : AutoLock::NONE)){
|
||||||
if(close){
|
if(close){
|
||||||
ent->Close();
|
ent->Close();
|
||||||
}
|
}
|
||||||
|
@ -310,9 +310,9 @@ int FdEntity::OpenMirrorFile()
|
|||||||
return mirrorfd;
|
return mirrorfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FdEntity::Open(headers_t* pmeta, off_t size, time_t time, bool no_fd_lock_wait)
|
int FdEntity::Open(headers_t* pmeta, off_t size, time_t time, AutoLock::Type type)
|
||||||
{
|
{
|
||||||
AutoLock auto_lock(&fdent_lock, no_fd_lock_wait ? AutoLock::NO_WAIT : AutoLock::NONE);
|
AutoLock auto_lock(&fdent_lock, type);
|
||||||
|
|
||||||
S3FS_PRN_DBG("[path=%s][fd=%d][size=%lld][time=%lld]", path.c_str(), fd, static_cast<long long>(size), static_cast<long long>(time));
|
S3FS_PRN_DBG("[path=%s][fd=%d][size=%lld][time=%lld]", path.c_str(), fd, static_cast<long long>(size), static_cast<long long>(time));
|
||||||
|
|
||||||
@ -554,7 +554,7 @@ bool FdEntity::OpenAndLoadAll(headers_t* pmeta, off_t* size, bool force_load)
|
|||||||
S3FS_PRN_INFO3("[path=%s][fd=%d]", path.c_str(), fd);
|
S3FS_PRN_INFO3("[path=%s][fd=%d]", path.c_str(), fd);
|
||||||
|
|
||||||
if(-1 == fd){
|
if(-1 == fd){
|
||||||
if(0 != Open(pmeta)){
|
if(0 != Open(pmeta, /*size=*/ -1, /*time=*/ -1, AutoLock::ALREADY_LOCKED)){
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1178,7 +1178,8 @@ int FdEntity::NoCacheCompleteMultipartPost()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t FdEntity::BytesModified() const {
|
off_t FdEntity::BytesModified() {
|
||||||
|
AutoLock auto_lock(&fdent_data_lock);
|
||||||
return pagelist.BytesModified();
|
return pagelist.BytesModified();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1186,20 +1187,16 @@ int FdEntity::RowFlush(const char* tpath, bool force_sync)
|
|||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
std::string tmppath;
|
AutoLock auto_lock(&fdent_lock);
|
||||||
headers_t tmporgmeta;
|
std::string tmppath = path;
|
||||||
{
|
headers_t tmporgmeta = orgmeta;
|
||||||
AutoLock auto_lock(&fdent_lock);
|
|
||||||
tmppath = path;
|
|
||||||
tmporgmeta = orgmeta;
|
|
||||||
}
|
|
||||||
|
|
||||||
S3FS_PRN_INFO3("[tpath=%s][path=%s][fd=%d]", SAFESTRPTR(tpath), tmppath.c_str(), fd);
|
S3FS_PRN_INFO3("[tpath=%s][path=%s][fd=%d]", SAFESTRPTR(tpath), tmppath.c_str(), fd);
|
||||||
|
|
||||||
if(-1 == fd){
|
if(-1 == fd){
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
}
|
}
|
||||||
AutoLock auto_lock(&fdent_data_lock);
|
AutoLock auto_lock2(&fdent_data_lock);
|
||||||
|
|
||||||
if(!force_sync && !pagelist.IsModified()){
|
if(!force_sync && !pagelist.IsModified()){
|
||||||
// nothing to update.
|
// nothing to update.
|
||||||
@ -1394,7 +1391,8 @@ ssize_t FdEntity::Read(char* bytes, off_t start, size_t size, bool force_load)
|
|||||||
if(-1 == fd){
|
if(-1 == fd){
|
||||||
return -EBADF;
|
return -EBADF;
|
||||||
}
|
}
|
||||||
AutoLock auto_lock(&fdent_data_lock);
|
AutoLock auto_lock(&fdent_lock);
|
||||||
|
AutoLock auto_lock2(&fdent_data_lock);
|
||||||
|
|
||||||
if(force_load){
|
if(force_load){
|
||||||
pagelist.SetPageLoadedStatus(start, size, PageList::PAGE_NOT_LOAD_MODIFIED);
|
pagelist.SetPageLoadedStatus(start, size, PageList::PAGE_NOT_LOAD_MODIFIED);
|
||||||
@ -1458,7 +1456,8 @@ ssize_t FdEntity::Write(const char* bytes, off_t start, size_t size)
|
|||||||
if(FdManager::IsCacheDir() && !FdManager::IsSafeDiskSpace(NULL, size)){
|
if(FdManager::IsCacheDir() && !FdManager::IsSafeDiskSpace(NULL, size)){
|
||||||
FdManager::get()->CleanupCacheDir();
|
FdManager::get()->CleanupCacheDir();
|
||||||
}
|
}
|
||||||
AutoLock auto_lock(&fdent_data_lock);
|
AutoLock auto_lock(&fdent_lock);
|
||||||
|
AutoLock auto_lock2(&fdent_data_lock);
|
||||||
|
|
||||||
// check file size
|
// check file size
|
||||||
if(pagelist.Size() < start){
|
if(pagelist.Size() < start){
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#ifndef S3FS_FDCACHE_ENTITY_H_
|
#ifndef S3FS_FDCACHE_ENTITY_H_
|
||||||
#define S3FS_FDCACHE_ENTITY_H_
|
#define S3FS_FDCACHE_ENTITY_H_
|
||||||
|
|
||||||
|
#include "autolock.h"
|
||||||
#include "fdcache_page.h"
|
#include "fdcache_page.h"
|
||||||
#include "metaheader.h"
|
#include "metaheader.h"
|
||||||
|
|
||||||
@ -74,7 +75,7 @@ class FdEntity
|
|||||||
|
|
||||||
void Close();
|
void Close();
|
||||||
bool IsOpen() const { return (-1 != fd); }
|
bool IsOpen() const { return (-1 != fd); }
|
||||||
int Open(headers_t* pmeta = NULL, off_t size = -1, time_t time = -1, bool no_fd_lock_wait = false);
|
int Open(headers_t* pmeta, off_t size, time_t time, AutoLock::Type type);
|
||||||
bool OpenAndLoadAll(headers_t* pmeta = NULL, off_t* size = NULL, bool force_load = false);
|
bool OpenAndLoadAll(headers_t* pmeta = NULL, off_t* size = NULL, bool force_load = false);
|
||||||
int Dup(bool lock_already_held = false);
|
int Dup(bool lock_already_held = false);
|
||||||
int GetRefCnt() const { return refcnt; } // [NOTE] Use only debugging
|
int GetRefCnt() const { return refcnt; } // [NOTE] Use only debugging
|
||||||
@ -109,7 +110,7 @@ class FdEntity
|
|||||||
int NoCacheMultipartPost(int tgfd, off_t start, off_t size);
|
int NoCacheMultipartPost(int tgfd, off_t start, off_t size);
|
||||||
int NoCacheCompleteMultipartPost();
|
int NoCacheCompleteMultipartPost();
|
||||||
|
|
||||||
off_t BytesModified() const;
|
off_t BytesModified();
|
||||||
int RowFlush(const char* tpath, bool force_sync = false);
|
int RowFlush(const char* tpath, bool force_sync = false);
|
||||||
int Flush(bool force_sync = false) { return RowFlush(NULL, force_sync); }
|
int Flush(bool force_sync = false) { return RowFlush(NULL, force_sync); }
|
||||||
|
|
||||||
|
@ -2292,7 +2292,7 @@ static int s3fs_open(const char* _path, struct fuse_file_info* fi)
|
|||||||
if (needs_flush){
|
if (needs_flush){
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
struct timespec ts = {now, 0};
|
struct timespec ts = {now, 0};
|
||||||
ent->SetMCtime(ts, ts, true);
|
ent->SetMCtime(ts, ts);
|
||||||
if(0 != (result = ent->RowFlush(path, true))){
|
if(0 != (result = ent->RowFlush(path, true))){
|
||||||
S3FS_PRN_ERR("could not upload file(%s): result=%d", path, result);
|
S3FS_PRN_ERR("could not upload file(%s): result=%d", path, result);
|
||||||
StatCache::getStatCacheData()->DelStat(path);
|
StatCache::getStatCacheData()->DelStat(path);
|
||||||
|
Loading…
Reference in New Issue
Block a user