On 2/9/13 5:38 PM, David Sterba wrote:
> 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.
When __btrfs_run_defrag_inode() calls btrfs_defrag_file() and gets
-EAGAIN back due to the cancellation, will it reset the defrag->
counters and call btrfs_requeue_inode_defrag()? Is that ok?
Should __btrfs_run_defrag_inode explicitly check for and handle
an actual error returned to it?
Thanks,
-Eric
> Signed-off-by: David Sterba <dsterba@xxxxxxx>
> ---
> fs/btrfs/ctree.h | 7 +++++++
> fs/btrfs/ioctl.c | 6 ++++++
> fs/btrfs/transaction.c | 6 ++++++
> 3 files changed, 19 insertions(+), 0 deletions(-)
>
> diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
> index 547b7b0..4b41d7c 100644
> --- a/fs/btrfs/ctree.h
> +++ b/fs/btrfs/ctree.h
> @@ -3745,4 +3745,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
> diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
> index 338f259..78a5580 100644
> --- a/fs/btrfs/ioctl.c
> +++ b/fs/btrfs/ioctl.c
> @@ -1206,6 +1206,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 &
> diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
> index fc03aa6..2c509c4 100644
> --- a/fs/btrfs/transaction.c
> +++ b/fs/btrfs/transaction.c
> @@ -986,6 +986,12 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly)
>
> 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;
>
--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html