mirror of
https://github.com/s3fs-fuse/s3fs-fuse.git
synced 2025-01-09 16:06:46 +00:00
Added a class for automating fdentity reference counts
This commit is contained in:
parent
8205607716
commit
3958450c05
@ -46,6 +46,7 @@ s3fs_SOURCES = \
|
|||||||
fdcache_entity.cpp \
|
fdcache_entity.cpp \
|
||||||
fdcache_page.cpp \
|
fdcache_page.cpp \
|
||||||
fdcache_stat.cpp \
|
fdcache_stat.cpp \
|
||||||
|
fdcache_auto.cpp \
|
||||||
addhead.cpp \
|
addhead.cpp \
|
||||||
sighandlers.cpp \
|
sighandlers.cpp \
|
||||||
autolock.cpp \
|
autolock.cpp \
|
||||||
|
@ -378,6 +378,7 @@ FdManager::~FdManager()
|
|||||||
if(this == FdManager::get()){
|
if(this == FdManager::get()){
|
||||||
for(fdent_map_t::iterator iter = fent.begin(); fent.end() != iter; ++iter){
|
for(fdent_map_t::iterator iter = fent.begin(); fent.end() != iter; ++iter){
|
||||||
FdEntity* ent = (*iter).second;
|
FdEntity* ent = (*iter).second;
|
||||||
|
S3FS_PRN_WARN("To exit with the cache file opened: path=%s, refcnt=%d", ent->GetPath(), ent->GetRefCnt());
|
||||||
delete ent;
|
delete ent;
|
||||||
}
|
}
|
||||||
fent.clear();
|
fent.clear();
|
||||||
@ -403,7 +404,7 @@ FdManager::~FdManager()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FdEntity* FdManager::GetFdEntity(const char* path, int existfd)
|
FdEntity* FdManager::GetFdEntity(const char* path, int existfd, bool increase_ref)
|
||||||
{
|
{
|
||||||
S3FS_PRN_INFO3("[path=%s][fd=%d]", SAFESTRPTR(path), existfd);
|
S3FS_PRN_INFO3("[path=%s][fd=%d]", SAFESTRPTR(path), existfd);
|
||||||
|
|
||||||
@ -414,7 +415,9 @@ FdEntity* FdManager::GetFdEntity(const char* path, int existfd)
|
|||||||
|
|
||||||
fdent_map_t::iterator iter = fent.find(std::string(path));
|
fdent_map_t::iterator iter = fent.find(std::string(path));
|
||||||
if(fent.end() != iter && (-1 == existfd || (*iter).second->GetFd() == existfd)){
|
if(fent.end() != iter && (-1 == existfd || (*iter).second->GetFd() == existfd)){
|
||||||
iter->second->Dup();
|
if(increase_ref){
|
||||||
|
iter->second->Dup();
|
||||||
|
}
|
||||||
return (*iter).second;
|
return (*iter).second;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,7 +426,9 @@ FdEntity* FdManager::GetFdEntity(const char* path, int existfd)
|
|||||||
if((*iter).second && (*iter).second->GetFd() == existfd){
|
if((*iter).second && (*iter).second->GetFd() == existfd){
|
||||||
// found opened fd in map
|
// found opened fd in map
|
||||||
if(0 == strcmp((*iter).second->GetPath(), path)){
|
if(0 == strcmp((*iter).second->GetPath(), path)){
|
||||||
iter->second->Dup();
|
if(increase_ref){
|
||||||
|
iter->second->Dup();
|
||||||
|
}
|
||||||
return (*iter).second;
|
return (*iter).second;
|
||||||
}
|
}
|
||||||
// found fd, but it is used another file(file descriptor is recycled)
|
// found fd, but it is used another file(file descriptor is recycled)
|
||||||
|
@ -76,7 +76,7 @@ class FdManager
|
|||||||
static bool HaveLseekHole(void);
|
static bool HaveLseekHole(void);
|
||||||
|
|
||||||
// Return FdEntity associated with path, returning NULL on error. This operation increments the reference count; callers must decrement via Close after use.
|
// Return FdEntity associated with path, returning NULL on error. This operation increments the reference count; callers must decrement via Close after use.
|
||||||
FdEntity* GetFdEntity(const char* path, int existfd = -1);
|
FdEntity* GetFdEntity(const char* path, int existfd = -1, bool increase_ref = true);
|
||||||
FdEntity* Open(const char* path, headers_t* pmeta = NULL, off_t size = -1, time_t time = -1, bool force_tmpfile = false, bool is_create = true, bool no_fd_lock_wait = false);
|
FdEntity* Open(const char* path, headers_t* pmeta = NULL, off_t size = -1, time_t time = -1, bool force_tmpfile = false, bool is_create = true, bool no_fd_lock_wait = false);
|
||||||
FdEntity* ExistOpen(const char* path, int existfd = -1, bool ignore_existfd = false);
|
FdEntity* ExistOpen(const char* path, int existfd = -1, bool ignore_existfd = false);
|
||||||
void Rename(const std::string &from, const std::string &to);
|
void Rename(const std::string &from, const std::string &to);
|
||||||
|
144
src/fdcache_auto.cpp
Normal file
144
src/fdcache_auto.cpp
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* s3fs - FUSE-based file system backed by Amazon S3
|
||||||
|
*
|
||||||
|
* Copyright(C) 2007 Takeshi Nakatani <ggtakec.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "s3fs.h"
|
||||||
|
#include "fdcache_auto.h"
|
||||||
|
#include "fdcache.h"
|
||||||
|
|
||||||
|
//------------------------------------------------
|
||||||
|
// AutoFdEntity methods
|
||||||
|
//------------------------------------------------
|
||||||
|
AutoFdEntity::AutoFdEntity() : pFdEntity(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// [NOTE]
|
||||||
|
// The copy constructor should not be called, then this is private method.
|
||||||
|
// Even if it is called, the consistency of the number of
|
||||||
|
// references can be maintained, but this case is not assumed.
|
||||||
|
//
|
||||||
|
AutoFdEntity::AutoFdEntity(AutoFdEntity& other) : pFdEntity(NULL)
|
||||||
|
{
|
||||||
|
S3FS_PRN_WARN("This method should not be called. Please check the caller.");
|
||||||
|
|
||||||
|
if(other.pFdEntity){
|
||||||
|
other.pFdEntity->Dup();
|
||||||
|
pFdEntity = other.pFdEntity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoFdEntity::~AutoFdEntity()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AutoFdEntity::Close()
|
||||||
|
{
|
||||||
|
if(pFdEntity){
|
||||||
|
if(!FdManager::get()->Close(pFdEntity)){
|
||||||
|
S3FS_PRN_ERR("Failed to close fdentity.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pFdEntity = NULL;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [NOTE]
|
||||||
|
// This method touches the internal fdentity with.
|
||||||
|
// This is used to keep the file open.
|
||||||
|
//
|
||||||
|
bool AutoFdEntity::Detach()
|
||||||
|
{
|
||||||
|
if(!pFdEntity){
|
||||||
|
S3FS_PRN_ERR("Does not have a associated FdEntity.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pFdEntity = NULL;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [NOTE]
|
||||||
|
// This method calls the FdManager method without incrementing the
|
||||||
|
// reference count.
|
||||||
|
// This means that it will only be used to map to a file descriptor
|
||||||
|
// that was already open.
|
||||||
|
//
|
||||||
|
FdEntity* AutoFdEntity::GetFdEntity(const char* path, int existfd, bool increase_ref)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
|
||||||
|
if(NULL == (pFdEntity = FdManager::get()->GetFdEntity(path, existfd, increase_ref))){
|
||||||
|
S3FS_PRN_ERR("Could not find fd(file=%s, existfd=%d)", path, existfd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return pFdEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
FdEntity* AutoFdEntity::Open(const char* path, headers_t* pmeta, off_t size, time_t time, bool force_tmpfile, bool is_create, bool no_fd_lock_wait)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
|
||||||
|
if(NULL == (pFdEntity = FdManager::get()->Open(path, pmeta, size, time, force_tmpfile, is_create, no_fd_lock_wait))){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return pFdEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
FdEntity* AutoFdEntity::ExistOpen(const char* path, int existfd, bool ignore_existfd)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
|
||||||
|
if(NULL == (pFdEntity = FdManager::get()->ExistOpen(path, existfd, ignore_existfd))){
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return pFdEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
// [NOTE]
|
||||||
|
// This operator should not be called, then this is private method.
|
||||||
|
// Even if it is called, the consistency of the number of
|
||||||
|
// references can be maintained, but this case is not assumed.
|
||||||
|
//
|
||||||
|
bool AutoFdEntity::operator=(AutoFdEntity& other)
|
||||||
|
{
|
||||||
|
S3FS_PRN_WARN("This method should not be called. Please check the caller.");
|
||||||
|
|
||||||
|
Close();
|
||||||
|
|
||||||
|
if(other.pFdEntity){
|
||||||
|
other.pFdEntity->Dup();
|
||||||
|
pFdEntity = other.pFdEntity;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local variables:
|
||||||
|
* tab-width: 4
|
||||||
|
* c-basic-offset: 4
|
||||||
|
* End:
|
||||||
|
* vim600: expandtab sw=4 ts=4 fdm=marker
|
||||||
|
* vim<600: expandtab sw=4 ts=4
|
||||||
|
*/
|
63
src/fdcache_auto.h
Normal file
63
src/fdcache_auto.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* s3fs - FUSE-based file system backed by Amazon S3
|
||||||
|
*
|
||||||
|
* Copyright(C) 2007 Randy Rizun <rrizun@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef S3FS_FDCACHE_AUTO_H_
|
||||||
|
#define S3FS_FDCACHE_AUTO_H_
|
||||||
|
|
||||||
|
#include "fdcache_entity.h"
|
||||||
|
|
||||||
|
//------------------------------------------------
|
||||||
|
// class AutoFdEntity
|
||||||
|
//------------------------------------------------
|
||||||
|
// A class that opens fdentiry and closes it automatically.
|
||||||
|
// This class object is used to prevent inconsistencies in
|
||||||
|
// the number of references in fdentiry.
|
||||||
|
// The methods are wrappers to the method of the FdManager class.
|
||||||
|
//
|
||||||
|
class AutoFdEntity
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
FdEntity* pFdEntity;
|
||||||
|
|
||||||
|
private:
|
||||||
|
AutoFdEntity(AutoFdEntity& other);
|
||||||
|
bool operator=(AutoFdEntity& other);
|
||||||
|
|
||||||
|
public:
|
||||||
|
AutoFdEntity();
|
||||||
|
~AutoFdEntity();
|
||||||
|
|
||||||
|
bool Close(void);
|
||||||
|
bool Detach(void);
|
||||||
|
FdEntity* GetFdEntity(const char* path, int existfd = -1, bool increase_ref = true);
|
||||||
|
FdEntity* Open(const char* path, headers_t* pmeta = NULL, off_t size = -1, time_t time = -1, bool force_tmpfile = false, bool is_create = true, bool no_fd_lock_wait = false);
|
||||||
|
FdEntity* ExistOpen(const char* path, int existfd = -1, bool ignore_existfd = false);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // S3FS_FDCACHE_AUTO_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Local variables:
|
||||||
|
* tab-width: 4
|
||||||
|
* c-basic-offset: 4
|
||||||
|
* End:
|
||||||
|
* vim600: expandtab sw=4 ts=4 fdm=marker
|
||||||
|
* vim<600: expandtab sw=4 ts=4
|
||||||
|
*/
|
@ -75,6 +75,7 @@ class FdEntity
|
|||||||
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 = NULL, off_t size = -1, time_t time = -1, bool no_fd_lock_wait = false);
|
||||||
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(void) const { return refcnt; } // [NOTE] Use only debugging
|
||||||
|
|
||||||
const char* GetPath(void) const { return path.c_str(); }
|
const char* GetPath(void) const { return path.c_str(); }
|
||||||
bool RenamePath(const std::string& newpath, std::string& fentmapkey);
|
bool RenamePath(const std::string& newpath, std::string& fentmapkey);
|
||||||
|
313
src/s3fs.cpp
313
src/s3fs.cpp
@ -32,6 +32,7 @@
|
|||||||
#include "s3fs.h"
|
#include "s3fs.h"
|
||||||
#include "metaheader.h"
|
#include "metaheader.h"
|
||||||
#include "fdcache.h"
|
#include "fdcache.h"
|
||||||
|
#include "fdcache_auto.h"
|
||||||
#include "curl.h"
|
#include "curl.h"
|
||||||
#include "curl_multi.h"
|
#include "curl_multi.h"
|
||||||
#include "s3objlist.h"
|
#include "s3objlist.h"
|
||||||
@ -116,7 +117,7 @@ static int get_object_attribute(const char* path, struct stat* pstbuf, headers_t
|
|||||||
static int check_object_access(const char* path, int mask, struct stat* pstbuf);
|
static int check_object_access(const char* path, int mask, struct stat* pstbuf);
|
||||||
static int check_object_owner(const char* path, struct stat* pstbuf);
|
static int check_object_owner(const char* path, struct stat* pstbuf);
|
||||||
static int check_parent_object_access(const char* path, int mask);
|
static int check_parent_object_access(const char* path, int mask);
|
||||||
static FdEntity* get_local_fent(const char* path, bool is_load = false);
|
static FdEntity* get_local_fent(AutoFdEntity& autoent, const char* path, bool is_load = false);
|
||||||
static bool multi_head_callback(S3fsCurl* s3fscurl);
|
static bool multi_head_callback(S3fsCurl* s3fscurl);
|
||||||
static S3fsCurl* multi_head_retry_callback(S3fsCurl* s3fscurl);
|
static S3fsCurl* multi_head_retry_callback(S3fsCurl* s3fscurl);
|
||||||
static int readdir_multi_head(const char* path, const S3ObjList& head, void* buf, fuse_fill_dir_t filler);
|
static int readdir_multi_head(const char* path, const S3ObjList& head, void* buf, fuse_fill_dir_t filler);
|
||||||
@ -674,7 +675,7 @@ bool get_object_sse_type(const char* path, sse_type_t& ssetype, std::string& sse
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static FdEntity* get_local_fent(const char* path, bool is_load)
|
static FdEntity* get_local_fent(AutoFdEntity& autoent, const char* path, bool is_load)
|
||||||
{
|
{
|
||||||
struct stat stobj;
|
struct stat stobj;
|
||||||
FdEntity* ent;
|
FdEntity* ent;
|
||||||
@ -690,14 +691,14 @@ static FdEntity* get_local_fent(const char* path, bool is_load)
|
|||||||
time_t mtime = (!S_ISREG(stobj.st_mode) || S_ISLNK(stobj.st_mode)) ? -1 : stobj.st_mtime;
|
time_t mtime = (!S_ISREG(stobj.st_mode) || S_ISLNK(stobj.st_mode)) ? -1 : stobj.st_mtime;
|
||||||
bool force_tmpfile = S_ISREG(stobj.st_mode) ? false : true;
|
bool force_tmpfile = S_ISREG(stobj.st_mode) ? false : true;
|
||||||
|
|
||||||
if(NULL == (ent = FdManager::get()->Open(path, &meta, stobj.st_size, mtime, force_tmpfile, true))){
|
if(NULL == (ent = autoent.Open(path, &meta, stobj.st_size, mtime, force_tmpfile, true))){
|
||||||
S3FS_PRN_ERR("Could not open file. errno(%d)", errno);
|
S3FS_PRN_ERR("Could not open file. errno(%d)", errno);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
// load
|
// load
|
||||||
if(is_load && !ent->OpenAndLoadAll(&meta)){
|
if(is_load && !ent->OpenAndLoadAll(&meta)){
|
||||||
S3FS_PRN_ERR("Could not load file. errno(%d)", errno);
|
S3FS_PRN_ERR("Could not load file. errno(%d)", errno);
|
||||||
FdManager::get()->Close(ent);
|
autoent.Close();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return ent;
|
return ent;
|
||||||
@ -739,18 +740,18 @@ int put_headers(const char* path, headers_t& meta, bool is_copy)
|
|||||||
// if path is 'dir/', it does not have cache(could not open file for directory stat)
|
// if path is 'dir/', it does not have cache(could not open file for directory stat)
|
||||||
//
|
//
|
||||||
if('/' != path[strlen(path) - 1]){
|
if('/' != path[strlen(path) - 1]){
|
||||||
FdEntity* ent = NULL;
|
AutoFdEntity autoent;
|
||||||
if(NULL == (ent = FdManager::get()->ExistOpen(path, -1, !FdManager::IsCacheDir()))){
|
FdEntity* ent;
|
||||||
|
if(NULL == (ent = autoent.ExistOpen(path, -1, !FdManager::IsCacheDir()))){
|
||||||
// no opened fd
|
// no opened fd
|
||||||
if(FdManager::IsCacheDir()){
|
if(FdManager::IsCacheDir()){
|
||||||
// create cache file if be needed
|
// create cache file if be needed
|
||||||
ent = FdManager::get()->Open(path, &meta, buf.st_size, -1, false, true);
|
ent = autoent.Open(path, &meta, buf.st_size, -1, false, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ent){
|
if(ent){
|
||||||
time_t mtime = get_mtime(meta);
|
time_t mtime = get_mtime(meta);
|
||||||
ent->SetMtime(mtime);
|
ent->SetMtime(mtime);
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -773,14 +774,13 @@ static int s3fs_getattr(const char* _path, struct stat* stbuf)
|
|||||||
// If has already opened fd, the st_size should be instead.
|
// If has already opened fd, the st_size should be instead.
|
||||||
// (See: Issue 241)
|
// (See: Issue 241)
|
||||||
if(stbuf){
|
if(stbuf){
|
||||||
FdEntity* ent;
|
AutoFdEntity autoent;
|
||||||
|
FdEntity* ent;
|
||||||
if(NULL != (ent = FdManager::get()->ExistOpen(path))){
|
if(NULL != (ent = autoent.ExistOpen(path))){
|
||||||
struct stat tmpstbuf;
|
struct stat tmpstbuf;
|
||||||
if(ent->GetStats(tmpstbuf)){
|
if(ent->GetStats(tmpstbuf)){
|
||||||
stbuf->st_size = tmpstbuf.st_size;
|
stbuf->st_size = tmpstbuf.st_size;
|
||||||
}
|
}
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
}
|
}
|
||||||
stbuf->st_blksize = 4096;
|
stbuf->st_blksize = 4096;
|
||||||
stbuf->st_blocks = get_blocks(stbuf->st_size);
|
stbuf->st_blocks = get_blocks(stbuf->st_size);
|
||||||
@ -803,32 +803,30 @@ static int s3fs_readlink(const char* _path, char* buf, size_t size)
|
|||||||
// check symblic link cache
|
// check symblic link cache
|
||||||
if(!StatCache::getStatCacheData()->GetSymlink(std::string(path), strValue)){
|
if(!StatCache::getStatCacheData()->GetSymlink(std::string(path), strValue)){
|
||||||
// not found in cache, then open the path
|
// not found in cache, then open the path
|
||||||
FdEntity* ent;
|
{ // scope for AutoFdEntity
|
||||||
if(NULL == (ent = get_local_fent(path))){
|
AutoFdEntity autoent;
|
||||||
S3FS_PRN_ERR("could not get fent(file=%s)", path);
|
FdEntity* ent;
|
||||||
return -EIO;
|
if(NULL == (ent = get_local_fent(autoent, path))){
|
||||||
|
S3FS_PRN_ERR("could not get fent(file=%s)", path);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
// Get size
|
||||||
|
off_t readsize;
|
||||||
|
if(!ent->GetSize(readsize)){
|
||||||
|
S3FS_PRN_ERR("could not get file size(file=%s)", path);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
if(static_cast<off_t>(size) <= readsize){
|
||||||
|
readsize = size - 1;
|
||||||
|
}
|
||||||
|
// Read
|
||||||
|
ssize_t ressize;
|
||||||
|
if(0 > (ressize = ent->Read(buf, 0, readsize))){
|
||||||
|
S3FS_PRN_ERR("could not read file(file=%s, ressize=%zd)", path, ressize);
|
||||||
|
return static_cast<int>(ressize);
|
||||||
|
}
|
||||||
|
buf[ressize] = '\0';
|
||||||
}
|
}
|
||||||
// Get size
|
|
||||||
off_t readsize;
|
|
||||||
if(!ent->GetSize(readsize)){
|
|
||||||
S3FS_PRN_ERR("could not get file size(file=%s)", path);
|
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
if(static_cast<off_t>(size) <= readsize){
|
|
||||||
readsize = size - 1;
|
|
||||||
}
|
|
||||||
// Read
|
|
||||||
ssize_t ressize;
|
|
||||||
if(0 > (ressize = ent->Read(buf, 0, readsize))){
|
|
||||||
S3FS_PRN_ERR("could not read file(file=%s, ressize=%zd)", path, ressize);
|
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return static_cast<int>(ressize);
|
|
||||||
}
|
|
||||||
buf[ressize] = '\0';
|
|
||||||
|
|
||||||
// close
|
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
|
|
||||||
// check buf if it has space words.
|
// check buf if it has space words.
|
||||||
strValue = trim(std::string(buf));
|
strValue = trim(std::string(buf));
|
||||||
@ -971,14 +969,17 @@ static int s3fs_create(const char* _path, mode_t mode, struct fuse_file_info* fi
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FdEntity* ent;
|
AutoFdEntity autoent;
|
||||||
headers_t meta;
|
FdEntity* ent;
|
||||||
|
headers_t meta;
|
||||||
get_object_attribute(path, NULL, &meta, true, NULL, true); // no truncate cache
|
get_object_attribute(path, NULL, &meta, true, NULL, true); // no truncate cache
|
||||||
if(NULL == (ent = FdManager::get()->Open(path, &meta, 0, -1, false, true))){
|
if(NULL == (ent = autoent.Open(path, &meta, 0, -1, false, true))){
|
||||||
StatCache::getStatCacheData()->DelStat(path);
|
StatCache::getStatCacheData()->DelStat(path);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
autoent.Detach(); // KEEP fdentity open
|
||||||
fi->fh = ent->GetFd();
|
fi->fh = ent->GetFd();
|
||||||
|
|
||||||
S3FS_MALLOCTRIM(0);
|
S3FS_MALLOCTRIM(0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -1161,24 +1162,26 @@ static int s3fs_symlink(const char* _from, const char* _to)
|
|||||||
headers["x-amz-meta-gid"] = str(pcxt->gid);
|
headers["x-amz-meta-gid"] = str(pcxt->gid);
|
||||||
|
|
||||||
// open tmpfile
|
// open tmpfile
|
||||||
FdEntity* ent;
|
std::string strFrom;
|
||||||
if(NULL == (ent = FdManager::get()->Open(to, &headers, 0, -1, true, true))){
|
{ // scope for AutoFdEntity
|
||||||
S3FS_PRN_ERR("could not open tmpfile(errno=%d)", errno);
|
AutoFdEntity autoent;
|
||||||
return -errno;
|
FdEntity* ent;
|
||||||
|
if(NULL == (ent = autoent.Open(to, &headers, 0, -1, true, true))){
|
||||||
|
S3FS_PRN_ERR("could not open tmpfile(errno=%d)", errno);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
// write(without space words)
|
||||||
|
strFrom = trim(std::string(from));
|
||||||
|
ssize_t from_size = static_cast<ssize_t>(strFrom.length());
|
||||||
|
if(from_size != ent->Write(strFrom.c_str(), 0, from_size)){
|
||||||
|
S3FS_PRN_ERR("could not write tmpfile(errno=%d)", errno);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
// upload
|
||||||
|
if(0 != (result = ent->Flush(true))){
|
||||||
|
S3FS_PRN_WARN("could not upload tmpfile(result=%d)", result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// write(without space words)
|
|
||||||
std::string strFrom = trim(std::string(from));
|
|
||||||
ssize_t from_size = static_cast<ssize_t>(strFrom.length());
|
|
||||||
if(from_size != ent->Write(strFrom.c_str(), 0, from_size)){
|
|
||||||
S3FS_PRN_ERR("could not write tmpfile(errno=%d)", errno);
|
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
// upload
|
|
||||||
if(0 != (result = ent->Flush(true))){
|
|
||||||
S3FS_PRN_WARN("could not upload tmpfile(result=%d)", result);
|
|
||||||
}
|
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
|
|
||||||
StatCache::getStatCacheData()->DelStat(to);
|
StatCache::getStatCacheData()->DelStat(to);
|
||||||
if(!StatCache::getStatCacheData()->AddSymlink(std::string(to), strFrom)){
|
if(!StatCache::getStatCacheData()->AddSymlink(std::string(to), strFrom)){
|
||||||
@ -1245,28 +1248,28 @@ static int rename_object_nocopy(const char* from, const char* to)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// open & load
|
// open & load
|
||||||
FdEntity* ent;
|
{ // scope for AutoFdEntity
|
||||||
if(NULL == (ent = get_local_fent(from, true))){
|
AutoFdEntity autoent;
|
||||||
S3FS_PRN_ERR("could not open and read file(%s)", from);
|
FdEntity* ent;
|
||||||
return -EIO;
|
if(NULL == (ent = get_local_fent(autoent, from, true))){
|
||||||
}
|
S3FS_PRN_ERR("could not open and read file(%s)", from);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
// Set header
|
// Set header
|
||||||
if(!ent->SetContentType(to)){
|
if(!ent->SetContentType(to)){
|
||||||
S3FS_PRN_ERR("could not set content-type for %s", to);
|
S3FS_PRN_ERR("could not set content-type for %s", to);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload
|
// upload
|
||||||
if(0 != (result = ent->RowFlush(to, true))){
|
if(0 != (result = ent->RowFlush(to, true))){
|
||||||
S3FS_PRN_ERR("could not upload file(%s): result=%d", to, result);
|
S3FS_PRN_ERR("could not upload file(%s): result=%d", to, result);
|
||||||
FdManager::get()->Close(ent);
|
return result;
|
||||||
return result;
|
}
|
||||||
|
FdManager::get()->Rename(from, to);
|
||||||
}
|
}
|
||||||
|
|
||||||
FdManager::get()->Rename(from, to);
|
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
|
|
||||||
// Remove file
|
// Remove file
|
||||||
result = s3fs_unlink(from);
|
result = s3fs_unlink(from);
|
||||||
|
|
||||||
@ -1489,15 +1492,16 @@ static int s3fs_rename(const char* _from, const char* _to)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// flush pending writes if file is open
|
// flush pending writes if file is open
|
||||||
FdEntity *entity = FdManager::get()->ExistOpen(from);
|
{ // scope for AutoFdEntity
|
||||||
if(entity != NULL){
|
AutoFdEntity autoent;
|
||||||
if(0 != (result = entity->Flush(true))){
|
FdEntity* ent;
|
||||||
S3FS_PRN_ERR("could not upload file(%s): result=%d", to, result);
|
if(NULL != (ent = autoent.ExistOpen(from))){
|
||||||
return result;
|
if(0 != (result = ent->Flush(true))){
|
||||||
|
S3FS_PRN_ERR("could not upload file(%s): result=%d", to, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
StatCache::getStatCacheData()->DelStat(from);
|
||||||
}
|
}
|
||||||
StatCache::getStatCacheData()->DelStat(from);
|
|
||||||
FdManager::get()->Close(entity);
|
|
||||||
entity = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// files larger than 5GB must be modified via the multipart interface
|
// files larger than 5GB must be modified via the multipart interface
|
||||||
@ -1588,8 +1592,9 @@ static int s3fs_chmod(const char* _path, mode_t mode)
|
|||||||
// we need to put these header after finishing upload.
|
// we need to put these header after finishing upload.
|
||||||
// Or if the file is only open, we must update to FdEntity's internal meta.
|
// Or if the file is only open, we must update to FdEntity's internal meta.
|
||||||
//
|
//
|
||||||
FdEntity* ent;
|
AutoFdEntity autoent;
|
||||||
if(NULL != (ent = FdManager::get()->ExistOpen(path, -1, true))){
|
FdEntity* ent;
|
||||||
|
if(NULL != (ent = autoent.ExistOpen(path, -1, true))){
|
||||||
// the file is opened now.
|
// the file is opened now.
|
||||||
if(ent->MergeOrgMeta(updatemeta)){
|
if(ent->MergeOrgMeta(updatemeta)){
|
||||||
// now uploading
|
// now uploading
|
||||||
@ -1599,12 +1604,10 @@ static int s3fs_chmod(const char* _path, mode_t mode)
|
|||||||
// allow to put header
|
// allow to put header
|
||||||
// updatemeta already merged the orgmeta of the opened files.
|
// updatemeta already merged the orgmeta of the opened files.
|
||||||
if(0 != put_headers(strpath.c_str(), updatemeta, true)){
|
if(0 != put_headers(strpath.c_str(), updatemeta, true)){
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
StatCache::getStatCacheData()->DelStat(nowcache);
|
StatCache::getStatCacheData()->DelStat(nowcache);
|
||||||
}
|
}
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
}else{
|
}else{
|
||||||
// not opened file, then put headers
|
// not opened file, then put headers
|
||||||
merge_headers(meta, updatemeta, true);
|
merge_headers(meta, updatemeta, true);
|
||||||
@ -1672,8 +1675,9 @@ static int s3fs_chmod_nocopy(const char* _path, mode_t mode)
|
|||||||
// normal object or directory object of newer version
|
// normal object or directory object of newer version
|
||||||
|
|
||||||
// open & load
|
// open & load
|
||||||
FdEntity* ent;
|
AutoFdEntity autoent;
|
||||||
if(NULL == (ent = get_local_fent(strpath.c_str(), true))){
|
FdEntity* ent;
|
||||||
|
if(NULL == (ent = get_local_fent(autoent, strpath.c_str(), true))){
|
||||||
S3FS_PRN_ERR("could not open and read file(%s)", strpath.c_str());
|
S3FS_PRN_ERR("could not open and read file(%s)", strpath.c_str());
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@ -1686,11 +1690,8 @@ static int s3fs_chmod_nocopy(const char* _path, mode_t mode)
|
|||||||
// upload
|
// upload
|
||||||
if(0 != (result = ent->Flush(true))){
|
if(0 != (result = ent->Flush(true))){
|
||||||
S3FS_PRN_ERR("could not upload file(%s): result=%d", strpath.c_str(), result);
|
S3FS_PRN_ERR("could not upload file(%s): result=%d", strpath.c_str(), result);
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
|
|
||||||
StatCache::getStatCacheData()->DelStat(nowcache);
|
StatCache::getStatCacheData()->DelStat(nowcache);
|
||||||
}
|
}
|
||||||
S3FS_MALLOCTRIM(0);
|
S3FS_MALLOCTRIM(0);
|
||||||
@ -1767,8 +1768,9 @@ static int s3fs_chown(const char* _path, uid_t uid, gid_t gid)
|
|||||||
// we need to put these header after finishing upload.
|
// we need to put these header after finishing upload.
|
||||||
// Or if the file is only open, we must update to FdEntity's internal meta.
|
// Or if the file is only open, we must update to FdEntity's internal meta.
|
||||||
//
|
//
|
||||||
FdEntity* ent;
|
AutoFdEntity autoent;
|
||||||
if(NULL != (ent = FdManager::get()->ExistOpen(path, -1, true))){
|
FdEntity* ent;
|
||||||
|
if(NULL != (ent = autoent.ExistOpen(path, -1, true))){
|
||||||
// the file is opened now.
|
// the file is opened now.
|
||||||
if(ent->MergeOrgMeta(updatemeta)){
|
if(ent->MergeOrgMeta(updatemeta)){
|
||||||
// now uploading
|
// now uploading
|
||||||
@ -1778,12 +1780,10 @@ static int s3fs_chown(const char* _path, uid_t uid, gid_t gid)
|
|||||||
// allow to put header
|
// allow to put header
|
||||||
// updatemeta already merged the orgmeta of the opened files.
|
// updatemeta already merged the orgmeta of the opened files.
|
||||||
if(0 != put_headers(strpath.c_str(), updatemeta, true)){
|
if(0 != put_headers(strpath.c_str(), updatemeta, true)){
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
StatCache::getStatCacheData()->DelStat(nowcache);
|
StatCache::getStatCacheData()->DelStat(nowcache);
|
||||||
}
|
}
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
}else{
|
}else{
|
||||||
// not opened file, then put headers
|
// not opened file, then put headers
|
||||||
merge_headers(meta, updatemeta, true);
|
merge_headers(meta, updatemeta, true);
|
||||||
@ -1858,8 +1858,9 @@ static int s3fs_chown_nocopy(const char* _path, uid_t uid, gid_t gid)
|
|||||||
// normal object or directory object of newer version
|
// normal object or directory object of newer version
|
||||||
|
|
||||||
// open & load
|
// open & load
|
||||||
FdEntity* ent;
|
AutoFdEntity autoent;
|
||||||
if(NULL == (ent = get_local_fent(strpath.c_str(), true))){
|
FdEntity* ent;
|
||||||
|
if(NULL == (ent = get_local_fent(autoent, strpath.c_str(), true))){
|
||||||
S3FS_PRN_ERR("could not open and read file(%s)", strpath.c_str());
|
S3FS_PRN_ERR("could not open and read file(%s)", strpath.c_str());
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@ -1873,11 +1874,8 @@ static int s3fs_chown_nocopy(const char* _path, uid_t uid, gid_t gid)
|
|||||||
// upload
|
// upload
|
||||||
if(0 != (result = ent->Flush(true))){
|
if(0 != (result = ent->Flush(true))){
|
||||||
S3FS_PRN_ERR("could not upload file(%s): result=%d", strpath.c_str(), result);
|
S3FS_PRN_ERR("could not upload file(%s): result=%d", strpath.c_str(), result);
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
|
|
||||||
StatCache::getStatCacheData()->DelStat(nowcache);
|
StatCache::getStatCacheData()->DelStat(nowcache);
|
||||||
}
|
}
|
||||||
S3FS_MALLOCTRIM(0);
|
S3FS_MALLOCTRIM(0);
|
||||||
@ -1948,8 +1946,9 @@ static int s3fs_utimens(const char* _path, const struct timespec ts[2])
|
|||||||
// we need to put these header after finishing upload.
|
// we need to put these header after finishing upload.
|
||||||
// Or if the file is only open, we must update to FdEntity's internal meta.
|
// Or if the file is only open, we must update to FdEntity's internal meta.
|
||||||
//
|
//
|
||||||
FdEntity* ent;
|
AutoFdEntity autoent;
|
||||||
if(NULL != (ent = FdManager::get()->ExistOpen(path, -1, true))){
|
FdEntity* ent;
|
||||||
|
if(NULL != (ent = autoent.ExistOpen(path, -1, true))){
|
||||||
// the file is opened now.
|
// the file is opened now.
|
||||||
if(ent->MergeOrgMeta(updatemeta)){
|
if(ent->MergeOrgMeta(updatemeta)){
|
||||||
// now uploading
|
// now uploading
|
||||||
@ -1959,12 +1958,10 @@ static int s3fs_utimens(const char* _path, const struct timespec ts[2])
|
|||||||
// allow to put header
|
// allow to put header
|
||||||
// updatemeta already merged the orgmeta of the opened files.
|
// updatemeta already merged the orgmeta of the opened files.
|
||||||
if(0 != put_headers(strpath.c_str(), updatemeta, true)){
|
if(0 != put_headers(strpath.c_str(), updatemeta, true)){
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
StatCache::getStatCacheData()->DelStat(nowcache);
|
StatCache::getStatCacheData()->DelStat(nowcache);
|
||||||
}
|
}
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
}else{
|
}else{
|
||||||
// not opened file, then put headers
|
// not opened file, then put headers
|
||||||
merge_headers(meta, updatemeta, true);
|
merge_headers(meta, updatemeta, true);
|
||||||
@ -2034,8 +2031,9 @@ static int s3fs_utimens_nocopy(const char* _path, const struct timespec ts[2])
|
|||||||
// normal object or directory object of newer version
|
// normal object or directory object of newer version
|
||||||
|
|
||||||
// open & load
|
// open & load
|
||||||
FdEntity* ent;
|
AutoFdEntity autoent;
|
||||||
if(NULL == (ent = get_local_fent(strpath.c_str(), true))){
|
FdEntity* ent;
|
||||||
|
if(NULL == (ent = get_local_fent(autoent, strpath.c_str(), true))){
|
||||||
S3FS_PRN_ERR("could not open and read file(%s)", strpath.c_str());
|
S3FS_PRN_ERR("could not open and read file(%s)", strpath.c_str());
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@ -2043,18 +2041,14 @@ static int s3fs_utimens_nocopy(const char* _path, const struct timespec ts[2])
|
|||||||
// set mtime
|
// set mtime
|
||||||
if(0 != (result = ent->SetMtime(ts[1].tv_sec))){
|
if(0 != (result = ent->SetMtime(ts[1].tv_sec))){
|
||||||
S3FS_PRN_ERR("could not set mtime to file(%s): result=%d", strpath.c_str(), result);
|
S3FS_PRN_ERR("could not set mtime to file(%s): result=%d", strpath.c_str(), result);
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// upload
|
// upload
|
||||||
if(0 != (result = ent->Flush(true))){
|
if(0 != (result = ent->Flush(true))){
|
||||||
S3FS_PRN_ERR("could not upload file(%s): result=%d", strpath.c_str(), result);
|
S3FS_PRN_ERR("could not upload file(%s): result=%d", strpath.c_str(), result);
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
|
|
||||||
StatCache::getStatCacheData()->DelStat(nowcache);
|
StatCache::getStatCacheData()->DelStat(nowcache);
|
||||||
}
|
}
|
||||||
S3FS_MALLOCTRIM(0);
|
S3FS_MALLOCTRIM(0);
|
||||||
@ -2065,9 +2059,10 @@ static int s3fs_utimens_nocopy(const char* _path, const struct timespec ts[2])
|
|||||||
static int s3fs_truncate(const char* _path, off_t size)
|
static int s3fs_truncate(const char* _path, off_t size)
|
||||||
{
|
{
|
||||||
WTF8_ENCODE(path)
|
WTF8_ENCODE(path)
|
||||||
int result;
|
int result;
|
||||||
headers_t meta;
|
headers_t meta;
|
||||||
FdEntity* ent = NULL;
|
AutoFdEntity autoent;
|
||||||
|
FdEntity* ent = NULL;
|
||||||
|
|
||||||
S3FS_PRN_INFO("[path=%s][size=%lld]", path, static_cast<long long>(size));
|
S3FS_PRN_INFO("[path=%s][size=%lld]", path, static_cast<long long>(size));
|
||||||
|
|
||||||
@ -2085,13 +2080,12 @@ static int s3fs_truncate(const char* _path, off_t size)
|
|||||||
// Get file information
|
// Get file information
|
||||||
if(0 == (result = get_object_attribute(path, NULL, &meta))){
|
if(0 == (result = get_object_attribute(path, NULL, &meta))){
|
||||||
// Exists -> Get file(with size)
|
// Exists -> Get file(with size)
|
||||||
if(NULL == (ent = FdManager::get()->Open(path, &meta, size, -1, false, true))){
|
if(NULL == (ent = autoent.Open(path, &meta, size, -1, false, true))){
|
||||||
S3FS_PRN_ERR("could not open file(%s): errno=%d", path, errno);
|
S3FS_PRN_ERR("could not open file(%s): errno=%d", path, errno);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
if(0 != (result = ent->Load(0, size))){
|
if(0 != (result = ent->Load(0, size))){
|
||||||
S3FS_PRN_ERR("could not download file(%s): result=%d", path, result);
|
S3FS_PRN_ERR("could not download file(%s): result=%d", path, result);
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2110,7 +2104,7 @@ static int s3fs_truncate(const char* _path, off_t size)
|
|||||||
meta["x-amz-meta-uid"] = str(pcxt->uid);
|
meta["x-amz-meta-uid"] = str(pcxt->uid);
|
||||||
meta["x-amz-meta-gid"] = str(pcxt->gid);
|
meta["x-amz-meta-gid"] = str(pcxt->gid);
|
||||||
|
|
||||||
if(NULL == (ent = FdManager::get()->Open(path, &meta, size, -1, true, true))){
|
if(NULL == (ent = autoent.Open(path, &meta, size, -1, true, true))){
|
||||||
S3FS_PRN_ERR("could not open file(%s): errno=%d", path, errno);
|
S3FS_PRN_ERR("could not open file(%s): errno=%d", path, errno);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@ -2119,10 +2113,8 @@ static int s3fs_truncate(const char* _path, off_t size)
|
|||||||
// upload
|
// upload
|
||||||
if(0 != (result = ent->Flush(true))){
|
if(0 != (result = ent->Flush(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);
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
|
|
||||||
StatCache::getStatCacheData()->DelStat(path);
|
StatCache::getStatCacheData()->DelStat(path);
|
||||||
S3FS_MALLOCTRIM(0);
|
S3FS_MALLOCTRIM(0);
|
||||||
@ -2174,10 +2166,11 @@ static int s3fs_open(const char* _path, struct fuse_file_info* fi)
|
|||||||
st.st_mtime = -1;
|
st.st_mtime = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
FdEntity* ent;
|
AutoFdEntity autoent;
|
||||||
headers_t meta;
|
FdEntity* ent;
|
||||||
|
headers_t meta;
|
||||||
get_object_attribute(path, NULL, &meta, true, NULL, true); // no truncate cache
|
get_object_attribute(path, NULL, &meta, true, NULL, true); // no truncate cache
|
||||||
if(NULL == (ent = FdManager::get()->Open(path, &meta, st.st_size, st.st_mtime, false, true))){
|
if(NULL == (ent = autoent.Open(path, &meta, st.st_size, st.st_mtime, false, true))){
|
||||||
StatCache::getStatCacheData()->DelStat(path);
|
StatCache::getStatCacheData()->DelStat(path);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@ -2185,13 +2178,13 @@ static int s3fs_open(const char* _path, struct fuse_file_info* fi)
|
|||||||
if (needs_flush){
|
if (needs_flush){
|
||||||
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);
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
StatCache::getStatCacheData()->DelStat(path);
|
StatCache::getStatCacheData()->DelStat(path);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
autoent.Detach(); // KEEP fdentity open
|
||||||
fi->fh = ent->GetFd();
|
fi->fh = ent->GetFd();
|
||||||
|
|
||||||
S3FS_MALLOCTRIM(0);
|
S3FS_MALLOCTRIM(0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -2204,8 +2197,9 @@ static int s3fs_read(const char* _path, char* buf, size_t size, off_t offset, st
|
|||||||
|
|
||||||
S3FS_PRN_DBG("[path=%s][size=%zu][offset=%lld][fd=%llu]", path, size, static_cast<long long>(offset), (unsigned long long)(fi->fh));
|
S3FS_PRN_DBG("[path=%s][size=%zu][offset=%lld][fd=%llu]", path, size, static_cast<long long>(offset), (unsigned long long)(fi->fh));
|
||||||
|
|
||||||
FdEntity* ent;
|
AutoFdEntity autoent;
|
||||||
if(NULL == (ent = FdManager::get()->ExistOpen(path, static_cast<int>(fi->fh)))){
|
FdEntity* ent;
|
||||||
|
if(NULL == (ent = autoent.ExistOpen(path, static_cast<int>(fi->fh)))){
|
||||||
S3FS_PRN_ERR("could not find opened fd(%s)", path);
|
S3FS_PRN_ERR("could not find opened fd(%s)", path);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@ -2217,14 +2211,12 @@ static int s3fs_read(const char* _path, char* buf, size_t size, off_t offset, st
|
|||||||
off_t realsize = 0;
|
off_t realsize = 0;
|
||||||
if(!ent->GetSize(realsize) || 0 == realsize){
|
if(!ent->GetSize(realsize) || 0 == realsize){
|
||||||
S3FS_PRN_DBG("file size is 0, so break to read.");
|
S3FS_PRN_DBG("file size is 0, so break to read.");
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(0 > (res = ent->Read(buf, offset, size, false))){
|
if(0 > (res = ent->Read(buf, offset, size, false))){
|
||||||
S3FS_PRN_WARN("failed to read file(%s). result=%zd", path, res);
|
S3FS_PRN_WARN("failed to read file(%s). result=%zd", path, res);
|
||||||
}
|
}
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
|
|
||||||
return static_cast<int>(res);
|
return static_cast<int>(res);
|
||||||
}
|
}
|
||||||
@ -2236,8 +2228,9 @@ static int s3fs_write(const char* _path, const char* buf, size_t size, off_t off
|
|||||||
|
|
||||||
S3FS_PRN_DBG("[path=%s][size=%zu][offset=%lld][fd=%llu]", path, size, static_cast<long long int>(offset), (unsigned long long)(fi->fh));
|
S3FS_PRN_DBG("[path=%s][size=%zu][offset=%lld][fd=%llu]", path, size, static_cast<long long int>(offset), (unsigned long long)(fi->fh));
|
||||||
|
|
||||||
FdEntity* ent;
|
AutoFdEntity autoent;
|
||||||
if(NULL == (ent = FdManager::get()->ExistOpen(path, static_cast<int>(fi->fh)))){
|
FdEntity* ent;
|
||||||
|
if(NULL == (ent = autoent.ExistOpen(path, static_cast<int>(fi->fh)))){
|
||||||
S3FS_PRN_ERR("could not find opened fd(%s)", path);
|
S3FS_PRN_ERR("could not find opened fd(%s)", path);
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@ -2247,7 +2240,6 @@ static int s3fs_write(const char* _path, const char* buf, size_t size, off_t off
|
|||||||
if(0 > (res = ent->Write(buf, offset, size))){
|
if(0 > (res = ent->Write(buf, offset, size))){
|
||||||
S3FS_PRN_WARN("failed to write file(%s). result=%zd", path, res);
|
S3FS_PRN_WARN("failed to write file(%s). result=%zd", path, res);
|
||||||
}
|
}
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
|
|
||||||
return static_cast<int>(res);
|
return static_cast<int>(res);
|
||||||
}
|
}
|
||||||
@ -2284,11 +2276,11 @@ static int s3fs_flush(const char* _path, struct fuse_file_info* fi)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
FdEntity* ent;
|
AutoFdEntity autoent;
|
||||||
if(NULL != (ent = FdManager::get()->ExistOpen(path, static_cast<int>(fi->fh)))){
|
FdEntity* ent;
|
||||||
|
if(NULL != (ent = autoent.ExistOpen(path, static_cast<int>(fi->fh)))){
|
||||||
ent->UpdateMtime();
|
ent->UpdateMtime();
|
||||||
result = ent->Flush(false);
|
result = ent->Flush(false);
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
}
|
}
|
||||||
S3FS_MALLOCTRIM(0);
|
S3FS_MALLOCTRIM(0);
|
||||||
|
|
||||||
@ -2305,13 +2297,13 @@ static int s3fs_fsync(const char* _path, int datasync, struct fuse_file_info* fi
|
|||||||
|
|
||||||
S3FS_PRN_INFO("[path=%s][fd=%llu]", path, (unsigned long long)(fi->fh));
|
S3FS_PRN_INFO("[path=%s][fd=%llu]", path, (unsigned long long)(fi->fh));
|
||||||
|
|
||||||
FdEntity* ent;
|
AutoFdEntity autoent;
|
||||||
if(NULL != (ent = FdManager::get()->ExistOpen(path, static_cast<int>(fi->fh)))){
|
FdEntity* ent;
|
||||||
|
if(NULL != (ent = autoent.ExistOpen(path, static_cast<int>(fi->fh)))){
|
||||||
if(0 == datasync){
|
if(0 == datasync){
|
||||||
ent->UpdateMtime();
|
ent->UpdateMtime();
|
||||||
}
|
}
|
||||||
result = ent->Flush(false);
|
result = ent->Flush(false);
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
}
|
}
|
||||||
S3FS_MALLOCTRIM(0);
|
S3FS_MALLOCTRIM(0);
|
||||||
|
|
||||||
@ -2341,22 +2333,30 @@ static int s3fs_release(const char* _path, struct fuse_file_info* fi)
|
|||||||
StatCache::getStatCacheData()->DelStat(path);
|
StatCache::getStatCacheData()->DelStat(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
FdEntity* ent;
|
{ // scope for AutoFdEntity
|
||||||
if(NULL == (ent = FdManager::get()->GetFdEntity(path, static_cast<int>(fi->fh)))){
|
AutoFdEntity autoent;
|
||||||
S3FS_PRN_ERR("could not find fd(file=%s)", path);
|
FdEntity* ent;
|
||||||
return -EIO;
|
|
||||||
}
|
|
||||||
if(ent->GetFd() != static_cast<int>(fi->fh)){
|
|
||||||
S3FS_PRN_WARN("different fd(%d - %llu)", ent->GetFd(), (unsigned long long)(fi->fh));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Once for the implicit refcnt from GetFdEntity and again for release
|
// [NOTE]
|
||||||
ent->Close();
|
// The number of references to fdEntity corresponding to fi-> fh is already incremented
|
||||||
FdManager::get()->Close(ent);
|
// when it is opened. Therefore, when an existing fdEntity is detected here, the reference
|
||||||
|
// count must not be incremented. And if detected, the number of references incremented
|
||||||
|
// when opened will be decremented when the AutoFdEntity object is subsequently destroyed.
|
||||||
|
//
|
||||||
|
if(NULL == (ent = autoent.GetFdEntity(path, static_cast<int>(fi->fh), false))){
|
||||||
|
S3FS_PRN_ERR("could not find fd(file=%s)", path);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
if(ent->GetFd() != static_cast<int>(fi->fh)){
|
||||||
|
S3FS_PRN_WARN("different fd(%d - %llu)", ent->GetFd(), (unsigned long long)(fi->fh));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check - for debug
|
// check - for debug
|
||||||
if(IS_S3FS_LOG_DBG()){
|
if(IS_S3FS_LOG_DBG()){
|
||||||
if(NULL != (ent = FdManager::get()->GetFdEntity(path, static_cast<int>(fi->fh)))){
|
AutoFdEntity autoent;
|
||||||
|
FdEntity* ent;
|
||||||
|
if(NULL != (ent = autoent.GetFdEntity(path, static_cast<int>(fi->fh)))){
|
||||||
S3FS_PRN_WARN("file(%s),fd(%d) is still opened.", path, ent->GetFd());
|
S3FS_PRN_WARN("file(%s),fd(%d) is still opened.", path, ent->GetFd());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2899,8 +2899,9 @@ static int s3fs_setxattr(const char* path, const char* name, const char* value,
|
|||||||
// we need to put these header after finishing upload.
|
// we need to put these header after finishing upload.
|
||||||
// Or if the file is only open, we must update to FdEntity's internal meta.
|
// Or if the file is only open, we must update to FdEntity's internal meta.
|
||||||
//
|
//
|
||||||
FdEntity* ent;
|
AutoFdEntity autoent;
|
||||||
if(NULL != (ent = FdManager::get()->ExistOpen(path, -1, true))){
|
FdEntity* ent;
|
||||||
|
if(NULL != (ent = autoent.ExistOpen(path, -1, true))){
|
||||||
// the file is opened now.
|
// the file is opened now.
|
||||||
|
|
||||||
// get xattr and make new xattr
|
// get xattr and make new xattr
|
||||||
@ -2914,7 +2915,6 @@ static int s3fs_setxattr(const char* path, const char* name, const char* value,
|
|||||||
ent->SetXattr(strxattr);
|
ent->SetXattr(strxattr);
|
||||||
}
|
}
|
||||||
if(0 != (result = set_xattrs_to_header(updatemeta, name, value, size, flags))){
|
if(0 != (result = set_xattrs_to_header(updatemeta, name, value, size, flags))){
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2926,12 +2926,10 @@ static int s3fs_setxattr(const char* path, const char* name, const char* value,
|
|||||||
// allow to put header
|
// allow to put header
|
||||||
// updatemeta already merged the orgmeta of the opened files.
|
// updatemeta already merged the orgmeta of the opened files.
|
||||||
if(0 != put_headers(strpath.c_str(), updatemeta, true)){
|
if(0 != put_headers(strpath.c_str(), updatemeta, true)){
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
StatCache::getStatCacheData()->DelStat(nowcache);
|
StatCache::getStatCacheData()->DelStat(nowcache);
|
||||||
}
|
}
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
}else{
|
}else{
|
||||||
// not opened file, then put headers
|
// not opened file, then put headers
|
||||||
merge_headers(meta, updatemeta, true);
|
merge_headers(meta, updatemeta, true);
|
||||||
@ -3191,8 +3189,9 @@ static int s3fs_removexattr(const char* path, const char* name)
|
|||||||
// we need to put these header after finishing upload.
|
// we need to put these header after finishing upload.
|
||||||
// Or if the file is only open, we must update to FdEntity's internal meta.
|
// Or if the file is only open, we must update to FdEntity's internal meta.
|
||||||
//
|
//
|
||||||
FdEntity* ent;
|
AutoFdEntity autoent;
|
||||||
if(NULL != (ent = FdManager::get()->ExistOpen(path, -1, true))){
|
FdEntity* ent;
|
||||||
|
if(NULL != (ent = autoent.ExistOpen(path, -1, true))){
|
||||||
// the file is opened now.
|
// the file is opened now.
|
||||||
if(ent->MergeOrgMeta(updatemeta)){
|
if(ent->MergeOrgMeta(updatemeta)){
|
||||||
// now uploading
|
// now uploading
|
||||||
@ -3205,12 +3204,10 @@ static int s3fs_removexattr(const char* path, const char* name)
|
|||||||
updatemeta.erase("x-amz-meta-xattr");
|
updatemeta.erase("x-amz-meta-xattr");
|
||||||
}
|
}
|
||||||
if(0 != put_headers(strpath.c_str(), updatemeta, true)){
|
if(0 != put_headers(strpath.c_str(), updatemeta, true)){
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
StatCache::getStatCacheData()->DelStat(nowcache);
|
StatCache::getStatCacheData()->DelStat(nowcache);
|
||||||
}
|
}
|
||||||
FdManager::get()->Close(ent);
|
|
||||||
}else{
|
}else{
|
||||||
// not opened file, then put headers
|
// not opened file, then put headers
|
||||||
if(updatemeta["x-amz-meta-xattr"].empty()){
|
if(updatemeta["x-amz-meta-xattr"].empty()){
|
||||||
|
Loading…
Reference in New Issue
Block a user