Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 210549eb authored by David Sterba's avatar David Sterba Committed by Josef Bacik
Browse files

btrfs: add cancellation points to defrag



The defrag operation can take very long, we want to have a way how to
cancel it. The code checks for a pending signal at safe points in the
defrag loops and returns EAGAIN. This means a user can press ^C after
running 'btrfs fi defrag', woks for both defrag modes, files and root.

Returning from the command was instant in my light tests, but may take
longer depending on the aging factor of the filesystem.

Signed-off-by: default avatarDavid Sterba <dsterba@suse.cz>
Signed-off-by: default avatarJosef Bacik <jbacik@fusionio.com>
parent b069e0c3
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -3786,4 +3786,11 @@ static inline int is_fstree(u64 rootid)
		return 1;
	return 0;
}

static inline int btrfs_defrag_cancelled(struct btrfs_fs_info *fs_info)
{
	return signal_pending(current);
}


#endif
+6 −0
Original line number Diff line number Diff line
@@ -1202,6 +1202,12 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
		if (!(inode->i_sb->s_flags & MS_ACTIVE))
			break;

		if (btrfs_defrag_cancelled(root->fs_info)) {
			printk(KERN_DEBUG "btrfs: defrag_file cancelled\n");
			ret = -EAGAIN;
			break;
		}

		if (!should_defrag_range(inode, (u64)i << PAGE_CACHE_SHIFT,
					 extent_thresh, &last_len, &skip,
					 &defrag_end, range->flags &
+6 −0
Original line number Diff line number Diff line
@@ -984,6 +984,12 @@ int btrfs_defrag_root(struct btrfs_root *root)

		if (btrfs_fs_closing(root->fs_info) || ret != -EAGAIN)
			break;

		if (btrfs_defrag_cancelled(root->fs_info)) {
			printk(KERN_DEBUG "btrfs: defrag_root cancelled\n");
			ret = -EAGAIN;
			break;
		}
	}
	root->defrag_running = 0;
	return ret;