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 {
// the inner file here.
InnerFile() File
Read(*ReadIn, BufferPool) ([]byte, Status)
Write(*WriteIn, []byte) (written uint32, code Status)
Read(dest []byte, off int64) ([]byte, Status)
Write(data []byte, off int64) (written uint32, code Status)
Flush() Status
Release()
Fsync(flags int) (code Status)
......@@ -278,7 +278,7 @@ type RawFileSystem interface {
// File handling.
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)
Read(*raw.InHeader, *ReadIn, BufferPool) ([]byte, Status)
Read(*raw.InHeader, *ReadIn, []byte) ([]byte, Status)
Release(header *raw.InHeader, input *raw.ReleaseIn)
Write(*raw.InHeader, *WriteIn, []byte) (written uint32, code Status)
......
......@@ -27,31 +27,27 @@ func CopyFile(srcFs, destFs FileSystem, srcFile, destFile string, context *Conte
defer dst.Release()
defer dst.Flush()
bp := NewBufferPool()
r := ReadIn{
Size: 128 * (1 << 10),
}
buf := make([]byte, 128 * (1 << 10))
off := int64(0)
for {
data, code := src.Read(&r, bp)
data, code := src.Read(buf, off)
if !code.Ok() {
return code
}
if len(data) == 0 {
break
}
n, code := dst.Write(&w, data)
n, code := dst.Write(data, off)
if !code.Ok() {
return code
}
if int(n) < len(data) {
return EIO
}
if len(data) < int(r.Size) {
if len(data) < len(buf) {
break
}
r.Offset += uint64(len(data))
w.Offset += uint64(len(data))
bp.FreeBuffer(data)
off += int64(len(data))
}
return OK
}
......@@ -19,11 +19,11 @@ func (f *DefaultFile) String() string {
return "DefaultFile"
}
func (f *DefaultFile) Read(*ReadIn, BufferPool) ([]byte, Status) {
return []byte(""), ENOSYS
func (f *DefaultFile) Read(buf []byte, off int64) ([]byte, Status) {
return nil, ENOSYS
}
func (f *DefaultFile) Write(*WriteIn, []byte) (uint32, Status) {
func (f *DefaultFile) Write(data []byte, off int64) (uint32, Status) {
return 0, ENOSYS
}
......
......@@ -97,7 +97,7 @@ func (fs *DefaultRawFileSystem) OpenDir(out *raw.OpenOut, header *raw.InHeader,
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
}
......
......@@ -17,6 +17,8 @@ type DataFile struct {
DefaultFile
}
var _ = (File)((*DataFile)(nil))
func (f *DataFile) String() string {
l := len(f.data)
if l > 10 {
......@@ -38,13 +40,13 @@ func NewDataFile(data []byte) *DataFile {
return f
}
func (f *DataFile) Read(input *ReadIn, bp BufferPool) ([]byte, Status) {
end := int(input.Offset) + int(input.Size)
func (f *DataFile) Read(buf []byte, off int64) ([]byte, Status) {
end := int(off) + int(len(buf))
if 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 {
return "DevNullFile"
}
func (f *DevNullFile) Read(input *ReadIn, bp BufferPool) ([]byte, Status) {
return []byte{}, OK
func (f *DevNullFile) Read(buf []byte, off int64) ([]byte, Status) {
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
}
......@@ -97,18 +99,16 @@ func (f *LoopbackFile) String() string {
return fmt.Sprintf("LoopbackFile(%s)", f.File.Name())
}
func (f *LoopbackFile) Read(input *ReadIn, buffers BufferPool) ([]byte, Status) {
slice := buffers.AllocBuffer(input.Size)
n, err := f.File.ReadAt(slice, int64(input.Offset))
func (f *LoopbackFile) Read(buf []byte, off int64) ([]byte, Status) {
n, err := f.File.ReadAt(buf, off)
if err == io.EOF {
err = nil
}
return slice[:n], ToStatus(err)
return buf[:n], ToStatus(err)
}
func (f *LoopbackFile) Write(input *WriteIn, data []byte) (uint32, Status) {
n, err := f.File.WriteAt(data, int64(input.Offset))
func (f *LoopbackFile) Write(data []byte, off int64) (uint32, Status) {
n, err := f.File.WriteAt(data, off)
return uint32(n), ToStatus(err)
}
......@@ -159,7 +159,7 @@ func (f *ReadOnlyFile) String() 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
}
......
......@@ -22,19 +22,19 @@ func (f *MutableDataFile) String() string {
return "MutableDataFile"
}
func (f *MutableDataFile) Read(r *ReadIn, bp BufferPool) ([]byte, Status) {
return f.data[r.Offset : r.Offset+uint64(r.Size)], OK
func (f *MutableDataFile) Read(buf []byte, off int64) ([]byte, Status) {
return f.data[off : off+int64(len(buf))], OK
}
func (f *MutableDataFile) Write(w *WriteIn, d []byte) (uint32, Status) {
end := uint64(w.Size) + w.Offset
func (f *MutableDataFile) Write(d []byte, off int64) (uint32, Status) {
end := int64(len(d)) + off
if int(end) > len(f.data) {
data := make([]byte, len(f.data), end)
copy(data, f.data)
f.data = data
}
copy(f.data[w.Offset:end], d)
return w.Size, OK
copy(f.data[off:end], d)
return uint32(end - off), OK
}
func (f *MutableDataFile) Flush() Status {
......
......@@ -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) {
node := c.toInode(header.NodeId)
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)
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 {
......
......@@ -276,9 +276,9 @@ func (fs *LockingRawFileSystem) ReleaseDir(header *raw.InHeader, h *raw.ReleaseI
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()()
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) {
......
......@@ -119,7 +119,7 @@ func doCreate(state *MountState, req *request) {
func doReadDir(state *MountState, req *request) {
in := (*ReadIn)(req.inData)
buf := state.buffers.AllocBuffer(in.Size)
buf := req.AllocOut(in.Size)
entries := NewDirEntryList(buf, uint64(in.Offset))
code := state.fileSystem.ReadDir(entries, req.inHeader, in)
......@@ -253,7 +253,9 @@ func doLink(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) {
......
......@@ -14,13 +14,22 @@ var sizeOfOutHeader = unsafe.Sizeof(raw.OutHeader{})
var zeroOutBuf [160]byte
func (req *request) Discard() {
req.pool.FreeBuffer(req.flatData)
req.pool.FreeBuffer(req.bufferPoolOutputBuf)
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 {
// the input, if obtained through bufferpool
bufferPoolInputBuf []byte
bufferPoolInputBuf []byte
bufferPoolOutputBuf []byte
pool BufferPool
// 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) {
}
defer f.Release()
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() {
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