Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explicitly handle CommonPrefixes with nocompat_dir #2212

Merged
merged 1 commit into from
Jul 13, 2023

Conversation

gaul
Copy link
Member

@gaul gaul commented Jul 12, 2023

Previously the test missed listing implicit directories and another test was incorrect. This fixes a regression from 1.91.

@gaul gaul requested a review from ggtakec July 12, 2023 13:42
@gaul
Copy link
Member Author

gaul commented Jul 12, 2023

@ggtakec this fixes a serious regression in the default behavior from 1.91. I think we can handle CommonPrefixes more elegantly/explicitly but this is a minimal fix.

@gaul gaul force-pushed the noncompat_dir/common-prefix branch from 4b5b98f to 026633a Compare July 12, 2023 13:46
@gaul gaul mentioned this pull request Jul 13, 2023
Copy link
Member

@ggtakec ggtakec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gaul Thanks for your fix!

Bit, it seems to be missing a place to set the path to filled yet.

With this current PR code, the ls command ends up listing the same file multiple times.

I've confirmed that adding the path to filled at every call to filler fixes this problem.

I made the code in this PR plus the following fixes and confirmed that fixed code works fine.
Could you check the following and fix it?

  • Added filled to Multi-Head request callback parameter
3067:  struct multi_head_callback_param
3067:  {
3067:      void*           buf;
3067:      fuse_fill_dir_t filler;
     +     std::set<std::string>* pfilled;
3067:  };
  • In Multi-Head request callback function
3091:      if(param){
3092:          struct multi_head_callback_param* pcbparam = reinterpret_cast<struct multi_head_callback_param*>(param);
3093:          struct stat st;
3094:          if(StatCache::getStatCacheData()->GetStat(saved_path, &st)){
3095:              pcbparam->filler(pcbparam->buf, bpath.c_str(), &st, 0);
3096:          }else{
3097:              S3FS_PRN_INFO2("Could not find %s file in stat cache.", saved_path.c_str());
3098:              pcbparam->filler(pcbparam->buf, bpath.c_str(), 0, 0);
3099:          }
     +         pcbparam->pfilled->insert(bpath);
3100:      }else{
3101:          S3FS_PRN_WARN("param(multi_head_callback_param*) is NULL, then can not call filler.");
3102:      }
  • Set filled pointer to Multi-Head callback parameter
3186:      struct multi_head_callback_param success_param;
3187:      success_param.buf    = buf;
3188:      success_param.filler = filler;
     +     success_param.pfilled = &filled;
3189:      curlmulti.SetSuccessCallbackParam(reinterpret_cast<void*>(&success_param));
  • The filled calling is leaking
3291:                  if(StatCache::getStatCacheData()->AddStat(dirpath, dummy_header, true)){    // set forcedir=true
3292:                      // Get stats from stats cache(for converting from meta), and fill
3293:                      std::string base_path = mybasename(dirpath);
3294:                      if(use_wtf8){
3295:                          base_path = s3fs_wtf8_decode(base_path);
3296:                      }
3297:  
3298:                      struct stat st;
3299:                      if(StatCache::getStatCacheData()->GetStat(dirpath, &st)){
3300:                          filler(buf, base_path.c_str(), &st, 0);
3301:                      }else{
3302:                          S3FS_PRN_INFO2("Could not find %s directory(no dir object) in stat cache.", dirpath.c_str());
3303:                          filler(buf, base_path.c_str(), 0, 0);
3304:                      }
     +                     filled.insert(base_path);
3305:                  }else{
3306:                      S3FS_PRN_ERR("failed adding stat cache [path=%s], but dontinue...", dirpath.c_str());
3307:                  }

Once this fix is done, I'll make a PR which is fixed possible the Thread data race soon.

Previously the test missed listing implicit directories and another
test was incorrect.  This fixes a regression from 1.91.
@gaul
Copy link
Member Author

gaul commented Jul 13, 2023

Bit, it seems to be missing a place to set the path to filled yet.

Done.

@gaul gaul force-pushed the noncompat_dir/common-prefix branch from 026633a to c405ad2 Compare July 13, 2023 11:55
Copy link
Member

@ggtakec ggtakec left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thnaks for fix.

@ggtakec ggtakec merged commit e650d8c into s3fs-fuse:master Jul 13, 2023
17 checks passed
@gaul gaul deleted the noncompat_dir/common-prefix branch July 13, 2023 12:36
@ggtakec
Copy link
Member

ggtakec commented Jul 13, 2023

@gaul
I started getting CI errors(failed test_not_existed_dir_obj test) when testing ALPINE(3.17).
It may not be directly related, but in the test_concurrent_directory_updates test before the test_not_existed_dir_obj test, I found the following log where s3proxy resulted in an Exception.
(Since the error is being re-executed, the log may have disappeared.)

[s3proxy] W 07-13 13:03:18.090 S3Proxy-Jetty-118 o.g.s.o.e.j.server.HttpChannel:776 |::] /s3fs-integration-test/testrun-23480/.fuse_hidden000000890000000a
java.lang.ArrayIndexOutOfBoundsException: arraycopy: length -6 is negative
	at java.base/java.lang.System.arraycopy(Native Method)
	at java.base/java.util.ArrayDeque.grow(ArrayDeque.java:154)
	at java.base/java.util.ArrayDeque.addFirst(ArrayDeque.java:290)
	at com.google.common.io.Closer.register(Closer.java:126)
	at org.jclouds.io.payloads.ByteSourcePayload.openStream(ByteSourcePayload.java:39)
	at org.jclouds.blobstore.config.LocalBlobStore.getBlob(LocalBlobStore.java:741)
	at org.jclouds.blobstore.config.LocalBlobStore.getBlob(LocalBlobStore.java:205)
	at org.jclouds.blobstore.config.LocalBlobStore.blobMetadata(LocalBlobStore.java:762)
	at jdk.internal.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at com.google.inject.internal.DelegatingInvocationHandler.invoke(DelegatingInvocationHandler.java:50)
	at jdk.proxy2/jdk.proxy2.$Proxy48.blobMetadata(Unknown Source)
	at org.gaul.s3proxy.S3ProxyHandler.handleBlobMetadata(S3ProxyHandler.java:1610)
	at org.gaul.s3proxy.S3ProxyHandler.doHandle(S3ProxyHandler.java:711)
	at org.gaul.s3proxy.S3ProxyHandlerJetty.handle(S3ProxyHandlerJetty.java:77)
	at org.gaul.shaded.org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127)
	at org.gaul.shaded.org.eclipse.jetty.server.Server.handle(Server.java:516)
	at org.gaul.shaded.org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487)
	at org.gaul.shaded.org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732)
	at org.gaul.shaded.org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479)
	at org.gaul.shaded.org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277)
	at org.gaul.shaded.org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
	at org.gaul.shaded.org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
	at org.gaul.shaded.org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:555)
	at org.gaul.shaded.org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:410)
	at org.gaul.shaded.org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:164)
	at org.gaul.shaded.org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105)
	at org.gaul.shaded.org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104)
	at org.gaul.shaded.org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338)
	at org.gaul.shaded.org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315)
	at org.gaul.shaded.org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173)
	at org.gaul.shaded.org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131)
	at org.gaul.shaded.org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409)
	at org.gaul.shaded.org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883)
	at org.gaul.shaded.org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034)
	at java.base/java.lang.Thread.run(Thread.java:833)

@gaul
Copy link
Member Author

gaul commented Jul 14, 2023

This symptom is gaul/s3proxy#303 which the next version will address.

@ggtakec
Copy link
Member

ggtakec commented Jul 14, 2023

@gaul Thanks, wait for next version.

@gaul gaul mentioned this pull request Feb 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants