/
storagefolderremove.go
95 lines (84 loc) · 2.55 KB
/
storagefolderremove.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package contractmanager
import (
"path/filepath"
)
type (
// storageFolderRemoval indicates a storage folder that has been removed
// from the WAL.
storageFolderRemoval struct {
Index uint16
Path string
}
)
// commitStorageFolderRemoval will finalize a storage folder removal from the
// contract manager.
func (wal *writeAheadLog) commitStorageFolderRemoval(sfr storageFolderRemoval) {
// Close any open file handles.
sf, exists := wal.cm.storageFolders[sfr.Index]
if exists {
delete(wal.cm.storageFolders, sfr.Index)
}
if exists && sf.metadataFile != nil {
err := sf.metadataFile.Close()
if err != nil {
wal.cm.log.Printf("Error: unable to close metadata file as storage folder %v is removed\n", sf.path)
}
}
if exists && sf.sectorFile != nil {
err := sf.sectorFile.Close()
if err != nil {
wal.cm.log.Printf("Error: unable to close sector file as storage folder %v is removed\n", sf.path)
}
}
// Delete the files.
err := wal.cm.dependencies.RemoveFile(filepath.Join(sfr.Path, metadataFile))
if err != nil {
wal.cm.log.Printf("Error: unable to remove metadata file as storage folder %v is removed\n", sfr.Path)
}
err = wal.cm.dependencies.RemoveFile(filepath.Join(sfr.Path, sectorFile))
if err != nil {
wal.cm.log.Printf("Error: unable to reomve sector file as storage folder %v is removed\n", sfr.Path)
}
}
// RemoveStorageFolder will delete a storage folder from the contract manager,
// moving all of the sectors in the storage folder to new storage folders.
func (cm *ContractManager) RemoveStorageFolder(index uint16, force bool) error {
cm.tg.Add()
defer cm.tg.Done()
// Retrieve the specified storage folder.
cm.wal.mu.Lock()
sf, exists := cm.storageFolders[index]
if !exists {
cm.wal.mu.Unlock()
return errStorageFolderNotFound
}
cm.wal.mu.Unlock()
// Lock the storage folder for the duration of the operation.
sf.mu.Lock()
defer sf.mu.Unlock()
// Clear out the sectors in the storage folder.
_, err := cm.wal.managedEmptyStorageFolder(index, 0)
if err != nil && !force {
return err
}
// Wait for a synchronize to confirm that all of the moves have succeeded
// in full.
cm.wal.mu.Lock()
syncChan := cm.wal.syncChan
cm.wal.mu.Unlock()
<-syncChan
// Submit a storage folder removal to the WAL and wait until the update is
// synced.
cm.wal.mu.Lock()
cm.wal.appendChange(stateChange{
StorageFolderRemovals: []storageFolderRemoval{{
Index: index,
Path: sf.path,
}},
})
// Wait until the removal action has been synchronized.
syncChan = cm.wal.syncChan
cm.wal.mu.Unlock()
<-syncChan
return nil
}