Commit 0e0d3f3b authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

fuse: remove custom BufferPool as tunable option

parent 9a423a77
......@@ -130,9 +130,6 @@ type MountOptions struct {
// interested in security labels.
IgnoreSecurityLabels bool // ignoring labels should be provided as a fusermount mount option.
// If given, use this buffer pool instead of the global one.
Buffers BufferPool
// If RememberInodes is set, we will never forget inodes.
// This may be useful for NFS.
RememberInodes bool
......
......@@ -9,39 +9,18 @@ import (
"sync"
)
// BufferPool implements explicit memory management. It is used for
// bufferPool implements explicit memory management. It is used for
// minimizing the GC overhead of communicating with the kernel.
type BufferPool interface {
// AllocBuffer creates a buffer of at least the given size. After use,
// it should be deallocated with FreeBuffer().
AllocBuffer(size uint32) []byte
// FreeBuffer takes back a buffer if it was allocated through
// AllocBuffer. It is not an error to call FreeBuffer() on a slice
// obtained elsewhere.
FreeBuffer(slice []byte)
}
type bufferPoolImpl struct {
type bufferPool struct {
lock sync.Mutex
// For each page size multiple a list of slice pointers.
buffersBySize []*sync.Pool
}
// NewBufferPool returns a BufferPool implementation that that returns
// slices with capacity of a multiple of page size, which have possibly
// been used, and may contain random contents. When using
// NewBufferPool, file system handlers may not hang on to passed-in
// buffers beyond the handler's return.
func NewBufferPool() BufferPool {
bp := new(bufferPoolImpl)
return bp
}
var pageSize = os.Getpagesize()
func (p *bufferPoolImpl) getPool(pageCount int) *sync.Pool {
func (p *bufferPool) getPool(pageCount int) *sync.Pool {
p.lock.Lock()
for len(p.buffersBySize) < pageCount+1 {
p.buffersBySize = append(p.buffersBySize, nil)
......@@ -56,7 +35,9 @@ func (p *bufferPoolImpl) getPool(pageCount int) *sync.Pool {
return pool
}
func (p *bufferPoolImpl) AllocBuffer(size uint32) []byte {
// AllocBuffer creates a buffer of at least the given size. After use,
// it should be deallocated with FreeBuffer().
func (p *bufferPool) AllocBuffer(size uint32) []byte {
sz := int(size)
if sz < pageSize {
sz = pageSize
......@@ -71,7 +52,10 @@ func (p *bufferPoolImpl) AllocBuffer(size uint32) []byte {
return b[:size]
}
func (p *bufferPoolImpl) FreeBuffer(slice []byte) {
// FreeBuffer takes back a buffer if it was allocated through
// AllocBuffer. It is not an error to call FreeBuffer() on a slice
// obtained elsewhere.
func (p *bufferPool) FreeBuffer(slice []byte) {
if slice == nil {
return
}
......
......@@ -9,11 +9,14 @@ import (
)
func TestBufferPool(t *testing.T) {
bp := NewBufferPool()
bp := bufferPool{}
size := 1500
buf := bp.AllocBuffer(uint32(size))
if len(buf) != size {
t.Errorf("Expected buffer of %d bytes, got %d bytes", size, len(buf))
buf1 := bp.AllocBuffer(uint32(size))
if len(buf1) != size {
t.Errorf("Expected buffer of %d bytes, got %d bytes", size, len(buf1))
}
bp.FreeBuffer(buf)
bp.FreeBuffer(buf1)
// tried testing to see if we get buf1 back if we ask again,
// but it's not guaranteed and sometimes fails
}
......@@ -39,6 +39,9 @@ type Server struct {
opts *MountOptions
// Pools for []byte
buffers bufferPool
// Pool for request structs.
reqPool sync.Pool
......@@ -132,9 +135,6 @@ func NewServer(fs RawFileSystem, mountPoint string, opts *MountOptions) (*Server
fs = NewLockingRawFileSystem(fs)
}
if o.Buffers == nil {
o.Buffers = defaultBufferPool
}
if o.MaxWrite < 0 {
o.MaxWrite = 0
}
......@@ -300,7 +300,7 @@ func (ms *Server) returnRequest(req *request) {
ms.recordStats(req)
if req.bufferPoolOutputBuf != nil {
ms.opts.Buffers.FreeBuffer(req.bufferPoolOutputBuf)
ms.buffers.FreeBuffer(req.bufferPoolOutputBuf)
req.bufferPoolOutputBuf = nil
}
......@@ -446,9 +446,9 @@ func (ms *Server) allocOut(req *request, size uint32) []byte {
return req.bufferPoolOutputBuf
}
if req.bufferPoolOutputBuf != nil {
ms.opts.Buffers.FreeBuffer(req.bufferPoolOutputBuf)
ms.buffers.FreeBuffer(req.bufferPoolOutputBuf)
}
req.bufferPoolOutputBuf = ms.opts.Buffers.AllocBuffer(size)
req.bufferPoolOutputBuf = ms.buffers.AllocBuffer(size)
return req.bufferPoolOutputBuf
}
......@@ -787,12 +787,6 @@ func (in *InitIn) SupportsNotify(notifyType int) bool {
return false
}
var defaultBufferPool BufferPool
func init() {
defaultBufferPool = NewBufferPool()
}
// WaitMount waits for the first request to be served. Use this to
// avoid racing between accessing the (empty or not yet mounted)
// mountpoint, and the OS trying to setup the user-space mount.
......
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