diff --git a/other/java/client/src/main/proto/filer.proto b/other/java/client/src/main/proto/filer.proto index f0334a377..daa20c378 100644 --- a/other/java/client/src/main/proto/filer.proto +++ b/other/java/client/src/main/proto/filer.proto @@ -95,7 +95,7 @@ message Entry { repeated FileChunk chunks = 3; FuseAttributes attributes = 4; map extended = 5; - int64 hard_link_id = 7; + bytes hard_link_id = 7; int32 hard_link_counter = 8; // only exists in hard link meta data } diff --git a/weed/filer/entry.go b/weed/filer/entry.go index 45ede0e8e..421e51432 100644 --- a/weed/filer/entry.go +++ b/weed/filer/entry.go @@ -64,7 +64,7 @@ func (entry *Entry) ToProtoEntry() *filer_pb.Entry { Attributes: EntryAttributeToPb(entry), Chunks: entry.Chunks, Extended: entry.Extended, - HardLinkId: int64(entry.HardLinkId), + HardLinkId: entry.HardLinkId, HardLinkCounter: entry.HardLinkCounter, } } diff --git a/weed/filer/entry_codec.go b/weed/filer/entry_codec.go index 21531ad7a..884fb2670 100644 --- a/weed/filer/entry_codec.go +++ b/weed/filer/entry_codec.go @@ -16,7 +16,7 @@ func (entry *Entry) EncodeAttributesAndChunks() ([]byte, error) { Attributes: EntryAttributeToPb(entry), Chunks: entry.Chunks, Extended: entry.Extended, - HardLinkId: int64(entry.HardLinkId), + HardLinkId: entry.HardLinkId, HardLinkCounter: entry.HardLinkCounter, } return proto.Marshal(message) @@ -36,7 +36,7 @@ func (entry *Entry) DecodeAttributesAndChunks(blob []byte) error { entry.Chunks = message.Chunks - entry.HardLinkId = HardLinkId(message.HardLinkId) + entry.HardLinkId = message.HardLinkId entry.HardLinkCounter = message.HardLinkCounter return nil @@ -116,7 +116,7 @@ func EqualEntry(a, b *Entry) bool { } } - if a.HardLinkId != b.HardLinkId { + if !bytes.Equal(a.HardLinkId, b.HardLinkId) { return false } if a.HardLinkCounter != b.HardLinkCounter { diff --git a/weed/filer/filer_delete_entry.go b/weed/filer/filer_delete_entry.go index 693b93f8b..6c9ff56d3 100644 --- a/weed/filer/filer_delete_entry.go +++ b/weed/filer/filer_delete_entry.go @@ -10,12 +10,7 @@ import ( "github.com/chrislusf/seaweedfs/weed/util" ) -type HardLinkId int64 -func (hardLinkId HardLinkId) Key() []byte{ - bytes := make([]byte, 8) - util.Uint64toBytes(bytes, uint64(hardLinkId)) - return bytes -} +type HardLinkId []byte func (f *Filer) DeleteEntryMetaAndData(ctx context.Context, p util.FullPath, isRecursive, ignoreRecursiveError, shouldDeleteChunks, isFromOtherCluster bool, signatures []int32) (err error) { if p == "/" { @@ -95,7 +90,7 @@ func (f *Filer) doBatchDeleteFolderMetaAndData(ctx context.Context, entry *Entry hardlinkIds = append(hardlinkIds, dirHardLinkIds...) } else { f.NotifyUpdateEvent(ctx, sub, nil, shouldDeleteChunks, isFromOtherCluster, nil) - if sub.HardLinkId != 0 { + if len(sub.HardLinkId) != 0 { // hard link chunk data are deleted separately hardlinkIds = append(hardlinkIds, sub.HardLinkId) } else { diff --git a/weed/filer/filerstore.go b/weed/filer/filerstore.go index 888168581..11e30878d 100644 --- a/weed/filer/filerstore.go +++ b/weed/filer/filerstore.go @@ -135,7 +135,7 @@ func (fsw *FilerStoreWrapper) DeleteEntry(ctx context.Context, fp util.FullPath) if findErr == filer_pb.ErrNotFound { return nil } - if existingEntry.HardLinkId != 0 { + if len(existingEntry.HardLinkId) != 0 { // remove hard link if err = fsw.DeleteHardLink(ctx, existingEntry.HardLinkId); err != nil { return err diff --git a/weed/filer/filerstore_hardlink.go b/weed/filer/filerstore_hardlink.go index ec768b9cb..9cb32f27f 100644 --- a/weed/filer/filerstore_hardlink.go +++ b/weed/filer/filerstore_hardlink.go @@ -1,6 +1,7 @@ package filer import ( + "bytes" "context" "fmt" "github.com/chrislusf/seaweedfs/weed/glog" @@ -8,7 +9,7 @@ import ( ) func (fsw *FilerStoreWrapper) handleUpdateToHardLinks(ctx context.Context, entry *Entry) error { - if entry.HardLinkId == 0 { + if len(entry.HardLinkId) == 0 { return nil } // handle hard links @@ -23,7 +24,7 @@ func (fsw *FilerStoreWrapper) handleUpdateToHardLinks(ctx context.Context, entry } // remove old hard link - if err == nil && existingEntry.HardLinkId != entry.HardLinkId { + if err == nil && bytes.Compare(existingEntry.HardLinkId, entry.HardLinkId) != 0 { if err = fsw.DeleteHardLink(ctx, existingEntry.HardLinkId); err != nil { return err } @@ -32,10 +33,10 @@ func (fsw *FilerStoreWrapper) handleUpdateToHardLinks(ctx context.Context, entry } func (fsw *FilerStoreWrapper) setHardLink(ctx context.Context, entry *Entry) error { - if entry.HardLinkId == 0 { + if len(entry.HardLinkId) == 0 { return nil } - key := entry.HardLinkId.Key() + key := entry.HardLinkId newBlob, encodeErr := entry.EncodeAttributesAndChunks() if encodeErr != nil { @@ -46,10 +47,10 @@ func (fsw *FilerStoreWrapper) setHardLink(ctx context.Context, entry *Entry) err } func (fsw *FilerStoreWrapper) maybeReadHardLink(ctx context.Context, entry *Entry) error { - if entry.HardLinkId == 0 { + if len(entry.HardLinkId) == 0 { return nil } - key := entry.HardLinkId.Key() + key := entry.HardLinkId value, err := fsw.KvGet(ctx, key) if err != nil { @@ -66,7 +67,7 @@ func (fsw *FilerStoreWrapper) maybeReadHardLink(ctx context.Context, entry *Entr } func (fsw *FilerStoreWrapper) DeleteHardLink(ctx context.Context, hardLinkId HardLinkId) error { - key := hardLinkId.Key() + key := hardLinkId value, err := fsw.KvGet(ctx, key) if err == ErrKvNotFound { return nil diff --git a/weed/filesys/dir_link.go b/weed/filesys/dir_link.go index ddc3248bd..f36918734 100644 --- a/weed/filesys/dir_link.go +++ b/weed/filesys/dir_link.go @@ -32,8 +32,8 @@ func (dir *Dir) Link(ctx context.Context, req *fuse.LinkRequest, old fs.Node) (f } // update old file to hardlink mode - if oldFile.entry.HardLinkId == 0 { - oldFile.entry.HardLinkId = util.RandomInt64() + if oldFile.entry.HardLinkId == nil { + oldFile.entry.HardLinkId = util.RandomBytes(16) oldFile.entry.HardLinkCounter = 1 } oldFile.entry.HardLinkCounter++ diff --git a/weed/filesys/file.go b/weed/filesys/file.go index f501e1ec8..98ee010d8 100644 --- a/weed/filesys/file.go +++ b/weed/filesys/file.go @@ -253,7 +253,7 @@ func (file *File) Forget() { } func (file *File) maybeLoadEntry(ctx context.Context) error { - if (file.entry == nil || file.entry.HardLinkId != 0) && file.isOpen <= 0 { + if (file.entry == nil || len(file.entry.HardLinkId) != 0) && file.isOpen <= 0 { entry, err := file.wfs.maybeLoadEntry(file.dir.FullPath(), file.Name) if err != nil { glog.V(3).Infof("maybeLoadEntry file %s/%s: %v", file.dir.FullPath(), file.Name, err) diff --git a/weed/pb/filer.proto b/weed/pb/filer.proto index f0334a377..daa20c378 100644 --- a/weed/pb/filer.proto +++ b/weed/pb/filer.proto @@ -95,7 +95,7 @@ message Entry { repeated FileChunk chunks = 3; FuseAttributes attributes = 4; map extended = 5; - int64 hard_link_id = 7; + bytes hard_link_id = 7; int32 hard_link_counter = 8; // only exists in hard link meta data } diff --git a/weed/pb/filer_pb/filer.pb.go b/weed/pb/filer_pb/filer.pb.go index 79c47548f..bf3adb78a 100644 --- a/weed/pb/filer_pb/filer.pb.go +++ b/weed/pb/filer_pb/filer.pb.go @@ -267,7 +267,7 @@ type Entry struct { Chunks []*FileChunk `protobuf:"bytes,3,rep,name=chunks,proto3" json:"chunks,omitempty"` Attributes *FuseAttributes `protobuf:"bytes,4,opt,name=attributes,proto3" json:"attributes,omitempty"` Extended map[string][]byte `protobuf:"bytes,5,rep,name=extended,proto3" json:"extended,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - HardLinkId int64 `protobuf:"varint,7,opt,name=hard_link_id,json=hardLinkId,proto3" json:"hard_link_id,omitempty"` + HardLinkId []byte `protobuf:"bytes,7,opt,name=hard_link_id,json=hardLinkId,proto3" json:"hard_link_id,omitempty"` HardLinkCounter int32 `protobuf:"varint,8,opt,name=hard_link_counter,json=hardLinkCounter,proto3" json:"hard_link_counter,omitempty"` // only exists in hard link meta data } @@ -338,11 +338,11 @@ func (x *Entry) GetExtended() map[string][]byte { return nil } -func (x *Entry) GetHardLinkId() int64 { +func (x *Entry) GetHardLinkId() []byte { if x != nil { return x.HardLinkId } - return 0 + return nil } func (x *Entry) GetHardLinkCounter() int32 { @@ -2947,7 +2947,7 @@ var file_filer_proto_rawDesc = []byte{ 0x5f, 0x70, 0x62, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0c, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x69, - 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0a, 0x68, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x6e, + 0x64, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x68, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x6e, 0x6b, 0x49, 0x64, 0x12, 0x2a, 0x0a, 0x11, 0x68, 0x61, 0x72, 0x64, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0f, 0x68, 0x61, 0x72, 0x64, 0x4c, 0x69, 0x6e, 0x6b, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x65, 0x72, 0x1a, diff --git a/weed/server/filer_grpc_server.go b/weed/server/filer_grpc_server.go index 3ac3357ca..ecd23413f 100644 --- a/weed/server/filer_grpc_server.go +++ b/weed/server/filer_grpc_server.go @@ -37,7 +37,7 @@ func (fs *FilerServer) LookupDirectoryEntry(ctx context.Context, req *filer_pb.L Attributes: filer.EntryAttributeToPb(entry), Chunks: entry.Chunks, Extended: entry.Extended, - HardLinkId: int64(entry.HardLinkId), + HardLinkId: entry.HardLinkId, HardLinkCounter: entry.HardLinkCounter, }, }, nil @@ -82,7 +82,7 @@ func (fs *FilerServer) ListEntries(req *filer_pb.ListEntriesRequest, stream file Chunks: entry.Chunks, Attributes: filer.EntryAttributeToPb(entry), Extended: entry.Extended, - HardLinkId: int64(entry.HardLinkId), + HardLinkId: entry.HardLinkId, HardLinkCounter: entry.HardLinkCounter, }, }); err != nil { diff --git a/weed/util/bytes.go b/weed/util/bytes.go index a7e0c20e2..67e6876fa 100644 --- a/weed/util/bytes.go +++ b/weed/util/bytes.go @@ -143,8 +143,8 @@ func RandomInt32() int32 { return int32(BytesToUint32(buf)) } -func RandomInt64() int64 { - buf := make([]byte, 8) +func RandomBytes(byteCount int) []byte { + buf := make([]byte, byteCount) rand.Read(buf) - return int64(BytesToUint64(buf)) + return buf }