diff --git a/vfs/vfscache/writeback/writeback.go b/vfs/vfscache/writeback/writeback.go index dd5a1fd06..b4e4d9e85 100644 --- a/vfs/vfscache/writeback/writeback.go +++ b/vfs/vfscache/writeback/writeback.go @@ -299,6 +299,28 @@ func (wb *WriteBack) Remove(id Handle) (found bool) { return found } +// Rename should be called when a file might be uploading and it gains +// a new name. This will cancel the upload and put it back in the +// queue. +func (wb *WriteBack) Rename(id Handle, name string) { + wb.mu.Lock() + defer wb.mu.Unlock() + + wbItem, ok := wb.lookup[id] + if !ok { + return + } + if wbItem.uploading { + // We are uploading already so cancel the upload + wb._cancelUpload(wbItem) + } + wbItem.name = name + // Kick the timer on + wb.items._update(wbItem, wb._newExpiry()) + + wb._resetTimer() +} + // upload the item - called as a goroutine // // uploading will have been incremented here already diff --git a/vfs/vfscache/writeback/writeback_test.go b/vfs/vfscache/writeback/writeback_test.go index 135dd796c..7f23d8559 100644 --- a/vfs/vfscache/writeback/writeback_test.go +++ b/vfs/vfscache/writeback/writeback_test.go @@ -540,12 +540,12 @@ func TestWriteBackMaxQueue(t *testing.T) { assert.Equal(t, inProgress, 0) } -func TestWriteBackRemove(t *testing.T) { +func TestWriteBackRename(t *testing.T) { wb, cancel := newTestWriteBack(t) defer cancel() // cancel when not in writeback - assert.False(t, wb.Remove(1)) + wb.Rename(1, "nonExistent") // add item pi1 := newPutItem(t) @@ -553,28 +553,34 @@ func TestWriteBackRemove(t *testing.T) { wbItem := wb.lookup[id] checkOnHeap(t, wb, wbItem) checkInLookup(t, wb, wbItem) + assert.Equal(t, wbItem.name, "one") - // cancel when not uploading - assert.True(t, wb.Remove(id)) - checkNotOnHeap(t, wb, wbItem) - checkNotInLookup(t, wb, wbItem) + // rename when not uploading + wb.Rename(id, "two") + checkOnHeap(t, wb, wbItem) + checkInLookup(t, wb, wbItem) assert.False(t, pi1.cancelled) + assert.Equal(t, wbItem.name, "two") // add item pi2 := newPutItem(t) - id = wb.Add(id, "one", true, pi2.put) + id = wb.Add(id, "two", true, pi2.put) wbItem = wb.lookup[id] checkOnHeap(t, wb, wbItem) checkInLookup(t, wb, wbItem) + assert.Equal(t, wbItem.name, "two") // wait for upload to start <-pi2.started - - // cancel when uploading - assert.True(t, wb.Remove(id)) checkNotOnHeap(t, wb, wbItem) - checkNotInLookup(t, wb, wbItem) + checkInLookup(t, wb, wbItem) + + // rename when uploading - goes back on heap + wb.Rename(id, "three") + checkOnHeap(t, wb, wbItem) + checkInLookup(t, wb, wbItem) assert.True(t, pi2.cancelled) + assert.Equal(t, wbItem.name, "three") } func TestWriteBackCancelUpload(t *testing.T) {