Class: FFI::Libfuse::Filesystem::Accounting

Inherits:
Object
  • Object
show all
Defined in:
lib/ffi/libfuse/filesystem/accounting.rb

Overview

Helper for filesystem accounting, ie to provide useful df output

Constant Summary collapse

OPTIONS =
{ 'max_space=' => :max_space, 'max_nodes=' => :max_nodes }.freeze
HELP =
<<~END_HELP
  #{name} options:
      -o max_space=<int>     maximum space consumed by files, --ve will always show free space
      -o max_nodes=<int>     maximum number of files and directories, -ve will always show free nodes

END_HELP

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(max_space: 0, max_nodes: 0, block_size: 1024) ⇒ Accounting

Returns a new instance of Accounting.



50
51
52
53
54
55
56
# File 'lib/ffi/libfuse/filesystem/accounting.rb', line 50

def initialize(max_space: 0, max_nodes: 0, block_size: 1024)
  @nodes = 0
  @space = 0
  @max_space = max_space
  @max_nodes = max_nodes
  @block_size = block_size
end

Instance Attribute Details

#block_sizeInteger

Returns block size for statvfs.

Returns:

  • (Integer)

    block size for statvfs



48
49
50
# File 'lib/ffi/libfuse/filesystem/accounting.rb', line 48

def block_size
  @block_size
end

#max_nodesInteger

Returns maximum number of (virtual) inodes

Positive values will limit #adjust to stay below this value

Negative or zero will simply report this number of inodes as 'free' in #to_statvfs.

Returns:

  • (Integer)

    maximum number of (virtual) inodes

    Positive values will limit #adjust to stay below this value

    Negative or zero will simply report this number of inodes as 'free' in #to_statvfs



39
40
41
# File 'lib/ffi/libfuse/filesystem/accounting.rb', line 39

def max_nodes
  @max_nodes
end

#max_spaceInteger

Returns maximum allowed space in bytes

Positive values will limit values in #adjust to stay below this value

Negative or zero will simply report this amount of space as 'free' in #to_statvfs.

Returns:

  • (Integer)

    maximum allowed space in bytes

    Positive values will limit values in #adjust to stay below this value

    Negative or zero will simply report this amount of space as 'free' in #to_statvfs



32
33
34
# File 'lib/ffi/libfuse/filesystem/accounting.rb', line 32

def max_space
  @max_space
end

#nodesInteger (readonly)

Returns accumulated inodes (typically count of files and directories).

Returns:

  • (Integer)

    accumulated inodes (typically count of files and directories)



45
46
47
# File 'lib/ffi/libfuse/filesystem/accounting.rb', line 45

def nodes
  @nodes
end

#spaceInteger (readonly)

Returns accumulated space in bytes.

Returns:

  • (Integer)

    accumulated space in bytes



42
43
44
# File 'lib/ffi/libfuse/filesystem/accounting.rb', line 42

def space
  @space
end

Instance Method Details

#adjust(delta_space, delta_nodes = 0, strict: true) ⇒ self

Adjust accumlated statistics

Parameters:

  • delta_space (Integer)

    change in #space usage

  • delta_nodes (Integer) (defaults to: 0)

    change in #nodes usage

Returns:

  • (self)

Raises:



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/ffi/libfuse/filesystem/accounting.rb', line 63

def adjust(delta_space, delta_nodes = 0, strict: true)
  strict_space = strict && delta_space.positive? && max_space.positive?
  raise Errno::ENOSPC if strict_space && space + delta_space > max_space

  strict_nodes = strict && delta_nodes.positive? && max_nodes.positive?
  raise Errno::ENOSPC if strict_nodes && nodes + delta_nodes > max_nodes

  @nodes += delta_nodes
  @space += delta_space
  self
end

#fuse_opt_proc(key:, value:) ⇒ Object



20
21
22
23
24
25
# File 'lib/ffi/libfuse/filesystem/accounting.rb', line 20

def fuse_opt_proc(key:, value:, **)
  return :keep unless OPTIONS.values.include?(key)

  public_send("#{key}=", value.to_i)
  :handled
end

#to_statvfs(statvfs = FFI::StatVfs.new, block_size: self.block_size || 1024) ⇒ FFI::StatVfs

Returns the filesystem statistics.

Parameters:

  • statvfs (FFI::StatVfs) (defaults to: FFI::StatVfs.new)

    an existing statvfs buffer to fill

  • block_size (Integer) (defaults to: self.block_size || 1024)

Returns:



99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/ffi/libfuse/filesystem/accounting.rb', line 99

def to_statvfs(statvfs = FFI::StatVfs.new, block_size: self.block_size || 1024)
  used_blocks, max_blocks = [space, max_space].map { |s| s / block_size }
  max_blocks = used_blocks - max_blocks unless max_blocks.positive?
  max_files = max_nodes.positive? ? max_nodes : nodes - max_nodes
  statvfs.bsize    = block_size # block size (in Kb)
  statvfs.frsize   = block_size # fragment size pretty much always bsize
  statvfs.blocks   = max_blocks
  statvfs.bfree    = max_blocks - used_blocks
  statvfs.bavail   = max_blocks - used_blocks
  statvfs.files    = max_files
  statvfs.ffree    = max_files - nodes
  statvfs
end

#truncate(current_size, new_size) ⇒ self

Adjust for truncate

Parameters:

  • current_size (Integer)
  • new_size (Integer)

    the size being truncated to

Returns:

  • (self)


89
90
91
92
# File 'lib/ffi/libfuse/filesystem/accounting.rb', line 89

def truncate(current_size, new_size)
  adjust(new_size - current_size, strict: false) if new_size < current_size
  self
end

#write(current_size, data_size, offset, strict: true) ⇒ self

Adjust for incremental write

Parameters:

  • current_size (Integer)
  • data_size (Integer)

    size of new data

  • offset (Integer)

    offset of new data

Returns:

  • (self)


80
81
82
83
# File 'lib/ffi/libfuse/filesystem/accounting.rb', line 80

def write(current_size, data_size, offset, strict: true)
  adjust(offset + data_size - current_size, strict: strict) if current_size < offset + data_size
  self
end