diff options
| author | Chris Lu <chris.lu@gmail.com> | 2019-07-17 23:57:34 -0700 |
|---|---|---|
| committer | Chris Lu <chris.lu@gmail.com> | 2019-07-17 23:57:34 -0700 |
| commit | c54d9221b90676b499830f27064cc7ef8f6cfdfd (patch) | |
| tree | b654e5a30cc657d6060513111288c0cc3b118a49 | |
| parent | 898d943b25975e83dff81bb532243cee823a47af (diff) | |
| download | seaweedfs-c54d9221b90676b499830f27064cc7ef8f6cfdfd.tar.xz seaweedfs-c54d9221b90676b499830f27064cc7ef8f6cfdfd.zip | |
write requests also checks cookie if overwrites
protect against edge cases, avoid https://github.com/chrislusf/seaweedfs/issues/1014
| -rw-r--r-- | weed/storage/volume_read_write.go | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/weed/storage/volume_read_write.go b/weed/storage/volume_read_write.go index fbc818905..0327e5a1f 100644 --- a/weed/storage/volume_read_write.go +++ b/weed/storage/volume_read_write.go @@ -96,13 +96,29 @@ func (v *Volume) writeNeedle(n *needle.Needle) (offset uint64, size uint32, isUn n.Ttl = v.Ttl } + // check whether existing needle cookie matches + nv, ok := v.nm.Get(n.Id) + if ok { + existingNeedle, _, _, existingNeedleReadErr := needle.ReadNeedleHeader(v.dataFile, v.Version(), nv.Offset.ToAcutalOffset()) + if existingNeedleReadErr != nil { + err = fmt.Errorf("reading existing needle: %v", existingNeedleReadErr) + return + } + if existingNeedle.Cookie != n.Cookie { + glog.V(0).Infof("write cookie mismatch: existing %x, new %x", existingNeedle.Cookie, n.Cookie) + err = fmt.Errorf("mismatching cookie %x", n.Cookie) + return + } + } + + // append to dat file n.AppendAtNs = uint64(time.Now().UnixNano()) if offset, size, _, err = n.Append(v.dataFile, v.Version()); err != nil { return } v.lastAppendAtNs = n.AppendAtNs - nv, ok := v.nm.Get(n.Id) + // add to needle map if !ok || uint64(nv.Offset.ToAcutalOffset()) < offset { if err = v.nm.Put(n.Id, ToOffset(int64(offset)), n.Size); err != nil { glog.V(4).Infof("failed to save in needle map %d: %v", n.Id, err) |
