Commit 1dcc6791 authored by Andrew Gaul's avatar Andrew Gaul

Report physical blocks used

Tools like du and ls -l use this value to calculate the space used.
Force block size to 512 bytes for simplicity and compatibility with
Mac OS X which uses an older FUSE.
parent bc664bf3
...@@ -633,6 +633,8 @@ func convertAttributes( ...@@ -633,6 +633,8 @@ func convertAttributes(
out.Nlink = in.Nlink out.Nlink = in.Nlink
out.Uid = in.Uid out.Uid = in.Uid
out.Gid = in.Gid out.Gid = in.Gid
// round up to the nearest 512 boundary
out.Blocks = (in.Size + 512 - 1) / 512
// Set the mode. // Set the mode.
out.Mode = uint32(in.Mode) & 0777 out.Mode = uint32(in.Mode) & 0777
......
...@@ -40,6 +40,9 @@ type FS interface { ...@@ -40,6 +40,9 @@ type FS interface {
// Set the canned response to be used for future statfs ops. // Set the canned response to be used for future statfs ops.
SetStatFSResponse(r fuseops.StatFSOp) SetStatFSResponse(r fuseops.StatFSOp)
// Set the canned response to be used for future stat ops.
SetStatResponse(r fuseops.InodeAttributes)
// Return the size of the most recent write delivered by the kernel, or -1 if // Return the size of the most recent write delivered by the kernel, or -1 if
// none. // none.
MostRecentWriteSize() int MostRecentWriteSize() int
...@@ -47,6 +50,9 @@ type FS interface { ...@@ -47,6 +50,9 @@ type FS interface {
func New() (fs FS) { func New() (fs FS) {
fs = &statFS{ fs = &statFS{
cannedStatResponse: fuseops.InodeAttributes{
Mode: 0666,
},
mostRecentWriteSize: -1, mostRecentWriteSize: -1,
} }
...@@ -59,8 +65,9 @@ type statFS struct { ...@@ -59,8 +65,9 @@ type statFS struct {
fuseutil.NotImplementedFileSystem fuseutil.NotImplementedFileSystem
mu sync.Mutex mu sync.Mutex
cannedResponse fuseops.StatFSOp // GUARDED_BY(mu) cannedResponse fuseops.StatFSOp // GUARDED_BY(mu)
mostRecentWriteSize int // GUARDED_BY(mu) cannedStatResponse fuseops.InodeAttributes // GUARDED_BY(mu)
mostRecentWriteSize int // GUARDED_BY(mu)
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
...@@ -73,10 +80,8 @@ func dirAttrs() fuseops.InodeAttributes { ...@@ -73,10 +80,8 @@ func dirAttrs() fuseops.InodeAttributes {
} }
} }
func fileAttrs() fuseops.InodeAttributes { func (fs *statFS) fileAttrs() fuseops.InodeAttributes {
return fuseops.InodeAttributes{ return fs.cannedStatResponse
Mode: 0666,
}
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
...@@ -91,6 +96,14 @@ func (fs *statFS) SetStatFSResponse(r fuseops.StatFSOp) { ...@@ -91,6 +96,14 @@ func (fs *statFS) SetStatFSResponse(r fuseops.StatFSOp) {
fs.cannedResponse = r fs.cannedResponse = r
} }
// LOCKS_EXCLUDED(fs.mu)
func (fs *statFS) SetStatResponse(r fuseops.InodeAttributes) {
fs.mu.Lock()
defer fs.mu.Unlock()
fs.cannedStatResponse = r
}
// LOCKS_EXCLUDED(fs.mu) // LOCKS_EXCLUDED(fs.mu)
func (fs *statFS) MostRecentWriteSize() int { func (fs *statFS) MostRecentWriteSize() int {
fs.mu.Lock() fs.mu.Lock()
...@@ -124,7 +137,7 @@ func (fs *statFS) LookUpInode( ...@@ -124,7 +137,7 @@ func (fs *statFS) LookUpInode(
} }
op.Entry.Child = childInodeID op.Entry.Child = childInodeID
op.Entry.Attributes = fileAttrs() op.Entry.Attributes = fs.fileAttrs()
return return
} }
...@@ -137,7 +150,7 @@ func (fs *statFS) GetInodeAttributes( ...@@ -137,7 +150,7 @@ func (fs *statFS) GetInodeAttributes(
op.Attributes = dirAttrs() op.Attributes = dirAttrs()
case childInodeID: case childInodeID:
op.Attributes = fileAttrs() op.Attributes = fs.fileAttrs()
default: default:
err = fuse.ENOENT err = fuse.ENOENT
......
...@@ -23,6 +23,7 @@ import ( ...@@ -23,6 +23,7 @@ import (
"path/filepath" "path/filepath"
"runtime" "runtime"
"strconv" "strconv"
"syscall"
"testing" "testing"
"github.com/jacobsa/fuse/fuseops" "github.com/jacobsa/fuse/fuseops"
...@@ -204,3 +205,24 @@ func (t *StatFSTest) WriteSize() { ...@@ -204,3 +205,24 @@ func (t *StatFSTest) WriteSize() {
AddFailure("Unhandled OS: %s", runtime.GOOS) AddFailure("Unhandled OS: %s", runtime.GOOS)
} }
} }
func (t *StatFSTest) StatBlocks() {
var err error
var stat syscall.Stat_t
const fileName = "foo"
const size = 1 << 22
err = ioutil.WriteFile(
path.Join(t.Dir, fileName),
bytes.Repeat([]byte{'x'}, size),
0400)
AssertEq(nil, err)
t.fs.SetStatResponse(fuseops.InodeAttributes{
Size: size,
})
err = syscall.Stat(path.Join(t.Dir, fileName), &stat)
AssertEq(nil, err)
ExpectEq(size/512, stat.Blocks)
}
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