Skip to content

Commit e6064c2

Browse files
authored
Merge pull request #3639 from mulkieran/issue_stratisd_3634
Ensured filesystem Used signal is sent if used value has changed on filesystem check
2 parents d917e2a + 4c1dd79 commit e6064c2

2 files changed

Lines changed: 62 additions & 56 deletions

File tree

src/engine/strat_engine/thinpool/filesystem.rs

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -258,20 +258,36 @@ impl StratFilesystem {
258258
}
259259
}
260260

261-
/// Check the filesystem usage and determine whether it should extend.
261+
/// Check the filesystem usage and determine whether it should extend
262+
/// or just update. If extend, return the amount to extend.
262263
///
263264
/// Returns:
264-
/// * Some(mount_point) if the filesystem should be extended
265-
/// * None if the filesystem does not need to be extended
266-
pub fn should_extend(&self) -> Option<PathBuf> {
267-
fn should_extend_fail(fs: &StratFilesystem) -> StratisResult<Option<PathBuf>> {
265+
/// * Some(_) if the filesystem is mounted and should be visited
266+
/// * Some((_, 0)) if the filesystem does not need to be extended
267+
/// * None if the filesystem is unmounted and should not be visited
268+
pub fn visit_values(
269+
&self,
270+
no_op_remaining_size: Option<&mut Sectors>,
271+
) -> Option<(PathBuf, Sectors)> {
272+
fn visit_values_fail(
273+
fs: &StratFilesystem,
274+
no_op_remaining_size: Option<&mut Sectors>,
275+
) -> StratisResult<Option<(PathBuf, Sectors)>> {
268276
match fs.thin_dev.status(get_dm(), DmOptions::default())? {
269277
ThinStatus::Working(_) => {
270278
if let Some(mount_point) = fs.mount_points()?.first() {
271-
let (fs_total_bytes, fs_total_used_bytes) = fs_usage(mount_point)?;
272-
if 2u64 * fs_total_used_bytes > fs_total_bytes {
273-
return Ok(Some(mount_point.clone()));
274-
}
279+
return fs_usage(mount_point).map(
280+
|(fs_total_bytes, fs_total_used_bytes)| {
281+
Some((
282+
mount_point.clone(),
283+
if 2u64 * fs_total_used_bytes > fs_total_bytes {
284+
fs.extend_size(no_op_remaining_size)
285+
} else {
286+
Sectors(0)
287+
},
288+
))
289+
},
290+
);
275291
}
276292
Ok(None)
277293
}
@@ -286,54 +302,56 @@ impl StratFilesystem {
286302
}
287303
}
288304

289-
match should_extend_fail(self) {
305+
match visit_values_fail(self, no_op_remaining_size) {
290306
Ok(mt_pt) => mt_pt,
291307
Err(e) => {
292308
warn!(
293-
"Checking whether the filesystem should be extended failed: {}; ignoring",
309+
"Checking whether the filesystem should be visited failed: {}; ignoring",
294310
e
295311
);
296312
None
297313
}
298314
}
299315
}
300316

301-
/// Handle the extension once the filesystem has been determined to be getting full
302-
/// and needs to be extended.
317+
/// Handle filesystem changes while checking, including updating cached
318+
/// state.
303319
///
304-
/// Precondition: should_extend has returned Some(_) before invocation.
305-
pub fn handle_extension(
320+
/// If extend_size is 0, it is not necessary to extend the filesystem,
321+
/// but the state may have changed.
322+
pub fn handle_fs_changes(
306323
&mut self,
307324
mount_point: &Path,
308325
extend_size: Sectors,
309326
) -> StratisResult<StratFilesystemDiff> {
310327
let original_state = self.cached();
311328

312-
let old_table = self.thin_dev.table().table.clone();
313-
let mut new_table = old_table.clone();
314-
new_table.length = original_state.size.sectors() + extend_size;
315-
self.thin_dev.set_table(get_dm(), new_table)?;
316-
if let Err(causal) = xfs_growfs(mount_point) {
317-
if let Err(rollback) = self.thin_dev.set_table(get_dm(), old_table) {
318-
return Err(StratisError::RollbackError {
319-
causal_error: Box::new(causal),
320-
rollback_error: Box::new(StratisError::from(rollback)),
321-
level: ActionAvailability::NoPoolChanges,
322-
});
323-
} else {
324-
return Err(causal);
329+
if extend_size > Sectors(0) {
330+
let old_table = self.thin_dev.table().table.clone();
331+
let mut new_table = old_table.clone();
332+
new_table.length = original_state.size.sectors() + extend_size;
333+
self.thin_dev.set_table(get_dm(), new_table)?;
334+
if let Err(causal) = xfs_growfs(mount_point) {
335+
if let Err(rollback) = self.thin_dev.set_table(get_dm(), old_table) {
336+
return Err(StratisError::RollbackError {
337+
causal_error: Box::new(causal),
338+
rollback_error: Box::new(StratisError::from(rollback)),
339+
level: ActionAvailability::NoPoolChanges,
340+
});
341+
} else {
342+
return Err(causal);
343+
}
325344
}
326345
}
327346

328347
Ok(original_state.diff(&self.dump(())))
329348
}
330349

331350
/// Return an extend size for the thindev under the filesystem
332-
pub fn extend_size(
333-
current_size: Sectors,
334-
no_op_remaining_size: Option<&mut Sectors>,
335-
fs_limit_remaining_size: Option<Sectors>,
336-
) -> Sectors {
351+
/// If no_op_remaining_size is None, then the pool allows overprovisioning.
352+
fn extend_size(&self, no_op_remaining_size: Option<&mut Sectors>) -> Sectors {
353+
let current_size = self.thindev_size();
354+
let fs_limit_remaining_size = self.size_limit().map(|sl| sl - self.thindev_size());
337355
match (no_op_remaining_size, fs_limit_remaining_size) {
338356
(Some(no_op_rem_size), Some(fs_lim_rem_size)) => {
339357
let extend_size = min(min(*no_op_rem_size, current_size), fs_lim_rem_size);

src/engine/strat_engine/thinpool/thinpool.rs

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use devicemapper::{
2323

2424
use crate::{
2525
engine::{
26-
engine::{DumpState, Filesystem, StateDiff},
26+
engine::{DumpState, StateDiff},
2727
strat_engine::{
2828
backstore::Backstore,
2929
cmd::{thin_check, thin_metadata_size, thin_repair},
@@ -682,10 +682,6 @@ impl ThinPool {
682682
None
683683
};
684684

685-
if let Some(Sectors(0)) = remaining_space.as_ref() {
686-
return Ok(HashMap::default());
687-
};
688-
689685
scope(|s| {
690686
// This collect is needed to ensure all threads are spawned in
691687
// parallel, not each thread being spawned and immediately joined
@@ -696,24 +692,12 @@ impl ThinPool {
696692
.filesystems
697693
.iter_mut()
698694
.filter_map(|(name, uuid, fs)| {
699-
if let Some(mt_pt) = fs.should_extend() {
700-
let extend_size = StratFilesystem::extend_size(
701-
fs.thindev_size(),
702-
remaining_space.as_mut(),
703-
fs.size_limit().map(|sl| sl - fs.thindev_size()),
704-
);
705-
if extend_size == Sectors(0) {
706-
None
707-
} else {
708-
Some((name, *uuid, fs, mt_pt, extend_size))
709-
}
710-
} else {
711-
None
712-
}
695+
fs.visit_values(remaining_space.as_mut())
696+
.map(|(mt_pt, extend_size)| (name, *uuid, fs, mt_pt, extend_size))
713697
})
714698
.map(|(name, uuid, fs, mt_pt, extend_size)| {
715699
s.spawn(move || -> StratisResult<_> {
716-
let diff = fs.handle_extension(&mt_pt, extend_size)?;
700+
let diff = fs.handle_fs_changes(&mt_pt, extend_size)?;
717701
Ok((name, uuid, fs, diff))
718702
})
719703
})
@@ -724,15 +708,19 @@ impl ThinPool {
724708
.filter_map(|h| {
725709
h.join()
726710
.map_err(|_| {
727-
warn!("Failed to get status of filesystem extension");
711+
warn!("Failed to get status of filesystem operation");
728712
})
729713
.ok()
730714
})
731715
.fold(Vec::new(), |mut acc, res| {
732716
match res {
733717
Ok((name, uuid, fs, diff)) => {
734-
updated.insert(uuid, diff);
735-
acc.push((name, uuid, fs));
718+
if diff.size.is_changed() {
719+
acc.push((name, uuid, fs));
720+
}
721+
if diff.size.is_changed() || diff.used.is_changed() {
722+
updated.insert(uuid, diff);
723+
}
736724
}
737725
Err(e) => {
738726
warn!("Failed to extend filesystem: {}", e);

0 commit comments

Comments
 (0)