expose resize

This commit is contained in:
Denys Smirnov 2017-01-11 18:53:23 +02:00
parent 532eaaa4b7
commit 3db12b2294
4 changed files with 104 additions and 13 deletions

View File

@ -6,6 +6,7 @@ import (
"io"
"os"
"path/filepath"
"strconv"
"syscall"
)
@ -242,3 +243,22 @@ func (f *FS) Balance(flags BalanceFlags) (BalanceProgress, error) {
err := iocBalanceV2(f.f, &args)
return args.stat, err
}
func (f *FS) Resize(size int64) error {
amount := strconv.FormatInt(size, 10)
args := &btrfs_ioctl_vol_args{}
args.SetName(amount)
if err := iocResize(f.f, args); err != nil {
return fmt.Errorf("resize failed: %v", err)
}
return nil
}
func (f *FS) ResizeToMax() error {
args := &btrfs_ioctl_vol_args{}
args.SetName("max")
if err := iocResize(f.f, args); err != nil {
return fmt.Errorf("resize failed: %v", err)
}
return nil
}

View File

@ -3,6 +3,7 @@ package btrfs
import (
"github.com/dennwc/btrfs/test"
"io"
"io/ioutil"
"os"
"path/filepath"
"reflect"
@ -215,3 +216,62 @@ func TestCloneFile(t *testing.T) {
t.Fatalf("wrong data returned: %q", string(buf))
}
}
func TestResize(t *testing.T) {
dir, err := ioutil.TempDir("", "btrfs_data_")
if err != nil {
t.Fatal(err)
}
defer os.RemoveAll(dir)
fname := filepath.Join(dir, "data")
if err = btrfstest.Mkfs(fname, sizeDef); err != nil {
t.Fatal(err)
}
mnt := filepath.Join(dir, "mnt")
if err = os.MkdirAll(mnt, 0755); err != nil {
t.Fatal(err)
}
if err = btrfstest.Mount(mnt, fname); err != nil {
t.Fatal(err)
}
defer btrfstest.Unmount(mnt)
fs, err := Open(mnt, false)
if err != nil {
t.Fatal(err)
}
st, err := fs.Usage()
fs.Close()
if err != nil {
t.Fatal(err)
}
if err = btrfstest.Unmount(mnt); err != nil {
t.Fatal(err)
}
var newSize int64 = sizeDef
newSize = int64(float64(newSize) * 1.1)
if err = os.Truncate(fname, newSize); err != nil {
t.Fatal(err)
}
if err = btrfstest.Mount(mnt, fname); err != nil {
t.Fatal(err)
}
fs, err = Open(mnt, false)
if err != nil {
t.Fatal(err)
}
defer fs.Close()
if err = fs.ResizeToMax(); err != nil {
t.Fatal(err)
}
st2, err := fs.Usage()
if err != nil {
t.Fatal(err)
} else if st.Total >= st2.Total {
t.Fatal("to resized:", st.Total, st2.Total)
}
}

View File

@ -60,6 +60,11 @@ type btrfs_ioctl_vol_args struct {
name [volNameMax + 1]byte
}
func (arg *btrfs_ioctl_vol_args) SetName(name string) {
n := copy(arg.name[:], name)
arg.name[n] = 0
}
type btrfs_qgroup_limit struct {
flags uint64
max_referenced uint64
@ -625,8 +630,8 @@ func iocDefrag(f *os.File, out *btrfs_ioctl_vol_args) error {
return ioctl.Do(f, _BTRFS_IOC_DEFRAG, out)
}
func iocResize(f *os.File, out *btrfs_ioctl_vol_args) error {
return ioctl.Do(f, _BTRFS_IOC_RESIZE, out)
func iocResize(f *os.File, in *btrfs_ioctl_vol_args) error {
return ioctl.Do(f, _BTRFS_IOC_RESIZE, in)
}
func iocScanDev(f *os.File, out *btrfs_ioctl_vol_args) error {

View File

@ -52,6 +52,21 @@ func Mount(mount string, file string) error {
return nil
}
func Unmount(mount string) error {
for i := 0; i < 5; i++ {
if err := run("umount", mount); err == nil {
break
} else {
if strings.Contains(err.Error(), "busy") {
time.Sleep(time.Second)
} else {
break
}
}
}
return nil
}
func New(t testing.TB, size int64) (string, func()) {
f, err := ioutil.TempFile("", "btrfs_vol")
if err != nil {
@ -85,17 +100,8 @@ func New(t testing.TB, size int64) (string, func()) {
if done {
return
}
for i := 0; i < 5; i++ {
if err := run("umount", mount); err == nil {
break
} else {
log.Println("umount failed:", err)
if strings.Contains(err.Error(), "busy") {
time.Sleep(time.Second)
} else {
break
}
}
if err := Unmount(mount); err != nil {
log.Println("umount failed:", err)
}
if err := os.Remove(mount); err != nil {
log.Println("cleanup failed:", err)