github.com/Cloud-Foundations/Dominator@v0.3.4/lib/filesystem/rebuild.go (about)

     1  package filesystem
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"path"
     7  )
     8  
     9  func (fs *FileSystem) rebuildInodePointers() error {
    10  	return fs.DirectoryInode.rebuildInodePointers(fs)
    11  }
    12  
    13  func (inode *DirectoryInode) rebuildInodePointers(fs *FileSystem) error {
    14  	for _, dirent := range inode.EntryList {
    15  		tableInode, ok := fs.InodeTable[dirent.InodeNumber]
    16  		if !ok {
    17  			return fmt.Errorf("%s: no entry in inode table for: %d %p",
    18  				dirent.Name, dirent.InodeNumber, dirent.inode)
    19  		}
    20  		if tableInode == nil {
    21  			return fmt.Errorf("%s: nil entry in inode table for: %d %p",
    22  				dirent.Name, dirent.InodeNumber, dirent.inode)
    23  		} else if dirent.inode != nil && dirent.inode != tableInode {
    24  			return fmt.Errorf(
    25  				"%s: changing inode entry for: %d from: %p to %p\n",
    26  				dirent.Name, dirent.InodeNumber, dirent.inode, tableInode)
    27  		}
    28  		dirent.inode = tableInode
    29  		if inode, ok := dirent.inode.(*DirectoryInode); ok {
    30  			if err := inode.rebuildInodePointers(fs); err != nil {
    31  				return errors.New(dirent.Name + "/" + err.Error())
    32  			}
    33  		}
    34  	}
    35  	return nil
    36  }
    37  
    38  func (fs *FileSystem) buildInodeToFilenamesTable() InodeToFilenamesTable {
    39  	if fs.inodeToFilenamesTable == nil {
    40  		fs.inodeToFilenamesTable = make(InodeToFilenamesTable)
    41  		fs.DirectoryInode.buildInodeToFilenamesTable(fs, "/")
    42  	}
    43  	return fs.inodeToFilenamesTable
    44  }
    45  
    46  func (inode *DirectoryInode) buildInodeToFilenamesTable(fs *FileSystem,
    47  	name string) {
    48  	for _, dirent := range inode.EntryList {
    49  		name := path.Join(name, dirent.Name)
    50  		fs.inodeToFilenamesTable[dirent.InodeNumber] = append(
    51  			fs.inodeToFilenamesTable[dirent.InodeNumber], name)
    52  		if inode, ok := dirent.inode.(*DirectoryInode); ok {
    53  			inode.buildInodeToFilenamesTable(fs, name)
    54  		}
    55  	}
    56  }
    57  
    58  func (fs *FileSystem) buildFilenameToInodeTable() FilenameToInodeTable {
    59  	if fs.filenameToInodeTable == nil {
    60  		fs.filenameToInodeTable = make(map[string]uint64)
    61  		for inum, filenames := range fs.InodeToFilenamesTable() {
    62  			for _, filename := range filenames {
    63  				fs.filenameToInodeTable[filename] = inum
    64  			}
    65  		}
    66  
    67  	}
    68  	return fs.filenameToInodeTable
    69  }
    70  
    71  func (fs *FileSystem) buildHashToInodesTable() HashToInodesTable {
    72  	if fs.hashToInodesTable == nil {
    73  		fs.hashToInodesTable = make(HashToInodesTable)
    74  		for inum, inode := range fs.InodeTable {
    75  			if inode, ok := inode.(*RegularInode); ok && inode.Size > 0 {
    76  				fs.hashToInodesTable[inode.Hash] = append(
    77  					fs.hashToInodesTable[inode.Hash], inum)
    78  			}
    79  		}
    80  	}
    81  	return fs.hashToInodesTable
    82  }
    83  
    84  func (fs *FileSystem) computeTotalDataBytes() {
    85  	fs.NumRegularInodes = 0
    86  	fs.TotalDataBytes = 0
    87  	for _, inode := range fs.InodeTable {
    88  		if inode, ok := inode.(*RegularInode); ok {
    89  			fs.NumRegularInodes++
    90  			fs.TotalDataBytes += uint64(inode.Size)
    91  		}
    92  	}
    93  }
    94  
    95  func (fs *FileSystem) computeNumComputedRegularInodes() uint64 {
    96  	if fs.numComputedRegularInodes == nil {
    97  		var numInodes uint64
    98  		for _, inode := range fs.InodeTable {
    99  			if _, ok := inode.(*ComputedRegularInode); ok {
   100  				numInodes++
   101  			}
   102  		}
   103  		fs.numComputedRegularInodes = &numInodes
   104  	}
   105  	return *fs.numComputedRegularInodes
   106  }
   107  
   108  func (inode *DirectoryInode) buildEntryMap() {
   109  	inode.EntriesByName = make(map[string]*DirectoryEntry)
   110  	for _, dirent := range inode.EntryList {
   111  		inode.EntriesByName[dirent.Name] = dirent
   112  		if inode, ok := dirent.inode.(*DirectoryInode); ok {
   113  			inode.buildEntryMap()
   114  		}
   115  	}
   116  }
   117  
   118  func (inode *DirectoryInode) registerStrings(registerFunc func(string)) {
   119  	for _, dirent := range inode.EntryList {
   120  		registerFunc(dirent.Name)
   121  		if inode, ok := dirent.inode.(*DirectoryInode); ok {
   122  			inode.registerStrings(registerFunc)
   123  		}
   124  	}
   125  }
   126  
   127  func (inode *DirectoryInode) replaceStrings(replaceFunc func(string) string) {
   128  	if inode.EntriesByName != nil {
   129  		inode.EntriesByName = make(map[string]*DirectoryEntry,
   130  			len(inode.EntryList))
   131  	}
   132  	for _, dirent := range inode.EntryList {
   133  		dirent.Name = replaceFunc(dirent.Name)
   134  		if inode.EntriesByName != nil {
   135  			inode.EntriesByName[dirent.Name] = dirent
   136  		}
   137  		if inode, ok := dirent.inode.(*DirectoryInode); ok {
   138  			inode.replaceStrings(replaceFunc)
   139  		}
   140  	}
   141  }