diff --git a/doc/man/s3fs.1 b/doc/man/s3fs.1 index f4a9c06..e727f39 100644 --- a/doc/man/s3fs.1 +++ b/doc/man/s3fs.1 @@ -10,6 +10,10 @@ S3FS \- FUSE-based file system backed by Amazon S3 .SS unmounting .TP \fBumount mountpoint +For root. +.TP +\fBfusermount -u mountpoint +For unprivileged user. .SS utility mode ( remove interrupted multipart uploading objects ) .TP \fBs3fs \-u bucket @@ -64,6 +68,10 @@ number of times to retry a failed S3 transaction. \fB\-o\fR use_cache (default="" which means disabled) local folder to use for local file cache. .TP +\fB\-o\fR check_cache_dir_exist (default is disable) +If use_cache is set, check if the cache directory exists. +If this option is not specified, it will be created at runtime when the cache directory does not exist. +.TP \fB\-o\fR del_cache - delete local file cache delete local file cache when s3fs starts and exits. .TP diff --git a/src/cache.cpp b/src/cache.cpp index 53557d0..53523de 100644 --- a/src/cache.cpp +++ b/src/cache.cpp @@ -505,7 +505,7 @@ bool StatCache::TruncateCache(void) if(IsExpireTime){ for(stat_cache_t::iterator iter = stat_cache.begin(); iter != stat_cache.end(); ){ stat_cache_entry* entry = iter->second; - if(!entry || (0L < entry->notruncate && IsExpireStatCacheTime(entry->cache_date, ExpireTime))){ + if(!entry || (0L == entry->notruncate && IsExpireStatCacheTime(entry->cache_date, ExpireTime))){ if(entry){ delete entry; } diff --git a/src/fdcache.cpp b/src/fdcache.cpp index 453599d..6e2f0c2 100644 --- a/src/fdcache.cpp +++ b/src/fdcache.cpp @@ -1711,6 +1711,7 @@ FdManager FdManager::singleton; pthread_mutex_t FdManager::fd_manager_lock; bool FdManager::is_lock_init(false); string FdManager::cache_dir(""); +bool FdManager::check_cache_dir_exist(false); size_t FdManager::free_disk_space = 0; //------------------------------------------------ @@ -1721,16 +1722,6 @@ bool FdManager::SetCacheDir(const char* dir) if(!dir || '\0' == dir[0]){ cache_dir = ""; }else{ - // check the directory - struct stat st; - if(0 != stat(dir, &st)){ - S3FS_PRN_ERR("could not access to cache directory(%s) by errno(%d).", cache_dir.c_str(), errno); - return false; - } - if(!S_ISDIR(st.st_mode)){ - S3FS_PRN_ERR("the cache directory(%s) is not directory.", cache_dir.c_str()); - return false; - } cache_dir = dir; } return true; @@ -1838,6 +1829,34 @@ bool FdManager::MakeRandomTempPath(const char* path, string& tmppath) return true; } +bool FdManager::SetCheckCacheDirExist(bool is_check) +{ + bool old = FdManager::check_cache_dir_exist; + FdManager::check_cache_dir_exist = is_check; + return old; +} + +bool FdManager::CheckCacheDirExist(void) +{ + if(!FdManager::check_cache_dir_exist){ + return true; + } + if(0 == FdManager::cache_dir.size()){ + return true; + } + // check the directory + struct stat st; + if(0 != stat(cache_dir.c_str(), &st)){ + S3FS_PRN_ERR("could not access to cache directory(%s) by errno(%d).", cache_dir.c_str(), errno); + return false; + } + if(!S_ISDIR(st.st_mode)){ + S3FS_PRN_ERR("the cache directory(%s) is not directory.", cache_dir.c_str()); + return false; + } + return true; +} + size_t FdManager::SetEnsureFreeDiskSpace(size_t size) { size_t old = FdManager::free_disk_space; @@ -1863,6 +1882,10 @@ fsblkcnt_t FdManager::GetFreeDiskSpace(const char* path) string ctoppath; if(0 < FdManager::cache_dir.size()){ ctoppath = FdManager::cache_dir + "/"; + ctoppath = get_exist_directory_path(ctoppath); // existed directory + if(ctoppath != "/"){ + ctoppath += "/"; + } }else{ ctoppath = TMPFILE_DIR_0PATH "/"; } diff --git a/src/fdcache.h b/src/fdcache.h index 2c5c9a3..d317f77 100644 --- a/src/fdcache.h +++ b/src/fdcache.h @@ -185,6 +185,7 @@ class FdManager static pthread_mutex_t fd_manager_lock; static bool is_lock_init; static std::string cache_dir; + static bool check_cache_dir_exist; static size_t free_disk_space; // limit free disk space fdent_map_t fent; @@ -207,6 +208,8 @@ class FdManager static bool MakeCachePath(const char* path, std::string& cache_path, bool is_create_dir = true, bool is_mirror_path = false); static bool CheckCacheTopDir(void); static bool MakeRandomTempPath(const char* path, std::string& tmppath); + static bool SetCheckCacheDirExist(bool is_check); + static bool CheckCacheDirExist(void); static size_t GetEnsureFreeDiskSpace(void) { return FdManager::free_disk_space; } static size_t SetEnsureFreeDiskSpace(size_t size); diff --git a/src/s3fs.cpp b/src/s3fs.cpp index 1a680c5..f9ec256 100644 --- a/src/s3fs.cpp +++ b/src/s3fs.cpp @@ -4351,10 +4351,11 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar return 0; } if(0 == STR2NCMP(arg, "use_cache=")){ - if(!FdManager::SetCacheDir(strchr(arg, '=') + sizeof(char))){ - S3FS_PRN_EXIT("cache directory(%s) is specified, but it does not exist or is not directory.", strchr(arg, '=') + sizeof(char)); - return -1; - } + FdManager::SetCacheDir(strchr(arg, '=') + sizeof(char)); + return 0; + } + if(0 == STR2NCMP(arg, "check_cache_dir_exist")){ + FdManager::SetCheckCacheDirExist(true); return 0; } if(0 == strcmp(arg, "del_cache")){ @@ -4922,7 +4923,7 @@ int main(int argc, char* argv[]) } // check cache dir permission - if(!FdManager::CheckCacheTopDir() || !CacheFileStat::CheckCacheFileStatTopDir()){ + if(!FdManager::CheckCacheDirExist() || !FdManager::CheckCacheTopDir() || !CacheFileStat::CheckCacheFileStatTopDir()){ S3FS_PRN_EXIT("could not allow cache directory permission, check permission of cache directories."); exit(EXIT_FAILURE); } diff --git a/src/s3fs_util.cpp b/src/s3fs_util.cpp index 2915861..e0f58bf 100644 --- a/src/s3fs_util.cpp +++ b/src/s3fs_util.cpp @@ -582,6 +582,28 @@ int mkdirp(const string& path, mode_t mode) return 0; } +// get existed directory path +string get_exist_directory_path(const string& path) +{ + string existed("/"); // "/" is existed. + string base; + string component; + stringstream ss(path); + while (getline(ss, component, '/')) { + if(base != "/"){ + base += "/"; + } + base += component; + struct stat st; + if(0 == stat(base.c_str(), &st) && S_ISDIR(st.st_mode)){ + existed = base; + }else{ + break; + } + } + return existed; +} + bool check_exist_dir_permission(const char* dirpath) { if(!dirpath || '\0' == dirpath[0]){ @@ -927,6 +949,11 @@ void show_help (void) " use_cache (default=\"\" which means disabled)\n" " - local folder to use for local file cache\n" "\n" + " check_cache_dir_exist (default is disable)\n" + " - if use_cache is set, check if the cache directory exists.\n" + " if this option is not specified, it will be created at runtime\n" + " when the cache directory does not exist.\n" + "\n" " del_cache (delete local file cache)\n" " - delete local file cache when s3fs starts and exits.\n" "\n" @@ -1019,6 +1046,7 @@ void show_help (void) "\n" " stat_cache_expire (default is no expire)\n" " - specify expire time(seconds) for entries in the stat cache.\n" + " This expire time indicates the time since stat cached.\n" "\n" " enable_noobj_cache (default is disable)\n" " - enable cache entries for the object which does not exist.\n" diff --git a/src/s3fs_util.h b/src/s3fs_util.h index f16e31a..e47ef62 100644 --- a/src/s3fs_util.h +++ b/src/s3fs_util.h @@ -111,6 +111,7 @@ std::string mydirname(std::string path); std::string mybasename(const char* path); std::string mybasename(std::string path); int mkdirp(const std::string& path, mode_t mode); +std::string get_exist_directory_path(const std::string& path); bool check_exist_dir_permission(const char* dirpath); bool delete_files_in_dir(const char* dir, bool is_remove_own);