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 */
 
                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);
        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) {
        }
        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 {