github.com/fozzysec/SiaPrime@v0.0.0-20190612043147-66c8e8d11fe3/modules/host/contractmanager/storagefolderremove.go (about)

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