mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-06-13 23:36:45 +03:00
storage: swap the volume data backend under the data lock
The tier-download swap closed v.DataBackend and assigned the new local DiskFile without holding dataFileAccessLock, racing concurrent reads/writes (use of a closed file / nil deref). Add an exported Volume.SwapDataBackend that performs the close-and-replace under the lock, and call it from the tier download.
This commit is contained in:
@@ -115,10 +115,9 @@ func swapToLocalDatBackend(v *storage.Volume, datFileName string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if v.DataBackend != nil {
|
||||
v.DataBackend.Close()
|
||||
}
|
||||
v.DataBackend = backend.NewDiskFile(dataFile)
|
||||
// Swap under the volume's data lock so concurrent reads never see a closed
|
||||
// or half-swapped backend.
|
||||
v.SwapDataBackend(backend.NewDiskFile(dataFile))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -310,6 +310,19 @@ func (v *Volume) Close() {
|
||||
v.doClose()
|
||||
}
|
||||
|
||||
// SwapDataBackend atomically replaces the data backend (e.g. swapping a
|
||||
// remote-tier backend for a freshly downloaded local .dat), closing the old
|
||||
// one. Held under dataFileAccessLock so a concurrent read/write never observes
|
||||
// a half-swapped or closed backend.
|
||||
func (v *Volume) SwapDataBackend(newBackend backend.BackendStorageFile) {
|
||||
v.dataFileAccessLock.Lock()
|
||||
defer v.dataFileAccessLock.Unlock()
|
||||
if v.DataBackend != nil {
|
||||
v.DataBackend.Close()
|
||||
}
|
||||
v.DataBackend = newBackend
|
||||
}
|
||||
|
||||
func (v *Volume) doClose() {
|
||||
if v.nm != nil {
|
||||
if err := v.nm.Sync(); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user