mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-05-30 05:30:23 +00:00
filer/posixlock: remove the unused lock-set serde (#9676)
The codec (Set.Marshal/Unmarshal) and its posix_lock.proto were built to let the lock set ride in an inode's entry metadata, but the authority is in-memory and ownership handoff/restart is handled by mounts re-asserting their held locks over the RPC — neither serializes the set. Nothing calls the serde outside its own tests, so drop it (codec, proto, generated pb, Makefile). The in-memory Set/Manager are unchanged.
This commit is contained in:
@@ -1,6 +0,0 @@
|
||||
all: gen
|
||||
|
||||
.PHONY : gen
|
||||
|
||||
gen:
|
||||
protoc posix_lock.proto --go_out=. --go-grpc_out=. --go_opt=paths=source_relative --go-grpc_opt=paths=source_relative
|
||||
@@ -1,58 +0,0 @@
|
||||
package posixlock
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
// The held lock set rides in an inode's entry metadata, so the wire format must
|
||||
// stay backward compatible across filer versions. It is a protobuf message
|
||||
// (LockSetProto), so new fields can be added without breaking old readers.
|
||||
|
||||
// Marshal encodes the held locks for storage in the inode's entry metadata. A
|
||||
// lock-free set encodes to nil, so an inode that holds no locks carries no blob.
|
||||
func (s *Set) Marshal() ([]byte, error) {
|
||||
if len(s.locks) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
pb := &LockSetProto{Locks: make([]*LockProto, len(s.locks))}
|
||||
for i, l := range s.locks {
|
||||
pb.Locks[i] = &LockProto{
|
||||
Start: l.Start,
|
||||
End: l.End,
|
||||
Type: l.Type,
|
||||
Sid: l.Sid,
|
||||
Owner: l.Owner,
|
||||
Pid: l.Pid,
|
||||
IsFlock: l.IsFlock,
|
||||
}
|
||||
}
|
||||
return proto.Marshal(pb)
|
||||
}
|
||||
|
||||
// Unmarshal decodes a Set produced by Marshal. Empty input is an empty set, so a
|
||||
// missing metadata key reads back as "no locks held". A malformed blob is
|
||||
// rejected rather than silently misread.
|
||||
func Unmarshal(b []byte) (*Set, error) {
|
||||
if len(b) == 0 {
|
||||
return &Set{}, nil
|
||||
}
|
||||
pb := &LockSetProto{}
|
||||
if err := proto.Unmarshal(b, pb); err != nil {
|
||||
return nil, fmt.Errorf("posixlock: %w", err)
|
||||
}
|
||||
locks := make([]Range, len(pb.Locks))
|
||||
for i, l := range pb.Locks {
|
||||
locks[i] = Range{
|
||||
Start: l.Start,
|
||||
End: l.End,
|
||||
Type: l.Type,
|
||||
Sid: l.Sid,
|
||||
Owner: l.Owner,
|
||||
Pid: l.Pid,
|
||||
IsFlock: l.IsFlock,
|
||||
}
|
||||
}
|
||||
return &Set{locks: locks}, nil
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
package posixlock
|
||||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMarshalEmptyIsNil(t *testing.T) {
|
||||
s := &Set{}
|
||||
b, err := s.Marshal()
|
||||
if err != nil {
|
||||
t.Fatalf("marshal empty: %v", err)
|
||||
}
|
||||
if b != nil {
|
||||
t.Fatalf("empty set should marshal to nil, got %d bytes", len(b))
|
||||
}
|
||||
got, err := Unmarshal(nil)
|
||||
if err != nil {
|
||||
t.Fatalf("unmarshal nil: %v", err)
|
||||
}
|
||||
if !got.Empty() {
|
||||
t.Fatal("unmarshal nil should be an empty set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshalRoundTrip(t *testing.T) {
|
||||
s := &Set{}
|
||||
// A spread of fields: EOF range, both namespaces, two sessions, distinct pids.
|
||||
mustAcquire(t, s, Range{Start: 0, End: 99, Type: Write, Sid: 1, Owner: 7, Pid: 10})
|
||||
mustAcquire(t, s, Range{Start: 200, End: math.MaxUint64, Type: Read, Sid: 2, Owner: 7, Pid: 20})
|
||||
mustAcquire(t, s, Range{Start: 0, End: math.MaxUint64, Type: Write, Sid: 2, Owner: 9, Pid: 30, IsFlock: true})
|
||||
|
||||
b, err := s.Marshal()
|
||||
if err != nil {
|
||||
t.Fatalf("marshal: %v", err)
|
||||
}
|
||||
got, err := Unmarshal(b)
|
||||
if err != nil {
|
||||
t.Fatalf("unmarshal: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(got.Locks(), s.Locks()) {
|
||||
t.Fatalf("round-trip mismatch:\n got %+v\nwant %+v", got.Locks(), s.Locks())
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalRejectsMalformed(t *testing.T) {
|
||||
// field 1 (locks), wire type 2 (length-delimited) declaring 5 bytes that
|
||||
// are not there: a corrupt blob must fail loudly, not read back as empty.
|
||||
if _, err := Unmarshal([]byte{0x0A, 0x05}); err == nil {
|
||||
t.Fatal("expected an error on malformed input")
|
||||
}
|
||||
}
|
||||
|
||||
// A decoded set must behave identically — conflict detection still fires.
|
||||
func TestRoundTripPreservesConflict(t *testing.T) {
|
||||
s := &Set{}
|
||||
mustAcquire(t, s, Range{Start: 0, End: 99, Type: Write, Sid: 1, Owner: 1, Pid: 10})
|
||||
|
||||
b, err := s.Marshal()
|
||||
if err != nil {
|
||||
t.Fatalf("marshal: %v", err)
|
||||
}
|
||||
decoded, err := Unmarshal(b)
|
||||
if err != nil {
|
||||
t.Fatalf("unmarshal: %v", err)
|
||||
}
|
||||
if _, granted := decoded.Acquire(Range{Start: 50, End: 149, Type: Write, Sid: 2, Owner: 1, Pid: 20}); granted {
|
||||
t.Fatal("decoded set should still report the conflict")
|
||||
}
|
||||
// Same owner across the wire is still the same owner.
|
||||
if _, granted := decoded.Acquire(Range{Start: 0, End: 99, Type: Read, Sid: 1, Owner: 1, Pid: 10}); !granted {
|
||||
t.Fatal("decoded set should still recognize the same (sid,owner)")
|
||||
}
|
||||
}
|
||||
@@ -1,230 +0,0 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// versions:
|
||||
// protoc-gen-go v1.36.6
|
||||
// protoc v6.33.4
|
||||
// source: posix_lock.proto
|
||||
|
||||
package posixlock
|
||||
|
||||
import (
|
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
|
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
|
||||
reflect "reflect"
|
||||
sync "sync"
|
||||
unsafe "unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
// Verify that this generated code is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
|
||||
// Verify that runtime/protoimpl is sufficiently up-to-date.
|
||||
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
|
||||
)
|
||||
|
||||
// LockSetProto is the serialized set of advisory locks held on one inode. It
|
||||
// rides in the inode's entry metadata, so the schema must stay backward
|
||||
// compatible across filer versions.
|
||||
type LockSetProto struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Locks []*LockProto `protobuf:"bytes,1,rep,name=locks,proto3" json:"locks,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *LockSetProto) Reset() {
|
||||
*x = LockSetProto{}
|
||||
mi := &file_posix_lock_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *LockSetProto) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*LockSetProto) ProtoMessage() {}
|
||||
|
||||
func (x *LockSetProto) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_posix_lock_proto_msgTypes[0]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use LockSetProto.ProtoReflect.Descriptor instead.
|
||||
func (*LockSetProto) Descriptor() ([]byte, []int) {
|
||||
return file_posix_lock_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *LockSetProto) GetLocks() []*LockProto {
|
||||
if x != nil {
|
||||
return x.Locks
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LockProto mirrors Range. Owner identity is the (sid, owner) pair; end is
|
||||
// inclusive and max uint64 means EOF; is_flock separates the flock and fcntl
|
||||
// namespaces, which never conflict.
|
||||
type LockProto struct {
|
||||
state protoimpl.MessageState `protogen:"open.v1"`
|
||||
Start uint64 `protobuf:"varint,1,opt,name=start,proto3" json:"start,omitempty"`
|
||||
End uint64 `protobuf:"varint,2,opt,name=end,proto3" json:"end,omitempty"`
|
||||
Type uint32 `protobuf:"varint,3,opt,name=type,proto3" json:"type,omitempty"`
|
||||
Sid uint64 `protobuf:"varint,4,opt,name=sid,proto3" json:"sid,omitempty"`
|
||||
Owner uint64 `protobuf:"varint,5,opt,name=owner,proto3" json:"owner,omitempty"`
|
||||
Pid uint32 `protobuf:"varint,6,opt,name=pid,proto3" json:"pid,omitempty"`
|
||||
IsFlock bool `protobuf:"varint,7,opt,name=is_flock,json=isFlock,proto3" json:"is_flock,omitempty"`
|
||||
unknownFields protoimpl.UnknownFields
|
||||
sizeCache protoimpl.SizeCache
|
||||
}
|
||||
|
||||
func (x *LockProto) Reset() {
|
||||
*x = LockProto{}
|
||||
mi := &file_posix_lock_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
|
||||
func (x *LockProto) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*LockProto) ProtoMessage() {}
|
||||
|
||||
func (x *LockProto) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_posix_lock_proto_msgTypes[1]
|
||||
if x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
return ms
|
||||
}
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use LockProto.ProtoReflect.Descriptor instead.
|
||||
func (*LockProto) Descriptor() ([]byte, []int) {
|
||||
return file_posix_lock_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
func (x *LockProto) GetStart() uint64 {
|
||||
if x != nil {
|
||||
return x.Start
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *LockProto) GetEnd() uint64 {
|
||||
if x != nil {
|
||||
return x.End
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *LockProto) GetType() uint32 {
|
||||
if x != nil {
|
||||
return x.Type
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *LockProto) GetSid() uint64 {
|
||||
if x != nil {
|
||||
return x.Sid
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *LockProto) GetOwner() uint64 {
|
||||
if x != nil {
|
||||
return x.Owner
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *LockProto) GetPid() uint32 {
|
||||
if x != nil {
|
||||
return x.Pid
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (x *LockProto) GetIsFlock() bool {
|
||||
if x != nil {
|
||||
return x.IsFlock
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var File_posix_lock_proto protoreflect.FileDescriptor
|
||||
|
||||
const file_posix_lock_proto_rawDesc = "" +
|
||||
"\n" +
|
||||
"\x10posix_lock.proto\x12\tposixlock\":\n" +
|
||||
"\fLockSetProto\x12*\n" +
|
||||
"\x05locks\x18\x01 \x03(\v2\x14.posixlock.LockProtoR\x05locks\"\x9c\x01\n" +
|
||||
"\tLockProto\x12\x14\n" +
|
||||
"\x05start\x18\x01 \x01(\x04R\x05start\x12\x10\n" +
|
||||
"\x03end\x18\x02 \x01(\x04R\x03end\x12\x12\n" +
|
||||
"\x04type\x18\x03 \x01(\rR\x04type\x12\x10\n" +
|
||||
"\x03sid\x18\x04 \x01(\x04R\x03sid\x12\x14\n" +
|
||||
"\x05owner\x18\x05 \x01(\x04R\x05owner\x12\x10\n" +
|
||||
"\x03pid\x18\x06 \x01(\rR\x03pid\x12\x19\n" +
|
||||
"\bis_flock\x18\a \x01(\bR\aisFlockB5Z3github.com/seaweedfs/seaweedfs/weed/filer/posixlockb\x06proto3"
|
||||
|
||||
var (
|
||||
file_posix_lock_proto_rawDescOnce sync.Once
|
||||
file_posix_lock_proto_rawDescData []byte
|
||||
)
|
||||
|
||||
func file_posix_lock_proto_rawDescGZIP() []byte {
|
||||
file_posix_lock_proto_rawDescOnce.Do(func() {
|
||||
file_posix_lock_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_posix_lock_proto_rawDesc), len(file_posix_lock_proto_rawDesc)))
|
||||
})
|
||||
return file_posix_lock_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_posix_lock_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
|
||||
var file_posix_lock_proto_goTypes = []any{
|
||||
(*LockSetProto)(nil), // 0: posixlock.LockSetProto
|
||||
(*LockProto)(nil), // 1: posixlock.LockProto
|
||||
}
|
||||
var file_posix_lock_proto_depIdxs = []int32{
|
||||
1, // 0: posixlock.LockSetProto.locks:type_name -> posixlock.LockProto
|
||||
1, // [1:1] is the sub-list for method output_type
|
||||
1, // [1:1] is the sub-list for method input_type
|
||||
1, // [1:1] is the sub-list for extension type_name
|
||||
1, // [1:1] is the sub-list for extension extendee
|
||||
0, // [0:1] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_posix_lock_proto_init() }
|
||||
func file_posix_lock_proto_init() {
|
||||
if File_posix_lock_proto != nil {
|
||||
return
|
||||
}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: unsafe.Slice(unsafe.StringData(file_posix_lock_proto_rawDesc), len(file_posix_lock_proto_rawDesc)),
|
||||
NumEnums: 0,
|
||||
NumMessages: 2,
|
||||
NumExtensions: 0,
|
||||
NumServices: 0,
|
||||
},
|
||||
GoTypes: file_posix_lock_proto_goTypes,
|
||||
DependencyIndexes: file_posix_lock_proto_depIdxs,
|
||||
MessageInfos: file_posix_lock_proto_msgTypes,
|
||||
}.Build()
|
||||
File_posix_lock_proto = out.File
|
||||
file_posix_lock_proto_goTypes = nil
|
||||
file_posix_lock_proto_depIdxs = nil
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package posixlock;
|
||||
|
||||
option go_package = "github.com/seaweedfs/seaweedfs/weed/filer/posixlock";
|
||||
|
||||
// LockSetProto is the serialized set of advisory locks held on one inode. It
|
||||
// rides in the inode's entry metadata, so the schema must stay backward
|
||||
// compatible across filer versions.
|
||||
message LockSetProto {
|
||||
repeated LockProto locks = 1;
|
||||
}
|
||||
|
||||
// LockProto mirrors Range. Owner identity is the (sid, owner) pair; end is
|
||||
// inclusive and max uint64 means EOF; is_flock separates the flock and fcntl
|
||||
// namespaces, which never conflict.
|
||||
message LockProto {
|
||||
uint64 start = 1;
|
||||
uint64 end = 2;
|
||||
uint32 type = 3;
|
||||
uint64 sid = 4;
|
||||
uint64 owner = 5;
|
||||
uint32 pid = 6;
|
||||
bool is_flock = 7;
|
||||
}
|
||||
Reference in New Issue
Block a user