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,
|
||||
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:
|
||||
o = &unknownOp{
|
||||
|
@ -793,6 +808,9 @@ func (c *Connection) kernelResponseForOp(
|
|||
case *fuseops.SetXattrOp:
|
||||
// Empty response
|
||||
|
||||
case *fuseops.FallocateOp:
|
||||
// Empty response
|
||||
|
||||
case *initOp:
|
||||
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:
|
||||
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.
|
||||
|
|
|
@ -865,3 +865,22 @@ type SetXattrOp struct {
|
|||
// simply replace the value if the attribute exists.
|
||||
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
|
||||
ListXattr(context.Context, *fuseops.ListXattrOp) 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
|
||||
// decremented to zero, and clean up any resources associated with the file
|
||||
|
@ -215,6 +216,9 @@ func (s *fileSystemServer) handleOp(
|
|||
|
||||
case *fuseops.SetXattrOp:
|
||||
err = s.fs.SetXattr(ctx, typed)
|
||||
|
||||
case *fuseops.FallocateOp:
|
||||
err = s.fs.Fallocate(ctx, typed)
|
||||
}
|
||||
|
||||
c.Reply(ctx, err)
|
||||
|
|
|
@ -219,5 +219,12 @@ func (fs *NotImplementedFileSystem) SetXattr(
|
|||
return
|
||||
}
|
||||
|
||||
func (fs *NotImplementedFileSystem) Fallocate(
|
||||
ctx context.Context,
|
||||
op *fuseops.FallocateOp) (err error) {
|
||||
err = fuse.ENOSYS
|
||||
return
|
||||
}
|
||||
|
||||
func (fs *NotImplementedFileSystem) Destroy() {
|
||||
}
|
||||
|
|
|
@ -380,6 +380,7 @@ const (
|
|||
OpDestroy = 38
|
||||
OpIoctl = 39 // Linux?
|
||||
OpPoll = 40 // Linux?
|
||||
OpFallocate = 43
|
||||
|
||||
// OS X
|
||||
OpSetvolname = 61
|
||||
|
@ -665,6 +666,14 @@ type ListxattrIn struct {
|
|||
Padding uint32
|
||||
}
|
||||
|
||||
type FallocateIn struct {
|
||||
Fh uint64
|
||||
Offset uint64
|
||||
Length uint64
|
||||
Mode uint32
|
||||
Padding uint32
|
||||
}
|
||||
|
||||
type LkIn struct {
|
||||
Fh uint64
|
||||
Owner uint64
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/jacobsa/fuse"
|
||||
"github.com/jacobsa/fuse/fuseops"
|
||||
"github.com/jacobsa/fuse/fuseutil"
|
||||
)
|
||||
|
@ -382,3 +383,18 @@ func (in *inode) SetAttributes(
|
|||
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
|
||||
}
|
||||
|
||||
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"
|
||||
"time"
|
||||
|
||||
fallocate "github.com/detailyang/go-fallocate"
|
||||
"github.com/jacobsa/fuse"
|
||||
"github.com/jacobsa/fuse/fusetesting"
|
||||
"github.com/jacobsa/fuse/samples"
|
||||
|
@ -1955,3 +1956,31 @@ func (t *MknodTest) NonExistentParent() {
|
|||
err = syscall.Mknod(p, syscall.S_IFREG|0600, 0)
|
||||
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