From cfe061f448614d30f87ec67d72db6271386b272c Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Mon, 6 Jul 2026 21:00:16 -0700 Subject: [PATCH] s3: fail over bucket-config writes when the owner filer is unreachable patchBucketEntry dialed the bucket's ring owner directly, so a restarted filer's stale ring address hung every bucket-config write (versioning, lifecycle, object lock, ownership, ACL, policy, CORS) - the same failure as routed object writes. Route it through objectTxnOnFiler so it skips an unreachable owner and a live filer forwards by route_key. --- weed/s3api/s3api_bucket_config.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/weed/s3api/s3api_bucket_config.go b/weed/s3api/s3api_bucket_config.go index 3e8fe3706..6a8bdd09b 100644 --- a/weed/s3api/s3api_bucket_config.go +++ b/weed/s3api/s3api_bucket_config.go @@ -17,7 +17,6 @@ import ( "github.com/seaweedfs/seaweedfs/weed/glog" "github.com/seaweedfs/seaweedfs/weed/kms" - "github.com/seaweedfs/seaweedfs/weed/pb" "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb" "github.com/seaweedfs/seaweedfs/weed/pb/s3_pb" "github.com/seaweedfs/seaweedfs/weed/s3api/cors" @@ -587,8 +586,7 @@ func (s3a *S3ApiServer) patchBucketEntry(bucket string, m *filer_pb.ObjectMutati RouteKey: objectWriteRouteKeyPrefix + bucketPath, Mutations: []*filer_pb.ObjectMutation{m}, } - txn := func(client filer_pb.SeaweedFilerClient) error { - resp, err := client.ObjectTransaction(context.Background(), req) + respErr := func(resp *filer_pb.ObjectTransactionResponse, err error) error { if err != nil { return err } @@ -598,11 +596,13 @@ func (s3a *S3ApiServer) patchBucketEntry(bucket string, m *filer_pb.ObjectMutati return nil } if s3a.objectWriteLockClient != nil { - if owner := s3a.objectWriteLockClient.PrimaryForKey(objectWriteRouteKeyPrefix + bucketPath); owner != "" { - return pb.WithFilerClient(false, 0, owner, s3a.option.GrpcDialOption, txn) + if owner := s3a.objectWriteLockClient.PrimaryForKey(req.RouteKey); owner != "" { + return respErr(s3a.objectTxnOnFiler(owner, req)) } } - return s3a.WithFilerClient(false, txn) + return s3a.WithFilerClient(false, func(client filer_pb.SeaweedFilerClient) error { + return respErr(client.ObjectTransaction(context.Background(), req)) + }) } // isVersioningEnabled checks if versioning is enabled for a bucket (with caching)