1 //go:build !windows
2 3 // Package storage provides storage management functionality including filesystem
4 // space detection, access tracking for events, and garbage collection based on
5 // access patterns.
6 package storage
7 8 import (
9 "syscall"
10 )
11 12 // FilesystemStats holds information about filesystem space usage.
13 type FilesystemStats struct {
14 Total uint64 // Total bytes on filesystem
15 Available uint64 // Available bytes (for unprivileged users)
16 Used uint64 // Used bytes
17 }
18 19 // GetFilesystemStats returns filesystem space information for the given path.
20 // The path should be a directory within the filesystem to check.
21 func GetFilesystemStats(path string) (stats FilesystemStats, err error) {
22 var stat syscall.Statfs_t
23 if err = syscall.Statfs(path, &stat); err != nil {
24 return
25 }
26 stats.Total = stat.Blocks * uint64(stat.Bsize)
27 stats.Available = stat.Bavail * uint64(stat.Bsize)
28 stats.Used = stats.Total - stats.Available
29 return
30 }
31 32 // CalculateMaxStorage calculates the maximum storage limit for the relay.
33 // If configuredMax > 0, it returns that value directly.
34 // Otherwise, it returns 80% of the available filesystem space.
35 func CalculateMaxStorage(dataDir string, configuredMax int64) (int64, error) {
36 if configuredMax > 0 {
37 return configuredMax, nil
38 }
39 40 stats, err := GetFilesystemStats(dataDir)
41 if err != nil {
42 return 0, err
43 }
44 45 // Return 80% of available space
46 maxBytes := int64(float64(stats.Available) * 0.8)
47 48 // Also ensure we don't exceed 80% of total filesystem
49 maxTotal := int64(float64(stats.Total) * 0.8)
50 if maxBytes > maxTotal {
51 maxBytes = maxTotal
52 }
53 54 return maxBytes, nil
55 }
56 57 // GetCurrentStorageUsage calculates the current storage usage of the data directory.
58 // This is an approximation based on filesystem stats for the given path.
59 func GetCurrentStorageUsage(dataDir string) (int64, error) {
60 stats, err := GetFilesystemStats(dataDir)
61 if err != nil {
62 return 0, err
63 }
64 return int64(stats.Used), err
65 }
66