mirror of
https://github.com/cubefs/cubefs.git
synced 2026-08-02 10:06:14 +00:00
fix(meta): empty file not check storage class. #22735527
Signed-off-by: Victor1319 <zengxuewei@oppo.com>
This commit is contained in:
parent
d1d8f1dfe1
commit
b00afa2e33
@ -149,6 +149,10 @@ func (i *Inode) setVerNoCheck(seq uint64) {
|
||||
i.verUpdate(seq)
|
||||
}
|
||||
|
||||
func (i *Inode) IsFile() bool {
|
||||
return proto.IsRegular(i.Type)
|
||||
}
|
||||
|
||||
func (i *Inode) setVer(seq uint64) {
|
||||
if i.getVer() > seq {
|
||||
syslog.Println(fmt.Sprintf("inode[%v] old seq [%v] cann't use seq [%v]", i.getVer(), seq, string(debug.Stack())))
|
||||
@ -778,7 +782,7 @@ func (i *Inode) MarshalInodeValue(buff *bytes.Buffer) {
|
||||
isFile := proto.IsRegular(i.Type)
|
||||
// to check flag
|
||||
|
||||
if !proto.IsValidStorageClass(i.StorageClass) && isFile {
|
||||
if !proto.IsValidStorageClass(i.StorageClass) && isFile && i.Size > 0 {
|
||||
panic(fmt.Sprintf("ino(%v) MarshalInodeValue failed, unsupport StorageClass %v", i.Inode, i.StorageClass))
|
||||
}
|
||||
|
||||
@ -1031,14 +1035,14 @@ func (i *Inode) UnmarshalInodeValue(buff *bytes.Buffer) (err error) {
|
||||
i.HybridCouldExtents = NewSortedHybridCloudExtents()
|
||||
}
|
||||
|
||||
isFile := proto.IsRegular(i.Type)
|
||||
isFile := i.IsFile()
|
||||
v3 := i.Reserved&V3EnableSnapInodeFlag > 0
|
||||
v4 := i.Reserved&V4EnableHybridCloud > 0
|
||||
|
||||
if i.Reserved == 0 {
|
||||
log.LogDebugf("#### [UnmarshalInodeValue] not v2 v3 V4, ino(%v), isFile %v", i.Inode, isFile)
|
||||
log.LogDebugf("#### [UnmarshalInodeValue] not v2 v3 V4, ino(%v), isFile %v, size %d", i.Inode, isFile, i.Size)
|
||||
i.StorageClass = legacyReplicaStorageClass
|
||||
if !isFile {
|
||||
if !isFile || i.Size == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
@ -1219,7 +1223,7 @@ func (i *Inode) UnmarshalInodeValue(buff *bytes.Buffer) (err error) {
|
||||
}
|
||||
|
||||
func (i *Inode) GetSpaceSize() (extSize uint64) {
|
||||
if i.IsTempFile() {
|
||||
if i.IsTempFile() || !i.IsFile() {
|
||||
return
|
||||
}
|
||||
if i.HybridCouldExtents.sortedEks == nil {
|
||||
|
||||
@ -3,6 +3,8 @@ package metanode
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"sync"
|
||||
"testing"
|
||||
@ -107,6 +109,8 @@ func TestV1InodeStoreInSSDToV4Inode_UnMarshal(t *testing.T) {
|
||||
FileOffset: 11, PartitionId: 12,
|
||||
ExtentId: 13, ExtentOffset: 0, Size: 0, CRC: 0,
|
||||
}})
|
||||
ino.Size = 10
|
||||
|
||||
var data []byte
|
||||
data, _ = ino.Marshal()
|
||||
targetIno := NewInode(0, 0)
|
||||
@ -221,6 +225,65 @@ func TestV4MigrationInodeCopyDirectly(t *testing.T) {
|
||||
assert.True(t, ino.Equal(temp))
|
||||
}
|
||||
|
||||
func TestCompitableWithOldVersion(t *testing.T) {
|
||||
// normal(dir, file, empty file), ebs(dir, file, empty file)
|
||||
legacyReplicaStorageClass = proto.MediaType_Unspecified
|
||||
checkInodeCompatibility := func(oldIno *OldVersionInode, t *testing.T) {
|
||||
newIno := NewInode(0, 0)
|
||||
data, err := oldIno.Marshal()
|
||||
require.NoError(t, err)
|
||||
|
||||
err = newIno.Unmarshal(data)
|
||||
require.NoError(t, err)
|
||||
require.True(t, oldIno.EqualNew(newIno))
|
||||
|
||||
data, err = newIno.Marshal()
|
||||
require.NoError(t, err)
|
||||
|
||||
oldIno2 := NewOldVersionInode(0, 0)
|
||||
err = oldIno2.Unmarshal(data)
|
||||
require.NoError(t, err)
|
||||
require.True(t, oldIno2.EqualNew(newIno))
|
||||
}
|
||||
|
||||
oldIno := NewOldVersionInode(1024, uint32(os.ModeDir))
|
||||
oldIno.Uid = 101
|
||||
oldIno.Gid = 102
|
||||
oldIno.Generation = 104
|
||||
oldIno.CreateTime = 105
|
||||
oldIno.AccessTime = 106
|
||||
oldIno.ModifyTime = 107
|
||||
oldIno.LinkTarget = []byte("test op")
|
||||
oldIno.NLink = 108
|
||||
oldIno.Flag = 109
|
||||
|
||||
// dir
|
||||
oldIno.Type = uint32(os.ModeDir)
|
||||
checkInodeCompatibility(oldIno, t)
|
||||
|
||||
// empty file
|
||||
oldIno.Type = 0
|
||||
checkInodeCompatibility(oldIno, t)
|
||||
|
||||
// old ebs file
|
||||
oldIno.ObjExtents = NewSortedObjExtentsFromObjEks([]proto.ObjExtentKey{{Size: uint64(100), FileOffset: uint64(100)}})
|
||||
oldIno.Size = 1024
|
||||
checkInodeCompatibility(oldIno, t)
|
||||
|
||||
// file
|
||||
oldIno.Extents = NewSortedExtentsFromEks([]proto.ExtentKey{{FileOffset: 100}})
|
||||
oldIno.ObjExtents = nil
|
||||
oldIno.Size = 1024
|
||||
data, err := oldIno.Marshal()
|
||||
require.NoError(t, err)
|
||||
newIno := NewInode(0, 0)
|
||||
err = newIno.Unmarshal(data)
|
||||
require.Error(t, err)
|
||||
|
||||
legacyReplicaStorageClass = proto.StorageClass_Replica_HDD
|
||||
checkInodeCompatibility(oldIno, t)
|
||||
}
|
||||
|
||||
func NewOldVersionInode(ino uint64, t uint32) *OldVersionInode {
|
||||
ts := timeutil.GetCurrentTimeUnix()
|
||||
i := &OldVersionInode{
|
||||
@ -258,6 +321,41 @@ type OldVersionInode struct {
|
||||
// Extents *ExtentsTree
|
||||
Extents *SortedExtents
|
||||
ObjExtents *SortedObjExtents
|
||||
multiSnap *InodeMultiSnap
|
||||
}
|
||||
|
||||
func (i *OldVersionInode) EqualNew(i1 *Inode) bool {
|
||||
if i.Inode != i1.Inode || i.Type != i1.Type || i.Uid != i1.Uid || i.Gid != i1.Gid || i.Size != i1.Size {
|
||||
return false
|
||||
}
|
||||
|
||||
if i.Generation != i1.Generation || i.CreateTime != i1.CreateTime || i.AccessTime != i1.AccessTime {
|
||||
return false
|
||||
}
|
||||
|
||||
if i.AccessTime != i1.AccessTime || i.ModifyTime != i1.ModifyTime || !bytes.Equal(i.LinkTarget, i1.LinkTarget) {
|
||||
return false
|
||||
}
|
||||
|
||||
if i.NLink != i1.NLink || i.Flag != i1.Flag {
|
||||
return false
|
||||
}
|
||||
|
||||
if i.Extents != nil && !i.Extents.IsEmpty() {
|
||||
ext := i1.HybridCouldExtents.sortedEks.(*SortedExtents)
|
||||
if !i.Extents.Equals(ext) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if i.ObjExtents != nil && !i.ObjExtents.IsEmpty() {
|
||||
ext := i1.HybridCouldExtents.sortedEks.(*SortedObjExtents)
|
||||
if !i.ObjExtents.Equals(ext) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (i *OldVersionInode) Marshal() (result []byte, err error) {
|
||||
@ -288,11 +386,12 @@ func (i *OldVersionInode) MarshalKey() (k []byte) {
|
||||
return
|
||||
}
|
||||
|
||||
func (i *OldVersionInode) MarshalValue() (val []byte) {
|
||||
var err error
|
||||
// MarshalValue marshals the value to bytes.
|
||||
func (i *OldVersionInode) MarshalValue() []byte {
|
||||
buff := bytes.NewBuffer(make([]byte, 0, 128))
|
||||
buff.Grow(64)
|
||||
i.RLock()
|
||||
|
||||
var err error
|
||||
if err = binary.Write(buff, binary.BigEndian, &i.Type); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
@ -332,25 +431,35 @@ func (i *OldVersionInode) MarshalValue() (val []byte) {
|
||||
if err = binary.Write(buff, binary.BigEndian, &i.Flag); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
i.Reserved = 0
|
||||
if i.ObjExtents != nil && len(i.ObjExtents.eks) > 0 {
|
||||
i.Reserved = V2EnableEbsFlag
|
||||
i.Reserved |= V2EnableEbsFlag
|
||||
}
|
||||
if i.multiSnap != nil {
|
||||
i.Reserved |= V3EnableSnapInodeFlag
|
||||
}
|
||||
|
||||
// log.LogInfof("action[MarshalInodeValue] inode[%v] Reserved %v", i.Inode, i.Reserved)
|
||||
if err = binary.Write(buff, binary.BigEndian, &i.Reserved); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if i.Reserved == V2EnableEbsFlag {
|
||||
// marshal ExtentsKey
|
||||
extData, err := i.Extents.MarshalBinary(false)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
// marshal ExtentsKey
|
||||
extData, err := i.Extents.MarshalBinary(i.Reserved&V3EnableSnapInodeFlag > 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if i.Reserved != 0 {
|
||||
if err = binary.Write(buff, binary.BigEndian, uint32(len(extData))); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if _, err = buff.Write(extData); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
if _, err = buff.Write(extData); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if i.Reserved&V2EnableEbsFlag > 0 {
|
||||
// marshal ObjExtentsKey
|
||||
objExtData, err := i.ObjExtents.MarshalBinary()
|
||||
if err != nil {
|
||||
@ -362,18 +471,164 @@ func (i *OldVersionInode) MarshalValue() (val []byte) {
|
||||
if _, err = buff.Write(objExtData); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
} else {
|
||||
// marshal ExtentsKey
|
||||
extData, err := i.Extents.MarshalBinary(false)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if _, err = buff.Write(extData); err != nil {
|
||||
}
|
||||
if i.multiSnap != nil {
|
||||
if err = binary.Write(buff, binary.BigEndian, i.multiSnap.verSeq); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
return buff.Bytes()
|
||||
}
|
||||
|
||||
func (i *OldVersionInode) Unmarshal(raw []byte) (err error) {
|
||||
var (
|
||||
keyLen uint32
|
||||
valLen uint32
|
||||
)
|
||||
buff := bytes.NewBuffer(raw)
|
||||
if err = binary.Read(buff, binary.BigEndian, &keyLen); err != nil {
|
||||
return
|
||||
}
|
||||
keyBytes := make([]byte, keyLen)
|
||||
if _, err = buff.Read(keyBytes); err != nil {
|
||||
return
|
||||
}
|
||||
if err = i.UnmarshalKey(keyBytes); err != nil {
|
||||
return
|
||||
}
|
||||
if err = binary.Read(buff, binary.BigEndian, &valLen); err != nil {
|
||||
return
|
||||
}
|
||||
valBytes := make([]byte, valLen)
|
||||
if _, err = buff.Read(valBytes); err != nil {
|
||||
return
|
||||
}
|
||||
err = i.UnmarshalValue(valBytes)
|
||||
return
|
||||
}
|
||||
|
||||
func (i *OldVersionInode) UnmarshalKey(k []byte) (err error) {
|
||||
i.Inode = binary.BigEndian.Uint64(k)
|
||||
return
|
||||
}
|
||||
|
||||
// UnmarshalValue unmarshals the value from bytes.
|
||||
func (i *OldVersionInode) UnmarshalValue(val []byte) (err error) {
|
||||
buff := bytes.NewBuffer(val)
|
||||
if err = binary.Read(buff, binary.BigEndian, &i.Type); err != nil {
|
||||
return
|
||||
}
|
||||
if err = binary.Read(buff, binary.BigEndian, &i.Uid); err != nil {
|
||||
return
|
||||
}
|
||||
if err = binary.Read(buff, binary.BigEndian, &i.Gid); err != nil {
|
||||
return
|
||||
}
|
||||
if err = binary.Read(buff, binary.BigEndian, &i.Size); err != nil {
|
||||
return
|
||||
}
|
||||
if err = binary.Read(buff, binary.BigEndian, &i.Generation); err != nil {
|
||||
return
|
||||
}
|
||||
if err = binary.Read(buff, binary.BigEndian, &i.CreateTime); err != nil {
|
||||
return
|
||||
}
|
||||
if err = binary.Read(buff, binary.BigEndian, &i.AccessTime); err != nil {
|
||||
return
|
||||
}
|
||||
if err = binary.Read(buff, binary.BigEndian, &i.ModifyTime); err != nil {
|
||||
return
|
||||
}
|
||||
// read symLink
|
||||
symSize := uint32(0)
|
||||
if err = binary.Read(buff, binary.BigEndian, &symSize); err != nil {
|
||||
return
|
||||
}
|
||||
if symSize > 0 {
|
||||
i.LinkTarget = make([]byte, symSize)
|
||||
if _, err = io.ReadFull(buff, i.LinkTarget); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err = binary.Read(buff, binary.BigEndian, &i.NLink); err != nil {
|
||||
return
|
||||
}
|
||||
if err = binary.Read(buff, binary.BigEndian, &i.Flag); err != nil {
|
||||
return
|
||||
}
|
||||
if err = binary.Read(buff, binary.BigEndian, &i.Reserved); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// unmarshal ExtentsKey
|
||||
if i.Extents == nil {
|
||||
i.Extents = NewSortedExtents()
|
||||
}
|
||||
if i.ObjExtents == nil {
|
||||
i.ObjExtents = NewSortedObjExtents()
|
||||
}
|
||||
|
||||
if i.Reserved == 0 {
|
||||
if err, _ = i.Extents.UnmarshalBinary(buff.Bytes(), false); err != nil {
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
v3 := i.Reserved&V3EnableSnapInodeFlag > 0
|
||||
v2 := i.Reserved&V2EnableEbsFlag > 0
|
||||
|
||||
extSize := uint32(0)
|
||||
if err = binary.Read(buff, binary.BigEndian, &extSize); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if extSize > 0 {
|
||||
extBytes := make([]byte, extSize)
|
||||
if _, err = io.ReadFull(buff, extBytes); err != nil {
|
||||
return
|
||||
}
|
||||
var ekRef *sync.Map
|
||||
if err, ekRef = i.Extents.UnmarshalBinary(extBytes, v3); err != nil {
|
||||
return
|
||||
}
|
||||
// log.LogDebugf("inode[%v] ekRef %v", i.Inode, ekRef)
|
||||
if ekRef != nil {
|
||||
if i.multiSnap == nil {
|
||||
i.multiSnap = NewMultiSnap(0)
|
||||
}
|
||||
// log.LogDebugf("inode[%v] ekRef %v", i.Inode, ekRef)
|
||||
i.multiSnap.ekRefMap = ekRef
|
||||
}
|
||||
}
|
||||
|
||||
if v2 {
|
||||
// unmarshal ObjExtentsKey
|
||||
ObjExtSize := uint32(0)
|
||||
if err = binary.Read(buff, binary.BigEndian, &ObjExtSize); err != nil {
|
||||
return
|
||||
}
|
||||
if ObjExtSize > 0 {
|
||||
objExtBytes := make([]byte, ObjExtSize)
|
||||
if _, err = io.ReadFull(buff, objExtBytes); err != nil {
|
||||
return
|
||||
}
|
||||
if err = i.ObjExtents.UnmarshalBinary(objExtBytes); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if v3 {
|
||||
var seq uint64
|
||||
if err = binary.Read(buff, binary.BigEndian, &seq); err != nil {
|
||||
return
|
||||
}
|
||||
if seq != 0 {
|
||||
// i.setVer(seq)
|
||||
}
|
||||
}
|
||||
|
||||
val = buff.Bytes()
|
||||
i.RUnlock()
|
||||
return
|
||||
}
|
||||
|
||||
@ -40,6 +40,7 @@ func (se *SortedObjExtents) String() string {
|
||||
func (se *SortedObjExtents) IsEmpty() bool {
|
||||
se.RLock()
|
||||
defer se.RUnlock()
|
||||
|
||||
return len(se.eks) == 0
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user