func makeKey(key cas.Key, typ string, level uint8) []byte { k := make([]byte, 0, cas.KeySize+len(typ)+1) k = append(k, key.Bytes()...) k = append(k, typ...) k = append(k, level) return k }
// Mkdir takes a snapshot of this volume and records it under the // given name. func (d *listSnaps) Mkdir(ctx context.Context, req *fuse.MkdirRequest) (fs.Node, error) { var snapshot *wiresnap.Snapshot record := func(tx *db.Tx) error { s, err := d.fs.Snapshot(ctx, tx) if err != nil { return err } snapshot = s return nil } if err := d.fs.db.View(record); err != nil { return nil, fmt.Errorf("cannot record snapshot: %v", err) } snapshot.Name = req.Name var key cas.Key { buf, err := proto.Marshal(snapshot) if err != nil { return nil, fmt.Errorf("cannot marshal snapshot: %v", err) } if len(buf) == 0 { return nil, errors.New("marshaled snapshot become empty; this is a bug") } // store the snapshot as a chunk, for disaster recovery key, err = d.fs.chunkStore.Add(&chunks.Chunk{ Type: "snap", Level: 0, Buf: buf, }) if err != nil { return nil, fmt.Errorf("cannot store snapshot: %v", err) } } var ref = wire.SnapshotRef{ Key: key.Bytes(), } buf, err := proto.Marshal(&ref) if err != nil { return nil, fmt.Errorf("cannot marshal snapshot pointer: %v", err) } add := func(tx *db.Tx) error { b := d.fs.bucket(tx).SnapBucket() if b == nil { return errors.New("snapshot bucket missing") } return b.Put([]byte(req.Name), buf) } if err := d.fs.db.Update(add); err != nil { return nil, fmt.Errorf("cannot save snapshot pointer: %v", err) } n, err := snap.Open(d.fs.chunkStore, snapshot.Contents) if err != nil { return nil, fmt.Errorf("cannot serve snapshot: %v", err) } return n, nil }