mirror of
https://github.com/cubefs/cubefs.git
synced 2026-08-02 02:00:56 +00:00
fix(shardnode): record Slice.ValidSize when alloc or seal
with #22357426 Signed-off-by: xiejian <xiejian3@oppo.com>
This commit is contained in:
parent
70f6955e1e
commit
76b2a6e6e3
@ -174,6 +174,7 @@ var errCodeMap = map[int]string{
|
||||
CodeNoEnoughRaftMember: "shardnode:no enough raft member",
|
||||
CodeIllegalUpdateUnit: "shardnode:illegal update suid",
|
||||
CodeItemIDEmpty: "shardnode:item ID is empty",
|
||||
CodeIllegalLocationSize: "shardnode:illegal location size",
|
||||
}
|
||||
|
||||
// HTTPError make rpc.HTTPError
|
||||
|
||||
@ -34,6 +34,7 @@ const (
|
||||
CodeNoEnoughRaftMember = 1017
|
||||
CodeIllegalUpdateUnit = 1018
|
||||
CodeItemIDEmpty = 1019
|
||||
CodeIllegalLocationSize = 1020
|
||||
)
|
||||
|
||||
// 10xx
|
||||
@ -57,4 +58,5 @@ var (
|
||||
ErrNoEnoughRaftMember = Error(CodeNoEnoughRaftMember)
|
||||
ErrIllegalUpdateUnit = Error(CodeIllegalUpdateUnit)
|
||||
ErrItemIDEmpty = Error(CodeItemIDEmpty)
|
||||
ErrIllegalLocationSize = Error(CodeIllegalLocationSize)
|
||||
)
|
||||
|
||||
@ -60,7 +60,6 @@ func (alc *allocator) AllocSlices(ctx context.Context, codeMode codemode.CodeMod
|
||||
|
||||
blobN := blobCount(fileSize, sliceSize)
|
||||
blobs := make([]proto.Slice, 0, blobN)
|
||||
var size uint64
|
||||
for _, bidRet := range allocRets {
|
||||
if blobN <= 0 {
|
||||
break
|
||||
@ -68,18 +67,12 @@ func (alc *allocator) AllocSlices(ctx context.Context, codeMode codemode.CodeMod
|
||||
|
||||
count := minU64(blobN, uint64(bidRet.BidEnd)-uint64(bidRet.BidStart)+1)
|
||||
blobN -= count
|
||||
validSize := uint64(sliceSize) * count
|
||||
if blobN <= 0 {
|
||||
validSize = fileSize - size
|
||||
}
|
||||
|
||||
blobs = append(blobs, proto.Slice{
|
||||
MinSliceID: bidRet.BidStart,
|
||||
Vid: bidRet.Vid,
|
||||
Count: uint32(count),
|
||||
ValidSize: validSize,
|
||||
})
|
||||
size += validSize
|
||||
}
|
||||
if blobN > 0 {
|
||||
return nil, errors.New("no enough blob ids from allocator")
|
||||
|
||||
@ -337,7 +337,35 @@ func (s *Space) SealBlob(ctx context.Context, req *shardnode.SealBlobArgs) error
|
||||
|
||||
b.Sealed = true
|
||||
b.Location.Size_ = req.GetSize_()
|
||||
b.Location.Slices = req.GetSlices()
|
||||
|
||||
sliceSize := b.Location.SliceSize
|
||||
remainSize := req.GetSize_()
|
||||
for i := range req.Slices {
|
||||
if i == len(req.Slices)-1 {
|
||||
if remainSize > uint64(req.Slices[i].Count*sliceSize) {
|
||||
return apierr.ErrIllegalLocationSize
|
||||
}
|
||||
req.Slices[i].ValidSize = remainSize
|
||||
break
|
||||
}
|
||||
// local validSize recorded
|
||||
if b.Location.Slices[i].ValidSize != 0 {
|
||||
validSize := b.Location.Slices[i].ValidSize
|
||||
if validSize >= remainSize {
|
||||
return apierr.ErrIllegalLocationSize
|
||||
}
|
||||
req.Slices[i].ValidSize = validSize
|
||||
remainSize -= validSize
|
||||
continue
|
||||
}
|
||||
validSize := uint64(req.Slices[i].Count * sliceSize)
|
||||
if validSize >= remainSize {
|
||||
return apierr.ErrIllegalLocationSize
|
||||
}
|
||||
req.Slices[i].ValidSize = validSize
|
||||
remainSize -= validSize
|
||||
}
|
||||
|
||||
if err = security.LocationCrcFill(&b.Location); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -425,6 +453,7 @@ func (s *Space) AllocSlice(ctx context.Context, req *shardnode.AllocSliceArgs) (
|
||||
var (
|
||||
idxes []uint32
|
||||
idx uint32
|
||||
validIdx uint32
|
||||
ok bool
|
||||
failedVid []proto.Vid
|
||||
)
|
||||
@ -456,10 +485,17 @@ func (s *Space) AllocSlice(ctx context.Context, req *shardnode.AllocSliceArgs) (
|
||||
localSlices[idx] = failedSlice
|
||||
localSlices = append(localSlices[:idx+1], append(slices, localSlices[idx+1:]...)...)
|
||||
}
|
||||
validIdx = idx
|
||||
} else {
|
||||
validIdx = uint32(len(localSlices))
|
||||
localSlices = append(localSlices, slices...)
|
||||
}
|
||||
|
||||
var i uint32
|
||||
for i = 0; i < validIdx; i++ {
|
||||
localSlices[i].ValidSize = uint64(sliceSize * localSlices[i].Count)
|
||||
}
|
||||
|
||||
b.Location.Slices = localSlices
|
||||
if err = security.LocationCrcFill(&b.Location); err != nil {
|
||||
return
|
||||
@ -574,7 +610,7 @@ func checkSlices(loc, req []proto.Slice, sliceSize uint32) ([]uint32, bool) {
|
||||
if _, ok := locMap[id]; !ok {
|
||||
return idxes, false
|
||||
}
|
||||
if req[i].Vid != locMap[id].Vid || req[i].Count > locMap[id].Count || req[i].ValidSize > locMap[id].ValidSize {
|
||||
if req[i].Vid != locMap[id].Vid || req[i].Count > locMap[id].Count {
|
||||
return idxes, false
|
||||
}
|
||||
idxes = append(idxes, locIndexMap[id])
|
||||
|
||||
@ -206,9 +206,9 @@ func TestSpace_AllocSlice(t *testing.T) {
|
||||
space.allocator = alc
|
||||
|
||||
locSlices := []proto.Slice{
|
||||
{Vid: 1, MinSliceID: 1, Count: 10, ValidSize: 100},
|
||||
{Vid: 1, MinSliceID: 2, Count: 20, ValidSize: 200},
|
||||
{Vid: 1, MinSliceID: 3, Count: 30, ValidSize: 300},
|
||||
{Vid: 1, MinSliceID: 1, Count: 10, ValidSize: 0},
|
||||
{Vid: 1, MinSliceID: 2, Count: 20, ValidSize: 0},
|
||||
{Vid: 1, MinSliceID: 3, Count: 30, ValidSize: 0},
|
||||
}
|
||||
name := []byte("blob")
|
||||
mode := codemode.EC6P6
|
||||
@ -240,7 +240,7 @@ func TestSpace_AllocSlice(t *testing.T) {
|
||||
require.Equal(t, newSlices, ret.Slices)
|
||||
|
||||
// illegal failedSlice
|
||||
args.FailedSlice = proto.Slice{Vid: 1, MinSliceID: 2, Count: 10, ValidSize: 300}
|
||||
args.FailedSlice = proto.Slice{Vid: 1, MinSliceID: 2, Count: 30, ValidSize: 300}
|
||||
_, err = space.AllocSlice(ctx, args)
|
||||
require.Equal(t, apierr.ErrIllegalSlices, err)
|
||||
|
||||
@ -282,8 +282,8 @@ func TestSpace_SealBlob(t *testing.T) {
|
||||
|
||||
locSlices := []proto.Slice{
|
||||
{Vid: 1, MinSliceID: 1, Count: 10, ValidSize: 100},
|
||||
{Vid: 1, MinSliceID: 2, Count: 20, ValidSize: 200},
|
||||
{Vid: 1, MinSliceID: 3, Count: 30, ValidSize: 300},
|
||||
{Vid: 1, MinSliceID: 2, Count: 20, ValidSize: 100},
|
||||
{Vid: 1, MinSliceID: 3, Count: 30, ValidSize: 0},
|
||||
}
|
||||
name := []byte("blob")
|
||||
mode := codemode.EC6P6
|
||||
@ -297,19 +297,36 @@ func TestSpace_SealBlob(t *testing.T) {
|
||||
}
|
||||
raw, err := b.Marshal()
|
||||
require.Nil(t, err)
|
||||
mockSpace.mockHandler.EXPECT().Get(A, A, A).Return(newMockValGetter(raw), nil).Times(2)
|
||||
mockSpace.mockHandler.EXPECT().Update(A, A, A).Return(nil).Times(1)
|
||||
mockSpace.mockHandler.EXPECT().Get(A, A, A).Return(newMockValGetter(raw), nil).Times(6)
|
||||
mockSpace.mockHandler.EXPECT().Update(A, A, A).Return(nil).Times(3)
|
||||
|
||||
args := &shardnode.SealBlobArgs{
|
||||
Header: shardnode.ShardOpHeader{},
|
||||
Name: name,
|
||||
Size_: 600,
|
||||
Size_: 300,
|
||||
Slices: locSlices,
|
||||
}
|
||||
err = space.SealBlob(ctx, args)
|
||||
require.Nil(t, err)
|
||||
|
||||
args.Slices[1].ValidSize = 300
|
||||
args.Size_ = 500
|
||||
err = space.SealBlob(ctx, args)
|
||||
require.Nil(t, err)
|
||||
|
||||
args.Size_ = 200
|
||||
err = space.SealBlob(ctx, args)
|
||||
require.Equal(t, apierr.ErrIllegalLocationSize, err)
|
||||
|
||||
args.Size_ = 700
|
||||
err = space.SealBlob(ctx, args)
|
||||
require.Equal(t, apierr.ErrIllegalLocationSize, err)
|
||||
|
||||
args.Size_ = 200
|
||||
args.Slices = args.Slices[:2]
|
||||
err = space.SealBlob(ctx, args)
|
||||
require.Equal(t, nil, err)
|
||||
|
||||
args.Slices[1].Count = 30
|
||||
err = space.SealBlob(ctx, args)
|
||||
require.Equal(t, apierr.ErrIllegalSlices, err)
|
||||
}
|
||||
@ -445,8 +462,8 @@ func TestCheckSlices(t *testing.T) {
|
||||
name: "valid slices",
|
||||
args: args{
|
||||
loc: []proto.Slice{
|
||||
{Vid: 1, MinSliceID: 1, Count: 10, ValidSize: 100},
|
||||
{Vid: 1, MinSliceID: 2, Count: 20, ValidSize: 200},
|
||||
{Vid: 1, MinSliceID: 1, Count: 10, ValidSize: 0},
|
||||
{Vid: 1, MinSliceID: 2, Count: 20, ValidSize: 0},
|
||||
},
|
||||
req: []proto.Slice{
|
||||
{Vid: 1, MinSliceID: 1, Count: 5, ValidSize: 50},
|
||||
@ -460,8 +477,8 @@ func TestCheckSlices(t *testing.T) {
|
||||
name: "invalid slices - missing MinSliceID",
|
||||
args: args{
|
||||
loc: []proto.Slice{
|
||||
{Vid: 1, MinSliceID: 1, Count: 10, ValidSize: 100},
|
||||
{Vid: 1, MinSliceID: 2, Count: 20, ValidSize: 200},
|
||||
{Vid: 1, MinSliceID: 1, Count: 10, ValidSize: 0},
|
||||
{Vid: 1, MinSliceID: 2, Count: 20, ValidSize: 0},
|
||||
},
|
||||
req: []proto.Slice{
|
||||
{Vid: 1, MinSliceID: 3, Count: 5, ValidSize: 50},
|
||||
@ -474,8 +491,8 @@ func TestCheckSlices(t *testing.T) {
|
||||
name: "invalid slices - count exceeds",
|
||||
args: args{
|
||||
loc: []proto.Slice{
|
||||
{Vid: 1, MinSliceID: 1, Count: 10, ValidSize: 100},
|
||||
{Vid: 1, MinSliceID: 2, Count: 20, ValidSize: 200},
|
||||
{Vid: 1, MinSliceID: 1, Count: 10, ValidSize: 0},
|
||||
{Vid: 1, MinSliceID: 2, Count: 20, ValidSize: 0},
|
||||
},
|
||||
req: []proto.Slice{
|
||||
{Vid: 1, MinSliceID: 1, Count: 15, ValidSize: 150},
|
||||
@ -488,8 +505,8 @@ func TestCheckSlices(t *testing.T) {
|
||||
name: "invalid slices - valid size exceeds",
|
||||
args: args{
|
||||
loc: []proto.Slice{
|
||||
{Vid: 1, MinSliceID: 1, Count: 10, ValidSize: 100},
|
||||
{Vid: 1, MinSliceID: 2, Count: 20, ValidSize: 200},
|
||||
{Vid: 1, MinSliceID: 1, Count: 10, ValidSize: 0},
|
||||
{Vid: 1, MinSliceID: 2, Count: 20, ValidSize: 0},
|
||||
},
|
||||
req: []proto.Slice{
|
||||
{Vid: 1, MinSliceID: 1, Count: 20, ValidSize: 200},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user