add support for fallocate (#66)
* Fallocate support * use fallocate wrapper that works on darwingeesefs-0-30-9
parent
081e9f4bc7
commit
4ee1cf7f62
|
@ -546,6 +546,21 @@ func convertInMessage(
|
||||||
Value: value,
|
Value: value,
|
||||||
Flags: in.Flags,
|
Flags: in.Flags,
|
||||||
}
|
}
|
||||||
|
case fusekernel.OpFallocate:
|
||||||
|
type input fusekernel.FallocateIn
|
||||||
|
in := (*input)(inMsg.Consume(unsafe.Sizeof(input{})))
|
||||||
|
if in == nil {
|
||||||
|
err = errors.New("Corrupt OpFallocate")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
o = &fuseops.FallocateOp{
|
||||||
|
Inode: fuseops.InodeID(inMsg.Header().Nodeid),
|
||||||
|
Handle: fuseops.HandleID(in.Fh),
|
||||||
|
Offset: in.Offset,
|
||||||
|
Length: in.Length,
|
||||||
|
Mode: in.Mode,
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
o = &unknownOp{
|
o = &unknownOp{
|
||||||
|
@ -793,6 +808,9 @@ func (c *Connection) kernelResponseForOp(
|
||||||
case *fuseops.SetXattrOp:
|
case *fuseops.SetXattrOp:
|
||||||
// Empty response
|
// Empty response
|
||||||
|
|
||||||
|
case *fuseops.FallocateOp:
|
||||||
|
// Empty response
|
||||||
|
|
||||||
case *initOp:
|
case *initOp:
|
||||||
out := (*fusekernel.InitOut)(m.Grow(int(unsafe.Sizeof(fusekernel.InitOut{}))))
|
out := (*fusekernel.InitOut)(m.Grow(int(unsafe.Sizeof(fusekernel.InitOut{}))))
|
||||||
|
|
||||||
|
|
5
debug.go
5
debug.go
|
@ -98,6 +98,11 @@ func describeRequest(op interface{}) (s string) {
|
||||||
|
|
||||||
case *fuseops.SetXattrOp:
|
case *fuseops.SetXattrOp:
|
||||||
addComponent("name %s", typed.Name)
|
addComponent("name %s", typed.Name)
|
||||||
|
|
||||||
|
case *fuseops.FallocateOp:
|
||||||
|
addComponent("offset %d", typed.Offset)
|
||||||
|
addComponent("length %d", typed.Length)
|
||||||
|
addComponent("mode %d", typed.Mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use just the name if there is no extra info.
|
// Use just the name if there is no extra info.
|
||||||
|
|
|
@ -865,3 +865,22 @@ type SetXattrOp struct {
|
||||||
// simply replace the value if the attribute exists.
|
// simply replace the value if the attribute exists.
|
||||||
Flags uint32
|
Flags uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FallocateOp struct {
|
||||||
|
// The inode and handle we are fallocating
|
||||||
|
Inode InodeID
|
||||||
|
Handle HandleID
|
||||||
|
|
||||||
|
// Start of the byte range
|
||||||
|
Offset uint64
|
||||||
|
|
||||||
|
// Length of the byte range
|
||||||
|
Length uint64
|
||||||
|
|
||||||
|
// If Mode is 0x0, allocate disk space within the range specified
|
||||||
|
// If Mode has 0x1, allocate the space but don't increase the file size
|
||||||
|
// If Mode has 0x2, deallocate space within the range specified
|
||||||
|
// If Mode has 0x2, it sbould also have 0x1 (deallocate should not increase
|
||||||
|
// file size)
|
||||||
|
Mode uint32
|
||||||
|
}
|
||||||
|
|
|
@ -61,6 +61,7 @@ type FileSystem interface {
|
||||||
GetXattr(context.Context, *fuseops.GetXattrOp) error
|
GetXattr(context.Context, *fuseops.GetXattrOp) error
|
||||||
ListXattr(context.Context, *fuseops.ListXattrOp) error
|
ListXattr(context.Context, *fuseops.ListXattrOp) error
|
||||||
SetXattr(context.Context, *fuseops.SetXattrOp) error
|
SetXattr(context.Context, *fuseops.SetXattrOp) error
|
||||||
|
Fallocate(context.Context, *fuseops.FallocateOp) error
|
||||||
|
|
||||||
// Regard all inodes (including the root inode) as having their lookup counts
|
// Regard all inodes (including the root inode) as having their lookup counts
|
||||||
// decremented to zero, and clean up any resources associated with the file
|
// decremented to zero, and clean up any resources associated with the file
|
||||||
|
@ -215,6 +216,9 @@ func (s *fileSystemServer) handleOp(
|
||||||
|
|
||||||
case *fuseops.SetXattrOp:
|
case *fuseops.SetXattrOp:
|
||||||
err = s.fs.SetXattr(ctx, typed)
|
err = s.fs.SetXattr(ctx, typed)
|
||||||
|
|
||||||
|
case *fuseops.FallocateOp:
|
||||||
|
err = s.fs.Fallocate(ctx, typed)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.Reply(ctx, err)
|
c.Reply(ctx, err)
|
||||||
|
|
|
@ -219,5 +219,12 @@ func (fs *NotImplementedFileSystem) SetXattr(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fs *NotImplementedFileSystem) Fallocate(
|
||||||
|
ctx context.Context,
|
||||||
|
op *fuseops.FallocateOp) (err error) {
|
||||||
|
err = fuse.ENOSYS
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (fs *NotImplementedFileSystem) Destroy() {
|
func (fs *NotImplementedFileSystem) Destroy() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -380,6 +380,7 @@ const (
|
||||||
OpDestroy = 38
|
OpDestroy = 38
|
||||||
OpIoctl = 39 // Linux?
|
OpIoctl = 39 // Linux?
|
||||||
OpPoll = 40 // Linux?
|
OpPoll = 40 // Linux?
|
||||||
|
OpFallocate = 43
|
||||||
|
|
||||||
// OS X
|
// OS X
|
||||||
OpSetvolname = 61
|
OpSetvolname = 61
|
||||||
|
@ -665,6 +666,14 @@ type ListxattrIn struct {
|
||||||
Padding uint32
|
Padding uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FallocateIn struct {
|
||||||
|
Fh uint64
|
||||||
|
Offset uint64
|
||||||
|
Length uint64
|
||||||
|
Mode uint32
|
||||||
|
Padding uint32
|
||||||
|
}
|
||||||
|
|
||||||
type LkIn struct {
|
type LkIn struct {
|
||||||
Fh uint64
|
Fh uint64
|
||||||
Owner uint64
|
Owner uint64
|
||||||
|
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/jacobsa/fuse"
|
||||||
"github.com/jacobsa/fuse/fuseops"
|
"github.com/jacobsa/fuse/fuseops"
|
||||||
"github.com/jacobsa/fuse/fuseutil"
|
"github.com/jacobsa/fuse/fuseutil"
|
||||||
)
|
)
|
||||||
|
@ -382,3 +383,18 @@ func (in *inode) SetAttributes(
|
||||||
in.attrs.Mtime = *mtime
|
in.attrs.Mtime = *mtime
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (in *inode) Fallocate(mode uint32, offset uint64, length uint64) (
|
||||||
|
err error) {
|
||||||
|
if mode == 0 {
|
||||||
|
newSize := int(offset + length)
|
||||||
|
if newSize > len(in.contents) {
|
||||||
|
padding := make([]byte, newSize-len(in.contents))
|
||||||
|
in.contents = append(in.contents, padding...)
|
||||||
|
in.attrs.Size = offset + length
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err = fuse.ENOSYS
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -753,3 +753,12 @@ func (fs *memFS) SetXattr(ctx context.Context,
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fs *memFS) Fallocate(ctx context.Context,
|
||||||
|
op *fuseops.FallocateOp) (err error) {
|
||||||
|
fs.mu.Lock()
|
||||||
|
defer fs.mu.Unlock()
|
||||||
|
inode := fs.getInodeOrDie(op.Inode)
|
||||||
|
inode.Fallocate(op.Mode, op.Length, op.Length)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
fallocate "github.com/detailyang/go-fallocate"
|
||||||
"github.com/jacobsa/fuse"
|
"github.com/jacobsa/fuse"
|
||||||
"github.com/jacobsa/fuse/fusetesting"
|
"github.com/jacobsa/fuse/fusetesting"
|
||||||
"github.com/jacobsa/fuse/samples"
|
"github.com/jacobsa/fuse/samples"
|
||||||
|
@ -1955,3 +1956,31 @@ func (t *MknodTest) NonExistentParent() {
|
||||||
err = syscall.Mknod(p, syscall.S_IFREG|0600, 0)
|
err = syscall.Mknod(p, syscall.S_IFREG|0600, 0)
|
||||||
ExpectEq(syscall.ENOENT, err)
|
ExpectEq(syscall.ENOENT, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *MknodTest) Fallocate_Larger() {
|
||||||
|
var err error
|
||||||
|
fileName := path.Join(t.Dir, "foo")
|
||||||
|
|
||||||
|
// Create a file.
|
||||||
|
err = ioutil.WriteFile(fileName, []byte("taco"), 0600)
|
||||||
|
AssertEq(nil, err)
|
||||||
|
|
||||||
|
// Open it for modification.
|
||||||
|
f, err := os.OpenFile(fileName, os.O_RDWR, 0)
|
||||||
|
t.ToClose = append(t.ToClose, f)
|
||||||
|
AssertEq(nil, err)
|
||||||
|
|
||||||
|
// Truncate it.
|
||||||
|
err = fallocate.Fallocate(f, 5, 1)
|
||||||
|
AssertEq(nil, err)
|
||||||
|
|
||||||
|
// Stat it.
|
||||||
|
fi, err := f.Stat()
|
||||||
|
AssertEq(nil, err)
|
||||||
|
ExpectEq(6, fi.Size())
|
||||||
|
|
||||||
|
// Read the contents.
|
||||||
|
contents, err := ioutil.ReadFile(fileName)
|
||||||
|
AssertEq(nil, err)
|
||||||
|
ExpectEq("taco\x00\x00", string(contents))
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue