diff --git a/weed/mount/filehandle.go b/weed/mount/filehandle.go index 3cd3d85f0..3b8aeb2bb 100644 --- a/weed/mount/filehandle.go +++ b/weed/mount/filehandle.go @@ -153,6 +153,12 @@ func (fh *FileHandle) AddChunks(chunks []*filer_pb.FileChunk) { } func (fh *FileHandle) ReleaseHandle() { + // Tear down FUSE passthrough first, outside the fhLockTable lock. + // teardownPassthrough is self-synchronized by passthroughMu and needs no + // other lock, so keeping it out of the fhLockTable critical section avoids + // any lock-order coupling between passthroughMu and fhLockTable. + fh.teardownPassthrough() + // Release distributed lock before cleaning up, so other mounts can // proceed as soon as this handle is done flushing. if fh.dlmLock != nil { @@ -165,7 +171,6 @@ func (fh *FileHandle) ReleaseHandle() { defer fh.wfs.fhLockTable.ReleaseLock(fh.fh, fhActiveLock) fh.dirtyPages.Destroy() - fh.teardownPassthrough() if IsDebugFileReadWrite { fh.mirrorFile.Close() } diff --git a/weed/mount/weedfs_passthrough_linux.go b/weed/mount/weedfs_passthrough_linux.go index f6f898af9..310142ac1 100644 --- a/weed/mount/weedfs_passthrough_linux.go +++ b/weed/mount/weedfs_passthrough_linux.go @@ -111,7 +111,10 @@ func (wfs *WFS) setupPassthroughBacking(fh *FileHandle, fileSize int64) (int32, // path the kernel Read handler uses, so the backing bytes are identical to what // a normal read would return. func materializeFile(fh *FileHandle, dst *os.File, fileSize int64) error { - buf := make([]byte, 1024*1024) + // Reuse the shared copy buffer pool (ChunkSizeLimit-sized) rather than + // allocating a fresh buffer per materialization. + buf := fh.wfs.copyBufferPool.Get().([]byte) + defer fh.wfs.copyBufferPool.Put(buf) for offset := int64(0); offset < fileSize; { // readDataByFileHandle reads chunks + dirty pages and maps EOF to nil. n, err := readDataByFileHandle(buf, fh, offset)