Skip to content

Commit 3219aa1

Browse files
committed
docs(fuse): clarify st_blocks/st_blksize rationale
1 parent c9ecc8b commit 3219aa1

File tree

2 files changed

+17
-14
lines changed

2 files changed

+17
-14
lines changed

fuse/readonly/readonly_unix.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,9 +181,9 @@ type roFileHandle struct {
181181
// Used by both Getattr and Lookup (to fill EntryOut.Attr so the kernel
182182
// doesn't cache zero values for the entry timeout duration).
183183
//
184-
// Blksize is set on every entry: go-fuse's setBlocks otherwise
185-
// auto-fills both st_blocks and st_blksize with a 4 KiB page-based
186-
// fallback, which would clobber the values set below.
184+
// Blocks and Blksize are set on every entry because go-fuse's setBlocks
185+
// otherwise auto-fills them from Size with a 4 KiB page-based fallback,
186+
// which clobbers the UnixFS-derived values set below.
187187
func (n *Node) fillAttr(a *fuse.Attr) {
188188
a.Blksize = fusemnt.DefaultBlksize
189189

@@ -204,6 +204,9 @@ func (n *Node) fillAttr(a *fuse.Attr) {
204204
switch n.cached.Type() {
205205
case ft.TDirectory, ft.THAMTShard:
206206
a.Mode = uint32(fusemnt.DefaultDirModeRO.Perm())
207+
// Nominal 1 block: du sums child leaves, so the directory's
208+
// own st_blocks is not arithmetically meaningful, but some
209+
// tools treat 0 as "unsupported" and skip the entry.
207210
a.Blocks = 1
208211
case ft.TFile:
209212
a.Mode = uint32(fusemnt.DefaultFileModeRO.Perm())

fuse/writable/writable.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,9 @@ type Config struct {
4444
// Blksize is the preferred I/O size advertised via st_blksize on
4545
// every stat. Callers should derive it from Import.UnixFSChunker via
4646
// fusemnt.BlksizeFromChunker so the hint matches the chunker MFS
47-
// will use for writes. Zero is normalized to fusemnt.DefaultBlksize
48-
// by NewDir.
47+
// will use for writes. If zero, NewDir writes fusemnt.DefaultBlksize
48+
// into this field in place, so fillAttr on every inode can read
49+
// cfg.Blksize without a nil-check on each stat.
4950
Blksize uint32
5051
}
5152

@@ -58,10 +59,9 @@ func NewDir(d *mfs.Directory, cfg *Config) *Dir {
5859
if cfg == nil || cfg.DAG == nil {
5960
panic("fuse/writable: Config.DAG is required")
6061
}
61-
// Normalize Blksize once so fillAttr on every inode can read
62-
// cfg.Blksize directly. Tests and callers that don't plumb
63-
// Import.UnixFSChunker leave this zero; we fall back to the FUSE
64-
// default so stat still advertises a usable st_blksize.
62+
// Tests and callers that don't plumb Import.UnixFSChunker leave
63+
// Blksize zero; fall back to the FUSE default so stat advertises a
64+
// usable st_blksize. See Config.Blksize for why we mutate in place.
6565
if cfg.Blksize == 0 {
6666
cfg.Blksize = fusemnt.DefaultBlksize
6767
}
@@ -75,11 +75,11 @@ type Dir struct {
7575
Cfg *Config
7676
}
7777

78-
// fillAttr fills stat attributes for a directory. Blksize is set on
79-
// every entry: go-fuse's setBlocks otherwise auto-fills both st_blocks
80-
// and st_blksize with a 4 KiB page-based fallback. For directories that
81-
// fallback computes Blocks from Size=0 and yields st_blocks=0, which
82-
// some tools treat as "unsupported".
78+
// fillAttr fills stat attributes for a directory. Blocks and Blksize
79+
// are set explicitly because go-fuse's setBlocks otherwise auto-fills
80+
// them from Size with a 4 KiB page-based fallback. For directories
81+
// Size is 0, so the fallback yields st_blocks=0, which some tools
82+
// (dedup scanners, file managers) treat as "unsupported".
8383
func (d *Dir) fillAttr(a *fuse.Attr) {
8484
a.Mode = uint32(fusemnt.DefaultDirModeRW.Perm())
8585
a.Blocks = 1

0 commit comments

Comments
 (0)