Skip to content

Commit

Permalink
Implement rename folder function in dir Inode interface (#2191)
Browse files Browse the repository at this point in the history
* local changes

* add rename folder method in dir.go

* fix format

* add comment

* add new unit test

* small fix

* small fix

* compare with not found error

* trigger e2e tests

* review comment
  • Loading branch information
Tulsishah authored Jul 19, 2024
1 parent 04d8722 commit a5d3a92
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 8 deletions.
5 changes: 5 additions & 0 deletions internal/fs/inode/base_dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,3 +242,8 @@ func (d *baseDirInode) ShouldInvalidateKernelListCache(ttl time.Duration) bool {
// for baseDirInode.
return true
}

func (d *baseDirInode) RenameFolder(ctx context.Context, folderName string, destinationFolderId string) (op *gcs.Folder, err error) {
err = fuse.ENOSYS
return
}
18 changes: 18 additions & 0 deletions internal/fs/inode/dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ type DirInode interface {
// true.
LookUpChild(ctx context.Context, name string) (*Core, error)

// Rename the directiory/folder.
RenameFolder(ctx context.Context, folderName string, destinationFolderId string) (*gcs.Folder, error)

// Read the children objects of this dir, recursively. The result count
// is capped at the given limit. Internal caches are not refreshed from this
// call.
Expand Down Expand Up @@ -939,3 +942,18 @@ func (d *dirInode) ShouldInvalidateKernelListCache(ttl time.Duration) bool {
cachedDuration := d.cacheClock.Now().Sub(d.prevDirListingTimeStamp)
return cachedDuration >= ttl
}

func (d *dirInode) RenameFolder(ctx context.Context, folderName string, destinationFolderName string) (*gcs.Folder, error) {
folder, err := d.bucket.RenameFolder(ctx, folderName, destinationFolderName)
if err != nil {
return nil, err
}

// TODO: Cache updates won't be necessary once type cache usage is removed from HNS.
// Remove old entry from type cache.
d.cache.Erase(folderName)
// Add new renamed folder in type cache.
d.cache.Insert(d.cacheClock.Now(), destinationFolderName, metadata.ExplicitDirType)

return folder, nil
}
43 changes: 43 additions & 0 deletions internal/fs/inode/dir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1565,3 +1565,46 @@ func (t *DirTest) TestShouldReturnNilWhenGCSFolderNotFound() {
AssertEq(nil, err)
AssertEq(nil, result)
}

func (t *DirTest) TestRenameFolderWithGivenName() {
const (
dirName = "qux"
renameDirName = "rename"
)
folderName := path.Join(dirInodeName, dirName) + "/"
renameFolderName := path.Join(dirInodeName, renameDirName) + "/"
// Create the original folder.
_, err := t.bucket.CreateFolder(t.ctx, folderName)
AssertEq(nil, err)

// Attempt to rename the folder.
f, err := t.in.RenameFolder(t.ctx, folderName, renameFolderName)

AssertEq(nil, err)
// Verify the original folder no longer exists.
_, err = t.bucket.GetFolder(t.ctx, folderName)
var notFoundErr *gcs.NotFoundError
ExpectTrue(errors.As(err, &notFoundErr))
// Verify the renamed folder exists.
_, err = t.bucket.GetFolder(t.ctx, renameFolderName)
AssertEq(nil, err)
AssertEq(renameFolderName, f.Name)
}

func (t *DirTest) TestRenameFolderWithNonExistentSourceFolder() {
const (
dirName = "qux"
renameDirName = "rename"
)
folderName := path.Join(dirInodeName, dirName) + "/"
renameFolderName := path.Join(dirInodeName, renameDirName) + "/"

// Attempt to rename the folder.
_, err := t.in.RenameFolder(t.ctx, folderName, renameFolderName)

var notFoundErr *gcs.NotFoundError
ExpectTrue(errors.As(err, &notFoundErr))
// Verify the renamed folder does not exist.
_, err = t.bucket.GetFolder(t.ctx, renameFolderName)
ExpectTrue(errors.As(err, &notFoundErr))
}
21 changes: 13 additions & 8 deletions internal/storage/fake/bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
"io"
"sort"
"strings"
"time"
"unicode/utf8"

"github.com/googlecloudplatform/gcsfuse/v2/internal/storage/gcs"
Expand Down Expand Up @@ -976,11 +977,11 @@ func (b *bucket) CreateFolder(ctx context.Context, folderName string) (*gcs.Fold
return &fo, nil
}

func (b *bucket) RenameFolder(ctx context.Context, folderName string, destinationFolderId string) (o *gcs.Folder, err error) {
func (b *bucket) RenameFolder(ctx context.Context, folderName string, destinationFolderId string) (*gcs.Folder, error) {
// Check that the destination name is legal.
err = checkName(destinationFolderId)
err := checkName(destinationFolderId)
if err != nil {
return
return nil, err
}

// Does the folder exist?
Expand All @@ -989,7 +990,7 @@ func (b *bucket) RenameFolder(ctx context.Context, folderName string, destinatio
err = &gcs.NotFoundError{
Err: fmt.Errorf("Object %q not found", folderName),
}
return
return nil, err
}

dst := b.folders[srcIndex]
Expand All @@ -1004,14 +1005,18 @@ func (b *bucket) RenameFolder(ctx context.Context, folderName string, destinatio
sort.Sort(b.folders)
}

folder := &gcs.Folder{
Name: destinationFolderId,
MetaGeneration: 1,
UpdateTime: time.Now()}

// Delete the src folder?
index := b.folders.find(folderName)
if index == len(b.folders) {
return
return folder, nil
}

// Remove the folder.
// Remove the src folder?
b.folders = append(b.folders[:index], b.folders[index+1:]...)

return
return folder, nil
}

0 comments on commit a5d3a92

Please sign in to comment.