mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2024-01-19 02:48:24 +00:00
mount: add locking to prevent nil pointer
fix https://github.com/seaweedfs/seaweedfs/issues/3479
This commit is contained in:
parent
7807f6641a
commit
8bac903d29
|
@ -3,6 +3,7 @@ package page_writer
|
||||||
import (
|
import (
|
||||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
"github.com/seaweedfs/seaweedfs/weed/util"
|
||||||
"github.com/seaweedfs/seaweedfs/weed/util/mem"
|
"github.com/seaweedfs/seaweedfs/weed/util/mem"
|
||||||
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -13,6 +14,7 @@ var (
|
||||||
)
|
)
|
||||||
|
|
||||||
type MemChunk struct {
|
type MemChunk struct {
|
||||||
|
sync.RWMutex
|
||||||
buf []byte
|
buf []byte
|
||||||
usage *ChunkWrittenIntervalList
|
usage *ChunkWrittenIntervalList
|
||||||
chunkSize int64
|
chunkSize int64
|
||||||
|
@ -30,11 +32,17 @@ func NewMemChunk(logicChunkIndex LogicChunkIndex, chunkSize int64) *MemChunk {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *MemChunk) FreeResource() {
|
func (mc *MemChunk) FreeResource() {
|
||||||
|
mc.Lock()
|
||||||
|
defer mc.Unlock()
|
||||||
|
|
||||||
atomic.AddInt64(&memChunkCounter, -1)
|
atomic.AddInt64(&memChunkCounter, -1)
|
||||||
mem.Free(mc.buf)
|
mem.Free(mc.buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *MemChunk) WriteDataAt(src []byte, offset int64) (n int) {
|
func (mc *MemChunk) WriteDataAt(src []byte, offset int64) (n int) {
|
||||||
|
mc.Lock()
|
||||||
|
defer mc.Unlock()
|
||||||
|
|
||||||
innerOffset := offset % mc.chunkSize
|
innerOffset := offset % mc.chunkSize
|
||||||
n = copy(mc.buf[innerOffset:], src)
|
n = copy(mc.buf[innerOffset:], src)
|
||||||
mc.usage.MarkWritten(innerOffset, innerOffset+int64(n))
|
mc.usage.MarkWritten(innerOffset, innerOffset+int64(n))
|
||||||
|
@ -42,6 +50,9 @@ func (mc *MemChunk) WriteDataAt(src []byte, offset int64) (n int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *MemChunk) ReadDataAt(p []byte, off int64) (maxStop int64) {
|
func (mc *MemChunk) ReadDataAt(p []byte, off int64) (maxStop int64) {
|
||||||
|
mc.RLock()
|
||||||
|
defer mc.RUnlock()
|
||||||
|
|
||||||
memChunkBaseOffset := int64(mc.logicChunkIndex) * mc.chunkSize
|
memChunkBaseOffset := int64(mc.logicChunkIndex) * mc.chunkSize
|
||||||
for t := mc.usage.head.next; t != mc.usage.tail; t = t.next {
|
for t := mc.usage.head.next; t != mc.usage.tail; t = t.next {
|
||||||
logicStart := max(off, int64(mc.logicChunkIndex)*mc.chunkSize+t.StartOffset)
|
logicStart := max(off, int64(mc.logicChunkIndex)*mc.chunkSize+t.StartOffset)
|
||||||
|
@ -55,14 +66,23 @@ func (mc *MemChunk) ReadDataAt(p []byte, off int64) (maxStop int64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *MemChunk) IsComplete() bool {
|
func (mc *MemChunk) IsComplete() bool {
|
||||||
|
mc.RLock()
|
||||||
|
defer mc.RUnlock()
|
||||||
|
|
||||||
return mc.usage.IsComplete(mc.chunkSize)
|
return mc.usage.IsComplete(mc.chunkSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *MemChunk) WrittenSize() int64 {
|
func (mc *MemChunk) WrittenSize() int64 {
|
||||||
|
mc.RLock()
|
||||||
|
defer mc.RUnlock()
|
||||||
|
|
||||||
return mc.usage.WrittenSize()
|
return mc.usage.WrittenSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mc *MemChunk) SaveContent(saveFn SaveToStorageFunc) {
|
func (mc *MemChunk) SaveContent(saveFn SaveToStorageFunc) {
|
||||||
|
mc.RLock()
|
||||||
|
defer mc.RUnlock()
|
||||||
|
|
||||||
if saveFn == nil {
|
if saveFn == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ type SwapFile struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type SwapFileChunk struct {
|
type SwapFileChunk struct {
|
||||||
|
sync.RWMutex
|
||||||
swapfile *SwapFile
|
swapfile *SwapFile
|
||||||
usage *ChunkWrittenIntervalList
|
usage *ChunkWrittenIntervalList
|
||||||
logicChunkIndex LogicChunkIndex
|
logicChunkIndex LogicChunkIndex
|
||||||
|
@ -79,11 +80,17 @@ func (sc *SwapFileChunk) FreeResource() {
|
||||||
sc.swapfile.logicToActualChunkIndexLock.Lock()
|
sc.swapfile.logicToActualChunkIndexLock.Lock()
|
||||||
defer sc.swapfile.logicToActualChunkIndexLock.Unlock()
|
defer sc.swapfile.logicToActualChunkIndexLock.Unlock()
|
||||||
|
|
||||||
|
sc.Lock()
|
||||||
|
defer sc.Unlock()
|
||||||
|
|
||||||
sc.swapfile.freeActualChunkList = append(sc.swapfile.freeActualChunkList, sc.actualChunkIndex)
|
sc.swapfile.freeActualChunkList = append(sc.swapfile.freeActualChunkList, sc.actualChunkIndex)
|
||||||
delete(sc.swapfile.logicToActualChunkIndex, sc.logicChunkIndex)
|
delete(sc.swapfile.logicToActualChunkIndex, sc.logicChunkIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *SwapFileChunk) WriteDataAt(src []byte, offset int64) (n int) {
|
func (sc *SwapFileChunk) WriteDataAt(src []byte, offset int64) (n int) {
|
||||||
|
sc.Lock()
|
||||||
|
defer sc.Unlock()
|
||||||
|
|
||||||
innerOffset := offset % sc.swapfile.chunkSize
|
innerOffset := offset % sc.swapfile.chunkSize
|
||||||
var err error
|
var err error
|
||||||
n, err = sc.swapfile.file.WriteAt(src, int64(sc.actualChunkIndex)*sc.swapfile.chunkSize+innerOffset)
|
n, err = sc.swapfile.file.WriteAt(src, int64(sc.actualChunkIndex)*sc.swapfile.chunkSize+innerOffset)
|
||||||
|
@ -96,6 +103,9 @@ func (sc *SwapFileChunk) WriteDataAt(src []byte, offset int64) (n int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *SwapFileChunk) ReadDataAt(p []byte, off int64) (maxStop int64) {
|
func (sc *SwapFileChunk) ReadDataAt(p []byte, off int64) (maxStop int64) {
|
||||||
|
sc.RLock()
|
||||||
|
defer sc.RUnlock()
|
||||||
|
|
||||||
chunkStartOffset := int64(sc.logicChunkIndex) * sc.swapfile.chunkSize
|
chunkStartOffset := int64(sc.logicChunkIndex) * sc.swapfile.chunkSize
|
||||||
for t := sc.usage.head.next; t != sc.usage.tail; t = t.next {
|
for t := sc.usage.head.next; t != sc.usage.tail; t = t.next {
|
||||||
logicStart := max(off, chunkStartOffset+t.StartOffset)
|
logicStart := max(off, chunkStartOffset+t.StartOffset)
|
||||||
|
@ -113,10 +123,14 @@ func (sc *SwapFileChunk) ReadDataAt(p []byte, off int64) (maxStop int64) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *SwapFileChunk) IsComplete() bool {
|
func (sc *SwapFileChunk) IsComplete() bool {
|
||||||
|
sc.RLock()
|
||||||
|
defer sc.RUnlock()
|
||||||
return sc.usage.IsComplete(sc.swapfile.chunkSize)
|
return sc.usage.IsComplete(sc.swapfile.chunkSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sc *SwapFileChunk) WrittenSize() int64 {
|
func (sc *SwapFileChunk) WrittenSize() int64 {
|
||||||
|
sc.RLock()
|
||||||
|
defer sc.RUnlock()
|
||||||
return sc.usage.WrittenSize()
|
return sc.usage.WrittenSize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +138,9 @@ func (sc *SwapFileChunk) SaveContent(saveFn SaveToStorageFunc) {
|
||||||
if saveFn == nil {
|
if saveFn == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
sc.Lock()
|
||||||
|
defer sc.Unlock()
|
||||||
|
|
||||||
for t := sc.usage.head.next; t != sc.usage.tail; t = t.next {
|
for t := sc.usage.head.next; t != sc.usage.tail; t = t.next {
|
||||||
data := mem.Allocate(int(t.Size()))
|
data := mem.Allocate(int(t.Size()))
|
||||||
sc.swapfile.file.ReadAt(data, t.StartOffset+int64(sc.actualChunkIndex)*sc.swapfile.chunkSize)
|
sc.swapfile.file.ReadAt(data, t.StartOffset+int64(sc.actualChunkIndex)*sc.swapfile.chunkSize)
|
||||||
|
@ -132,5 +149,6 @@ func (sc *SwapFileChunk) SaveContent(saveFn SaveToStorageFunc) {
|
||||||
})
|
})
|
||||||
mem.Free(data)
|
mem.Free(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
sc.usage = newChunkWrittenIntervalList()
|
sc.usage = newChunkWrittenIntervalList()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue