diff --git a/weed/filesys/dir.go b/weed/filesys/dir.go index b7cf8f5e9..24130af2c 100644 --- a/weed/filesys/dir.go +++ b/weed/filesys/dir.go @@ -39,6 +39,7 @@ func (dir *Dir) Attr(context context.Context, attr *fuse.Attr) error { attr.Mtime = time.Unix(entry.Attributes.Mtime, 0) attr.Ctime = time.Unix(entry.Attributes.Crtime, 0) + attr.Mode = os.FileMode(entry.Attributes.FileMode) attr.Gid = entry.Attributes.Gid attr.Uid = entry.Attributes.Uid @@ -260,78 +261,3 @@ func (dir *Dir) Remove(ctx context.Context, req *fuse.RemoveRequest) error { }) } - -func (dir *Dir) Rename(ctx context.Context, req *fuse.RenameRequest, newDirectory fs.Node) error { - - newDir := newDirectory.(*Dir) - - var entry *filer_pb.Entry - err := dir.wfs.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { - - // find existing entry - { - request := &filer_pb.LookupDirectoryEntryRequest{ - Directory: dir.Path, - Name: req.OldName, - } - - glog.V(4).Infof("find existing directory entry: %v", request) - resp, err := client.LookupDirectoryEntry(ctx, request) - if err != nil { - glog.V(0).Infof("renaming find %s/%s: %v", dir.Path, req.OldName, err) - return fuse.ENOENT - } - - entry = resp.Entry - - if entry.IsDirectory { - // do not support moving directory - return fuse.ENOTSUP - } - - glog.V(4).Infof("found existing directory entry resp: %+v", resp) - - } - - // add to new directory - { - request := &filer_pb.CreateEntryRequest{ - Directory: newDir.Path, - Entry: &filer_pb.Entry{ - Name: req.NewName, - IsDirectory: false, - Attributes: entry.Attributes, - Chunks: entry.Chunks, - }, - } - - glog.V(1).Infof("create new entry: %v", request) - if _, err := client.CreateEntry(ctx, request); err != nil { - glog.V(0).Infof("renaming create %s/%s: %v", newDir.Path, req.NewName, err) - return fuse.EIO - } - } - - // delete old entry - { - request := &filer_pb.DeleteEntryRequest{ - Directory: dir.Path, - Name: req.OldName, - IsDirectory: false, - IsDeleteData: false, - } - - glog.V(1).Infof("remove old entry: %v", request) - _, err := client.DeleteEntry(ctx, request) - if err != nil { - glog.V(0).Infof("renaming delete %s/%s: %v", dir.Path, req.OldName, err) - return fuse.EIO - } - - } - - return nil - }) - - return err -} diff --git a/weed/filesys/dir_rename.go b/weed/filesys/dir_rename.go new file mode 100644 index 000000000..a89c51b31 --- /dev/null +++ b/weed/filesys/dir_rename.go @@ -0,0 +1,102 @@ +package filesys + +import ( + "context" + "bazil.org/fuse" + "bazil.org/fuse/fs" + "github.com/chrislusf/seaweedfs/weed/glog" + "github.com/chrislusf/seaweedfs/weed/pb/filer_pb" + "path/filepath" +) + +func (dir *Dir) Rename(ctx context.Context, req *fuse.RenameRequest, newDirectory fs.Node) error { + + newDir := newDirectory.(*Dir) + + return dir.wfs.withFilerClient(func(client filer_pb.SeaweedFilerClient) error { + + // find existing entry + request := &filer_pb.LookupDirectoryEntryRequest{ + Directory: dir.Path, + Name: req.OldName, + } + + glog.V(4).Infof("find existing directory entry: %v", request) + resp, err := client.LookupDirectoryEntry(ctx, request) + if err != nil { + glog.V(0).Infof("renaming find %s/%s: %v", dir.Path, req.OldName, err) + return fuse.ENOENT + } + + entry := resp.Entry + + glog.V(4).Infof("found existing directory entry resp: %+v", resp) + + return moveEntry(ctx, client, dir.Path, entry, newDir.Path, req.NewName) + }) + +} + +func moveEntry(ctx context.Context, client filer_pb.SeaweedFilerClient, oldParent string, entry *filer_pb.Entry, newParent, newName string) error { + if entry.IsDirectory { + currentDirPath := filepath.Join(oldParent, entry.Name) + request := &filer_pb.ListEntriesRequest{ + Directory: currentDirPath, + } + + glog.V(4).Infof("read directory: %v", request) + resp, err := client.ListEntries(ctx, request) + if err != nil { + glog.V(0).Infof("list %s: %v", oldParent, err) + return fuse.EIO + } + + for _, item := range resp.Entries { + err := moveEntry(ctx, client, currentDirPath, item, filepath.Join(newParent, newName), item.Name) + if err != nil { + return err + } + } + + } + + // add to new directory + { + request := &filer_pb.CreateEntryRequest{ + Directory: newParent, + Entry: &filer_pb.Entry{ + Name: newName, + IsDirectory: entry.IsDirectory, + Attributes: entry.Attributes, + Chunks: entry.Chunks, + }, + } + + glog.V(1).Infof("create new entry: %v", request) + if _, err := client.CreateEntry(ctx, request); err != nil { + glog.V(0).Infof("renaming create %s/%s: %v", newParent, newName, err) + return fuse.EIO + } + } + + // delete old entry + { + request := &filer_pb.DeleteEntryRequest{ + Directory: oldParent, + Name: entry.Name, + IsDirectory: entry.IsDirectory, + IsDeleteData: false, + } + + glog.V(1).Infof("remove old entry: %v", request) + _, err := client.DeleteEntry(ctx, request) + if err != nil { + glog.V(0).Infof("renaming delete %s/%s: %v", oldParent, entry.Name, err) + return fuse.EIO + } + + } + + return nil + +}