瀏覽代碼

Merge pull request #3231 from xiang90/fallocate

pkg/fileutil: support perallocate
Xiang Li 10 年之前
父節點
當前提交
01c286ccb6
共有 4 個文件被更改,包括 117 次插入0 次删除
  1. 23 0
      pkg/fileutil/perallocate_unsupported.go
  2. 28 0
      pkg/fileutil/preallocate.go
  3. 53 0
      pkg/fileutil/preallocate_test.go
  4. 13 0
      wal/wal.go

+ 23 - 0
pkg/fileutil/perallocate_unsupported.go

@@ -0,0 +1,23 @@
+// Copyright 2015 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// +build !linux
+
+package fileutil
+
+import "os"
+
+func Preallocate(f *os.File, sizeInBytes int) error {
+	return nil
+}

+ 28 - 0
pkg/fileutil/preallocate.go

@@ -0,0 +1,28 @@
+// Copyright 2015 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// +build linux
+
+package fileutil
+
+import (
+	"os"
+	"syscall"
+)
+
+func Preallocate(f *os.File, sizeInBytes int) error {
+	// use mode = 1 to keep size
+	// see FALLOC_FL_KEEP_SIZE
+	return syscall.Fallocate(int(f.Fd()), 1, 0, int64(sizeInBytes))
+}

+ 53 - 0
pkg/fileutil/preallocate_test.go

@@ -0,0 +1,53 @@
+// Copyright 2015 CoreOS, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package fileutil
+
+import (
+	"io/ioutil"
+	"os"
+	"runtime"
+	"testing"
+)
+
+func TestPreallocate(t *testing.T) {
+	if runtime.GOOS != "linux" {
+		t.Skipf("skip testPreallocate, OS = %s", runtime.GOOS)
+	}
+
+	p, err := ioutil.TempDir(os.TempDir(), "preallocateTest")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(p)
+
+	f, err := ioutil.TempFile(p, "")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	size := 64 * 1000
+	err = Preallocate(f, size)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	stat, err := f.Stat()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if stat.Size() != 0 {
+		t.Errorf("size = %d, want %d", stat.Size(), 0)
+	}
+}

+ 13 - 0
wal/wal.go

@@ -203,6 +203,12 @@ func openAtIndex(dirpath string, snap walpb.Snapshot, write bool) (*WAL, error)
 			rc.Close()
 			rc.Close()
 			return nil, err
 			return nil, err
 		}
 		}
+		err = fileutil.Preallocate(f, segmentSizeBytes)
+		if err != nil {
+			rc.Close()
+			plog.Errorf("failed to allocate space when creating new wal file (%v)", err)
+			return nil, err
+		}
 
 
 		w.f = f
 		w.f = f
 		w.seq = seq
 		w.seq = seq
@@ -360,6 +366,12 @@ func (w *WAL) cut() error {
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
+	err = fileutil.Preallocate(f, segmentSizeBytes)
+	if err != nil {
+		plog.Errorf("failed to allocate space when creating new wal file (%v)", err)
+		return err
+	}
+
 	w.f = f
 	w.f = f
 	prevCrc = w.encoder.crc.Sum32()
 	prevCrc = w.encoder.crc.Sum32()
 	w.encoder = newEncoder(w.f, prevCrc)
 	w.encoder = newEncoder(w.f, prevCrc)
@@ -369,6 +381,7 @@ func (w *WAL) cut() error {
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
+
 	err = l.Lock()
 	err = l.Lock()
 	if err != nil {
 	if err != nil {
 		return err
 		return err