From 3ac39d61f84134bb4dbc60b203be154cf56eae1b Mon Sep 17 00:00:00 2001 From: Takeshi Nakatani Date: Fri, 5 May 2017 17:28:29 +0000 Subject: [PATCH] Added notsup_compat_dir option --- doc/man/s3fs.1 | 11 +++++++++++ src/s3fs.cpp | 29 +++++++++++++++++++++-------- src/s3fs_util.cpp | 18 ++++++++++++++++++ 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/doc/man/s3fs.1 b/doc/man/s3fs.1 index 2f06e57..afc6f4c 100644 --- a/doc/man/s3fs.1 +++ b/doc/man/s3fs.1 @@ -252,6 +252,17 @@ https://curl.haxx.se/docs/ssl-ciphers.html s3fs complements lack of information about file/directory mode if a file or a directory object does not have x-amz-meta-mode header. As default, s3fs does not complements stat information for a object, then the object will not be able to be allowed to list/modify. .TP +\fB\-o\fR notsup_compat_dir (not support compatibility directory types) +As a default, s3fs supports objects of the directory type as much as possible and recognizes them as directories. +Objects that can be recognized as directory objects are "dir/", "dir", "dir_$folder$", and there is a file object that does not have a directory object but contains that directory path. +s3fs needs redundant communication to support all these directory types. +The object as the directory created by s3fs is "dir/". +By restricting s3fs to recognize only "dir/" as a directory, communication traffic can be reduced. +This option is used to give this restriction to s3fs. +However, if there is a directory object other than "dir/" in the bucket, specifying this option is not recommended. +s3fs may not be able to recognize the object correctly if an object created by s3fs exists in the bucket. +Please use this option when the directory in the bucket is only "dir/" object. +.TP \fB\-o\fR dbglevel (default="crit") Set the debug message level. set value as crit(critical), err(error), warn(warning), info(information) to debug level. default debug level is critical. If s3fs run with "-d" option, the debug level is set information. diff --git a/src/s3fs.cpp b/src/s3fs.cpp index 822fe36..a4e047f 100644 --- a/src/s3fs.cpp +++ b/src/s3fs.cpp @@ -127,6 +127,7 @@ static bool create_bucket = false; static int64_t singlepart_copy_limit = FIVE_GB; static bool is_specified_endpoint = false; static int s3fs_init_deferred_exit_status = 0; +static bool support_compat_dir = true;// default supports compatibility directory type //------------------------------------------------------------------- // Static functions : prototype @@ -272,6 +273,12 @@ static s3fs_log_level bumpup_s3fs_log_level(void) static bool is_special_name_folder_object(const char* path) { + if(!support_compat_dir){ + // s3fs does not support compatibility directory type("_$folder$" etc) now, + // thus always returns false. + return false; + } + if(!path || '\0' == path[0]){ return false; } @@ -327,7 +334,7 @@ static int chk_dir_object_type(const char* path, string& newpath, string& nowpat if(0 == (result = get_object_attribute(newpath.c_str(), NULL, pmeta, false, &isforce))){ // Found "dir/" cache --> Check for "_$folder$", "no dir object" nowcache = newpath; - if(is_special_name_folder_object(newpath.c_str())){ + if(is_special_name_folder_object(newpath.c_str())){ // check support_compat_dir in this function // "_$folder$" type. (*pType) = DIRTYPE_FOLDER; nowpath = newpath.substr(0, newpath.length() - 1) + "_$folder$"; // cut and add @@ -345,8 +352,8 @@ static int chk_dir_object_type(const char* path, string& newpath, string& nowpat (*pType) = DIRTYPE_OLD; } } - }else{ - // Check "dir" + }else if(support_compat_dir){ + // Check "dir" when support_compat_dir is enabled nowpath = newpath.substr(0, newpath.length() - 1); if(0 == (result = get_object_attribute(nowpath.c_str(), NULL, pmeta, false, &isforce))){ // Found "dir" cache --> this case is only "dir" type. @@ -361,6 +368,7 @@ static int chk_dir_object_type(const char* path, string& newpath, string& nowpat } }else{ // Not found cache --> check for "_$folder$" and "no dir object". + // (come here is that support_compat_dir is enabled) nowcache = ""; // This case is no cache. nowpath += "_$folder$"; if(is_special_name_folder_object(nowpath.c_str())){ @@ -424,7 +432,7 @@ static int get_object_attribute(const char* path, struct stat* pstbuf, headers_t pisforce = (NULL != pisforce ? pisforce : &forcedir); (*pisforce) = false; strpath = path; - if(overcheck && string::npos != (Pos = strpath.find("_$folder$", 0))){ + if(support_compat_dir && overcheck && string::npos != (Pos = strpath.find("_$folder$", 0))){ strpath = strpath.substr(0, Pos); strpath += "/"; } @@ -445,13 +453,14 @@ static int get_object_attribute(const char* path, struct stat* pstbuf, headers_t // if not found target path object, do over checking if(0 != result){ if(overcheck){ - if('/' != strpath[strpath.length() - 1]){ + // when support_compat_dir is disabled, strpath maybe have "_$folder$". + if('/' != strpath[strpath.length() - 1] && string::npos == strpath.find("_$folder$", 0)){ // now path is "object", do check "object/" for over checking strpath += "/"; result = s3fscurl.HeadRequest(strpath.c_str(), (*pheader)); s3fscurl.DestroyCurlHandle(); } - if(0 != result){ + if(support_compat_dir && 0 != result){ // now path is "object/", do check "object_$folder$" for over checking strpath = strpath.substr(0, strpath.length() - 1); strpath += "_$folder$"; @@ -466,7 +475,7 @@ static int get_object_attribute(const char* path, struct stat* pstbuf, headers_t } } } - if(0 != result && string::npos == strpath.find("_$folder$", 0)){ + if(support_compat_dir && 0 != result && string::npos == strpath.find("_$folder$", 0)){ // now path is "object" or "object/", do check "no dir object" which is not object but has only children. if('/' == strpath[strpath.length() - 1]){ strpath = strpath.substr(0, strpath.length() - 1); @@ -479,7 +488,7 @@ static int get_object_attribute(const char* path, struct stat* pstbuf, headers_t } } }else{ - if('/' != strpath[strpath.length() - 1] && string::npos == strpath.find("_$folder$", 0) && is_need_check_obj_detail(*pheader)){ + if(support_compat_dir && '/' != strpath[strpath.length() - 1] && string::npos == strpath.find("_$folder$", 0) && is_need_check_obj_detail(*pheader)){ // check a case of that "object" does not have attribute and "object" is possible to be directory. if(-ENOTEMPTY == directory_empty(strpath.c_str())){ // found "no dir object". @@ -4666,6 +4675,10 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar complement_stat = true; return 0; } + if(0 == strcmp(arg, "notsup_compat_dir")){ + support_compat_dir = false; + return 0; + } if(0 == strcmp(arg, "enable_content_md5")){ S3fsCurl::SetContentMd5(true); return 0; diff --git a/src/s3fs_util.cpp b/src/s3fs_util.cpp index f1054e4..90d9f81 100644 --- a/src/s3fs_util.cpp +++ b/src/s3fs_util.cpp @@ -1221,6 +1221,24 @@ void show_help (void) " for a object, then the object will not be able to be allowed to\n" " list/modify.\n" "\n" + " notsup_compat_dir (not support compatibility directory types)\n" + " As a default, s3fs supports objects of the directory type as\n" + " much as possible and recognizes them as directories.\n" + " Objects that can be recognized as directory objects are \"dir/\",\n" + " \"dir\", \"dir_$folder$\", and there is a file object that does\n" + " not have a directory object but contains that directory path.\n" + " s3fs needs redundant communication to support all these\n" + " directory types. The object as the directory created by s3fs\n" + " is \"dir/\". By restricting s3fs to recognize only \"dir/\" as\n" + " a directory, communication traffic can be reduced. This option\n" + " is used to give this restriction to s3fs.\n" + " However, if there is a directory object other than \"dir/\" in\n" + " the bucket, specifying this option is not recommended. s3fs may\n" + " not be able to recognize the object correctly if an object\n" + " created by s3fs exists in the bucket.\n" + " Please use this option when the directory in the bucket is\n" + " only \"dir/\" object.\n" + "\n" "FUSE/mount Options:\n" "\n" " Most of the generic mount options described in 'man mount' are\n"