From 2f112ac6827d24f5e8c87915a31a86ec721ebf9e Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Thu, 7 Sep 2023 14:42:20 +0200 Subject: [PATCH] correct free data space accounting for multiple data dirs on same fs --- src/rpc/system.rs | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/src/rpc/system.rs b/src/rpc/system.rs index c5751d5d..cf480549 100644 --- a/src/rpc/system.rs +++ b/src/rpc/system.rs @@ -911,12 +911,30 @@ impl NodeStatus { self.data_disk_avail = match data_dir { DataDirEnum::Single(dir) => mount_avail(dir), DataDirEnum::Multiple(dirs) => { - dirs.iter() - .map(|d| mount_avail(&d.path)) - .fold(Some((0, 0)), |acc, cur| match (acc, cur) { - (Some((x, y)), Some((a, b))) => Some((x + a, y + b)), - _ => None, + // Take mounts corresponding to all specified data directories that + // can be used for writing data + let mounts = dirs + .iter() + .filter(|dir| dir.capacity.is_some()) + .map(|dir| { + mounts + .iter() + .filter(|mnt| dir.path.starts_with(&mnt.fs_mounted_on)) + .max_by_key(|mnt| mnt.fs_mounted_on.len()) }) + .collect::>(); + if mounts.iter().any(|x| x.is_none()) { + None // could not get info for at least one mount + } else { + // dedup mounts in case several data directories are on the same filesystem + let mut mounts = mounts.iter().map(|x| x.unwrap()).collect::>(); + mounts.sort_by(|x, y| x.fs_mounted_on.cmp(&y.fs_mounted_on)); + mounts.dedup_by(|x, y| x.fs_mounted_on == y.fs_mounted_on); + // calculate sum of available and total space + Some(mounts.iter().fold((0, 0), |(x, y), mnt| { + (x + mnt.avail.as_u64(), y + mnt.total.as_u64()) + })) + } } };