Set f_frsize, fixing free space calculation by `df` on OS X.
parent
81a0bd26c3
commit
c96d308a7a
|
@ -564,7 +564,35 @@ func (c *Connection) kernelResponseForOp(
|
|||
out.St.Bavail = o.BlocksAvailable
|
||||
out.St.Files = o.Inodes
|
||||
out.St.Ffree = o.InodesFree
|
||||
|
||||
// The posix spec for sys/statvfs.h defines the following fields, among
|
||||
// others:
|
||||
//
|
||||
// f_bsize File system block size.
|
||||
// f_frsize Fundamental file system block size.
|
||||
// f_blocks Total number of blocks on file system in units of f_frsize.
|
||||
//
|
||||
// It appears as though f_bsize was the only thing supported by most unixes
|
||||
// originally, but then f_frsize was added when new sorts of file systems
|
||||
// came about. Quoth The Linux Programming Interface by Michael Kerrisk
|
||||
// (https://goo.gl/5LZMxQ):
|
||||
//
|
||||
// For most Linux file systems, the values of f_bsize and f_frsize are
|
||||
// the same. However, some file systems support the notion of block
|
||||
// fragments, which can be used to allocate a smaller unit of storage
|
||||
// at the end of the file if if a full block is not required. This
|
||||
// avoids the waste of space that would otherwise occur if a full block
|
||||
// was allocated. On such file systems, f_frsize is the size of a
|
||||
// fragment, and f_bsize is the size of a whole block. (The notion of
|
||||
// fragments in UNIX file systems first appeared in the early 1980s
|
||||
// with the 4.2BSD Fast File System.)
|
||||
//
|
||||
// Confusingly, it appears as though osxfuse surfaces f_bsize as f_iosize
|
||||
// (of advisory use only), and f_frsize as f_bsize (which affects free
|
||||
// space display in the Finder). In any case, we don't care to let the user
|
||||
// distinguish, so set both to the same value.
|
||||
out.St.Bsize = o.BlockSize
|
||||
out.St.Frsize = o.BlockSize
|
||||
|
||||
case *initOp:
|
||||
out := (*fusekernel.InitOut)(m.Grow(unsafe.Sizeof(fusekernel.InitOut{})))
|
||||
|
|
|
@ -38,16 +38,31 @@ import (
|
|||
// convert_fuse_statfs to convert the response in a straightforward
|
||||
// manner.
|
||||
//
|
||||
// Note that this op is particularly important on OS X: if you don't implement
|
||||
// it, the file system will not successfully mount. If you don't model a sane
|
||||
// amount of free space, the Finder will refuse to copy files into the file
|
||||
// system.
|
||||
// This op is particularly important on OS X: if you don't implement it, the
|
||||
// file system will not successfully mount. If you don't model a sane amount of
|
||||
// free space, the Finder will refuse to copy files into the file system.
|
||||
type StatFSOp struct {
|
||||
// The size of the file system's blocks, and how many there are in total.
|
||||
// The size of the file system's blocks. This may be used, in combination
|
||||
// with the block counts below, by callers of statfs(2) to infer the file
|
||||
// system's capacity and space availability.
|
||||
//
|
||||
// TODO(jacobsa): Document the range of values accepted on OS X and Linux.
|
||||
// Cite sources in Linux if possible.
|
||||
//
|
||||
// On OS X this also affects statfs::f_iosize, which is documented as the
|
||||
// "optimal transfer block size". It does not appear to cause osxfuse to
|
||||
// change the size of data in WriteFile ops, though.
|
||||
//
|
||||
// This interface does not distinguish between blocks and block fragments.
|
||||
BlockSize uint32
|
||||
Blocks uint64
|
||||
|
||||
// The number of blocks free, and how many are available to non-root users.
|
||||
// The total number of blocks in the file system, the number of unused
|
||||
// blocks, and the count of the latter that are available for use by non-root
|
||||
// users.
|
||||
//
|
||||
// For each category, the corresponding number of bytes is derived by
|
||||
// multiplying by BlockSize.
|
||||
Blocks uint64
|
||||
BlocksFree uint64
|
||||
BlocksAvailable uint64
|
||||
|
||||
|
|
|
@ -203,7 +203,7 @@ func (t *StatFSTest) Syscall_NonZeroValues() {
|
|||
err = syscall.Statfs(t.Dir, &stat)
|
||||
AssertEq(nil, err)
|
||||
|
||||
ExpectEq(4096, stat.Bsize) // OS X seems to always make this 4096.
|
||||
ExpectEq(canned.BlockSize, stat.Bsize)
|
||||
ExpectEq(canned.BlockSize, stat.Iosize)
|
||||
ExpectEq(canned.Blocks, stat.Blocks)
|
||||
ExpectEq(canned.BlocksFree, stat.Bfree)
|
||||
|
|
Loading…
Reference in New Issue