Просмотр исходного кода

recursively move files and directories

Chris Lu 6 лет назад
Родитель
Сommit
cec1d97035
2 измененных файлов с 103 добавлено и 75 удалено
  1. 1 75
      weed/filesys/dir.go
  2. 102 0
      weed/filesys/dir_rename.go

+ 1 - 75
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
-}

+ 102 - 0
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
+
+}