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 <dste...@suse.cz>
> ---
>  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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to