func (c *checkPoint) Restore(r *bitmap.File) (err error) { size := r.Size() // make sure is blksize-round off := size - (size & int64(c.blkSize-1)) buf := make([]byte, 2) for { if off == 0 { break } off -= int64(c.blkSize) _, err = r.ReadAt(buf, off) if err != nil { return } if !bytes.Equal(buf, MagicBytes) { continue } bio := utils.NewBufio(utils.NewReader(r, off+2)) if err = gob.NewDecoder(bio).Decode(&c.Data); err != nil { logex.Error(err) return } off = bio.Offset(-1) break } // move offset to next blk off = c.calFloor(off) if c.Data == nil { c.Data = make(map[string]int64) } updated := false if off < size { logex.Info("trying to resore ino into checkpoint") } bio := utils.NewBufio(utils.NewReader(r, off)) for off < size { bio.Offset(off) ino, err := ReadInode(bio, c.blkBit) if err != nil { if logex.Equal(err, io.EOF) { break } off += int64(c.blkSize) continue } updated = true c.Data[ino.Name.String()] = off off = c.calFloor(bio.Offset(-1)) } if updated { // write down anything which checkpoint is missing err = logex.Trace(c.Save(utils.NewWriter(r, r.Size()))) } return }
// make a new one if not found // TODO: there is two locks here func (i *Ins) findIno(name string, blkBit uint) *Inode { ino, _ := NewInode(rpc.NewString(name), blkBit) off := i.cp.GetInoOffset(name) if off > 0 { err := ino.PRead(utils.NewBufio(utils.NewReader(i.rfd, off))) if err != nil { logex.Error(err) } } return ino }
func (ino *Inode) prevEx(ra io.ReaderAt) *Inode { elem := ino.elem.Prev() if elem != nil { return elem.Value.(*Inode) } if ino.IndirIno == 0 { return nil } // read from disk r := utils.NewReader(ra, ino.IndirIno) preIno, err := ReadInodeEx(r, ino.inodeShare) if err != nil { return nil } preIno.elem = ino.tbl.PushBack(preIno) return preIno }