mirror of
https://github.com/dennwc/btrfs
synced 2025-03-11 06:48:27 +00:00
expose resize
This commit is contained in:
parent
532eaaa4b7
commit
3db12b2294
20
btrfs.go
20
btrfs.go
@ -6,6 +6,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"syscall"
|
"syscall"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -242,3 +243,22 @@ func (f *FS) Balance(flags BalanceFlags) (BalanceProgress, error) {
|
|||||||
err := iocBalanceV2(f.f, &args)
|
err := iocBalanceV2(f.f, &args)
|
||||||
return args.stat, err
|
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 (
|
import (
|
||||||
"github.com/dennwc/btrfs/test"
|
"github.com/dennwc/btrfs/test"
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"reflect"
|
"reflect"
|
||||||
@ -215,3 +216,62 @@ func TestCloneFile(t *testing.T) {
|
|||||||
t.Fatalf("wrong data returned: %q", string(buf))
|
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
|
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 {
|
type btrfs_qgroup_limit struct {
|
||||||
flags uint64
|
flags uint64
|
||||||
max_referenced 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)
|
return ioctl.Do(f, _BTRFS_IOC_DEFRAG, out)
|
||||||
}
|
}
|
||||||
|
|
||||||
func iocResize(f *os.File, out *btrfs_ioctl_vol_args) error {
|
func iocResize(f *os.File, in *btrfs_ioctl_vol_args) error {
|
||||||
return ioctl.Do(f, _BTRFS_IOC_RESIZE, out)
|
return ioctl.Do(f, _BTRFS_IOC_RESIZE, in)
|
||||||
}
|
}
|
||||||
|
|
||||||
func iocScanDev(f *os.File, out *btrfs_ioctl_vol_args) error {
|
func iocScanDev(f *os.File, out *btrfs_ioctl_vol_args) error {
|
||||||
|
@ -52,6 +52,21 @@ func Mount(mount string, file string) error {
|
|||||||
return nil
|
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()) {
|
func New(t testing.TB, size int64) (string, func()) {
|
||||||
f, err := ioutil.TempFile("", "btrfs_vol")
|
f, err := ioutil.TempFile("", "btrfs_vol")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -85,17 +100,8 @@ func New(t testing.TB, size int64) (string, func()) {
|
|||||||
if done {
|
if done {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for i := 0; i < 5; i++ {
|
if err := Unmount(mount); err != nil {
|
||||||
if err := run("umount", mount); err == nil {
|
log.Println("umount failed:", err)
|
||||||
break
|
|
||||||
} else {
|
|
||||||
log.Println("umount failed:", err)
|
|
||||||
if strings.Contains(err.Error(), "busy") {
|
|
||||||
time.Sleep(time.Second)
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if err := os.Remove(mount); err != nil {
|
if err := os.Remove(mount); err != nil {
|
||||||
log.Println("cleanup failed:", err)
|
log.Println("cleanup failed:", err)
|
||||||
|
Loading…
Reference in New Issue
Block a user