From 58a36cb651bc6bfda1f893938e5278b34c28caa0 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Thu, 25 Aug 2016 13:15:13 -0700 Subject: [PATCH] fileutil: add ZeroToEnd for zeroing files --- pkg/fileutil/fileutil.go | 23 +++++++++++++++++++++ pkg/fileutil/fileutil_test.go | 39 +++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/pkg/fileutil/fileutil.go b/pkg/fileutil/fileutil.go index c963a7903..8d9e725f0 100644 --- a/pkg/fileutil/fileutil.go +++ b/pkg/fileutil/fileutil.go @@ -96,3 +96,26 @@ func Exist(name string) bool { _, err := os.Stat(name) return err == nil } + +// ZeroToEnd zeros a file starting from SEEK_CUR to its SEEK_END. May temporarily +// shorten the length of the file. +func ZeroToEnd(f *os.File) error { + // TODO: support FALLOC_FL_ZERO_RANGE + off, err := f.Seek(0, os.SEEK_CUR) + if err != nil { + return err + } + lenf, lerr := f.Seek(0, os.SEEK_END) + if lerr != nil { + return lerr + } + if err = f.Truncate(off); err != nil { + return err + } + // make sure blocks remain allocated + if err = Preallocate(f, lenf, true); err != nil { + return err + } + _, err = f.Seek(off, os.SEEK_SET) + return err +} diff --git a/pkg/fileutil/fileutil_test.go b/pkg/fileutil/fileutil_test.go index 43644311c..28fe4007c 100644 --- a/pkg/fileutil/fileutil_test.go +++ b/pkg/fileutil/fileutil_test.go @@ -118,3 +118,42 @@ func TestExist(t *testing.T) { t.Errorf("exist = %v, want false", g) } } + +func TestZeroToEnd(t *testing.T) { + f, err := ioutil.TempFile(os.TempDir(), "fileutil") + if err != nil { + t.Fatal(err) + } + defer f.Close() + + b := make([]byte, 1024) + for i := range b { + b[i] = 12 + } + if _, err = f.Write(b); err != nil { + t.Fatal(err) + } + if _, err = f.Seek(512, os.SEEK_SET); err != nil { + t.Fatal(err) + } + if err = ZeroToEnd(f); err != nil { + t.Fatal(err) + } + off, serr := f.Seek(0, os.SEEK_CUR) + if serr != nil { + t.Fatal(serr) + } + if off != 512 { + t.Fatalf("expected offset 512, got %d", off) + } + + b = make([]byte, 512) + if _, err = f.Read(b); err != nil { + t.Fatal(err) + } + for i := range b { + if b[i] != 0 { + t.Errorf("expected b[%d] = 0, got %d", i, b[i]) + } + } +}