mirror of
https://github.com/versity/scoutfs-go.git
synced 2026-01-05 03:24:07 +00:00
add scoutfs move_blocks
This commit is contained in:
@@ -62,6 +62,7 @@ package scoutfs
|
||||
// };
|
||||
//
|
||||
// typedef struct scoutfs_ioctl_alloc_detail_entry_mod scoutfs_ioctl_alloc_detail_entry_t;
|
||||
// typedef struct scoutfs_ioctl_move_blocks scoutfs_ioctl_move_blocks_t;
|
||||
import "C"
|
||||
|
||||
const IOCQUERYINODES = C.SCOUTFS_IOC_WALK_INODES
|
||||
@@ -76,6 +77,7 @@ const IOCSEARCHXATTRS = C.SCOUTFS_IOC_SEARCH_XATTRS
|
||||
const IOCSTATFSMORE = C.SCOUTFS_IOC_STATFS_MORE
|
||||
const IOCDATAWAITERR = C.SCOUTFS_IOC_DATA_WAIT_ERR
|
||||
const IOCALLOCDETAIL = C.SCOUTFS_IOC_ALLOC_DETAIL
|
||||
const IOCMOVEBLOCKS = C.SCOUTFS_IOC_MOVE_BLOCKS
|
||||
|
||||
const QUERYINODESMETASEQ = C.SCOUTFS_IOC_WALK_INODES_META_SEQ
|
||||
const QUERYINODESDATASEQ = C.SCOUTFS_IOC_WALK_INODES_DATA_SEQ
|
||||
@@ -101,5 +103,6 @@ type searchXattrs C.scoutfs_ioctl_search_xattrs_t
|
||||
type statfsMore C.scoutfs_ioctl_statfs_more_t
|
||||
type allocDetail C.scoutfs_ioctl_alloc_detail_t
|
||||
type allocDetailEntry C.scoutfs_ioctl_alloc_detail_entry_t
|
||||
type moveBlocks C.scoutfs_ioctl_move_blocks_t
|
||||
|
||||
const sizeofstatfsMore = C.sizeof_scoutfs_ioctl_statfs_more_t
|
||||
|
||||
41
examples/moveblocks/main.go
Normal file
41
examples/moveblocks/main.go
Normal file
@@ -0,0 +1,41 @@
|
||||
// Copyright (c) 2021 Versity Software, Inc.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-3-Clause license
|
||||
// that can be found in the LICENSE file in the root of the source
|
||||
// tree.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
scoutfs "github.com/versity/scoutfs-go"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if len(os.Args) != 3 || os.Args[1] == "-h" {
|
||||
fmt.Fprintln(os.Stderr, "usage:", os.Args[0], "<file_to_move_blocks_from> <file_to_append_blocks_to>")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
ffrom, err := os.OpenFile(os.Args[1], os.O_RDWR, 0666)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "open %v: %v\n", os.Args[1], err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer ffrom.Close()
|
||||
|
||||
fto, err := os.OpenFile(os.Args[2], os.O_RDWR, 0666)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "open %v: %v\n", os.Args[2], err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer fto.Close()
|
||||
|
||||
err = scoutfs.MoveData(ffrom, fto)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr, "move blocks: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
42
scoutfs.go
42
scoutfs.go
@@ -10,6 +10,7 @@ import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math"
|
||||
"os"
|
||||
@@ -716,3 +717,44 @@ func GetDF(f *os.File) (DiskUsage, error) {
|
||||
FreeDataBlocks: dataFree,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// MoveData will move all of the extents in "from" file handle
|
||||
// and append to the end of "to" file handle.
|
||||
// The end of "to" must be 4KB aligned boundary.
|
||||
// errors this can return:
|
||||
// EINVAL: from_off, len, or to_off aren't a multiple of 4KB; the source
|
||||
// and destination files are the same inode; either the source or
|
||||
// destination is not a regular file; the destination file has
|
||||
// an existing overlapping extent.
|
||||
// EOVERFLOW: either from_off + len or to_off + len exceeded 64bits.
|
||||
// EBADF: from_fd isn't a valid open file descriptor.
|
||||
// EXDEV: the source and destination files are in different filesystems.
|
||||
// EISDIR: either the source or destination is a directory.
|
||||
// ENODATA: either the source or destination file have offline extents.
|
||||
func MoveData(from, to *os.File) error {
|
||||
ffi, err := from.Stat()
|
||||
if err != nil {
|
||||
return fmt.Errorf("stat from: %v", err)
|
||||
}
|
||||
tfi, err := to.Stat()
|
||||
if err != nil {
|
||||
return fmt.Errorf("stat to: %v", err)
|
||||
}
|
||||
|
||||
mb := moveBlocks{
|
||||
From_fd: uint64(from.Fd()),
|
||||
From_off: 0,
|
||||
Len: uint64(ffi.Size()),
|
||||
To_off: uint64(tfi.Size()),
|
||||
}
|
||||
|
||||
_, err = scoutfsctl(to, IOCMOVEBLOCKS, unsafe.Pointer(&mb))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
from.Truncate(0)
|
||||
from.Seek(0, io.SeekStart)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ const IOCSEARCHXATTRS = 0x80387309
|
||||
const IOCSTATFSMORE = 0x8030730a
|
||||
const IOCDATAWAITERR = 0x8030730b
|
||||
const IOCALLOCDETAIL = 0x8010730c
|
||||
const IOCMOVEBLOCKS = 0x8020730d
|
||||
|
||||
const QUERYINODESMETASEQ = 0x0
|
||||
const QUERYINODESDATASEQ = 0x1
|
||||
@@ -132,5 +133,11 @@ type allocDetailEntry struct {
|
||||
Flags uint8
|
||||
Pad_cgo_0 [6]byte
|
||||
}
|
||||
type moveBlocks struct {
|
||||
From_fd uint64
|
||||
From_off uint64
|
||||
Len uint64
|
||||
To_off uint64
|
||||
}
|
||||
|
||||
const sizeofstatfsMore = 0x30
|
||||
|
||||
Reference in New Issue
Block a user