diff --git a/internal/operations/fs.go b/internal/operations/fs.go
index 8c7ca7e262c..dc70631860a 100644
--- a/internal/operations/fs.go
+++ b/internal/operations/fs.go
@@ -130,5 +130,22 @@ func Remove(ctx context.Context, account driver.Driver, path string) error {
 }
 
 func Put(ctx context.Context, account driver.Driver, parentPath string, file model.FileStreamer) error {
+	f, err := Get(ctx, account, parentPath)
+	if err != nil {
+		// if parent dir not exists, create it
+		if driver.IsErrObjectNotFound(err) {
+			err = MakeDir(ctx, account, parentPath)
+			if err != nil {
+				return errors.WithMessagef(err, "failed to make parent dir [%s]", parentPath)
+			}
+		} else {
+			return errors.WithMessage(err, "failed to get parent dir")
+		}
+	} else {
+		// object exists, check if it is a dir
+		if !f.IsDir() {
+			return errors.Errorf("object [%s] is not a dir", parentPath)
+		}
+	}
 	return account.Put(ctx, parentPath, file)
 }
diff --git a/internal/task/task.go b/internal/task/task.go
index 24c25785b20..b78cce446d3 100644
--- a/internal/task/task.go
+++ b/internal/task/task.go
@@ -1,12 +1,10 @@
 // manage task, such as file upload, file copy between accounts, offline download, etc.
 package task
 
-import "context"
-
 type Task struct {
-	Name   string
-	Func   func(context.Context) error
-	Status string
-	Error  error
-	Finish bool
+	Name     string
+	Status   string
+	Error    error
+	Finish   bool
+	Children []*Task
 }