forked from RepoMirrors/btrfs
expose resize
This commit is contained in:
parent
532eaaa4b7
commit
3db12b2294
20
btrfs.go
20
btrfs.go
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user