mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-22 22:11:39 +02:00
filer: serialize inode index row updates in the filer
storeInodeIndex and removePathFromInodeIndex read-modify-write a shared KV row; concurrent writes on one inode (hard links share an inode) could overwrite each other and drop a path. Stripe-lock the row like the shell backfill already does.
This commit is contained in:
1 parent
44235b5def
commit
ff4b43e0f1
1 file changed
+17
@@ -5,6 +5,7 @@ import (
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"sort"
|
||||
"sync"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/glog"
|
||||
"github.com/seaweedfs/seaweedfs/weed/util"
|
||||
@@ -13,6 +14,14 @@ import (
|
||||
const inodeIndexKeyPrefix = "filer.inode.path."
|
||||
const InodeIndexInitialGeneration uint64 = 1
|
||||
|
||||
// inodeRowLocks serializes the read-modify-write of one inode's index row so
|
||||
// concurrent writers (hard links share an inode) cannot overwrite each other.
|
||||
var inodeRowLocks [256]sync.Mutex
|
||||
|
||||
func inodeRowLock(inode uint64) *sync.Mutex {
|
||||
return &inodeRowLocks[inode%uint64(len(inodeRowLocks))]
|
||||
}
|
||||
|
||||
type inodeIndexEntry struct {
|
||||
path util.FullPath
|
||||
inode uint64
|
||||
@@ -190,6 +199,10 @@ func (fsw *FilerStoreWrapper) storeInodeIndex(ctx context.Context, path util.Ful
|
||||
return nil
|
||||
}
|
||||
|
||||
lock := inodeRowLock(inode)
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
record, err := fsw.lookupInodeIndex(ctx, inode)
|
||||
if err != nil {
|
||||
if err != ErrKvNotFound {
|
||||
@@ -237,6 +250,10 @@ func (fsw *FilerStoreWrapper) removePathFromInodeIndex(ctx context.Context, path
|
||||
return nil
|
||||
}
|
||||
|
||||
lock := inodeRowLock(inode)
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
record, err := fsw.lookupInodeIndex(ctx, inode)
|
||||
if err != nil {
|
||||
if err == ErrKvNotFound {
|
||||
|
||||
Reference in new issue
Block a user