@@ -131,7 +131,6 @@ static int rename_object(const char* from, const char* to, bool update_ctime);
131
131
static int rename_object_nocopy (const char * from, const char * to, bool update_ctime);
132
132
static int clone_directory_object (const char * from, const char * to, bool update_ctime);
133
133
static int rename_directory (const char * from, const char * to);
134
- static int remote_mountpath_exists (const char * path);
135
134
static void free_xattrs (xattrs_t & xattrs);
136
135
static bool parse_xattr_keyval (const std::string& xattrpair, std::string& key, PXATTRVAL& pval);
137
136
static size_t parse_xattrs (const std::string& strxattrs, xattrs_t & xattrs);
@@ -396,26 +395,7 @@ static int get_object_attribute(const char* path, struct stat* pstbuf, headers_t
396
395
s3fscurl.DestroyCurlHandle ();
397
396
398
397
// if not found target path object, do over checking
399
- if (-EPERM == result){
400
- // [NOTE]
401
- // In case of a permission error, it exists in directory
402
- // file list but inaccessible. So there is a problem that
403
- // it will send a HEAD request every time, because it is
404
- // not registered in the Stats cache.
405
- // Therefore, even if the file has a permission error, it
406
- // should be registered in the Stats cache. However, if
407
- // the response without modifying is registered in the
408
- // cache, the file permission will be 0644(umask dependent)
409
- // because the meta header does not exist.
410
- // Thus, set the mode of 0000 here in the meta header so
411
- // that ossfs can print a permission error when the file
412
- // is actually accessed.
413
- // It is better not to set meta header other than mode,
414
- // so do not do it.
415
- //
416
- (*pheader)[" x-oss-meta-mode" ] = str (0 );
417
-
418
- }else if (0 != result){
398
+ if (0 != result){
419
399
if (overcheck){
420
400
// when support_compat_dir is disabled, strpath maybe have "_$folder$".
421
401
if (' /' != *strpath.rbegin () && std::string::npos == strpath.find (" _$folder$" , 0 )){
@@ -467,7 +447,7 @@ static int get_object_attribute(const char* path, struct stat* pstbuf, headers_t
467
447
// If the file is listed but not allowed access, put it in
468
448
// the positive cache instead of the negative cache.
469
449
//
470
- if (0 != result && -EPERM != result ){
450
+ if (0 != result){
471
451
// finally, "path" object did not find. Add no object cache.
472
452
strpath = path; // reset original
473
453
StatCache::getStatCacheData ()->AddNoObjectCache (strpath);
@@ -3031,24 +3011,6 @@ static int list_bucket(const char* path, S3ObjList& head, const char* delimiter,
3031
3011
return 0 ;
3032
3012
}
3033
3013
3034
- static int remote_mountpath_exists (const char * path)
3035
- {
3036
- struct stat stbuf;
3037
- int result;
3038
-
3039
- S3FS_PRN_INFO1 (" [path=%s]" , path);
3040
-
3041
- // getattr will prefix the path with the remote mountpoint
3042
- if (0 != (result = get_object_attribute (" /" , &stbuf, NULL ))){
3043
- return result;
3044
- }
3045
- if (!S_ISDIR (stbuf.st_mode )){
3046
- return -ENOTDIR;
3047
- }
3048
- return 0 ;
3049
- }
3050
-
3051
-
3052
3014
static void free_xattrs (xattrs_t & xattrs)
3053
3015
{
3054
3016
for (xattrs_t ::iterator iter = xattrs.begin (); iter != xattrs.end (); ++iter){
@@ -3777,7 +3739,7 @@ static int s3fs_check_service()
3777
3739
3778
3740
S3fsCurl s3fscurl;
3779
3741
int res;
3780
- if (0 > (res = s3fscurl.CheckBucket (" /" ))){
3742
+ if (0 > (res = s3fscurl.CheckBucket (get_realpath ( " /" ). c_str () ))){
3781
3743
// get response code
3782
3744
long responseCode = s3fscurl.GetLastResponseCode ();
3783
3745
@@ -3828,7 +3790,9 @@ static int s3fs_check_service()
3828
3790
} else {
3829
3791
s3host = " http://" + expecthost;
3830
3792
}
3831
- // extract region from host for sigv4
3793
+ // extract region from host for sigv4
3794
+ // The region of the government cloud/financial cloud may not be derived from the domain name
3795
+ // https://help.aliyun.com/zh/oss/user-guide/regions-and-endpoints?spm=a2c4g.11186623.0.0.13ad12c1N7PoaV
3832
3796
if (!strncasecmp (expecthost.c_str (), " oss-" , 4 )){
3833
3797
std::size_t found;
3834
3798
if ((found = expecthost.find_first_of (" ." )) != std::string::npos) {
@@ -3838,18 +3802,11 @@ static int s3fs_check_service()
3838
3802
}
3839
3803
// retry to check with new host
3840
3804
s3fscurl.DestroyCurlHandle ();
3841
- res = s3fscurl.CheckBucket (" /" );
3805
+ res = s3fscurl.CheckBucket (get_realpath ( " /" ). c_str () );
3842
3806
responseCode = s3fscurl.GetLastResponseCode ();
3843
3807
}
3844
3808
}
3845
3809
3846
- // retry to check with mount prefix
3847
- if (300 <= responseCode && responseCode < 500 && !mount_prefix.empty ()){
3848
- s3fscurl.DestroyCurlHandle ();
3849
- res = s3fscurl.CheckBucket (get_realpath (" /" ).c_str ());
3850
- responseCode = s3fscurl.GetLastResponseCode ();
3851
- }
3852
-
3853
3810
// try signature v2
3854
3811
/*
3855
3812
if(0 > res && (responseCode == 400 || responseCode == 403) && S3fsCurl::GetSignatureType() == V1_OR_V4){
@@ -3864,35 +3821,39 @@ static int s3fs_check_service()
3864
3821
}
3865
3822
*/
3866
3823
// check errors(after retrying)
3824
+ // [NOTE]
3825
+ // When mounting a bucket, an error code is returned and the mount fails.
3826
+ // However, when mounting a prefix, success should be returned if the prefix does not exist.
3827
+ //
3867
3828
if (0 > res && responseCode != 200 && responseCode != 301 ){
3868
3829
// parse error message if existed
3869
3830
std::string errMessage;
3870
3831
const std::string* body = s3fscurl.GetBodyData ();
3871
3832
check_error_message (body->c_str (), body->size (), errMessage);
3872
-
3833
+ bool is_failure = true ;
3873
3834
if (responseCode == 400 ){
3874
3835
S3FS_PRN_CRIT (" Failed to check bucket and directory for mount point : Bad Request(host=%s, message=%s)" , s3host.c_str (), errMessage.c_str ());
3875
3836
}else if (responseCode == 403 ){
3876
3837
S3FS_PRN_CRIT (" Failed to check bucket and directory for mount point : Invalid Credentials(host=%s, message=%s)" , s3host.c_str (), errMessage.c_str ());
3877
- }else if (responseCode == 404 ){
3878
- S3FS_PRN_CRIT (" Failed to check bucket and directory for mount point : Bucket or directory not found(host=%s, message=%s)" , s3host.c_str (), errMessage.c_str ());
3838
+ }else if (responseCode == 404 ) {
3839
+ std::string value;
3840
+ if (simple_parse_xml (body->c_str (), body->size (), " Code" , value)) {
3841
+ if (value == " NoSuchBucket" ) {
3842
+ S3FS_PRN_CRIT (" Failed to check bucket : Bucket not found(host=%s, message=%s)" , s3host.c_str (), errMessage.c_str ());
3843
+ } else {
3844
+ is_failure = false ;
3845
+ }
3846
+ }
3879
3847
}else {
3880
3848
S3FS_PRN_CRIT (" Failed to check bucket and directory for mount point : Unable to connect(host=%s, message=%s)" , s3host.c_str (), errMessage.c_str ());
3881
3849
}
3882
- return EXIT_FAILURE;
3883
- }
3884
- }
3885
- s3fscurl.DestroyCurlHandle ();
3886
-
3887
- // make sure remote mountpath exists and is a directory
3888
- if (!mount_prefix.empty ()){
3889
- if (remote_mountpath_exists (mount_prefix.c_str ()) != 0 ){
3890
- S3FS_PRN_CRIT (" remote mountpath %s not found." , mount_prefix.c_str ());
3891
- return EXIT_FAILURE;
3850
+ if (is_failure) {
3851
+ return EXIT_FAILURE;
3852
+ }
3892
3853
}
3893
3854
}
3894
3855
S3FS_MALLOCTRIM (0 );
3895
-
3856
+
3896
3857
return EXIT_SUCCESS;
3897
3858
}
3898
3859
@@ -4407,8 +4368,34 @@ static int my_fuse_opt_proc(void* data, const char* arg, int key, struct fuse_ar
4407
4368
max_dirty_data = size;
4408
4369
return 0 ;
4409
4370
}
4371
+ if (is_prefix (arg, " free_space_ratio=" )){
4372
+ int ratio = static_cast <int >(cvt_strtoofft (strchr (arg, ' =' ) + sizeof (char ), /* base=*/ 10 ));
4373
+ if (FdManager::GetEnsureFreeDiskSpace ()!=0 ){
4374
+ S3FS_PRN_EXIT (" option free_space_ratio conflicts with ensure_diskfree, please set only one of them." );
4375
+ return -1 ;
4376
+ }
4377
+ if (ratio < 0 || ratio > 100 ){
4378
+ S3FS_PRN_EXIT (" option free_space_ratio must between 0 to 100, which is: %d" , ratio);
4379
+ return -1 ;
4380
+ }
4381
+ off_t dfsize = FdManager::GetTotalDiskSpaceByRatio (ratio);
4382
+ S3FS_PRN_INFO (" Free space ratio set to %d %%, ensure the available disk space is greater than %.3f MB" , ratio, static_cast <double >(dfsize) / 1024 / 1024 );
4383
+ if (dfsize < S3fsCurl::GetMultipartSize ()){
4384
+ S3FS_PRN_WARN (" specified size to ensure disk free space is smaller than multipart size, so set multipart size to it." );
4385
+ dfsize = S3fsCurl::GetMultipartSize ();
4386
+ }
4387
+ FdManager::SetEnsureFreeDiskSpace (dfsize);
4388
+ return 0 ;
4389
+ }
4410
4390
if (is_prefix (arg, " ensure_diskfree=" )){
4411
4391
off_t dfsize = cvt_strtoofft (strchr (arg, ' =' ) + sizeof (char ), /* base=*/ 10 ) * 1024 * 1024 ;
4392
+
4393
+ if (FdManager::GetEnsureFreeDiskSpace ()!=0 ){
4394
+ S3FS_PRN_EXIT (" option free_space_ratio conflicts with ensure_diskfree, please set only one of them." );
4395
+ return -1 ;
4396
+ }
4397
+ S3FS_PRN_INFO (" Set and ensure the available disk space is greater than %.3f MB." , static_cast <double >(dfsize) / 1024 / 1024 );
4398
+
4412
4399
if (dfsize < S3fsCurl::GetMultipartSize ()){
4413
4400
S3FS_PRN_WARN (" specified size to ensure disk free space is smaller than multipart size, so set multipart size to it." );
4414
4401
dfsize = S3fsCurl::GetMultipartSize ();
@@ -5078,12 +5065,16 @@ int main(int argc, char* argv[])
5078
5065
5079
5066
// check free disk space
5080
5067
if (!FdManager::IsSafeDiskSpace (NULL , S3fsCurl::GetMultipartSize () * S3fsCurl::GetMaxParallelCount ())){
5081
- S3FS_PRN_EXIT (" There is no enough disk space for used as cache(or temporary) directory by s3fs." );
5082
- S3fsCurl::DestroyS3fsCurl ();
5083
- s3fs_destroy_global_ssl ();
5084
- destroy_parser_xml_lock ();
5085
- delete ps3fscred;
5086
- exit (EXIT_FAILURE);
5068
+ // clean cache dir and retry
5069
+ S3FS_PRN_WARN (" No enough disk space for ossfs, try to clean cache dir" );
5070
+ FdManager::get ()->CleanupCacheDir ();
5071
+ if (!FdManager::IsSafeDiskSpaceWithLog (nullptr , S3fsCurl::GetMultipartSize () * S3fsCurl::GetMaxParallelCount ())){
5072
+ S3fsCurl::DestroyS3fsCurl ();
5073
+ s3fs_destroy_global_ssl ();
5074
+ destroy_parser_xml_lock ();
5075
+ delete ps3fscred;
5076
+ exit (EXIT_FAILURE);
5077
+ }
5087
5078
}
5088
5079
5089
5080
// check readdir_optimize
@@ -5101,6 +5092,11 @@ int main(int argc, char* argv[])
5101
5092
S3FS_PRN_INFO (" Readdir optimize, flag(%d, %lld)" , is_refresh_fakemeta, static_cast <long long int >(readdir_check_size));
5102
5093
}
5103
5094
5095
+ // try to check s3fs service
5096
+ if (EXIT_SUCCESS != s3fs_check_service ()) {
5097
+ exit (EXIT_FAILURE);
5098
+ }
5099
+
5104
5100
s3fs_oper.getattr = s3fs_getattr;
5105
5101
s3fs_oper.readlink = s3fs_readlink;
5106
5102
s3fs_oper.mknod = s3fs_mknod;
0 commit comments