mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-04 09:34:12 +08:00
btrfs: use async_chunk::async_cow to replace the confusing pending pointer
For structure async_chunk, we use a very strange member layout to grab structure async_cow who owns this async_chunk. At initialization, it goes like this: async_chunk[i].pending = &ctx->num_chunks; Then at async_cow_free() we do a super weird freeing: /* * Since the pointer to 'pending' is at the beginning of the array of * async_chunk's, freeing it ensures the whole array has been freed. */ if (atomic_dec_and_test(async_chunk->pending)) kvfree(async_chunk->pending); This is absolutely an abuse of kvfree(). Replace async_chunk::pending with async_chunk::async_cow, so that we can grab the async_cow structure directly, without this strange dancing. And with this change, there is no requirement for any specific member location. Reviewed-by: Nikolay Borisov <nborisov@suse.com> Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
cf3075fb36
commit
9e895a8f7e
@ -455,11 +455,10 @@ struct async_chunk {
|
||||
struct list_head extents;
|
||||
struct cgroup_subsys_state *blkcg_css;
|
||||
struct btrfs_work work;
|
||||
atomic_t *pending;
|
||||
struct async_cow *async_cow;
|
||||
};
|
||||
|
||||
struct async_cow {
|
||||
/* Number of chunks in flight; must be first in the structure */
|
||||
atomic_t num_chunks;
|
||||
struct async_chunk chunks[];
|
||||
};
|
||||
@ -1324,18 +1323,17 @@ static noinline void async_cow_submit(struct btrfs_work *work)
|
||||
static noinline void async_cow_free(struct btrfs_work *work)
|
||||
{
|
||||
struct async_chunk *async_chunk;
|
||||
struct async_cow *async_cow;
|
||||
|
||||
async_chunk = container_of(work, struct async_chunk, work);
|
||||
if (async_chunk->inode)
|
||||
btrfs_add_delayed_iput(async_chunk->inode);
|
||||
if (async_chunk->blkcg_css)
|
||||
css_put(async_chunk->blkcg_css);
|
||||
/*
|
||||
* Since the pointer to 'pending' is at the beginning of the array of
|
||||
* async_chunk's, freeing it ensures the whole array has been freed.
|
||||
*/
|
||||
if (atomic_dec_and_test(async_chunk->pending))
|
||||
kvfree(async_chunk->pending);
|
||||
|
||||
async_cow = async_chunk->async_cow;
|
||||
if (atomic_dec_and_test(&async_cow->num_chunks))
|
||||
kvfree(async_cow);
|
||||
}
|
||||
|
||||
static int cow_file_range_async(struct btrfs_inode *inode,
|
||||
@ -1396,7 +1394,7 @@ static int cow_file_range_async(struct btrfs_inode *inode,
|
||||
* lightweight reference for the callback lifetime
|
||||
*/
|
||||
ihold(&inode->vfs_inode);
|
||||
async_chunk[i].pending = &ctx->num_chunks;
|
||||
async_chunk[i].async_cow = ctx;
|
||||
async_chunk[i].inode = &inode->vfs_inode;
|
||||
async_chunk[i].start = start;
|
||||
async_chunk[i].end = cur_end;
|
||||
|
Loading…
Reference in New Issue
Block a user