Can someone tell me what it is that I'm failing to understand with file
truncation/write and FUSE?

The issue is demonstrated here with this code (exerted from [1] in
sisyphus_test.go):

f, err := os.OpenFile(fusemountedfilename, os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
        log.Fatalf("unexpected error opening rw buffer: %v", err)
}

// other data writing and reading... then

err = f.Truncate(0)
if err != nil {
        log.Fatalf("unexpected error truncating rw buffer: %v", err)
}
_, err = f.Write(data) // Causes panic in server below.


[1]https://github.com/ev3go/sisyphus/tree/e7c5bdfd0a7f29ca88f2c0d9d90e99f219ffbead

2016/09/05 02:57:52 fuse: panic in handler for Write [ID=0x25 Node=0x8
Uid=1000 Gid=1000 Pid=3299] 0x2 17 @31 fl=0 lock=0 ffl=OpenReadWrite:
runtime error: slice bounds out of range

goroutine 50 [running]:
bazil.org/fuse/fs.(*Server).serve.func2(0x65e4a0, 0xc4200a4460, 0xc420042ec8, 
0xc420042e1f)
        /home/travis/gopath/src/bazil.org/fuse/fs/serve.go:857 +0x1d9
panic(0x5702e0, 0xc420018150)
        /home/travis/.gimme/versions/go1.7.linux.amd64/src/runtime/panic.go:458 
+0x243
github.com/ev3go/sisyphus.(*Bytes).WriteAt(0xc42000c680, 0xc42014a050, 0x11, 
0x20fb0, 0x1f, 0x590ba0, 0xc420042901, 0x7fd968d874c0)
        /home/travis/gopath/src/github.com/ev3go/sisyphus/sisyphus.go:102 +0x115
github.com/ev3go/sisyphus.(*RW).Write(0xc420022240, 0x7fd968d44000, 
0xc420015a40, 0xc4200a4460, 0xc4200191b8, 0x0, 0x0)
        /home/travis/gopath/src/github.com/ev3go/sisyphus/rw_node.go:161 +0xf7
bazil.org/fuse/fs.(*Server).handleRequest(0xc4200d0000, 0x7fd968d44000, 
0xc420015a40, 0x7fd968d48230, 0xc420022240, 0xc4200987c0, 0x65e4a0, 
0xc4200a4460, 0xc420042ec8, 0x0, ...)
        /home/travis/gopath/src/bazil.org/fuse/fs/serve.go:1265 +0x1877
bazil.org/fuse/fs.(*Server).serve(0xc4200d0000, 0x65e4a0, 0xc4200a4460)
        /home/travis/gopath/src/bazil.org/fuse/fs/serve.go:878 +0x4a3
bazil.org/fuse/fs.(*Server).Serve.func1(0xc4200d0000, 0x65e4a0, 0xc4200a4460)
        /home/travis/gopath/src/bazil.org/fuse/fs/serve.go:425 +0x6e
created by bazil.org/fuse/fs.(*Server).Serve
        /home/travis/gopath/src/bazil.org/fuse/fs/serve.go:426 +0x3e4


The relevant server code is here

//line rw_node.go:147
// Write satisfies the bazil.org/fuse/fs.HandleWriter interface.
func (f *RW) Write(ctx context.Context, req *fuse.WriteRequest, resp 
*fuse.WriteResponse) error {
        f.mu.Lock()
        defer f.mu.Unlock()

        f.mtime = f.fs.now()

        var err error
        if req.FileFlags&fuse.OpenTruncate != 0 {
                err = f.dev.Truncate(req.Offset)
                if err != nil {
                        return err
                }
        }
        resp.Size, err = f.dev.WriteAt(req.Data, req.Offset) // PANIC
        return err
}

and implementations (the RW dev field is an interface implementing the
following methods) here

//line sisyphus.go:91
// Truncate truncates the Bytes at n bytes from the beginning of the slice.
func (f *Bytes) Truncate(n int64) error {
        if n < 0 || n > int64(len(*f)) {
                return syscall.EINVAL
        }
        (*f) = (*f)[:n]
        return nil
}

//line sisyphus.go:100
// WriteAt satisfies the io.WriterAt interface.
func (f *Bytes) WriteAt(b []byte, off int64) (int, error) {
        (*f) = append((*f)[off:], b...) // PANIC due to off > 0.
        return len(b), nil
}


Clearly I'm misunderstanding how truncating writes are handled; the
writeable file implementations actively truncate the bytes prior to a
write, leading to a WriteAt with the off being greater than the (zero)
length of the byte slice. However, if I don't do this I end up with the
data being appended to the end of the data that exists without
truncation.

There is undoubtedly something really trivial I'm missing here about how
unix files work (shame). Can someone point me to what that is?

thanks
Dan

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to