Skip to content
Permalink
Browse files

fs: implement Write for MemRegularFile

Change-Id: Iac5c1a8329ceb0d8538029bd737cfede2af4d9a2
  • Loading branch information...
hanwen committed Aug 5, 2019
1 parent e9498b6 commit a3bb2189dd75e519c3c70563526e09f04f08456e
Showing with 45 additions and 4 deletions.
  1. +34 −3 fs/mem.go
  2. +11 −1 fs/mem_test.go
@@ -6,6 +6,7 @@ package fs

import (
"context"
"sync"
"syscall"

"github.com/hanwen/go-fuse/v2/fuse"
@@ -15,35 +16,65 @@ import (
// slice in memory.
type MemRegularFile struct {
Inode

mu sync.Mutex
Data []byte
Attr fuse.Attr
}

var _ = (NodeOpener)((*MemRegularFile)(nil))
var _ = (NodeReader)((*MemRegularFile)(nil))
var _ = (NodeWriter)((*MemRegularFile)(nil))
var _ = (NodeSetattrer)((*MemRegularFile)(nil))
var _ = (NodeFlusher)((*MemRegularFile)(nil))

func (f *MemRegularFile) Open(ctx context.Context, flags uint32) (fh FileHandle, fuseFlags uint32, errno syscall.Errno) {
if flags&(syscall.O_RDWR) != 0 || flags&syscall.O_WRONLY != 0 {
return nil, 0, syscall.EPERM
return nil, fuse.FOPEN_KEEP_CACHE, OK
}

func (f *MemRegularFile) Write(ctx context.Context, fh FileHandle, data []byte, off int64) (uint32, syscall.Errno) {
f.mu.Lock()
defer f.mu.Unlock()
end := int64(len(data)) + off
if int64(len(f.Data)) < end {
n := make([]byte, end)
copy(n, f.Data)
f.Data = n
}

return nil, fuse.FOPEN_KEEP_CACHE, OK
copy(f.Data[off:off+int64(len(data))], data)

return uint32(len(data)), 0
}

var _ = (NodeGetattrer)((*MemRegularFile)(nil))

func (f *MemRegularFile) Getattr(ctx context.Context, fh FileHandle, out *fuse.AttrOut) syscall.Errno {
f.mu.Lock()
defer f.mu.Unlock()
out.Attr = f.Attr
out.Attr.Size = uint64(len(f.Data))
return OK
}

func (f *MemRegularFile) Setattr(ctx context.Context, fh FileHandle, in *fuse.SetAttrIn, out *fuse.AttrOut) syscall.Errno {
f.mu.Lock()
defer f.mu.Unlock()
if sz, ok := in.GetSize(); ok {
f.Data = f.Data[:sz]
}
out.Attr = f.Attr
out.Size = uint64(len(f.Data))
return OK
}

func (f *MemRegularFile) Flush(ctx context.Context, fh FileHandle) syscall.Errno {
return 0
}

func (f *MemRegularFile) Read(ctx context.Context, fh FileHandle, dest []byte, off int64) (fuse.ReadResult, syscall.Errno) {
f.mu.Lock()
defer f.mu.Unlock()
end := int(off) + len(dest)
if end > len(f.Data) {
end = len(f.Data)
@@ -64,7 +64,6 @@ func TestDefaultOwner(t *testing.T) {
} else if st.Uid != 42 || st.Gid != 43 {
t.Fatalf("Got Lstat %d, %d want 42,43", st.Uid, st.Gid)
}

}

func TestDataFile(t *testing.T) {
@@ -116,6 +115,17 @@ func TestDataFile(t *testing.T) {
if got != want {
t.Errorf("got %q want %q", got, want)
}

replace := []byte("replaced!")
if err := ioutil.WriteFile(mntDir+"/file", replace, 0644); err != nil {
t.Fatalf("WriteFile: %v", err)
}

if gotBytes, err := ioutil.ReadFile(mntDir + "/file"); err != nil {
t.Fatalf("ReadFile: %v", err)
} else if bytes.Compare(replace, gotBytes) != 0 {
t.Fatalf("read: got %q want %q", gotBytes, replace)
}
}

func TestDataFileLargeRead(t *testing.T) {

0 comments on commit a3bb218

Please sign in to comment.
You can’t perform that action at this time.