@@ -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) ;
0 commit comments