While testing -o compress,discard=async I got an -ENOSPC where I shouldn't, which resulted in things going horribly wrong. The -ENOSPC was my bug, but things going horribly wrong wasn't. This is where I got the abort
I'm not sure why we started spinning on the discard_ctl->lock. Just looking at the code I didn't spot any obvious locking mistakes, but I did notice we don't hold a ref for the block_group on the discard lists, which we should probably fix. It may be possible that we freed the block group when we cleaned up the aborted transaction and then we hung when trying to access some free'd discard_ctl. But I can't be sure, it warrants investigation. The code looks like this where we aborted
skip_backref:
ret = btrfs_delete_delayed_dir_index(trans, dir, index);
if (ret) {
btrfs_abort_transaction(trans, ret);
goto err;
}
ret = btrfs_del_inode_ref_in_log(trans, root, name, name_len, inode,
dir_ino);
if (ret != 0 && ret != -ENOENT) {
btrfs_abort_transaction(trans, ret);
goto err;
}
ret = btrfs_del_dir_entries_in_log(trans, root, name, name_len, dir,
index);
if (ret == -ENOENT)
ret = 0;
else if (ret)
btrfs_abort_transaction(trans, ret);
Probably just rig up some error injection here and try to reproduce the problem.
While testing
-o compress,discard=async
I got an-ENOSPC
where I shouldn't, which resulted in things going horribly wrong. The-ENOSPC
was my bug, but things going horribly wrong wasn't. This is where I got the abortI'm not sure why we started spinning on the
discard_ctl->lock
. Just looking at the code I didn't spot any obvious locking mistakes, but I did notice we don't hold a ref for theblock_group
on the discard lists, which we should probably fix. It may be possible that we freed the block group when we cleaned up the aborted transaction and then we hung when trying to access some free'd discard_ctl. But I can't be sure, it warrants investigation. The code looks like this where we abortedProbably just rig up some error injection here and try to reproduce the problem.