Documentation
¶
Index ¶
- Constants
- func BitmapPath(filePath string) string
- func GetFreeDiskSpace(path string) (freeBytesAvail, totalNumberOfBytes, totalNumberFreeBytes uint64, err error)
- func OpenShared(path string, flags int, mode uint32) (*os.File, error)
- func RenameShared(oldpath, newpath string) error
- type ChunkBitmap
- func (b *ChunkBitmap) ChunkSizeBytes() int
- func (b *ChunkBitmap) Clear(chunkIdx int)
- func (b *ChunkBitmap) ClearRange(offset int64, size int)
- func (b *ChunkBitmap) FileSize() int64
- func (b *ChunkBitmap) Has(chunkIdx int) bool
- func (b *ChunkBitmap) HasHashes() bool
- func (b *ChunkBitmap) HasRange(offset int64, size int) bool
- func (b *ChunkBitmap) Hash(chunkIdx int) (uint64, bool)
- func (b *ChunkBitmap) Have() int
- func (b *ChunkBitmap) IsComplete() bool
- func (b *ChunkBitmap) NextMissing(from int) int
- func (b *ChunkBitmap) Progress() float64
- func (b *ChunkBitmap) Save(path string) error
- func (b *ChunkBitmap) Set(chunkIdx int)
- func (b *ChunkBitmap) SetHash(chunkIdx int, h uint64)
- func (b *ChunkBitmap) SetRange(offset int64, size int)
- func (b *ChunkBitmap) Total() int
- type Dir
- func (d *Dir) Access(path string, _mask uint32) (errCode int)
- func (d *Dir) AddRemoteFile(logger *slog.Logger, path string, name string, stat *winfuse.Stat_t) error
- func (d *Dir) AddRemoteFileWithBase(logger *slog.Logger, path string, name string, stat *winfuse.Stat_t, ...) error
- func (d *Dir) Chmod(path string, mode uint32) (errCode int)
- func (d *Dir) Chown(path string, uid uint32, gid uint32) (errCode int)
- func (d *Dir) Create(path string, flags int, mode uint32) (errCode int, retFh uint64)
- func (d *Dir) CreateEx(path string, mode uint32, fi *winfuse.FileInfo_t) (errCode int)
- func (d *Dir) Ctx() context.Context
- func (d *Dir) Destroy()
- func (d *Dir) EditRemoteFile(logger *slog.Logger, path string, name string, stat *winfuse.Stat_t) error
- func (d *Dir) EditRemoteFileWithBase(logger *slog.Logger, path string, name string, stat *winfuse.Stat_t, ...) error
- func (d *Dir) Flush(path string, fh uint64) (errCode int)
- func (d *Dir) Fsync(path string, datasync bool, fh uint64) (errCode int)
- func (d *Dir) Fsyncdir(path string, datasync bool, fh uint64) (errCode int)
- func (d *Dir) Getattr(path string, stat *winfuse.Stat_t, fh uint64) (errCode int)
- func (d *Dir) Getxattr(path string, name string) (errCode int, data []byte)
- func (d *Dir) Init()
- func (d *Dir) Link(oldpath string, newpath string) (errCode int)
- func (d *Dir) Listxattr(path string, fill func(name string) bool) (errCode int)
- func (d *Dir) Mkdir(path string, mode uint32) (errCode int)
- func (d *Dir) MkdirFromPeer(path string, mode uint32) (errCode int)
- func (d *Dir) Mknod(path string, mode uint32, dev uint64) (errCode int)
- func (d *Dir) OnLocalChange(event types.FileEvent)
- func (d *Dir) Open(path string, flags int) (errCode int, retFh uint64)
- func (d *Dir) OpenEx(path string, fi *winfuse.FileInfo_t) (errCode int)
- func (d *Dir) OpenStreamProvider() types.FileStreamProvider
- func (d *Dir) Opendir(path string) (errCode int, retFh uint64)
- func (d *Dir) PendingAnnounceSuperseded(path string) bool
- func (d *Dir) Read(path string, buff []byte, offset int64, fh uint64) (errCode int)
- func (d *Dir) Readdir(path string, fill func(name string, stat *winfuse.Stat_t, offset int64) bool, ...) (errCode int)
- func (d *Dir) Readlink(path string) (errCode int, target string)
- func (d *Dir) Release(path string, fh uint64) (errCode int)
- func (d *Dir) Releasedir(path string, fh uint64) (errCode int)
- func (d *Dir) Removexattr(path string, name string) (errCode int)
- func (d *Dir) Rename(oldpath string, newpath string) (errCode int)
- func (d *Dir) Rmdir(path string) (errCode int)
- func (d *Dir) RmdirFromPeer(path string) (errCode int)
- func (d *Dir) SetCallbacks(onLocalChange func(event types.FileEvent), ...)
- func (d *Dir) SetCtx(ctx context.Context)
- func (d *Dir) SetOnLocalChange(fn func(event types.FileEvent))
- func (d *Dir) SetStreamProvider(fn func() types.FileStreamProvider)
- func (d *Dir) Setxattr(path string, name string, value []byte, flags int) (errCode int)
- func (d *Dir) Statfs(path string, stat *winfuse.Statfs_t) (errCode int)
- func (d *Dir) StreamProviderFn() func() types.FileStreamProvider
- func (d *Dir) SwapWouldConflict(path string, baseMtimeNs int64) bool
- func (d *Dir) Symlink(target string, newpath string) (errCode int)
- func (d *Dir) Truncate(path string, size int64, fh uint64) (errCode int)
- func (d *Dir) Unlink(path string) (errCode int)
- func (d *Dir) UnlinkFromPeer(path string) (errCode int)
- func (d *Dir) Utimens(path string, tmsp []winfuse.Timespec) (errCode int)
- func (d *Dir) Write(path string, buff []byte, offset int64, fh uint64) (errCode int)
- type DownloadState
- func (ds *DownloadState) CanRetry() bool
- func (ds *DownloadState) Checksum() uint64
- func (ds *DownloadState) IsComplete() bool
- func (ds *DownloadState) Progress() float64
- func (ds *DownloadState) RecordAttempt() int32
- func (ds *DownloadState) Reset(totalSize uint64)
- func (ds *DownloadState) UpdateChecksum(data []byte)
- func (ds *DownloadState) UpdateProgress(offset int64, bytesRead int)
- type FS
- func (fs *FS) CancelInFlight()
- func (fs *FS) ClearFiles()
- func (fs *FS) EnsurePeerScope(fp string)
- func (fs *FS) IsMounted() bool
- func (fs *FS) Mount(mountPoint string, isSecond bool, downloadPath string) error
- func (fs *FS) RefreshCallbacks()
- func (fs *FS) Root() *Dir
- func (fs *FS) SetRoot(root *Dir)
- func (fs *FS) Unmount()
- type File
- type HandleEntry
- type OpenFileCounter
- type StreamPool
- type WriteStats
Constants ¶
const ChunkSize = 512 * 1024 // 512 KiB
ChunkSize is the granularity for tracking downloaded segments.
const FilesystemBlockSize = 2 << 17 // 256 KiB. Optimal for Linux cp (uses 128 KiB blocks).
const ReadAheadBlock = config.GRPCStreamBuffer // 16 MiB
ReadAheadBlock is the amount one on-demand read miss fetches per round trip. The gRPC frame size caps it, so the block lands in a single message. The whole block is cached, so later reads inside it are local. This turns ~32 round trips per 16 MiB into one.
const StreamPoolSize = 4
StreamPoolSize is the number of parallel gRPC streams per file. Matches typical FUSE readahead parallelism on Linux.
Variables ¶
This section is empty.
Functions ¶
func BitmapPath ¶
BitmapPath returns the .kdbitmap sidecar path for a given file path.
func GetFreeDiskSpace ¶
func OpenShared ¶ added in v0.4.0
OpenShared opens path with FILE_SHARE_DELETE on Windows so a long-lived writer handle does not block rename or unlink of the file (plain os.OpenFile passes no delete sharing). Unix behaves like os.OpenFile.
func RenameShared ¶ added in v0.4.0
RenameShared renames with the platform strategy platRename implements: POSIX-semantics replace plus copy fallback on Windows, plain rename on unix. Receive-path disk moves need it for the same reason the FUSE Rename does — pinned cache handles.
Types ¶
type ChunkBitmap ¶
type ChunkBitmap struct {
// contains filtered or unexported fields
}
ChunkBitmap tracks which chunks of a file are downloaded. Thread-safe: Has() uses RLock, Set() uses Lock. hashes stays nil until the first SetHash call (no fingerprints, e.g. fresh load).
func LoadChunkBitmap ¶
func LoadChunkBitmap(path string, expectedFileSize int64) (*ChunkBitmap, error)
LoadChunkBitmap reads a bitmap from a .kdbitmap file. It returns an error when the file is corrupt or the fileSize does not match.
func NewChunkBitmap ¶
func NewChunkBitmap(fileSize int64) *ChunkBitmap
NewChunkBitmap creates a bitmap for a file of the given size using ChunkSize granularity. Returns nil for size <= 0 (empty files need no tracking).
func NewChunkBitmapWithSize ¶
func NewChunkBitmapWithSize(fileSize int64, chunkSize int) *ChunkBitmap
NewChunkBitmapWithSize creates a bitmap with a custom chunk size.
func (*ChunkBitmap) ChunkSizeBytes ¶
func (b *ChunkBitmap) ChunkSizeBytes() int
ChunkSizeBytes returns the chunk size used by this bitmap.
func (*ChunkBitmap) Clear ¶ added in v0.3.6
func (b *ChunkBitmap) Clear(chunkIdx int)
Clear clears the bit for chunkIdx and decrements have. Zeroes hashes[chunkIdx] if hashes is allocated. Idempotent for already-clear chunks.
func (*ChunkBitmap) ClearRange ¶ added in v0.3.6
func (b *ChunkBitmap) ClearRange(offset int64, size int)
ClearRange clears all chunks covering [offset, offset+size). Mirrors SetRange.
func (*ChunkBitmap) FileSize ¶
func (b *ChunkBitmap) FileSize() int64
FileSize returns the tracked file size.
func (*ChunkBitmap) Has ¶
func (b *ChunkBitmap) Has(chunkIdx int) bool
Has reports whether the chunk at chunkIdx is downloaded.
func (*ChunkBitmap) HasHashes ¶ added in v0.3.6
func (b *ChunkBitmap) HasHashes() bool
HasHashes reports whether the bitmap stores per-chunk fingerprints. A fresh or disk-loaded bitmap has none until the first SetHash call.
func (*ChunkBitmap) HasRange ¶
func (b *ChunkBitmap) HasRange(offset int64, size int) bool
HasRange reports whether all chunks covering [offset, offset+size) are downloaded.
func (*ChunkBitmap) Hash ¶ added in v0.3.6
func (b *ChunkBitmap) Hash(chunkIdx int) (uint64, bool)
Hash returns the stored fingerprint for a chunk. It returns (0, false) when hashes is nil, the chunk index is out of range, or the chunk is absent. A zero hash value does not mean absent; only the bit and the alloc matter.
func (*ChunkBitmap) Have ¶
func (b *ChunkBitmap) Have() int
Have returns the number of downloaded chunks.
func (*ChunkBitmap) IsComplete ¶
func (b *ChunkBitmap) IsComplete() bool
IsComplete reports whether all chunks are downloaded.
func (*ChunkBitmap) NextMissing ¶
func (b *ChunkBitmap) NextMissing(from int) int
NextMissing returns the index of the first missing chunk at or after from. It returns -1 when no missing chunks remain.
func (*ChunkBitmap) Progress ¶
func (b *ChunkBitmap) Progress() float64
Progress returns download completion as a fraction [0.0, 1.0].
func (*ChunkBitmap) Save ¶
func (b *ChunkBitmap) Save(path string) error
Save writes the bitmap state to a .kdbitmap file.
func (*ChunkBitmap) Set ¶
func (b *ChunkBitmap) Set(chunkIdx int)
Set marks a chunk as downloaded. Idempotent.
func (*ChunkBitmap) SetHash ¶ added in v0.3.6
func (b *ChunkBitmap) SetHash(chunkIdx int, h uint64)
SetHash stores a per-chunk content fingerprint. Lazily allocates hashes on first use.
func (*ChunkBitmap) SetRange ¶
func (b *ChunkBitmap) SetRange(offset int64, size int)
SetRange marks all chunks covering [offset, offset+size) as downloaded.
func (*ChunkBitmap) Total ¶
func (b *ChunkBitmap) Total() int
Total returns the total number of chunks.
type Dir ¶
type Dir struct {
Inode uint64 `json:"inode"` // Inodes must be unique and never reused.
Name string `json:"name"`
RelativePath string `json:"relativePath"` // Path relative to the mount root.
RealPathOfFile string `json:"pathOnLocalSystem"` // Path on the local system.
PeerLastEdit uint64 `json:"peerLastEdit"`
IsLocalPresent bool `json:"isLocalPresent"`
LocalDownloadFolder string // Folder that stores files downloaded from the peer.
Parent *Dir
Root *Dir
OpenFileHandlers map[uint64]*HandleEntry
OpenMapLock sync.RWMutex
Adm sync.RWMutex
AllDirMap map[string]*Dir
AfmLock sync.RWMutex
AllFileMap map[string]*File
// Collab sync options (propagated from FS).
PrefetchOnOpen bool // If true, Open() fetches the whole file and writes it to local disk.
PrefetchAutoMB int // Files at or above this many MB prefetch on open (0=off).
PushOnWrite bool // If true, Write() pushes deltas to the peer asynchronously.
// ReadAheadWindowBlocks caps predictive sequential read-ahead. Sequential
// reads fetch up to this many ReadAheadBlock-sized blocks ahead of the read
// head, so a high-RTT link does not stall at each block boundary. The in-use
// window self-tunes by hit/miss feedback and never exceeds this cap. A slow
// consumer (e.g. video) settles well below it. 0 = off (pure on-demand).
// The value comes from config read_ahead_window_mb.
ReadAheadWindowBlocks int
RemoteFilesLock sync.RWMutex
RemoteFiles map[string]*File
// PrefetchSem limits concurrent prefetch goroutines. Without a limit, a large
// clone (600+ files) opens 600+ parallel StreamFile gRPC streams and
// overwhelms the connection.
PrefetchSem chan struct{}
// contains filtered or unexported fields
}
func (*Dir) AddRemoteFile ¶
func (*Dir) AddRemoteFileWithBase ¶ added in v0.4.0
func (d *Dir) AddRemoteFileWithBase(logger *slog.Logger, path string, name string, stat *winfuse.Stat_t, baseMtimeNs int64) error
AddRemoteFileWithBase is AddRemoteFile plus the announcement's declared base (see NotifyRequest.base_mtime_ns). Base 0 means unknown: plain LWW, never a conflict copy.
func (*Dir) Create ¶
Create creates a new file.
oflag includes exactly one access mode: O_RDONLY, O_WRONLY, or O_RDWR. O_APPEND, O_CREAT, O_TRUNC, and O_EXCL can be OR'd in. Use winfuse.O_ACCMODE to extract the access mode (portable across macOS/Linux/Windows).
Create is dead on all platforms: cgofuse routes creates through CreateEx (see host.go create dispatch). It exists only to satisfy fuse.FileSystemInterface. It delegates to CreateEx so one implementation exists: no duplicated logic to drift, and it stays correct if ever called.
func (*Dir) CreateEx ¶
CreateEx implements FileSystemOpenEx interface for per-file direct_io control.
func (*Dir) Ctx ¶ added in v0.4.0
Ctx returns the live FUSE context from the root. Disconnect swaps it, so do not cache the returned context across sessions.
func (*Dir) EditRemoteFile ¶
func (*Dir) EditRemoteFileWithBase ¶ added in v0.4.0
func (d *Dir) EditRemoteFileWithBase(logger *slog.Logger, path string, name string, stat *winfuse.Stat_t, baseMtimeNs int64) error
EditRemoteFileWithBase is EditRemoteFile plus the announcement's declared base (see NotifyRequest.base_mtime_ns). Base 0 means unknown: plain LWW, never a conflict copy.
func (*Dir) MkdirFromPeer ¶
MkdirFromPeer creates a directory without notifying the peer (to avoid loops).
func (*Dir) OnLocalChange ¶
OnLocalChange reports a local file event to the session. It routes through the root's atomically published callback and does nothing while no session callback is wired.
func (*Dir) Open ¶
Open is dead on all platforms: cgofuse routes opens through OpenEx (see host.go's open dispatch). The suite passes with this returning ENOSYS on Linux+macOS. It exists only to satisfy the base fuse.FileSystemInterface; OpenEx is the real open path. It delegates to OpenEx so no duplicated open logic can drift. That duplication hid the handle-counter bug, now fixed once in OpenEx.
func (*Dir) OpenEx ¶
func (d *Dir) OpenEx(path string, fi *winfuse.FileInfo_t) (errCode int)
OpenEx implements FileSystemOpenEx interface for per-file direct_io control.
func (*Dir) OpenStreamProvider ¶
func (d *Dir) OpenStreamProvider() types.FileStreamProvider
OpenStreamProvider returns the current session's stream provider, or nil while no session factory is wired. It routes through the root's atomically published factory.
func (*Dir) PendingAnnounceSuperseded ¶ added in v0.4.0
PendingAnnounceSuperseded reports that path's queued ADD announce describes bytes whose authority was lost to an acceptance: no open edit session and LocalNewer cleared. The CancelPendingNotify fast path usually wins the race; this state check closes it when the flush fires first (CI-speed runners bounced the peer's own bytes back as a newer edit and diverged).
func (*Dir) Rename ¶
Rename renames a file or directory. macOS apps use atomic rename-swap (renamex_np with RENAME_SWAP), which cgofuse does not expose. Such requests fall back to a basic rename.
func (*Dir) RmdirFromPeer ¶
RmdirFromPeer removes a directory without notifying the peer (to avoid loops).
func (*Dir) SetCallbacks ¶ added in v0.4.0
func (d *Dir) SetCallbacks(onLocalChange func(event types.FileEvent), provider func() types.FileStreamProvider)
SetCallbacks publishes both session callbacks. Call it on the root.
func (*Dir) SetOnLocalChange ¶ added in v0.4.0
SetOnLocalChange publishes the local-change callback. Call it on the root.
func (*Dir) SetStreamProvider ¶ added in v0.4.0
func (d *Dir) SetStreamProvider(fn func() types.FileStreamProvider)
SetStreamProvider publishes the stream-provider factory. Call it on the root.
func (*Dir) StreamProviderFn ¶ added in v0.4.0
func (d *Dir) StreamProviderFn() func() types.FileStreamProvider
StreamProviderFn returns the published factory itself, for callers that wrap and restore it (tests).
func (*Dir) SwapWouldConflict ¶ added in v0.4.0
SwapWouldConflict reports whether a swap arriving for path with the given declared base would hit LOCAL authority it provably never saw. The rename handler must then not clobber the disk before the acceptance verdict runs.
func (*Dir) Truncate ¶
Truncate sets the file size. On Windows, open has no truncate flag, so Open is followed at once by Truncate.
func (*Dir) UnlinkFromPeer ¶
UnlinkFromPeer removes a file without notifying the peer (to avoid loops).
type DownloadState ¶
type DownloadState struct {
TotalSize atomic.Uint64 // Expected total bytes from peer.
BytesDownloaded atomic.Uint64 // Bytes successfully written to local cache.
LastReadOffset atomic.Int64 // Last successfully read offset.
StartedAt atomic.Int64 // Unix nano when download started.
LastSuccessAt atomic.Int64 // Unix nano of last successful read.
AttemptCount atomic.Int32 // Reconnection attempts since last success.
MaxRetries int // Maximum retries before the download stops (default 5).
// contains filtered or unexported fields
}
DownloadState tracks download progress for resume after reconnect.
func (*DownloadState) CanRetry ¶
func (ds *DownloadState) CanRetry() bool
CanRetry reports whether the download can try another reconnect.
func (*DownloadState) Checksum ¶
func (ds *DownloadState) Checksum() uint64
Checksum returns the current xxHash3 checksum of received data.
func (*DownloadState) IsComplete ¶
func (ds *DownloadState) IsComplete() bool
IsComplete reports whether all bytes are downloaded.
func (*DownloadState) Progress ¶
func (ds *DownloadState) Progress() float64
Progress returns download completion percentage (0-100).
func (*DownloadState) RecordAttempt ¶
func (ds *DownloadState) RecordAttempt() int32
RecordAttempt increments the retry counter.
func (*DownloadState) Reset ¶
func (ds *DownloadState) Reset(totalSize uint64)
Reset clears download state for a new download.
func (*DownloadState) UpdateChecksum ¶
func (ds *DownloadState) UpdateChecksum(data []byte)
UpdateChecksum adds data to the running checksum. Pass bytes in receive order, not offset order.
func (*DownloadState) UpdateProgress ¶
func (ds *DownloadState) UpdateProgress(offset int64, bytesRead int)
UpdateProgress records successful read progress and updates the checksum.
type FS ¶
type FS struct {
OnLocalChange func(event types.FileEvent)
OpenStreamProvider func() types.FileStreamProvider
// Collab sync options (set from env before Mount).
PrefetchOnOpen bool // If true, Open() fetches the whole file and writes it to local disk.
PrefetchAutoMB int // Files at or above this many MB prefetch on open (0=off; PrefetchOnOpen forces any size).
ReadAheadWindowMB int // MB cap for predictive sequential read-ahead (0=off). Each Dir converts it to blocks.
PushOnWrite bool // If true, Write() pushes deltas to the peer asynchronously.
AutoCache bool // If true (live_collab), add macFUSE auto_cache so a peer's same-size in-place edit shows live. Costs mmap-write integrity (git) on macOS; no-op on Linux/Windows.
// contains filtered or unexported fields
}
func (*FS) CancelInFlight ¶ added in v0.3.6
func (fs *FS) CancelInFlight()
CancelInFlight cancels in-flight reads/prefetches and resets the FUSE context. It preserves the cached file view (maps + bitmaps). Use it on a disconnect from a peer that may reconnect or resume: the same peer finds its files still there and resumes on-demand with no re-fetch. The full ClearFiles wipe is only for a switch to a different peer (see EnsurePeerScope).
func (*FS) ClearFiles ¶ added in v0.3.2
func (fs *FS) ClearFiles()
ClearFiles cancels in-flight operations and clears all file/dir maps. The mount stays alive as an empty folder, so a reconnect after disconnect reuses it (cgofuse allows only one mount per process).
func (*FS) EnsurePeerScope ¶ added in v0.3.6
EnsurePeerScope binds the cached file view to a peer identity. A different peer than the cached one drops the cache first, so one peer's artifacts never leak to the next. The same peer (reconnect or later session) keeps the cache with no re-fetch. The first peer adopts the empty cache without a clear. Repeat calls are idempotent and cheap. fp is the peer's actual verified fingerprint, so this is correct in TOFU mode too.
func (*FS) Mount ¶
Mount blocks for the lifetime of the FUSE session. It returns an error at once if the mount point is invalid or host.Mount() fails. On success it returns nil only after a clean unmount.
func (*FS) RefreshCallbacks ¶ added in v0.3.2
func (fs *FS) RefreshCallbacks()
RefreshCallbacks updates the Root's callbacks to match the FS-level ones. Call it after setupFilesystem re-wires OnLocalChange/OpenStreamProvider, so the persistent Root uses the new session's gRPC client.
type File ¶
type File struct {
Inode uint64 `json:"inode"` // Inodes must be unique and never reused.
CurrentHandleID uint64 // Opaque FUSE handle ID for the currently-open fd.
Name string `json:"name"`
RelativePath string `json:"relativePath"` // Path relative to the mount root.
RealPathOfFile string // Path on the local system.
Parent *Dir
Root *Dir
LastEditTime uint64 `json:"lastEdit"` // Use time.Now().UnixNano().
CreatedTime uint64 `json:"createdAt"`
PeerLastEdit uint64 `json:"peerLastEdit"`
IsLocalPresent bool `json:"isLocalPresent"`
NotLocalSynced bool
NotRemoteSynced bool
LocalNewer bool
HadEdits bool
// RemoteMtimeNs is the newest peer-announced mtime (UnixNano). Only
// notifications set it, under RemoteFilesLock. Local ops overwrite
// stat.Mtim and must not join the staleness comparison.
RemoteMtimeNs int64
// EditBaseMtimeNs is max(HeldMtimeNs, LastAnnouncedMtimeNs), snapshotted
// at the first dirtying op of an edit session under metaMu. The announce
// carries it so the receiver can prove a concurrent edit: a base below the
// version the receiver holds means the edit never saw that version.
EditBaseMtimeNs int64
// HeldMtimeNs is the newest version stamp whose BYTES are materialized
// locally: own announces, landed fetches, and the startup scan raise it;
// a metadata-only accept does not. The session base uses it, so an
// announce can never claim a version this peer never held. Model v3
// proves the rule: a blind overwrite then loses the base comparison and
// the receiver preserves the only copy of the victim bytes.
HeldMtimeNs int64
// LastAnnouncedMtimeNs is the mtime of our newest announce for this file,
// guarded by metaMu. RemoteMtimeNs records only the peer's announcements,
// so without this an owner-side base degrades to unknown and a conflict on
// its own file cannot be proved.
LastAnnouncedMtimeNs int64
// WasTruncatedToZero records an explicit Truncate(size=0) call. With
// HadEdits, it separates legitimate empty files from transient states.
WasTruncatedToZero bool
// LastNotifiedSize is the file size last sent to the peer in ADD_FILE. It
// prevents duplicate same-size notifications during a file copy.
LastNotifiedSize int64
// PeerStoppedSharing is set when the peer sends REMOVE_FILE during a download.
// On Release with 0 open handles, the code removes the file reference.
PeerStoppedSharing bool
StreamProvider types.FileStreamProvider
StreamPool *StreamPool // Pool of parallel gRPC streams for on-demand reads.
StreamCancel context.CancelFunc // Cancel function for the stream context.
CacheFD *os.File // Persistent cache file descriptor for on-demand writes.
CacheWg sync.WaitGroup // Tracks in-flight async cache writes. Release waits for them.
// Download resumption state.
Download DownloadState
// Bitmap tracks which 512 KiB chunks are downloaded from the remote peer.
// It is nil for local-origin files and empty files (size=0).
Bitmap *ChunkBitmap
// PrefetchCancel cancels the background prefetch goroutine for this file.
PrefetchCancel context.CancelFunc
// contains filtered or unexported fields
}
func (*File) CountOpenDescriptors ¶
CountOpenDescriptors returns the number of open file handles.
func (*File) NotifyPeer ¶
func (f *File) NotifyPeer()
type HandleEntry ¶
HandleEntry maps an opaque FUSE handle ID to the kernel fd and File metadata. Handle IDs only increase and never repeat, so a kernel fd number reused after close() causes no race.
type OpenFileCounter ¶
type OpenFileCounter struct {
// contains filtered or unexported fields
}
OpenFileCounter counts open file handles. Each Create and Open call must have a matching Release call.
func (*OpenFileCounter) CountOpenDescriptors ¶
func (ofc *OpenFileCounter) CountOpenDescriptors() uint64
func (*OpenFileCounter) Open ¶
func (ofc *OpenFileCounter) Open()
func (*OpenFileCounter) OpenIfActive ¶ added in v0.3.3
func (ofc *OpenFileCounter) OpenIfActive() bool
OpenIfActive increments the count and returns true only if it was already >0. This prevents reuse of a handle whose last Release runs teardown.
func (*OpenFileCounter) Release ¶
func (ofc *OpenFileCounter) Release() uint64
type StreamPool ¶
type StreamPool struct {
// contains filtered or unexported fields
}
StreamPool holds N parallel gRPC streams for a single file. FUSE reads pick a stream by chunk-index modulo N. This removes lock contention between concurrent readahead requests.
func NewStreamPool ¶
func NewStreamPool(provider types.FileStreamProvider, ctx context.Context, inode uint64, path string, n int) (*StreamPool, error)
NewStreamPool opens n parallel gRPC streams for the given file. On partial failure, it closes the already-open streams.
func (*StreamPool) ReadAt ¶
ReadAt routes the request to a stream selected by read-ahead block index. Consecutive 16 MiB blocks land on different streams, so a multi-block read-ahead window pipelines across the pool in parallel. Sharding by chunk index would map every block-aligned fetch (the only kind the on-demand path issues) to stream 0 and serialize the whole window on one stream. Any stream can serve any offset, so this is pure load distribution. Singleflight above this layer already collapses concurrent reads of the same block, so one stream per block adds no contention.
type WriteStats ¶
type WriteStats struct {
// contains filtered or unexported fields
}
WriteStats tracks timing for Write operations (for profiling)