reduce lock contention on file open

This commit is contained in:
Or Ozeri 2018-02-04 16:36:59 +02:00
parent e1dafe76dd
commit 0edf056e95
2 changed files with 66 additions and 57 deletions

View File

@ -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)){

View File

@ -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; }