OSDN Git Service

btrfs: defrag: pass file_ra_state instead of file to btrfs_defrag_file()
authorQu Wenruo <wqu@suse.com>
Fri, 6 Aug 2021 08:12:32 +0000 (16:12 +0800)
committerDavid Sterba <dsterba@suse.com>
Tue, 26 Oct 2021 17:04:39 +0000 (19:04 +0200)
Currently btrfs_defrag_file() accepts both "struct inode" and "struct
file" as parameter.  We can easily grab "struct inode" from "struct
file" using file_inode() helper.

The reason why we need "struct file" is just to re-use its f_ra.

Change this to pass "struct file_ra_state" parameter, so that it's more
clear what we really want.  Since we're here, also add some comments on
the function btrfs_defrag_file().

Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/ctree.h
fs/btrfs/ioctl.c

index 8736347..8f0174c 100644 (file)
@@ -3243,9 +3243,9 @@ int btrfs_fileattr_set(struct user_namespace *mnt_userns,
 int btrfs_ioctl_get_supported_features(void __user *arg);
 void btrfs_sync_inode_flags_to_i_flags(struct inode *inode);
 int __pure btrfs_is_empty_uuid(u8 *uuid);
-int btrfs_defrag_file(struct inode *inode, struct file *file,
+int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra,
                      struct btrfs_ioctl_defrag_range_args *range,
-                     u64 newer_than, unsigned long max_pages);
+                     u64 newer_than, unsigned long max_to_defrag);
 void btrfs_get_block_group_info(struct list_head *groups_list,
                                struct btrfs_ioctl_space_info *space);
 void btrfs_update_ioctl_balance_args(struct btrfs_fs_info *fs_info,
index 1c4b624..033726a 100644 (file)
@@ -1403,13 +1403,22 @@ out:
 
 }
 
-int btrfs_defrag_file(struct inode *inode, struct file *file,
+/*
+ * Entry point to file defragmentation.
+ *
+ * @inode:        inode to be defragged
+ * @ra:                   readahead state (can be NUL)
+ * @range:        defrag options including range and flags
+ * @newer_than:           minimum transid to defrag
+ * @max_to_defrag: max number of sectors to be defragged, if 0, the whole inode
+ *                will be defragged.
+ */
+int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra,
                      struct btrfs_ioctl_defrag_range_args *range,
                      u64 newer_than, unsigned long max_to_defrag)
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        struct btrfs_root *root = BTRFS_I(inode)->root;
-       struct file_ra_state *ra = NULL;
        unsigned long last_index;
        u64 isize = i_size_read(inode);
        u64 last_len = 0;
@@ -1427,6 +1436,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
        u64 new_align = ~((u64)SZ_128K - 1);
        struct page **pages = NULL;
        bool do_compress = range->flags & BTRFS_DEFRAG_RANGE_COMPRESS;
+       bool ra_allocated = false;
 
        if (isize == 0)
                return 0;
@@ -1445,16 +1455,15 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
                extent_thresh = SZ_256K;
 
        /*
-        * If we were not given a file, allocate a readahead context. As
+        * If we were not given a ra, allocate a readahead context. As
         * readahead is just an optimization, defrag will work without it so
         * we don't error out.
         */
-       if (!file) {
+       if (!ra) {
+               ra_allocated = true;
                ra = kzalloc(sizeof(*ra), GFP_KERNEL);
                if (ra)
                        file_ra_state_init(ra, inode->i_mapping);
-       } else {
-               ra = &file->f_ra;
        }
 
        pages = kmalloc_array(max_cluster, sizeof(struct page *), GFP_KERNEL);
@@ -1536,7 +1545,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
                        ra_index = max(i, ra_index);
                        if (ra)
                                page_cache_sync_readahead(inode->i_mapping, ra,
-                                               file, ra_index, cluster);
+                                               NULL, ra_index, cluster);
                        ra_index += cluster;
                }
 
@@ -1607,7 +1616,7 @@ out_ra:
                BTRFS_I(inode)->defrag_compress = BTRFS_COMPRESS_NONE;
                btrfs_inode_unlock(inode, 0);
        }
-       if (!file)
+       if (ra_allocated)
                kfree(ra);
        kfree(pages);
        return ret;
@@ -3176,7 +3185,7 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp)
                        /* the rest are all set to zero by kzalloc */
                        range.len = (u64)-1;
                }
-               ret = btrfs_defrag_file(file_inode(file), file,
+               ret = btrfs_defrag_file(file_inode(file), &file->f_ra,
                                        &range, BTRFS_OLDEST_GENERATION, 0);
                if (ret > 0)
                        ret = 0;