mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2025-09-20 02:19:23 +08:00
mount: streaming renaming folders
This commit is contained in:
@@ -30,6 +30,8 @@ service SeaweedFiler {
|
|||||||
|
|
||||||
rpc AtomicRenameEntry (AtomicRenameEntryRequest) returns (AtomicRenameEntryResponse) {
|
rpc AtomicRenameEntry (AtomicRenameEntryRequest) returns (AtomicRenameEntryResponse) {
|
||||||
}
|
}
|
||||||
|
rpc StreamRenameEntry (StreamRenameEntryRequest) returns (stream StreamRenameEntryResponse) {
|
||||||
|
}
|
||||||
|
|
||||||
rpc AssignVolume (AssignVolumeRequest) returns (AssignVolumeResponse) {
|
rpc AssignVolume (AssignVolumeRequest) returns (AssignVolumeResponse) {
|
||||||
}
|
}
|
||||||
@@ -225,6 +227,18 @@ message AtomicRenameEntryRequest {
|
|||||||
message AtomicRenameEntryResponse {
|
message AtomicRenameEntryResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message StreamRenameEntryRequest {
|
||||||
|
string old_directory = 1;
|
||||||
|
string old_name = 2;
|
||||||
|
string new_directory = 3;
|
||||||
|
string new_name = 4;
|
||||||
|
repeated int32 signatures = 5;
|
||||||
|
}
|
||||||
|
message StreamRenameEntryResponse {
|
||||||
|
string directory = 1;
|
||||||
|
EventNotification event_notification = 2;
|
||||||
|
int64 ts_ns = 3;
|
||||||
|
}
|
||||||
message AssignVolumeRequest {
|
message AssignVolumeRequest {
|
||||||
int32 count = 1;
|
int32 count = 1;
|
||||||
string collection = 2;
|
string collection = 2;
|
||||||
|
@@ -2,12 +2,10 @@ package filesys
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"github.com/chrislusf/seaweedfs/weed/filer"
|
"github.com/chrislusf/seaweedfs/weed/filer"
|
||||||
"math"
|
|
||||||
|
|
||||||
"github.com/seaweedfs/fuse"
|
"github.com/seaweedfs/fuse"
|
||||||
"github.com/seaweedfs/fuse/fs"
|
"github.com/seaweedfs/fuse/fs"
|
||||||
|
"io"
|
||||||
|
|
||||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||||
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
|
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
|
||||||
@@ -23,19 +21,12 @@ func (dir *Dir) Rename(ctx context.Context, req *fuse.RenameRequest, newDirector
|
|||||||
|
|
||||||
glog.V(4).Infof("dir Rename %s => %s", oldPath, newPath)
|
glog.V(4).Infof("dir Rename %s => %s", oldPath, newPath)
|
||||||
|
|
||||||
// find local old entry
|
|
||||||
oldEntry, err := dir.wfs.metaCache.FindEntry(context.Background(), oldPath)
|
|
||||||
if err != nil {
|
|
||||||
glog.Errorf("dir Rename can not find source %s : %v", oldPath, err)
|
|
||||||
return fuse.ENOENT
|
|
||||||
}
|
|
||||||
|
|
||||||
// update remote filer
|
// update remote filer
|
||||||
err = dir.wfs.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
|
err := dir.wfs.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
request := &filer_pb.AtomicRenameEntryRequest{
|
request := &filer_pb.StreamRenameEntryRequest{
|
||||||
OldDirectory: dir.FullPath(),
|
OldDirectory: dir.FullPath(),
|
||||||
OldName: req.OldName,
|
OldName: req.OldName,
|
||||||
NewDirectory: newDir.FullPath(),
|
NewDirectory: newDir.FullPath(),
|
||||||
@@ -43,12 +34,28 @@ func (dir *Dir) Rename(ctx context.Context, req *fuse.RenameRequest, newDirector
|
|||||||
Signatures: []int32{dir.wfs.signature},
|
Signatures: []int32{dir.wfs.signature},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := client.AtomicRenameEntry(ctx, request)
|
stream, err := client.StreamRenameEntry(ctx, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("dir AtomicRenameEntry %s => %s : %v", oldPath, newPath, err)
|
glog.Errorf("dir AtomicRenameEntry %s => %s : %v", oldPath, newPath, err)
|
||||||
return fuse.EXDEV
|
return fuse.EXDEV
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for {
|
||||||
|
resp, recvErr := stream.Recv()
|
||||||
|
if recvErr != nil {
|
||||||
|
if recvErr == io.EOF {
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
return recvErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = dir.handleRenameResponse(ctx, resp); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
})
|
})
|
||||||
@@ -57,23 +64,25 @@ func (dir *Dir) Rename(ctx context.Context, req *fuse.RenameRequest, newDirector
|
|||||||
return fuse.EIO
|
return fuse.EIO
|
||||||
}
|
}
|
||||||
|
|
||||||
err = dir.moveEntry(context.Background(), util.FullPath(dir.FullPath()), oldEntry, util.FullPath(newDir.FullPath()), req.NewName)
|
|
||||||
if err != nil {
|
|
||||||
glog.V(0).Infof("dir local Rename %s => %s : %v", oldPath, newPath, err)
|
|
||||||
return fuse.EIO
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (dir *Dir) moveEntry(ctx context.Context, oldParent util.FullPath, entry *filer.Entry, newParent util.FullPath, newName string) error {
|
|
||||||
|
|
||||||
oldName := entry.Name()
|
func (dir *Dir) handleRenameResponse(ctx context.Context, resp *filer_pb.StreamRenameEntryResponse) error {
|
||||||
|
// comes from filer StreamRenameEntry, can only be create or delete entry
|
||||||
|
|
||||||
oldPath := oldParent.Child(oldName)
|
if resp.EventNotification.NewEntry != nil {
|
||||||
newPath := newParent.Child(newName)
|
// with new entry, the old entry name also exists. This is the first step to create new entry
|
||||||
if err := dir.moveSelfEntry(ctx, oldParent, entry, newParent, newName, func() error {
|
newEntry := filer.FromPbEntry(resp.EventNotification.NewParentPath, resp.EventNotification.NewEntry)
|
||||||
|
if err := dir.wfs.metaCache.AtomicUpdateEntryFromFiler(ctx, "", newEntry); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
oldParent, newParent := util.FullPath(resp.Directory), util.FullPath(resp.EventNotification.NewParentPath)
|
||||||
|
oldName, newName := resp.EventNotification.OldEntry.Name, resp.EventNotification.NewEntry.Name
|
||||||
|
|
||||||
|
oldPath := oldParent.Child(oldName)
|
||||||
|
newPath := newParent.Child(newName)
|
||||||
oldFsNode := NodeWithId(oldPath.AsInode())
|
oldFsNode := NodeWithId(oldPath.AsInode())
|
||||||
newFsNode := NodeWithId(newPath.AsInode())
|
newFsNode := NodeWithId(newPath.AsInode())
|
||||||
newDirNode, found := dir.wfs.Server.FindInternalNode(NodeWithId(newParent.AsInode()))
|
newDirNode, found := dir.wfs.Server.FindInternalNode(NodeWithId(newParent.AsInode()))
|
||||||
@@ -110,65 +119,13 @@ func (dir *Dir) moveEntry(ctx context.Context, oldParent util.FullPath, entry *f
|
|||||||
}
|
}
|
||||||
dir.wfs.handlesLock.Unlock()
|
dir.wfs.handlesLock.Unlock()
|
||||||
|
|
||||||
if entry.IsDirectory() {
|
}else if resp.EventNotification.OldEntry != nil {
|
||||||
if err := dir.moveFolderSubEntries(ctx, oldParent, oldName, newParent, newName); err != nil {
|
// without new entry, only old entry name exists. This is the second step to delete old entry
|
||||||
return err
|
if err := dir.wfs.metaCache.AtomicUpdateEntryFromFiler(ctx, util.NewFullPath(resp.Directory, resp.EventNotification.OldEntry.Name), nil); err != nil {
|
||||||
}
|
return err
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}); err != nil {
|
|
||||||
return fmt.Errorf("fail to move %s => %s: %v", oldPath, newPath, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dir *Dir) moveFolderSubEntries(ctx context.Context, oldParent util.FullPath, oldName string, newParent util.FullPath, newName string) error {
|
|
||||||
|
|
||||||
currentDirPath := oldParent.Child(oldName)
|
|
||||||
newDirPath := newParent.Child(newName)
|
|
||||||
|
|
||||||
glog.V(1).Infof("moving folder %s => %s", currentDirPath, newDirPath)
|
|
||||||
|
|
||||||
var moveErr error
|
|
||||||
listErr := dir.wfs.metaCache.ListDirectoryEntries(ctx, currentDirPath, "", false, int64(math.MaxInt32), func(item *filer.Entry) bool {
|
|
||||||
moveErr = dir.moveEntry(ctx, currentDirPath, item, newDirPath, item.Name())
|
|
||||||
if moveErr != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
if listErr != nil {
|
|
||||||
return listErr
|
|
||||||
}
|
|
||||||
if moveErr != nil {
|
|
||||||
return moveErr
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (dir *Dir) moveSelfEntry(ctx context.Context, oldParent util.FullPath, entry *filer.Entry, newParent util.FullPath, newName string, moveFolderSubEntries func() error) error {
|
|
||||||
|
|
||||||
newPath := newParent.Child(newName)
|
|
||||||
oldPath := oldParent.Child(entry.Name())
|
|
||||||
|
|
||||||
entry.FullPath = newPath
|
|
||||||
if err := dir.wfs.metaCache.InsertEntry(ctx, entry); err != nil {
|
|
||||||
glog.V(0).Infof("dir Rename insert local %s => %s : %v", oldPath, newPath, err)
|
|
||||||
return fuse.EIO
|
|
||||||
}
|
|
||||||
|
|
||||||
if moveFolderSubEntries != nil {
|
|
||||||
if moveChildrenErr := moveFolderSubEntries(); moveChildrenErr != nil {
|
|
||||||
return moveChildrenErr
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := dir.wfs.metaCache.DeleteEntry(ctx, oldPath); err != nil {
|
|
||||||
glog.V(0).Infof("dir Rename delete local %s => %s : %v", oldPath, newPath, err)
|
|
||||||
return fuse.EIO
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,6 @@ package meta_cache
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"github.com/chrislusf/seaweedfs/weed/filer"
|
"github.com/chrislusf/seaweedfs/weed/filer"
|
||||||
"github.com/chrislusf/seaweedfs/weed/filer/leveldb"
|
"github.com/chrislusf/seaweedfs/weed/filer/leveldb"
|
||||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||||
@@ -122,7 +121,8 @@ func (mc *MetaCache) ListDirectoryEntries(ctx context.Context, dirPath util.Full
|
|||||||
//defer mc.RUnlock()
|
//defer mc.RUnlock()
|
||||||
|
|
||||||
if !mc.visitedBoundary.HasVisited(dirPath) {
|
if !mc.visitedBoundary.HasVisited(dirPath) {
|
||||||
return fmt.Errorf("unsynchronized dir: %v", dirPath)
|
// if this request comes after renaming, it should be fine
|
||||||
|
glog.Warningf("unsynchronized dir: %v", dirPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := mc.localStore.ListDirectoryEntries(ctx, dirPath, startFileName, includeStartFile, limit, func(entry *filer.Entry) bool {
|
_, err := mc.localStore.ListDirectoryEntries(ctx, dirPath, startFileName, includeStartFile, limit, func(entry *filer.Entry) bool {
|
||||||
|
@@ -30,6 +30,8 @@ service SeaweedFiler {
|
|||||||
|
|
||||||
rpc AtomicRenameEntry (AtomicRenameEntryRequest) returns (AtomicRenameEntryResponse) {
|
rpc AtomicRenameEntry (AtomicRenameEntryRequest) returns (AtomicRenameEntryResponse) {
|
||||||
}
|
}
|
||||||
|
rpc StreamRenameEntry (StreamRenameEntryRequest) returns (stream StreamRenameEntryResponse) {
|
||||||
|
}
|
||||||
|
|
||||||
rpc AssignVolume (AssignVolumeRequest) returns (AssignVolumeResponse) {
|
rpc AssignVolume (AssignVolumeRequest) returns (AssignVolumeResponse) {
|
||||||
}
|
}
|
||||||
@@ -225,6 +227,18 @@ message AtomicRenameEntryRequest {
|
|||||||
message AtomicRenameEntryResponse {
|
message AtomicRenameEntryResponse {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message StreamRenameEntryRequest {
|
||||||
|
string old_directory = 1;
|
||||||
|
string old_name = 2;
|
||||||
|
string new_directory = 3;
|
||||||
|
string new_name = 4;
|
||||||
|
repeated int32 signatures = 5;
|
||||||
|
}
|
||||||
|
message StreamRenameEntryResponse {
|
||||||
|
string directory = 1;
|
||||||
|
EventNotification event_notification = 2;
|
||||||
|
int64 ts_ns = 3;
|
||||||
|
}
|
||||||
message AssignVolumeRequest {
|
message AssignVolumeRequest {
|
||||||
int32 count = 1;
|
int32 count = 1;
|
||||||
string collection = 2;
|
string collection = 2;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/chrislusf/seaweedfs/weed/filer"
|
"github.com/chrislusf/seaweedfs/weed/filer"
|
||||||
"github.com/chrislusf/seaweedfs/weed/glog"
|
"github.com/chrislusf/seaweedfs/weed/glog"
|
||||||
@@ -33,7 +34,7 @@ func (fs *FilerServer) AtomicRenameEntry(ctx context.Context, req *filer_pb.Atom
|
|||||||
return nil, fmt.Errorf("%s/%s not found: %v", req.OldDirectory, req.OldName, err)
|
return nil, fmt.Errorf("%s/%s not found: %v", req.OldDirectory, req.OldName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
moveErr := fs.moveEntry(ctx, oldParent, oldEntry, newParent, req.NewName, req.Signatures)
|
moveErr := fs.moveEntry(ctx, nil, oldParent, oldEntry, newParent, req.NewName, req.Signatures)
|
||||||
if moveErr != nil {
|
if moveErr != nil {
|
||||||
fs.filer.RollbackTransaction(ctx)
|
fs.filer.RollbackTransaction(ctx)
|
||||||
return nil, fmt.Errorf("%s/%s move error: %v", req.OldDirectory, req.OldName, moveErr)
|
return nil, fmt.Errorf("%s/%s move error: %v", req.OldDirectory, req.OldName, moveErr)
|
||||||
@@ -47,11 +48,49 @@ func (fs *FilerServer) AtomicRenameEntry(ctx context.Context, req *filer_pb.Atom
|
|||||||
return &filer_pb.AtomicRenameEntryResponse{}, nil
|
return &filer_pb.AtomicRenameEntryResponse{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FilerServer) moveEntry(ctx context.Context, oldParent util.FullPath, entry *filer.Entry, newParent util.FullPath, newName string, signatures []int32) error {
|
func (fs *FilerServer) StreamRenameEntry(req *filer_pb.StreamRenameEntryRequest, stream filer_pb.SeaweedFiler_StreamRenameEntryServer) (err error) {
|
||||||
|
|
||||||
if err := fs.moveSelfEntry(ctx, oldParent, entry, newParent, newName, func() error {
|
glog.V(1).Infof("StreamRenameEntry %v", req)
|
||||||
|
|
||||||
|
oldParent := util.FullPath(filepath.ToSlash(req.OldDirectory))
|
||||||
|
newParent := util.FullPath(filepath.ToSlash(req.NewDirectory))
|
||||||
|
|
||||||
|
if err := fs.filer.CanRename(oldParent, newParent); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
|
||||||
|
ctx, err = fs.filer.BeginTransaction(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
oldEntry, err := fs.filer.FindEntry(ctx, oldParent.Child(req.OldName))
|
||||||
|
if err != nil {
|
||||||
|
fs.filer.RollbackTransaction(ctx)
|
||||||
|
return fmt.Errorf("%s/%s not found: %v", req.OldDirectory, req.OldName, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
moveErr := fs.moveEntry(ctx, stream, oldParent, oldEntry, newParent, req.NewName, req.Signatures)
|
||||||
|
if moveErr != nil {
|
||||||
|
fs.filer.RollbackTransaction(ctx)
|
||||||
|
return fmt.Errorf("%s/%s move error: %v", req.OldDirectory, req.OldName, moveErr)
|
||||||
|
} else {
|
||||||
|
if commitError := fs.filer.CommitTransaction(ctx); commitError != nil {
|
||||||
|
fs.filer.RollbackTransaction(ctx)
|
||||||
|
return fmt.Errorf("%s/%s move commit error: %v", req.OldDirectory, req.OldName, commitError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (fs *FilerServer) moveEntry(ctx context.Context, stream filer_pb.SeaweedFiler_StreamRenameEntryServer, oldParent util.FullPath, entry *filer.Entry, newParent util.FullPath, newName string, signatures []int32) error {
|
||||||
|
|
||||||
|
if err := fs.moveSelfEntry(ctx, stream, oldParent, entry, newParent, newName, func() error {
|
||||||
if entry.IsDirectory() {
|
if entry.IsDirectory() {
|
||||||
if err := fs.moveFolderSubEntries(ctx, oldParent, entry, newParent, newName, signatures); err != nil {
|
if err := fs.moveFolderSubEntries(ctx, stream, oldParent, entry, newParent, newName, signatures); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,7 +102,7 @@ func (fs *FilerServer) moveEntry(ctx context.Context, oldParent util.FullPath, e
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FilerServer) moveFolderSubEntries(ctx context.Context, oldParent util.FullPath, entry *filer.Entry, newParent util.FullPath, newName string, signatures []int32) error {
|
func (fs *FilerServer) moveFolderSubEntries(ctx context.Context, stream filer_pb.SeaweedFiler_StreamRenameEntryServer, oldParent util.FullPath, entry *filer.Entry, newParent util.FullPath, newName string, signatures []int32) error {
|
||||||
|
|
||||||
currentDirPath := oldParent.Child(entry.Name())
|
currentDirPath := oldParent.Child(entry.Name())
|
||||||
newDirPath := newParent.Child(newName)
|
newDirPath := newParent.Child(newName)
|
||||||
@@ -84,7 +123,7 @@ func (fs *FilerServer) moveFolderSubEntries(ctx context.Context, oldParent util.
|
|||||||
for _, item := range entries {
|
for _, item := range entries {
|
||||||
lastFileName = item.Name()
|
lastFileName = item.Name()
|
||||||
// println("processing", lastFileName)
|
// println("processing", lastFileName)
|
||||||
err := fs.moveEntry(ctx, currentDirPath, item, newDirPath, item.Name(), signatures)
|
err := fs.moveEntry(ctx, stream, currentDirPath, item, newDirPath, item.Name(), signatures)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -96,7 +135,7 @@ func (fs *FilerServer) moveFolderSubEntries(ctx context.Context, oldParent util.
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fs *FilerServer) moveSelfEntry(ctx context.Context, oldParent util.FullPath, entry *filer.Entry, newParent util.FullPath, newName string, moveFolderSubEntries func() error, signatures []int32) error {
|
func (fs *FilerServer) moveSelfEntry(ctx context.Context, stream filer_pb.SeaweedFiler_StreamRenameEntryServer, oldParent util.FullPath, entry *filer.Entry, newParent util.FullPath, newName string, moveFolderSubEntries func() error, signatures []int32) error {
|
||||||
|
|
||||||
oldPath, newPath := oldParent.Child(entry.Name()), newParent.Child(newName)
|
oldPath, newPath := oldParent.Child(entry.Name()), newParent.Child(newName)
|
||||||
|
|
||||||
@@ -118,6 +157,24 @@ func (fs *FilerServer) moveSelfEntry(ctx context.Context, oldParent util.FullPat
|
|||||||
if createErr := fs.filer.CreateEntry(ctx, newEntry, false, false, signatures); createErr != nil {
|
if createErr := fs.filer.CreateEntry(ctx, newEntry, false, false, signatures); createErr != nil {
|
||||||
return createErr
|
return createErr
|
||||||
}
|
}
|
||||||
|
if stream != nil {
|
||||||
|
if err := stream.Send(&filer_pb.StreamRenameEntryResponse{
|
||||||
|
Directory: string(newParent),
|
||||||
|
EventNotification: &filer_pb.EventNotification{
|
||||||
|
OldEntry: &filer_pb.Entry{
|
||||||
|
Name: entry.Name(),
|
||||||
|
},
|
||||||
|
NewEntry: newEntry.ToProtoEntry(),
|
||||||
|
DeleteChunks: false,
|
||||||
|
NewParentPath: string(newParent),
|
||||||
|
IsFromOtherCluster: false,
|
||||||
|
Signatures: nil,
|
||||||
|
},
|
||||||
|
TsNs: time.Now().UnixNano(),
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if moveFolderSubEntries != nil {
|
if moveFolderSubEntries != nil {
|
||||||
if moveChildrenErr := moveFolderSubEntries(); moveChildrenErr != nil {
|
if moveChildrenErr := moveFolderSubEntries(); moveChildrenErr != nil {
|
||||||
@@ -130,6 +187,24 @@ func (fs *FilerServer) moveSelfEntry(ctx context.Context, oldParent util.FullPat
|
|||||||
if deleteErr != nil {
|
if deleteErr != nil {
|
||||||
return deleteErr
|
return deleteErr
|
||||||
}
|
}
|
||||||
|
if stream != nil {
|
||||||
|
if err := stream.Send(&filer_pb.StreamRenameEntryResponse{
|
||||||
|
Directory: string(oldParent),
|
||||||
|
EventNotification: &filer_pb.EventNotification{
|
||||||
|
OldEntry: &filer_pb.Entry{
|
||||||
|
Name: entry.Name(),
|
||||||
|
},
|
||||||
|
NewEntry: nil,
|
||||||
|
DeleteChunks: false,
|
||||||
|
NewParentPath: "",
|
||||||
|
IsFromOtherCluster: false,
|
||||||
|
Signatures: nil,
|
||||||
|
},
|
||||||
|
TsNs: time.Now().UnixNano(),
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user