mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2025-02-03 11:08:26 +00:00
reduce lock contention on file open
This commit is contained in:
parent
e1dafe76dd
commit
0edf056e95
@ -725,15 +725,12 @@ void FdEntity::Close(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int FdEntity::Dup(bool no_fd_lock_wait)
|
int FdEntity::Dup()
|
||||||
{
|
{
|
||||||
S3FS_PRN_DBG("[path=%s][fd=%d][refcnt=%d]", path.c_str(), fd, (-1 != fd ? refcnt + 1 : refcnt));
|
S3FS_PRN_DBG("[path=%s][fd=%d][refcnt=%d]", path.c_str(), fd, (-1 != fd ? refcnt + 1 : refcnt));
|
||||||
|
|
||||||
if(-1 != fd){
|
if(-1 != fd){
|
||||||
AutoLock auto_lock(&fdent_lock, no_fd_lock_wait);
|
AutoLock auto_lock(&fdent_lock);
|
||||||
if (!auto_lock.isLockAcquired()) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
refcnt++;
|
refcnt++;
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
@ -756,13 +753,23 @@ int FdEntity::OpenMirrorFile(void)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// create seed generating mirror file name
|
||||||
|
unsigned int seed = static_cast<unsigned int>(time(NULL));
|
||||||
|
int urandom_fd;
|
||||||
|
if(-1 != (urandom_fd = open("/dev/urandom", O_RDONLY))){
|
||||||
|
unsigned int rand_data;
|
||||||
|
if(sizeof(rand_data) == read(urandom_fd, &rand_data, sizeof(rand_data))){
|
||||||
|
seed ^= rand_data;
|
||||||
|
}
|
||||||
|
close(urandom_fd);
|
||||||
|
}
|
||||||
|
|
||||||
// try to link mirror file
|
// try to link mirror file
|
||||||
while(true){
|
while(true){
|
||||||
// make random(temp) file path
|
// make random(temp) file path
|
||||||
// (do not care for threading, because allowed any value returned.)
|
// (do not care for threading, because allowed any value returned.)
|
||||||
//
|
//
|
||||||
char szfile[NAME_MAX + 1];
|
char szfile[NAME_MAX + 1];
|
||||||
unsigned int seed = static_cast<unsigned int>(time(NULL));
|
|
||||||
sprintf(szfile, "%x.tmp", rand_r(&seed));
|
sprintf(szfile, "%x.tmp", rand_r(&seed));
|
||||||
mirrorpath = bupdir + "/" + szfile;
|
mirrorpath = bupdir + "/" + szfile;
|
||||||
|
|
||||||
@ -774,6 +781,7 @@ int FdEntity::OpenMirrorFile(void)
|
|||||||
S3FS_PRN_ERR("could not link mirror file(%s) to cache file(%s) by errno(%d).", mirrorpath.c_str(), cachepath.c_str(), errno);
|
S3FS_PRN_ERR("could not link mirror file(%s) to cache file(%s) by errno(%d).", mirrorpath.c_str(), cachepath.c_str(), errno);
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
++seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
// open mirror file
|
// open mirror file
|
||||||
@ -785,21 +793,20 @@ int FdEntity::OpenMirrorFile(void)
|
|||||||
return mirrorfd;
|
return mirrorfd;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [NOTE]
|
|
||||||
// This method does not lock fdent_lock, because FdManager::fd_manager_lock
|
|
||||||
// is locked before calling.
|
|
||||||
//
|
|
||||||
int FdEntity::Open(headers_t* pmeta, ssize_t size, time_t time, bool no_fd_lock_wait)
|
int FdEntity::Open(headers_t* pmeta, ssize_t size, time_t time, bool no_fd_lock_wait)
|
||||||
{
|
{
|
||||||
S3FS_PRN_DBG("[path=%s][fd=%d][size=%jd][time=%jd]", path.c_str(), fd, (intmax_t)size, (intmax_t)time);
|
S3FS_PRN_DBG("[path=%s][fd=%d][size=%jd][time=%jd]", path.c_str(), fd, (intmax_t)size, (intmax_t)time);
|
||||||
|
|
||||||
if(-1 != fd){
|
AutoLock auto_lock(&fdent_lock, no_fd_lock_wait);
|
||||||
// already opened, needs to increment refcnt.
|
if (!auto_lock.isLockAcquired()) {
|
||||||
if (fd != Dup(no_fd_lock_wait)) {
|
|
||||||
// had to wait for fd lock, return
|
// had to wait for fd lock, return
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(-1 != fd){
|
||||||
|
// already opened, needs to increment refcnt.
|
||||||
|
Dup();
|
||||||
|
|
||||||
// check only file size(do not need to save cfs and time.
|
// check only file size(do not need to save cfs and time.
|
||||||
if(0 <= size && pagelist.Size() != static_cast<size_t>(size)){
|
if(0 <= size && pagelist.Size() != static_cast<size_t>(size)){
|
||||||
// truncate temporary file size
|
// truncate temporary file size
|
||||||
@ -2027,6 +2034,8 @@ FdEntity* FdManager::Open(const char* path, headers_t* pmeta, ssize_t size, time
|
|||||||
if(!path || '\0' == path[0]){
|
if(!path || '\0' == path[0]){
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
FdEntity* ent;
|
||||||
|
{
|
||||||
AutoLock auto_lock(&FdManager::fd_manager_lock);
|
AutoLock auto_lock(&FdManager::fd_manager_lock);
|
||||||
|
|
||||||
// search in mapping by key(path)
|
// search in mapping by key(path)
|
||||||
@ -2045,7 +2054,6 @@ FdEntity* FdManager::Open(const char* path, headers_t* pmeta, ssize_t size, time
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FdEntity* ent;
|
|
||||||
if(fent.end() != iter){
|
if(fent.end() != iter){
|
||||||
// found
|
// found
|
||||||
ent = (*iter).second;
|
ent = (*iter).second;
|
||||||
@ -2078,6 +2086,7 @@ FdEntity* FdManager::Open(const char* path, headers_t* pmeta, ssize_t size, time
|
|||||||
}else{
|
}else{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// open
|
// open
|
||||||
if(0 != ent->Open(pmeta, size, time, no_fd_lock_wait)){
|
if(0 != ent->Open(pmeta, size, time, no_fd_lock_wait)){
|
||||||
|
@ -146,7 +146,7 @@ class FdEntity
|
|||||||
bool IsOpen(void) const { return (-1 != fd); }
|
bool IsOpen(void) const { return (-1 != fd); }
|
||||||
int Open(headers_t* pmeta = NULL, ssize_t size = -1, time_t time = -1, bool no_fd_lock_wait = false);
|
int Open(headers_t* pmeta = NULL, ssize_t size = -1, time_t time = -1, bool no_fd_lock_wait = false);
|
||||||
bool OpenAndLoadAll(headers_t* pmeta = NULL, size_t* size = NULL, bool force_load = false);
|
bool OpenAndLoadAll(headers_t* pmeta = NULL, size_t* size = NULL, bool force_load = false);
|
||||||
int Dup(bool no_fd_lock_wait = false);
|
int Dup();
|
||||||
|
|
||||||
const char* GetPath(void) const { return path.c_str(); }
|
const char* GetPath(void) const { return path.c_str(); }
|
||||||
void SetPath(const std::string &newpath) { path = newpath; }
|
void SetPath(const std::string &newpath) { path = newpath; }
|
||||||
|
Loading…
x
Reference in New Issue
Block a user