btrfs: qgroup: exit the rescan worker during umount
I was hitting a consistent NULL pointer dereference during shutdown that showed the trace running through end_workqueue_bio(). I traced it back to the endio_meta_workers workqueue being poked after it had already been destroyed. Eventually I found that the root cause was a qgroup rescan that was still in progress while we were stopping all the btrfs workers. Currently we explicitly pause balance and scrub operations in close_ctree(), but we do nothing to stop the qgroup rescan. We should probably be doing the same for qgroup rescan, but that's a much larger change. This small change is good enough to allow me to unmount without crashing. Signed-off-by: Justin Maggard <jmaggard@netgear.com> Reviewed-by: Filipe Manana <fdmanana@suse.com>
This commit is contained in:
		
							parent
							
								
									9c9464cc92
								
							
						
					
					
						commit
						7343dd61fd
					
				| @ -3780,6 +3780,9 @@ void close_ctree(struct btrfs_root *root) | ||||
| 	fs_info->closing = 1; | ||||
| 	smp_mb(); | ||||
| 
 | ||||
| 	/* wait for the qgroup rescan worker to stop */ | ||||
| 	btrfs_qgroup_wait_for_completion(fs_info); | ||||
| 
 | ||||
| 	/* wait for the uuid_scan task to finish */ | ||||
| 	down(&fs_info->uuid_tree_rescan_sem); | ||||
| 	/* avoid complains from lockdep et al., set sem back to initial state */ | ||||
|  | ||||
| @ -2286,7 +2286,7 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work) | ||||
| 		goto out; | ||||
| 
 | ||||
| 	err = 0; | ||||
| 	while (!err) { | ||||
| 	while (!err && !btrfs_fs_closing(fs_info)) { | ||||
| 		trans = btrfs_start_transaction(fs_info->fs_root, 0); | ||||
| 		if (IS_ERR(trans)) { | ||||
| 			err = PTR_ERR(trans); | ||||
| @ -2307,7 +2307,8 @@ out: | ||||
| 	btrfs_free_path(path); | ||||
| 
 | ||||
| 	mutex_lock(&fs_info->qgroup_rescan_lock); | ||||
| 	fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN; | ||||
| 	if (!btrfs_fs_closing(fs_info)) | ||||
| 		fs_info->qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN; | ||||
| 
 | ||||
| 	if (err > 0 && | ||||
| 	    fs_info->qgroup_flags & BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT) { | ||||
| @ -2336,7 +2337,9 @@ out: | ||||
| 	} | ||||
| 	btrfs_end_transaction(trans, fs_info->quota_root); | ||||
| 
 | ||||
| 	if (err >= 0) { | ||||
| 	if (btrfs_fs_closing(fs_info)) { | ||||
| 		btrfs_info(fs_info, "qgroup scan paused"); | ||||
| 	} else if (err >= 0) { | ||||
| 		btrfs_info(fs_info, "qgroup scan completed%s", | ||||
| 			err > 0 ? " (inconsistency flag cleared)" : ""); | ||||
| 	} else { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user