Skip to content

Commit 26fbac2

Browse files
adam900710kdave
authored andcommitted
btrfs: autodefrag: only scan one inode once
Although we have btrfs_requeue_inode_defrag(), for autodefrag we are still just exhausting all inode_defrag items in the tree. This means, it doesn't make much difference to requeue an inode_defrag, other than scan the inode from the beginning till its end. Change the behaviour to always scan from offset 0 of an inode, and till the end. By this we get the following benefit: - Straight-forward code - No more re-queue related check - Fewer members in inode_defrag We still keep the same btrfs_get_fs_root() and btrfs_iget() check for each loop, and added extra should_auto_defrag() check per-loop. Note: the patch needs to be backported and is intentionally written to minimize the diff size, code will be cleaned up later. CC: stable@vger.kernel.org # 5.16 Signed-off-by: Qu Wenruo <wqu@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 199257a commit 26fbac2

1 file changed

Lines changed: 22 additions & 62 deletions

File tree

fs/btrfs/file.c

Lines changed: 22 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,6 @@ struct inode_defrag {
4949

5050
/* root objectid */
5151
u64 root;
52-
53-
/* last offset we were able to defrag */
54-
u64 last_offset;
55-
56-
/* if we've wrapped around back to zero once already */
57-
int cycled;
5852
};
5953

6054
static int __compare_inode_defrag(struct inode_defrag *defrag1,
@@ -107,8 +101,6 @@ static int __btrfs_add_inode_defrag(struct btrfs_inode *inode,
107101
*/
108102
if (defrag->transid < entry->transid)
109103
entry->transid = defrag->transid;
110-
if (defrag->last_offset > entry->last_offset)
111-
entry->last_offset = defrag->last_offset;
112104
return -EEXIST;
113105
}
114106
}
@@ -178,34 +170,6 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
178170
return 0;
179171
}
180172

181-
/*
182-
* Requeue the defrag object. If there is a defrag object that points to
183-
* the same inode in the tree, we will merge them together (by
184-
* __btrfs_add_inode_defrag()) and free the one that we want to requeue.
185-
*/
186-
static void btrfs_requeue_inode_defrag(struct btrfs_inode *inode,
187-
struct inode_defrag *defrag)
188-
{
189-
struct btrfs_fs_info *fs_info = inode->root->fs_info;
190-
int ret;
191-
192-
if (!__need_auto_defrag(fs_info))
193-
goto out;
194-
195-
/*
196-
* Here we don't check the IN_DEFRAG flag, because we need merge
197-
* them together.
198-
*/
199-
spin_lock(&fs_info->defrag_inodes_lock);
200-
ret = __btrfs_add_inode_defrag(inode, defrag);
201-
spin_unlock(&fs_info->defrag_inodes_lock);
202-
if (ret)
203-
goto out;
204-
return;
205-
out:
206-
kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
207-
}
208-
209173
/*
210174
* pick the defragable inode that we want, if it doesn't exist, we will get
211175
* the next one.
@@ -278,8 +242,14 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
278242
struct btrfs_root *inode_root;
279243
struct inode *inode;
280244
struct btrfs_ioctl_defrag_range_args range;
281-
int num_defrag;
282-
int ret;
245+
int ret = 0;
246+
u64 cur = 0;
247+
248+
again:
249+
if (test_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state))
250+
goto cleanup;
251+
if (!__need_auto_defrag(fs_info))
252+
goto cleanup;
283253

284254
/* get the inode */
285255
inode_root = btrfs_get_fs_root(fs_info, defrag->root, true);
@@ -295,39 +265,29 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
295265
goto cleanup;
296266
}
297267

268+
if (cur >= i_size_read(inode)) {
269+
iput(inode);
270+
goto cleanup;
271+
}
272+
298273
/* do a chunk of defrag */
299274
clear_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags);
300275
memset(&range, 0, sizeof(range));
301276
range.len = (u64)-1;
302-
range.start = defrag->last_offset;
277+
range.start = cur;
303278

304279
sb_start_write(fs_info->sb);
305-
num_defrag = btrfs_defrag_file(inode, NULL, &range, defrag->transid,
280+
ret = btrfs_defrag_file(inode, NULL, &range, defrag->transid,
306281
BTRFS_DEFRAG_BATCH);
307282
sb_end_write(fs_info->sb);
308-
/*
309-
* if we filled the whole defrag batch, there
310-
* must be more work to do. Queue this defrag
311-
* again
312-
*/
313-
if (num_defrag == BTRFS_DEFRAG_BATCH) {
314-
defrag->last_offset = range.start;
315-
btrfs_requeue_inode_defrag(BTRFS_I(inode), defrag);
316-
} else if (defrag->last_offset && !defrag->cycled) {
317-
/*
318-
* we didn't fill our defrag batch, but
319-
* we didn't start at zero. Make sure we loop
320-
* around to the start of the file.
321-
*/
322-
defrag->last_offset = 0;
323-
defrag->cycled = 1;
324-
btrfs_requeue_inode_defrag(BTRFS_I(inode), defrag);
325-
} else {
326-
kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
327-
}
328-
329283
iput(inode);
330-
return 0;
284+
285+
if (ret < 0)
286+
goto cleanup;
287+
288+
cur = max(cur + fs_info->sectorsize, range.start);
289+
goto again;
290+
331291
cleanup:
332292
kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
333293
return ret;

0 commit comments

Comments
 (0)