@@ -333,6 +333,12 @@ int btrfs_verify_qgroup_counts(struct btrfs_fs_info *fs_info, u64 qgroupid,
333
333
}
334
334
#endif
335
335
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
+
336
342
/*
337
343
* The full config is read in one go, only called from open_ctree()
338
344
* 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)
401
407
}
402
408
if (btrfs_qgroup_status_generation (l , ptr ) !=
403
409
fs_info -> generation ) {
404
- flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
410
+ qgroup_mark_inconsistent ( fs_info ) ;
405
411
btrfs_err (fs_info ,
406
412
"qgroup generation mismatch, marked as inconsistent" );
407
413
}
@@ -419,7 +425,7 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info)
419
425
if ((qgroup && found_key .type == BTRFS_QGROUP_INFO_KEY ) ||
420
426
(!qgroup && found_key .type == BTRFS_QGROUP_LIMIT_KEY )) {
421
427
btrfs_err (fs_info , "inconsistent qgroup config" );
422
- flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
428
+ qgroup_mark_inconsistent ( fs_info ) ;
423
429
}
424
430
if (!qgroup ) {
425
431
qgroup = add_qgroup_rb (fs_info , found_key .offset );
@@ -1734,7 +1740,7 @@ int btrfs_limit_qgroup(struct btrfs_trans_handle *trans, u64 qgroupid,
1734
1740
1735
1741
ret = update_qgroup_limit_item (trans , qgroup );
1736
1742
if (ret ) {
1737
- fs_info -> qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
1743
+ qgroup_mark_inconsistent ( fs_info ) ;
1738
1744
btrfs_info (fs_info , "unable to update quota limit for %llu" ,
1739
1745
qgroupid );
1740
1746
}
@@ -1810,7 +1816,7 @@ int btrfs_qgroup_trace_extent_post(struct btrfs_trans_handle *trans,
1810
1816
ret = btrfs_find_all_roots (NULL , trans -> fs_info , bytenr , 0 , & old_root ,
1811
1817
true);
1812
1818
if (ret < 0 ) {
1813
- trans -> fs_info -> qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
1819
+ qgroup_mark_inconsistent ( trans -> fs_info ) ;
1814
1820
btrfs_warn (trans -> fs_info ,
1815
1821
"error accounting new delayed refs extent (err code: %d), quota inconsistent" ,
1816
1822
ret );
@@ -2286,7 +2292,7 @@ static int qgroup_trace_subtree_swap(struct btrfs_trans_handle *trans,
2286
2292
out :
2287
2293
btrfs_free_path (dst_path );
2288
2294
if (ret < 0 )
2289
- fs_info -> qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
2295
+ qgroup_mark_inconsistent ( fs_info ) ;
2290
2296
return ret ;
2291
2297
}
2292
2298
@@ -2790,12 +2796,10 @@ int btrfs_run_qgroups(struct btrfs_trans_handle *trans)
2790
2796
spin_unlock (& fs_info -> qgroup_lock );
2791
2797
ret = update_qgroup_info_item (trans , qgroup );
2792
2798
if (ret )
2793
- fs_info -> qgroup_flags |=
2794
- BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
2799
+ qgroup_mark_inconsistent (fs_info );
2795
2800
ret = update_qgroup_limit_item (trans , qgroup );
2796
2801
if (ret )
2797
- fs_info -> qgroup_flags |=
2798
- BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
2802
+ qgroup_mark_inconsistent (fs_info );
2799
2803
spin_lock (& fs_info -> qgroup_lock );
2800
2804
}
2801
2805
if (test_bit (BTRFS_FS_QUOTA_ENABLED , & fs_info -> flags ))
@@ -2806,7 +2810,7 @@ int btrfs_run_qgroups(struct btrfs_trans_handle *trans)
2806
2810
2807
2811
ret = update_qgroup_status_item (trans );
2808
2812
if (ret )
2809
- fs_info -> qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
2813
+ qgroup_mark_inconsistent ( fs_info ) ;
2810
2814
2811
2815
return ret ;
2812
2816
}
@@ -2924,7 +2928,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
2924
2928
2925
2929
ret = update_qgroup_limit_item (trans , dstgroup );
2926
2930
if (ret ) {
2927
- fs_info -> qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
2931
+ qgroup_mark_inconsistent ( fs_info ) ;
2928
2932
btrfs_info (fs_info ,
2929
2933
"unable to update quota limit for %llu" ,
2930
2934
dstgroup -> qgroupid );
@@ -3030,7 +3034,7 @@ int btrfs_qgroup_inherit(struct btrfs_trans_handle *trans, u64 srcid,
3030
3034
if (!committing )
3031
3035
mutex_unlock (& fs_info -> qgroup_ioctl_lock );
3032
3036
if (need_rescan )
3033
- fs_info -> qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
3037
+ qgroup_mark_inconsistent ( fs_info ) ;
3034
3038
return ret ;
3035
3039
}
3036
3040
@@ -3303,7 +3307,8 @@ static bool rescan_should_stop(struct btrfs_fs_info *fs_info)
3303
3307
{
3304
3308
return btrfs_fs_closing (fs_info ) ||
3305
3309
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 ;
3307
3312
}
3308
3313
3309
3314
static void btrfs_qgroup_rescan_worker (struct btrfs_work * work )
@@ -3368,7 +3373,8 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
3368
3373
}
3369
3374
3370
3375
mutex_lock (& fs_info -> qgroup_rescan_lock );
3371
- if (!stopped )
3376
+ if (!stopped ||
3377
+ fs_info -> qgroup_flags & BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN )
3372
3378
fs_info -> qgroup_flags &= ~BTRFS_QGROUP_STATUS_FLAG_RESCAN ;
3373
3379
if (trans ) {
3374
3380
ret = update_qgroup_status_item (trans );
@@ -3379,6 +3385,7 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
3379
3385
}
3380
3386
}
3381
3387
fs_info -> qgroup_rescan_running = false;
3388
+ fs_info -> qgroup_flags &= ~BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN ;
3382
3389
complete_all (& fs_info -> qgroup_rescan_completion );
3383
3390
mutex_unlock (& fs_info -> qgroup_rescan_lock );
3384
3391
@@ -3389,6 +3396,8 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
3389
3396
3390
3397
if (stopped ) {
3391
3398
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" );
3392
3401
} else if (err >= 0 ) {
3393
3402
btrfs_info (fs_info , "qgroup scan completed%s" ,
3394
3403
err > 0 ? " (inconsistency flag cleared)" : "" );
@@ -3451,6 +3460,7 @@ qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
3451
3460
3452
3461
memset (& fs_info -> qgroup_rescan_progress , 0 ,
3453
3462
sizeof (fs_info -> qgroup_rescan_progress ));
3463
+ fs_info -> qgroup_flags &= ~BTRFS_QGROUP_RUNTIME_FLAG_CANCEL_RESCAN ;
3454
3464
fs_info -> qgroup_rescan_progress .objectid = progress_objectid ;
3455
3465
init_completion (& fs_info -> qgroup_rescan_completion );
3456
3466
mutex_unlock (& fs_info -> qgroup_rescan_lock );
@@ -4248,8 +4258,7 @@ int btrfs_qgroup_add_swapped_blocks(struct btrfs_trans_handle *trans,
4248
4258
spin_unlock (& blocks -> lock );
4249
4259
out :
4250
4260
if (ret < 0 )
4251
- fs_info -> qgroup_flags |=
4252
- BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
4261
+ qgroup_mark_inconsistent (fs_info );
4253
4262
return ret ;
4254
4263
}
4255
4264
@@ -4336,7 +4345,7 @@ int btrfs_qgroup_trace_subtree_after_cow(struct btrfs_trans_handle *trans,
4336
4345
btrfs_err_rl (fs_info ,
4337
4346
"failed to account subtree at bytenr %llu: %d" ,
4338
4347
subvol_eb -> start , ret );
4339
- fs_info -> qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;
4348
+ qgroup_mark_inconsistent ( fs_info ) ;
4340
4349
}
4341
4350
return ret ;
4342
4351
}
0 commit comments