s3: propagate storage rule fsync to volume server uploads (#10906)

The storage rule's fsync decision was computed by the filer
(detectStorageOption -> rule.Fsync) and applied on the filer's own HTTP
write path, but was never carried onto the chunk uploads S3 issues: the
AssignVolumeResponse had no fsync field, so the s3api client could not
learn the decision, and the chunked upload URL was hardcoded without it.
Every S3 write to a path with fsync configured went to the volume server
as a non-fsync write.

Carry the decision through the assign response:

- filer.proto: AssignVolumeResponse gains bool fsync, filled from the
  storage option the assign resolved.
- operation.AssignResult gains Fsync, so uploadChunk can append
  ?fsync=true to the volume server upload URL (single and replica
  fan-out paths).
- The S3 PUT/UploadPart assignFunc, the S3 copy path, the admin file
  browser upload, and the Iceberg worker assign functions all forward
  the response field.

Adds TestUploadReaderInChunksAppendsFsyncWhenAssigned.
This commit is contained in:
孙超
2026-08-23 22:11:08 -07:00
committed by GitHub
parent 71a8c77a36
commit c80664ec21
12 changed files with 121 additions and 17 deletions
+33
View File
@@ -2944,6 +2944,16 @@ func (m *AssignVolumeResponse) MarshalToSizedBufferVT(dAtA []byte) (int, error)
i -= len(m.unknownFields)
copy(dAtA[i:], m.unknownFields)
}
if m.Fsync {
i--
if m.Fsync {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i--
dAtA[i] = 0x58
}
if len(m.Replicas) > 0 {
for iNdEx := len(m.Replicas) - 1; iNdEx >= 0; iNdEx-- {
size, err := m.Replicas[iNdEx].MarshalToSizedBufferVT(dAtA[:i])
@@ -7424,6 +7434,9 @@ func (m *AssignVolumeResponse) SizeVT() (n int) {
n += 1 + l + protohelpers.SizeOfVarint(uint64(l))
}
}
if m.Fsync {
n += 2
}
n += len(m.unknownFields)
return n
}
@@ -17003,6 +17016,26 @@ func (m *AssignVolumeResponse) UnmarshalVT(dAtA []byte) error {
return err
}
iNdEx = postIndex
case 11:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Fsync", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return protohelpers.ErrIntOverflow
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
m.Fsync = bool(v != 0)
default:
iNdEx = preIndex
skippy, err := protohelpers.Skip(dAtA[iNdEx:])