Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason: "We have a few fixes in my for-linus branch. Qu Wenruo's batch fix a regression between some our merge window pull and the inode_cache feature. The rest are smaller bugs" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: btrfs: Don't call btrfs_start_transaction() on frozen fs to avoid deadlock. btrfs: Fix the bug that fs_info->pending_changes is never cleared. btrfs: fix state->private cast on 32 bit machines Btrfs: fix race deleting block group from space_info->ro_bgs list Btrfs: fix incorrect freeing in scrub_stripe btrfs: sync ioctl, handle errors after transaction start
This commit is contained in:
commit
c4e00f1d31
|
@ -1171,6 +1171,7 @@ struct btrfs_space_info {
|
||||||
struct percpu_counter total_bytes_pinned;
|
struct percpu_counter total_bytes_pinned;
|
||||||
|
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
|
/* Protected by the spinlock 'lock'. */
|
||||||
struct list_head ro_bgs;
|
struct list_head ro_bgs;
|
||||||
|
|
||||||
struct rw_semaphore groups_sem;
|
struct rw_semaphore groups_sem;
|
||||||
|
|
|
@ -9422,7 +9422,6 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
|
||||||
* are still on the list after taking the semaphore
|
* are still on the list after taking the semaphore
|
||||||
*/
|
*/
|
||||||
list_del_init(&block_group->list);
|
list_del_init(&block_group->list);
|
||||||
list_del_init(&block_group->ro_list);
|
|
||||||
if (list_empty(&block_group->space_info->block_groups[index])) {
|
if (list_empty(&block_group->space_info->block_groups[index])) {
|
||||||
kobj = block_group->space_info->block_group_kobjs[index];
|
kobj = block_group->space_info->block_group_kobjs[index];
|
||||||
block_group->space_info->block_group_kobjs[index] = NULL;
|
block_group->space_info->block_group_kobjs[index] = NULL;
|
||||||
|
@ -9464,6 +9463,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
|
||||||
btrfs_remove_free_space_cache(block_group);
|
btrfs_remove_free_space_cache(block_group);
|
||||||
|
|
||||||
spin_lock(&block_group->space_info->lock);
|
spin_lock(&block_group->space_info->lock);
|
||||||
|
list_del_init(&block_group->ro_list);
|
||||||
block_group->space_info->total_bytes -= block_group->key.offset;
|
block_group->space_info->total_bytes -= block_group->key.offset;
|
||||||
block_group->space_info->bytes_readonly -= block_group->key.offset;
|
block_group->space_info->bytes_readonly -= block_group->key.offset;
|
||||||
block_group->space_info->disk_total -= block_group->key.offset * factor;
|
block_group->space_info->disk_total -= block_group->key.offset * factor;
|
||||||
|
|
|
@ -2190,7 +2190,7 @@ void btrfs_free_io_failure_record(struct inode *inode, u64 start, u64 end)
|
||||||
|
|
||||||
next = next_state(state);
|
next = next_state(state);
|
||||||
|
|
||||||
failrec = (struct io_failure_record *)state->private;
|
failrec = (struct io_failure_record *)(unsigned long)state->private;
|
||||||
free_extent_state(state);
|
free_extent_state(state);
|
||||||
kfree(failrec);
|
kfree(failrec);
|
||||||
|
|
||||||
|
|
|
@ -3053,7 +3053,7 @@ static noinline_for_stack int scrub_stripe(struct scrub_ctx *sctx,
|
||||||
|
|
||||||
ppath = btrfs_alloc_path();
|
ppath = btrfs_alloc_path();
|
||||||
if (!ppath) {
|
if (!ppath) {
|
||||||
btrfs_free_path(ppath);
|
btrfs_free_path(path);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1000,10 +1000,20 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
|
||||||
*/
|
*/
|
||||||
if (fs_info->pending_changes == 0)
|
if (fs_info->pending_changes == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
/*
|
||||||
|
* A non-blocking test if the fs is frozen. We must not
|
||||||
|
* start a new transaction here otherwise a deadlock
|
||||||
|
* happens. The pending operations are delayed to the
|
||||||
|
* next commit after thawing.
|
||||||
|
*/
|
||||||
|
if (__sb_start_write(sb, SB_FREEZE_WRITE, false))
|
||||||
|
__sb_end_write(sb, SB_FREEZE_WRITE);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
trans = btrfs_start_transaction(root, 0);
|
trans = btrfs_start_transaction(root, 0);
|
||||||
} else {
|
|
||||||
return PTR_ERR(trans);
|
|
||||||
}
|
}
|
||||||
|
if (IS_ERR(trans))
|
||||||
|
return PTR_ERR(trans);
|
||||||
}
|
}
|
||||||
return btrfs_commit_transaction(trans, root);
|
return btrfs_commit_transaction(trans, root);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2118,7 +2118,7 @@ void btrfs_apply_pending_changes(struct btrfs_fs_info *fs_info)
|
||||||
unsigned long prev;
|
unsigned long prev;
|
||||||
unsigned long bit;
|
unsigned long bit;
|
||||||
|
|
||||||
prev = cmpxchg(&fs_info->pending_changes, 0, 0);
|
prev = xchg(&fs_info->pending_changes, 0);
|
||||||
if (!prev)
|
if (!prev)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue