func addSymlink(dirent *filesystem.DirectoryEntry, fileSystem, oldFS *FileSystem, directoryPathName string, stat *syscall.Stat_t) error { if inode, ok := fileSystem.InodeTable[stat.Ino]; ok { if inode, ok := inode.(*filesystem.SymlinkInode); ok { dirent.SetInode(inode) return nil } return errors.New("Inode changed type: " + dirent.Name) } inode := makeSymlinkInode(stat) err := scanSymlinkInode(inode, fileSystem, path.Join(directoryPathName, dirent.Name)) if err != nil { return err } if oldFS != nil && oldFS.InodeTable != nil { if oldInode, found := oldFS.InodeTable[stat.Ino]; found { if oldInode, ok := oldInode.(*filesystem.SymlinkInode); ok { if filesystem.CompareSymlinkInodes(inode, oldInode, nil) { inode = oldInode } } } } dirent.SetInode(inode) fileSystem.InodeTable[stat.Ino] = inode return nil }
func addDirectory(dirent, oldDirent *filesystem.DirectoryEntry, fileSystem, oldFS *FileSystem, directoryPathName string, stat *syscall.Stat_t) error { myPathName := path.Join(directoryPathName, dirent.Name) if stat.Ino == fileSystem.inodeNumber { return errors.New("Recursive directory: " + myPathName) } if _, ok := fileSystem.InodeTable[stat.Ino]; ok { return errors.New("Hardlinked directory: " + myPathName) } inode := new(filesystem.DirectoryInode) dirent.SetInode(inode) fileSystem.InodeTable[stat.Ino] = inode inode.Mode = filesystem.FileMode(stat.Mode) inode.Uid = stat.Uid inode.Gid = stat.Gid var oldInode *filesystem.DirectoryInode if oldDirent != nil { if oi, ok := oldDirent.Inode().(*filesystem.DirectoryInode); ok { oldInode = oi } } err, copied := scanDirectory(inode, oldInode, fileSystem, oldFS, myPathName) if err != nil { return err } if copied && filesystem.CompareDirectoriesMetadata(inode, oldInode, nil) { dirent.SetInode(oldInode) fileSystem.InodeTable[stat.Ino] = oldInode } fileSystem.DirectoryCount++ return nil }
func (decoderData *decoderData) addEntry(parent *filesystem.DirectoryInode, fullName, name string, inode filesystem.GenericInode) { var newEntry filesystem.DirectoryEntry newEntry.Name = name newEntry.InodeNumber = decoderData.nextInodeNumber newEntry.SetInode(inode) parent.EntryList = append(parent.EntryList, &newEntry) decoderData.addInode(fullName, inode) }
func addSpecialFile(dirent *filesystem.DirectoryEntry, fileSystem, oldFS *FileSystem, stat *syscall.Stat_t) error { if inode, ok := fileSystem.InodeTable[stat.Ino]; ok { if inode, ok := inode.(*filesystem.SpecialInode); ok { dirent.SetInode(inode) return nil } return errors.New("Inode changed type: " + dirent.Name) } inode := makeSpecialInode(stat) if oldFS != nil && oldFS.InodeTable != nil { if oldInode, found := oldFS.InodeTable[stat.Ino]; found { if oldInode, ok := oldInode.(*filesystem.SpecialInode); ok { if filesystem.CompareSpecialInodes(inode, oldInode, nil) { inode = oldInode } } } } dirent.SetInode(inode) fileSystem.InodeTable[stat.Ino] = inode return nil }
// Returns true if there is a failure due to missing computed files. func (sub *Sub) compareDirectories(request *subproto.UpdateRequest, subDirectory, requiredDirectory *filesystem.DirectoryInode, myPathName string, deleteMissingComputedFiles bool, logger *log.Logger) bool { // First look for entries that should be deleted. if sub.filter != nil && subDirectory != nil { for name := range subDirectory.EntriesByName { pathname := path.Join(myPathName, name) if sub.filter.Match(pathname) { continue } if _, ok := requiredDirectory.EntriesByName[name]; !ok { request.PathsToDelete = append(request.PathsToDelete, pathname) } } } for name, requiredEntry := range requiredDirectory.EntriesByName { pathname := path.Join(myPathName, name) if sub.filter != nil && sub.filter.Match(pathname) { continue } var subEntry *filesystem.DirectoryEntry if subDirectory != nil { if se, ok := subDirectory.EntriesByName[name]; ok { subEntry = se } } requiredInode := requiredEntry.Inode() if _, ok := requiredInode.(*filesystem.ComputedRegularInode); ok { // Replace with computed file. inode, ok := sub.ComputedInodes[pathname] if !ok { if deleteMissingComputedFiles { if subEntry != nil { request.PathsToDelete = append(request.PathsToDelete, pathname) } continue } logger.Printf( "compareDirectories(%s): missing computed file: %s\n", sub, pathname) return true } setComputedFileMtime(inode, subEntry) newEntry := new(filesystem.DirectoryEntry) newEntry.Name = name newEntry.InodeNumber = requiredEntry.InodeNumber newEntry.SetInode(inode) requiredEntry = newEntry } if subEntry == nil { sub.addEntry(request, requiredEntry, pathname) } else { sub.compareEntries(request, subEntry, requiredEntry, pathname) } // If a directory: descend (possibly with the directory for the sub). if requiredInode, ok := requiredInode.(*filesystem.DirectoryInode); ok { var subInode *filesystem.DirectoryInode if subEntry != nil { if si, ok := subEntry.Inode().(*filesystem.DirectoryInode); ok { subInode = si } } sub.compareDirectories(request, subInode, requiredInode, pathname, deleteMissingComputedFiles, logger) } } return false }