mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2025-01-24 06:18:25 +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));
|
||||
|
||||
if(-1 != fd){
|
||||
AutoLock auto_lock(&fdent_lock, no_fd_lock_wait);
|
||||
if (!auto_lock.isLockAcquired()) {
|
||||
return -1;
|
||||
}
|
||||
AutoLock auto_lock(&fdent_lock);
|
||||
refcnt++;
|
||||
}
|
||||
return fd;
|
||||
@ -756,13 +753,23 @@ int FdEntity::OpenMirrorFile(void)
|
||||
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
|
||||
while(true){
|
||||
// make random(temp) file path
|
||||
// (do not care for threading, because allowed any value returned.)
|
||||
//
|
||||
char szfile[NAME_MAX + 1];
|
||||
unsigned int seed = static_cast<unsigned int>(time(NULL));
|
||||
sprintf(szfile, "%x.tmp", rand_r(&seed));
|
||||
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);
|
||||
return -errno;
|
||||
}
|
||||
++seed;
|
||||
}
|
||||
|
||||
// open mirror file
|
||||
@ -785,21 +793,20 @@ int FdEntity::OpenMirrorFile(void)
|
||||
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)
|
||||
{
|
||||
S3FS_PRN_DBG("[path=%s][fd=%d][size=%jd][time=%jd]", path.c_str(), fd, (intmax_t)size, (intmax_t)time);
|
||||
|
||||
if(-1 != fd){
|
||||
// already opened, needs to increment refcnt.
|
||||
if (fd != Dup(no_fd_lock_wait)) {
|
||||
AutoLock auto_lock(&fdent_lock, no_fd_lock_wait);
|
||||
if (!auto_lock.isLockAcquired()) {
|
||||
// had to wait for fd lock, return
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if(-1 != fd){
|
||||
// already opened, needs to increment refcnt.
|
||||
Dup();
|
||||
|
||||
// check only file size(do not need to save cfs and time.
|
||||
if(0 <= size && pagelist.Size() != static_cast<size_t>(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]){
|
||||
return NULL;
|
||||
}
|
||||
FdEntity* ent;
|
||||
{
|
||||
AutoLock auto_lock(&FdManager::fd_manager_lock);
|
||||
|
||||
// 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){
|
||||
// found
|
||||
ent = (*iter).second;
|
||||
@ -2078,6 +2086,7 @@ FdEntity* FdManager::Open(const char* path, headers_t* pmeta, ssize_t size, time
|
||||
}else{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// open
|
||||
if(0 != ent->Open(pmeta, size, time, no_fd_lock_wait)){
|
||||
|
@ -146,7 +146,7 @@ class FdEntity
|
||||
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);
|
||||
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(); }
|
||||
void SetPath(const std::string &newpath) { path = newpath; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user