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 }
// simplest test for write and read a file func TestSingleReadWrite(t *testing.T) { var err error defer utils.TDefer(t, &err) testData := genBlock(9 << 10) ins, err := newIns() if err != nil { return } defer ins.Pruge() f, err := ins.Open("lfsTestTopic") if err != nil { return } defer f.Close() w := &utils.Writer{f, 0} if err = safeWrite(w, testData); err != nil { return } testDataBuf := make([]byte, len(testData)) r := utils.NewBufio(&utils.Reader{f, 0}) if err = safeRead(r, testDataBuf); err != nil { return } 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 (t *Ins) get(arg *getArgs, mustReply bool) error { if arg.size > MaxGetBenchSize { return ErrBenchSizeTooLarge.Trace(arg.size) } msgs := make([]*message.Ins, arg.size) var ( msg *message.Ins err error ) var header message.Header // check offset r := utils.NewBufio(&utils.Reader{t.file, arg.offset}) p := 0 for i := 0; i < arg.size; i++ { msg, err = message.Read(&header, r, message.RF_RESEEK_ON_FAULT) err = logex.Trace(err, i, arg.offset) if logex.EqualAny(err, ErrNeedAddToWaiter) { // not finish, add to waiterList t.addToWaiterList(newWaiter(arg, r.Offset(-1), p)) break } if err != nil { break } msgs[p] = msg p++ } if mustReply || p > 0 { arg.reply <- rpc.NewReply(t.Name, msgs[:p]) } if logex.Equal(err, io.EOF) { err = nil } return err }