@@ -333,6 +333,12 @@ int btrfs_verify_qgroup_counts(struct btrfs_fs_info *fs_info, u64 qgroupid,
333333}
334334#endif
335335
336+ static void qgroup_mark_inconsistent (struct btrfs_fs_info * fs_info )
337+ {
338+ fs_info -> qgroup_flags |= (BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT |
339+ BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN );
340+ }
341+
336342/*
337343 * The full config is read in one go, only called from open_ctree()
338344 * It doesn't use any locking, as at this point we're still single-threaded
@@ -401,7 +407,7 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
401407 }
402408 if (btrfs_qgroup_status_generation (l , ptr ) !=
403409 fs_info -> generation ) {
404- flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
410+ qgroup_mark_inconsistent ( fs_info ) ;
405411 btrfs_err (fs_info ,
406412 "qgroup generation mismatch, marked as inconsistent" );
407413 }
@@ -419,7 +425,7 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
419425 if ((qgroup && found_key .type == BTRFS_QGROUP_INFO_KEY ) ||
420426 (!qgroup && found_key .type == BTRFS_QGROUP_LIMIT_KEY )) {
421427 btrfs_err (fs_info , "inconsistent qgroup config" );
422- flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
428+ qgroup_mark_inconsistent ( fs_info ) ;
423429 }
424430 if (!qgroup ) {
425431 qgroup = add_qgroup_rb (fs_info , found_key .offset );
@@ -1734,7 +1740,7 @@ int btrfs_limit_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid,
17341740
17351741 ret = update_qgroup_limit_item (trans , qgroup );
17361742 if (ret ) {
1737- fs_info -> qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
1743+ qgroup_mark_inconsistent ( fs_info ) ;
17381744 btrfs_info (fs_info , "unable to update quota limit for %llu" ,
17391745 qgroupid );
17401746 }
@@ -1810,7 +1816,7 @@ int btrfs_qgroup_trace_extent_post(struct btrfs_trans_handle *trans,
18101816 ret = btrfs_find_all_roots (NULL , trans -> fs_info , bytenr , 0 , & old_root ,
18111817 true);
18121818 if (ret < 0 ) {
1813- trans -> fs_info -> qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
1819+ qgroup_mark_inconsistent ( trans -> fs_info ) ;
18141820 btrfs_warn (trans -> fs_info ,
18151821"error accounting new delayed refs extent (err code: %d), quota inconsistent" ,
18161822 ret );
@@ -2286,7 +2292,7 @@ static int qgroup_trace_subtree_swap(struct btrfs_trans_handle *trans,
22862292out :
22872293 btrfs_free_path (dst_path );
22882294 if (ret < 0 )
2289- fs_info -> qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
2295+ qgroup_mark_inconsistent ( fs_info ) ;
22902296 return ret ;
22912297}
22922298
@@ -2790,12 +2796,10 @@ int btrfs_run_qgroups(struct btrfs_trans_handle *trans)
27902796 spin_unlock (& fs_info -> qgroup_lock );
27912797 ret = update_qgroup_info_item (trans , qgroup );
27922798 if (ret )
2793- fs_info -> qgroup_flags |=
2794- BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
2799+ qgroup_mark_inconsistent (fs_info );
27952800 ret = update_qgroup_limit_item (trans , qgroup );
27962801 if (ret )
2797- fs_info -> qgroup_flags |=
2798- BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
2802+ qgroup_mark_inconsistent (fs_info );
27992803 spin_lock (& fs_info -> qgroup_lock );
28002804 }
28012805 if (test_bit (BTRFS_FS_QUOTA_ENABLED , & fs_info -> flags ))
@@ -2806,7 +2810,7 @@ int btrfs_run_qgroups(struct btrfs_trans_handle *trans)
28062810
28072811 ret = update_qgroup_status_item (trans );
28082812 if (ret )
2809- fs_info -> qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
2813+ qgroup_mark_inconsistent ( fs_info ) ;
28102814
28112815 return ret ;
28122816}
@@ -2924,7 +2928,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
29242928
29252929 ret = update_qgroup_limit_item (trans , dstgroup );
29262930 if (ret ) {
2927- fs_info -> qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
2931+ qgroup_mark_inconsistent ( fs_info ) ;
29282932 btrfs_info (fs_info ,
29292933 "unable to update quota limit for %llu" ,
29302934 dstgroup -> qgroupid );
@@ -3030,7 +3034,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
30303034 if (!committing )
30313035 mutex_unlock (& fs_info -> qgroup_ioctl_lock );
30323036 if (need_rescan )
3033- fs_info -> qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
3037+ qgroup_mark_inconsistent ( fs_info ) ;
30343038 return ret ;
30353039}
30363040
@@ -3303,7 +3307,8 @@ static bool rescan_should_stop(struct btrfs_fs_info *fs_info)
33033307{
33043308 return btrfs_fs_closing (fs_info ) ||
33053309 test_bit (BTRFS_FS_STATE_REMOUNTING , & fs_info -> fs_state ) ||
3306- !test_bit (BTRFS_FS_QUOTA_ENABLED , & fs_info -> flags );
3310+ !test_bit (BTRFS_FS_QUOTA_ENABLED , & fs_info -> flags ) ||
3311+ fs_info -> qgroup_flags & BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN ;
33073312}
33083313
33093314static void btrfs_qgroup_rescan_worker (struct btrfs_work * work )
@@ -3368,7 +3373,8 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
33683373 }
33693374
33703375 mutex_lock (& fs_info -> qgroup_rescan_lock );
3371- if (!stopped )
3376+ if (!stopped ||
3377+ fs_info -> qgroup_flags & BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN )
33723378 fs_info -> qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN ;
33733379 if (trans ) {
33743380 ret = update_qgroup_status_item (trans );
@@ -3379,6 +3385,7 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
33793385 }
33803386 }
33813387 fs_info -> qgroup_rescan_running = false;
3388+ fs_info -> qgroup_flags &= ~BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN ;
33823389 complete_all (& fs_info -> qgroup_rescan_completion );
33833390 mutex_unlock (& fs_info -> qgroup_rescan_lock );
33843391
@@ -3389,6 +3396,8 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
33893396
33903397 if (stopped ) {
33913398 btrfs_info (fs_info , "qgroup scan paused" );
3399+ } else if (fs_info -> qgroup_flags & BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN ) {
3400+ btrfs_info (fs_info , "qgroup scan cancelled" );
33923401 } else if (err >= 0 ) {
33933402 btrfs_info (fs_info , "qgroup scan completed%s" ,
33943403 err > 0 ? " (inconsistency flag cleared)" : "" );
@@ -3451,6 +3460,7 @@ qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
34513460
34523461 memset (& fs_info -> qgroup_rescan_progress , 0 ,
34533462 sizeof (fs_info -> qgroup_rescan_progress ));
3463+ fs_info -> qgroup_flags &= ~BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN ;
34543464 fs_info -> qgroup_rescan_progress .objectid = progress_objectid ;
34553465 init_completion (& fs_info -> qgroup_rescan_completion );
34563466 mutex_unlock (& fs_info -> qgroup_rescan_lock );
@@ -4248,8 +4258,7 @@ int btrfs_qgroup_add_swapped_blocks(struct btrfs_trans_handle *trans,
42484258 spin_unlock (& blocks -> lock );
42494259out :
42504260 if (ret < 0 )
4251- fs_info -> qgroup_flags |=
4252- BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
4261+ qgroup_mark_inconsistent (fs_info );
42534262 return ret ;
42544263}
42554264
@@ -4336,7 +4345,7 @@ int btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans,
43364345 btrfs_err_rl (fs_info ,
43374346 "failed to account subtree at bytenr %llu: %d" ,
43384347 subvol_eb -> start , ret );
4339- fs_info -> qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
4348+ qgroup_mark_inconsistent ( fs_info ) ;
43404349 }
43414350 return ret ;
43424351}
0 commit comments