Commit a88bf602 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Change file Read/Write API.

parent 40776fb9
...@@ -161,8 +161,8 @@ type File interface { ...@@ -161,8 +161,8 @@ type File interface {
// the inner file here. // the inner file here.
InnerFile() File InnerFile() File
Read(*ReadIn, BufferPool) ([]byte, Status) Read(dest []byte, off int64) ([]byte, Status)
Write(*WriteIn, []byte) (written uint32, code Status) Write(data []byte, off int64) (written uint32, code Status)
Flush() Status Flush() Status
Release() Release()
Fsync(flags int) (code Status) Fsync(flags int) (code Status)
...@@ -278,7 +278,7 @@ type RawFileSystem interface { ...@@ -278,7 +278,7 @@ type RawFileSystem interface {
// File handling. // File handling.
Create(out *raw.CreateOut, header *raw.InHeader, input *raw.CreateIn, name string) (code Status) Create(out *raw.CreateOut, header *raw.InHeader, input *raw.CreateIn, name string) (code Status)
Open(out *raw.OpenOut, header *raw.InHeader, input *raw.OpenIn) (status Status) Open(out *raw.OpenOut, header *raw.InHeader, input *raw.OpenIn) (status Status)
Read(*raw.InHeader, *ReadIn, BufferPool) ([]byte, Status) Read(*raw.InHeader, *ReadIn, []byte) ([]byte, Status)
Release(header *raw.InHeader, input *raw.ReleaseIn) Release(header *raw.InHeader, input *raw.ReleaseIn)
Write(*raw.InHeader, *WriteIn, []byte) (written uint32, code Status) Write(*raw.InHeader, *WriteIn, []byte) (written uint32, code Status)
......
...@@ -27,31 +27,27 @@ func CopyFile(srcFs, destFs FileSystem, srcFile, destFile string, context *Conte ...@@ -27,31 +27,27 @@ func CopyFile(srcFs, destFs FileSystem, srcFile, destFile string, context *Conte
defer dst.Release() defer dst.Release()
defer dst.Flush() defer dst.Flush()
bp := NewBufferPool() buf := make([]byte, 128 * (1 << 10))
r := ReadIn{ off := int64(0)
Size: 128 * (1 << 10),
}
for { for {
data, code := src.Read(&r, bp) data, code := src.Read(buf, off)
if !code.Ok() { if !code.Ok() {
return code return code
} }
if len(data) == 0 { if len(data) == 0 {
break break
} }
n, code := dst.Write(&w, data) n, code := dst.Write(data, off)
if !code.Ok() { if !code.Ok() {
return code return code
} }
if int(n) < len(data) { if int(n) < len(data) {
return EIO return EIO
} }
if len(data) < int(r.Size) { if len(data) < len(buf) {
break break
} }
r.Offset += uint64(len(data)) off += int64(len(data))
w.Offset += uint64(len(data))
bp.FreeBuffer(data)
} }
return OK return OK
} }
...@@ -19,11 +19,11 @@ func (f *DefaultFile) String() string { ...@@ -19,11 +19,11 @@ func (f *DefaultFile) String() string {
return "DefaultFile" return "DefaultFile"
} }
func (f *DefaultFile) Read(*ReadIn, BufferPool) ([]byte, Status) { func (f *DefaultFile) Read(buf []byte, off int64) ([]byte, Status) {
return []byte(""), ENOSYS return nil, ENOSYS
} }
func (f *DefaultFile) Write(*WriteIn, []byte) (uint32, Status) { func (f *DefaultFile) Write(data []byte, off int64) (uint32, Status) {
return 0, ENOSYS return 0, ENOSYS
} }
......
...@@ -97,7 +97,7 @@ func (fs *DefaultRawFileSystem) OpenDir(out *raw.OpenOut, header *raw.InHeader, ...@@ -97,7 +97,7 @@ func (fs *DefaultRawFileSystem) OpenDir(out *raw.OpenOut, header *raw.InHeader,
return ENOSYS return ENOSYS
} }
func (fs *DefaultRawFileSystem) Read(header *raw.InHeader, input *ReadIn, bp BufferPool) ([]byte, Status) { func (fs *DefaultRawFileSystem) Read(header *raw.InHeader, input *ReadIn, buf []byte) ([]byte, Status) {
return nil, ENOSYS return nil, ENOSYS
} }
......
...@@ -17,6 +17,8 @@ type DataFile struct { ...@@ -17,6 +17,8 @@ type DataFile struct {
DefaultFile DefaultFile
} }
var _ = (File)((*DataFile)(nil))
func (f *DataFile) String() string { func (f *DataFile) String() string {
l := len(f.data) l := len(f.data)
if l > 10 { if l > 10 {
...@@ -38,13 +40,13 @@ func NewDataFile(data []byte) *DataFile { ...@@ -38,13 +40,13 @@ func NewDataFile(data []byte) *DataFile {
return f return f
} }
func (f *DataFile) Read(input *ReadIn, bp BufferPool) ([]byte, Status) { func (f *DataFile) Read(buf []byte, off int64) ([]byte, Status) {
end := int(input.Offset) + int(input.Size) end := int(off) + int(len(buf))
if end > len(f.data) { if end > len(f.data) {
end = len(f.data) end = len(f.data)
} }
return f.data[input.Offset:end], OK return f.data[off:end], OK
} }
//////////////// ////////////////
...@@ -64,11 +66,11 @@ func (f *DevNullFile) String() string { ...@@ -64,11 +66,11 @@ func (f *DevNullFile) String() string {
return "DevNullFile" return "DevNullFile"
} }
func (f *DevNullFile) Read(input *ReadIn, bp BufferPool) ([]byte, Status) { func (f *DevNullFile) Read(buf []byte, off int64) ([]byte, Status) {
return []byte{}, OK return nil, OK
} }
func (f *DevNullFile) Write(input *WriteIn, content []byte) (uint32, Status) { func (f *DevNullFile) Write(content []byte, off int64) (uint32, Status) {
return uint32(len(content)), OK return uint32(len(content)), OK
} }
...@@ -97,18 +99,16 @@ func (f *LoopbackFile) String() string { ...@@ -97,18 +99,16 @@ func (f *LoopbackFile) String() string {
return fmt.Sprintf("LoopbackFile(%s)", f.File.Name()) return fmt.Sprintf("LoopbackFile(%s)", f.File.Name())
} }
func (f *LoopbackFile) Read(input *ReadIn, buffers BufferPool) ([]byte, Status) { func (f *LoopbackFile) Read(buf []byte, off int64) ([]byte, Status) {
slice := buffers.AllocBuffer(input.Size) n, err := f.File.ReadAt(buf, off)
n, err := f.File.ReadAt(slice, int64(input.Offset))
if err == io.EOF { if err == io.EOF {
err = nil err = nil
} }
return slice[:n], ToStatus(err) return buf[:n], ToStatus(err)
} }
func (f *LoopbackFile) Write(input *WriteIn, data []byte) (uint32, Status) { func (f *LoopbackFile) Write(data []byte, off int64) (uint32, Status) {
n, err := f.File.WriteAt(data, int64(input.Offset)) n, err := f.File.WriteAt(data, off)
return uint32(n), ToStatus(err) return uint32(n), ToStatus(err)
} }
...@@ -159,7 +159,7 @@ func (f *ReadOnlyFile) String() string { ...@@ -159,7 +159,7 @@ func (f *ReadOnlyFile) String() string {
return fmt.Sprintf("ReadOnlyFile(%s)", f.File.String()) return fmt.Sprintf("ReadOnlyFile(%s)", f.File.String())
} }
func (f *ReadOnlyFile) Write(input *WriteIn, data []byte) (uint32, Status) { func (f *ReadOnlyFile) Write(data []byte, off int64) (uint32, Status) {
return 0, EPERM return 0, EPERM
} }
......
...@@ -22,19 +22,19 @@ func (f *MutableDataFile) String() string { ...@@ -22,19 +22,19 @@ func (f *MutableDataFile) String() string {
return "MutableDataFile" return "MutableDataFile"
} }
func (f *MutableDataFile) Read(r *ReadIn, bp BufferPool) ([]byte, Status) { func (f *MutableDataFile) Read(buf []byte, off int64) ([]byte, Status) {
return f.data[r.Offset : r.Offset+uint64(r.Size)], OK return f.data[off : off+int64(len(buf))], OK
} }
func (f *MutableDataFile) Write(w *WriteIn, d []byte) (uint32, Status) { func (f *MutableDataFile) Write(d []byte, off int64) (uint32, Status) {
end := uint64(w.Size) + w.Offset end := int64(len(d)) + off
if int(end) > len(f.data) { if int(end) > len(f.data) {
data := make([]byte, len(f.data), end) data := make([]byte, len(f.data), end)
copy(data, f.data) copy(data, f.data)
f.data = data f.data = data
} }
copy(f.data[w.Offset:end], d) copy(f.data[off:end], d)
return w.Size, OK return uint32(end - off), OK
} }
func (f *MutableDataFile) Flush() Status { func (f *MutableDataFile) Flush() Status {
......
...@@ -347,13 +347,14 @@ func (c *FileSystemConnector) ListXAttr(header *raw.InHeader) (data []byte, code ...@@ -347,13 +347,14 @@ func (c *FileSystemConnector) ListXAttr(header *raw.InHeader) (data []byte, code
func (c *FileSystemConnector) Write(header *raw.InHeader, input *WriteIn, data []byte) (written uint32, code Status) { func (c *FileSystemConnector) Write(header *raw.InHeader, input *WriteIn, data []byte) (written uint32, code Status) {
node := c.toInode(header.NodeId) node := c.toInode(header.NodeId)
opened := node.mount.getOpenedFile(input.Fh) opened := node.mount.getOpenedFile(input.Fh)
return opened.WithFlags.File.Write(input, data) return opened.WithFlags.File.Write(data, int64(input.Offset))
} }
func (c *FileSystemConnector) Read(header *raw.InHeader, input *ReadIn, bp BufferPool) ([]byte, Status) { func (c *FileSystemConnector) Read(header *raw.InHeader, input *ReadIn, buf []byte) ([]byte, Status) {
node := c.toInode(header.NodeId) node := c.toInode(header.NodeId)
opened := node.mount.getOpenedFile(input.Fh) opened := node.mount.getOpenedFile(input.Fh)
return opened.WithFlags.File.Read(input, bp)
return opened.WithFlags.File.Read(buf, int64(input.Offset))
} }
func (c *FileSystemConnector) StatFs(out *StatfsOut, header *raw.InHeader) Status { func (c *FileSystemConnector) StatFs(out *StatfsOut, header *raw.InHeader) Status {
......
...@@ -276,9 +276,9 @@ func (fs *LockingRawFileSystem) ReleaseDir(header *raw.InHeader, h *raw.ReleaseI ...@@ -276,9 +276,9 @@ func (fs *LockingRawFileSystem) ReleaseDir(header *raw.InHeader, h *raw.ReleaseI
fs.RawFileSystem.ReleaseDir(header, h) fs.RawFileSystem.ReleaseDir(header, h)
} }
func (fs *LockingRawFileSystem) Read(header *raw.InHeader, input *ReadIn, bp BufferPool) ([]byte, Status) { func (fs *LockingRawFileSystem) Read(header *raw.InHeader, input *ReadIn, buf []byte) ([]byte, Status) {
defer fs.locked()() defer fs.locked()()
return fs.RawFileSystem.Read(header, input, bp) return fs.RawFileSystem.Read(header, input, buf)
} }
func (fs *LockingRawFileSystem) Write(header *raw.InHeader, input *WriteIn, data []byte) (written uint32, code Status) { func (fs *LockingRawFileSystem) Write(header *raw.InHeader, input *WriteIn, data []byte) (written uint32, code Status) {
......
...@@ -119,7 +119,7 @@ func doCreate(state *MountState, req *request) { ...@@ -119,7 +119,7 @@ func doCreate(state *MountState, req *request) {
func doReadDir(state *MountState, req *request) { func doReadDir(state *MountState, req *request) {
in := (*ReadIn)(req.inData) in := (*ReadIn)(req.inData)
buf := state.buffers.AllocBuffer(in.Size) buf := req.AllocOut(in.Size)
entries := NewDirEntryList(buf, uint64(in.Offset)) entries := NewDirEntryList(buf, uint64(in.Offset))
code := state.fileSystem.ReadDir(entries, req.inHeader, in) code := state.fileSystem.ReadDir(entries, req.inHeader, in)
...@@ -253,7 +253,9 @@ func doLink(state *MountState, req *request) { ...@@ -253,7 +253,9 @@ func doLink(state *MountState, req *request) {
} }
func doRead(state *MountState, req *request) { func doRead(state *MountState, req *request) {
req.flatData, req.status = state.fileSystem.Read(req.inHeader, (*ReadIn)(req.inData), state.buffers) in := (*ReadIn)(req.inData)
buf := req.AllocOut(in.Size)
req.flatData, req.status = state.fileSystem.Read(req.inHeader, in, buf)
} }
func doFlush(state *MountState, req *request) { func doFlush(state *MountState, req *request) {
......
...@@ -14,13 +14,22 @@ var sizeOfOutHeader = unsafe.Sizeof(raw.OutHeader{}) ...@@ -14,13 +14,22 @@ var sizeOfOutHeader = unsafe.Sizeof(raw.OutHeader{})
var zeroOutBuf [160]byte var zeroOutBuf [160]byte
func (req *request) Discard() { func (req *request) Discard() {
req.pool.FreeBuffer(req.flatData) req.pool.FreeBuffer(req.bufferPoolOutputBuf)
req.pool.FreeBuffer(req.bufferPoolInputBuf) req.pool.FreeBuffer(req.bufferPoolInputBuf)
} }
func (req *request) AllocOut(size uint32) []byte {
if req.bufferPoolOutputBuf != nil {
req.pool.FreeBuffer(req.bufferPoolOutputBuf)
}
req.bufferPoolOutputBuf = req.pool.AllocBuffer(size)
return req.pool.AllocBuffer(size)
}
type request struct { type request struct {
// the input, if obtained through bufferpool // the input, if obtained through bufferpool
bufferPoolInputBuf []byte bufferPoolInputBuf []byte
bufferPoolOutputBuf []byte
pool BufferPool pool BufferPool
// If we have a small input, we quickly copy it to here, and // If we have a small input, we quickly copy it to here, and
......
...@@ -257,7 +257,7 @@ func (fs *UnionFs) putDeletion(name string) (code fuse.Status) { ...@@ -257,7 +257,7 @@ func (fs *UnionFs) putDeletion(name string) (code fuse.Status) {
} }
defer f.Release() defer f.Release()
defer f.Flush() defer f.Flush()
n, code := f.Write(&fuse.WriteIn{}, []byte(name)) n, code := f.Write([]byte(name), 0)
if int(n) != len(name) || !code.Ok() { if int(n) != len(name) || !code.Ok() {
panic(fmt.Sprintf("Error for writing %v: %v, %v (exp %v) %v", name, marker, n, len(name), code)) panic(fmt.Sprintf("Error for writing %v: %v, %v (exp %v) %v", name, marker, n, len(name), code))
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment