github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/kbfs/libkbfs/disk_limits_unix.go (about)

     1  // Copyright 2017 Keybase Inc. All rights reserved.
     2  // Use of this source code is governed by a BSD
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build !windows
     6  // +build !windows
     7  
     8  package libkbfs
     9  
    10  import (
    11  	"math"
    12  	"syscall"
    13  
    14  	"github.com/pkg/errors"
    15  )
    16  
    17  // getDiskLimits gets the disk limits for the logical disk containing
    18  // the given path.
    19  func getDiskLimits(path string) (
    20  	availableBytes, totalBytes, availableFiles, totalFiles uint64, err error) {
    21  	// Notably we are using syscall rather than golang.org/x/sys/unix here.
    22  	// The latter is broken on iOS with go1.11.8 (and likely earlier versions)
    23  	// and always gives us 0 as available storage space. go1.12.3 is known to
    24  	// work fine with sys/unix.
    25  	var stat syscall.Statfs_t
    26  	err = syscall.Statfs(path, &stat)
    27  	if err != nil {
    28  		return 0, 0, 0, 0, errors.WithStack(err)
    29  	}
    30  
    31  	// Bavail is the free block count for an unprivileged user.
    32  	availableBytes = stat.Bavail * uint64(stat.Bsize)
    33  	totalBytes = stat.Blocks * uint64(stat.Bsize)
    34  	// Some filesystems, like btrfs, don't keep track of inodes.
    35  	// (See https://github.com/keybase/client/issues/6206 .) Use
    36  	// the total inode count to detect that case.
    37  	if stat.Files > 0 {
    38  		availableFiles = stat.Ffree
    39  		totalFiles = stat.Files
    40  	} else {
    41  		availableFiles = math.MaxInt64
    42  		totalFiles = math.MaxInt64
    43  	}
    44  	return availableBytes, totalBytes, availableFiles, totalFiles, nil
    45  }