summaryrefslogtreecommitdiff
path: root/lib/btrfs/btrfssum
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2022-08-21 22:09:22 -0600
committerLuke Shumaker <lukeshu@lukeshu.com>2022-08-21 22:09:22 -0600
commit6dd6e79120562f5e914c386b654a233662d5ab40 (patch)
tree7dad82542c5ed4971704c6926ebead773f962bea /lib/btrfs/btrfssum
parentc910df75c332f605a26f9f9e09b04e98df054a5f (diff)
polish off dbgsums
Diffstat (limited to 'lib/btrfs/btrfssum')
-rw-r--r--lib/btrfs/btrfssum/shortsum.go78
1 files changed, 77 insertions, 1 deletions
diff --git a/lib/btrfs/btrfssum/shortsum.go b/lib/btrfs/btrfssum/shortsum.go
index 90d2612..2d995b5 100644
--- a/lib/btrfs/btrfssum/shortsum.go
+++ b/lib/btrfs/btrfssum/shortsum.go
@@ -102,7 +102,7 @@ func (sum *ShortSum) DecodeJSON(r io.RuneScanner) error {
type SumRun[Addr btrfsvol.IntAddr[Addr]] struct {
// How big a ShortSum is in this Run.
- ChecksumSize int
+ ChecksumSize int `json:",omitempty"`
// Base address where this run starts.
Addr Addr `json:",omitempty"`
// All of the ShortSums in this run, concatenated together.
@@ -157,6 +157,11 @@ type SumRunWithGaps[Addr btrfsvol.IntAddr[Addr]] struct {
Runs []SumRun[Addr]
}
+var (
+ _ lowmemjson.Encodable = SumRunWithGaps[btrfsvol.LogicalAddr]{}
+ _ lowmemjson.Decodable = (*SumRunWithGaps[btrfsvol.LogicalAddr])(nil)
+)
+
func (sg SumRunWithGaps[Addr]) NumSums() int {
return int(sg.Size / BlockSize)
}
@@ -192,3 +197,74 @@ func (sg SumRunWithGaps[Addr]) Get(sumIdx int64) (ShortSum, error) {
addr := sg.Addr.Add(btrfsvol.AddrDelta(sumIdx) * BlockSize)
return sg.SumForAddr(addr)
}
+
+func (sg SumRunWithGaps[Addr]) EncodeJSON(w io.Writer) error {
+ if _, err := fmt.Fprintf(w, `{"Addr":%d,"Size":%d,"Runs":[`, sg.Addr, sg.Size); err != nil {
+ return err
+ }
+ cur := sg.Addr
+ for i, run := range sg.Runs {
+ if i > 0 {
+ if _, err := w.Write([]byte{','}); err != nil {
+ return err
+ }
+ }
+ switch {
+ case run.Addr < cur:
+ return fmt.Errorf("invalid %T: addr went backwards: %v < %v", sg, run.Addr, cur)
+ case run.Addr > cur:
+ if _, err := fmt.Fprintf(w, `{"Gap":%d},`, run.Addr.Sub(cur)); err != nil {
+ return err
+ }
+ fallthrough
+ default:
+ if err := lowmemjson.Encode(w, run); err != nil {
+ return err
+ }
+ cur = run.Addr.Add(run.Size())
+ }
+ }
+ end := sg.Addr.Add(sg.Size)
+ switch {
+ case end < cur:
+ return fmt.Errorf("invalid %T: addr went backwards: %v < %v", sg, end, cur)
+ case end > cur:
+ if _, err := fmt.Fprintf(w, `,{"Gap":%d}`, end.Sub(cur)); err != nil {
+ return err
+ }
+ }
+ if _, err := w.Write([]byte("]}")); err != nil {
+ return err
+ }
+ return nil
+}
+
+func (sg *SumRunWithGaps[Addr]) DecodeJSON(r io.RuneScanner) error {
+ *sg = SumRunWithGaps[Addr]{}
+ var name string
+ return lowmemjson.DecodeObject(r,
+ func(r io.RuneScanner) error {
+ return lowmemjson.Decode(r, &name)
+ },
+ func(r io.RuneScanner) error {
+ switch name {
+ case "Addr":
+ return lowmemjson.Decode(r, &sg.Addr)
+ case "Size":
+ return lowmemjson.Decode(r, &sg.Size)
+ case "Runs":
+ return lowmemjson.DecodeArray(r, func(r io.RuneScanner) error {
+ var run SumRun[Addr]
+ if err := lowmemjson.Decode(r, &run); err != nil {
+ return err
+ }
+ if run.ChecksumSize > 0 {
+ sg.Runs = append(sg.Runs, run)
+ }
+ return nil
+ })
+ default:
+ return fmt.Errorf("unknown key %q", name)
+ }
+ })
+}