Re: [PATCH v4 2/3] Btrfs: rescan for qgroups
On 01.05.2013 13:42, Wang Shilong wrote: > Hi Jan, > >> Hi Wang, >> >> On 01.05.2013 09:29, Wang Shilong wrote: >>> Hello Jan, >>> If qgroup tracking is out of sync, a rescan operation can be started. It iterates the complete extent tree and recalculates all qgroup tracking data. This is an expensive operation and should not be used unless required. A filesystem under rescan can still be umounted. The rescan continues on the next mount. Status information is provided with a separate ioctl while a rescan operation is in progress. Signed-off-by: Jan Schmidt --- fs/btrfs/ctree.h | 17 ++- fs/btrfs/disk-io.c |5 + fs/btrfs/ioctl.c | 83 ++-- fs/btrfs/qgroup.c | 318 ++-- include/uapi/linux/btrfs.h | 12 ++- 5 files changed, 400 insertions(+), 35 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 412c306..e4f28a6 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1021,9 +1021,9 @@ struct btrfs_block_group_item { */ #define BTRFS_QGROUP_STATUS_FLAG_ON(1ULL << 0) /* - * SCANNING is set during the initialization phase + * RESCAN is set during the initialization phase */ -#define BTRFS_QGROUP_STATUS_FLAG_SCANNING (1ULL << 1) +#define BTRFS_QGROUP_STATUS_FLAG_RESCAN (1ULL << 1) /* * Some qgroup entries are known to be out of date, * either because the configuration has changed in a way that @@ -1052,7 +1052,7 @@ struct btrfs_qgroup_status_item { * only used during scanning to record the progress * of the scan. It contains a logical address */ - __le64 scan; + __le64 rescan; } __attribute__ ((__packed__)); struct btrfs_qgroup_info_item { @@ -1603,6 +1603,11 @@ struct btrfs_fs_info { /* used by btrfs_qgroup_record_ref for an efficient tree traversal */ u64 qgroup_seq; + /* qgroup rescan items */ + struct mutex qgroup_rescan_lock; /* protects the progress item */ + struct btrfs_key qgroup_rescan_progress; + struct btrfs_workers qgroup_rescan_workers; + /* filesystem state */ unsigned long fs_state; @@ -2888,8 +2893,8 @@ BTRFS_SETGET_FUNCS(qgroup_status_version, struct btrfs_qgroup_status_item, version, 64); BTRFS_SETGET_FUNCS(qgroup_status_flags, struct btrfs_qgroup_status_item, flags, 64); -BTRFS_SETGET_FUNCS(qgroup_status_scan, struct btrfs_qgroup_status_item, - scan, 64); +BTRFS_SETGET_FUNCS(qgroup_status_rescan, struct btrfs_qgroup_status_item, + rescan, 64); /* btrfs_qgroup_info_item */ BTRFS_SETGET_FUNCS(qgroup_info_generation, struct btrfs_qgroup_info_item, @@ -3834,7 +3839,7 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); int btrfs_quota_disable(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); -int btrfs_quota_rescan(struct btrfs_fs_info *fs_info); +int btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info); int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, u64 src, u64 dst); int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 7717363..63e9348 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2010,6 +2010,7 @@ static void btrfs_stop_all_workers(struct btrfs_fs_info *fs_info) btrfs_stop_workers(&fs_info->caching_workers); btrfs_stop_workers(&fs_info->readahead_workers); btrfs_stop_workers(&fs_info->flush_workers); + btrfs_stop_workers(&fs_info->qgroup_rescan_workers); } /* helper to cleanup tree roots */ @@ -2301,6 +2302,7 @@ int open_ctree(struct super_block *sb, fs_info->qgroup_seq = 1; fs_info->quota_enabled = 0; fs_info->pending_quota_state = 0; + mutex_init(&fs_info->qgroup_rescan_lock); btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); btrfs_init_free_cluster(&fs_info->data_alloc_cluster); @@ -2529,6 +2531,8 @@ int open_ctree(struct super_block *sb, btrfs_init_workers(&fs_info->readahead_workers, "readahead", fs_info->thread_pool_size, &fs_info->generic_worker); + btrfs_init_workers(&fs_info->qgroup_rescan_workers, "qgroup-rescan", 1, + &fs_info->generic_worker); /* * endios are largely parallel and should have a very @@ -2563,6 +2567,7 @@ int open_ctree(struct super_block *sb, ret |=
Re: [PATCH v4 2/3] Btrfs: rescan for qgroups
Hi Jan, > Hi Wang, > > On 01.05.2013 09:29, Wang Shilong wrote: >> Hello Jan, >> >>> If qgroup tracking is out of sync, a rescan operation can be started. It >>> iterates the complete extent tree and recalculates all qgroup tracking data. >>> This is an expensive operation and should not be used unless required. >>> >>> A filesystem under rescan can still be umounted. The rescan continues on the >>> next mount. Status information is provided with a separate ioctl while a >>> rescan operation is in progress. >>> >>> Signed-off-by: Jan Schmidt >>> --- >>> fs/btrfs/ctree.h | 17 ++- >>> fs/btrfs/disk-io.c |5 + >>> fs/btrfs/ioctl.c | 83 ++-- >>> fs/btrfs/qgroup.c | 318 >>> ++-- >>> include/uapi/linux/btrfs.h | 12 ++- >>> 5 files changed, 400 insertions(+), 35 deletions(-) >>> >>> diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h >>> index 412c306..e4f28a6 100644 >>> --- a/fs/btrfs/ctree.h >>> +++ b/fs/btrfs/ctree.h >>> @@ -1021,9 +1021,9 @@ struct btrfs_block_group_item { >>> */ >>> #define BTRFS_QGROUP_STATUS_FLAG_ON (1ULL << 0) >>> /* >>> - * SCANNING is set during the initialization phase >>> + * RESCAN is set during the initialization phase >>> */ >>> -#define BTRFS_QGROUP_STATUS_FLAG_SCANNING (1ULL << 1) >>> +#define BTRFS_QGROUP_STATUS_FLAG_RESCAN(1ULL << 1) >>> /* >>> * Some qgroup entries are known to be out of date, >>> * either because the configuration has changed in a way that >>> @@ -1052,7 +1052,7 @@ struct btrfs_qgroup_status_item { >>> * only used during scanning to record the progress >>> * of the scan. It contains a logical address >>> */ >>> - __le64 scan; >>> + __le64 rescan; >>> } __attribute__ ((__packed__)); >>> >>> struct btrfs_qgroup_info_item { >>> @@ -1603,6 +1603,11 @@ struct btrfs_fs_info { >>> /* used by btrfs_qgroup_record_ref for an efficient tree traversal */ >>> u64 qgroup_seq; >>> >>> + /* qgroup rescan items */ >>> + struct mutex qgroup_rescan_lock; /* protects the progress item */ >>> + struct btrfs_key qgroup_rescan_progress; >>> + struct btrfs_workers qgroup_rescan_workers; >>> + >>> /* filesystem state */ >>> unsigned long fs_state; >>> >>> @@ -2888,8 +2893,8 @@ BTRFS_SETGET_FUNCS(qgroup_status_version, struct >>> btrfs_qgroup_status_item, >>>version, 64); >>> BTRFS_SETGET_FUNCS(qgroup_status_flags, struct btrfs_qgroup_status_item, >>>flags, 64); >>> -BTRFS_SETGET_FUNCS(qgroup_status_scan, struct btrfs_qgroup_status_item, >>> - scan, 64); >>> +BTRFS_SETGET_FUNCS(qgroup_status_rescan, struct btrfs_qgroup_status_item, >>> + rescan, 64); >>> >>> /* btrfs_qgroup_info_item */ >>> BTRFS_SETGET_FUNCS(qgroup_info_generation, struct btrfs_qgroup_info_item, >>> @@ -3834,7 +3839,7 @@ int btrfs_quota_enable(struct btrfs_trans_handle >>> *trans, >>>struct btrfs_fs_info *fs_info); >>> int btrfs_quota_disable(struct btrfs_trans_handle *trans, >>> struct btrfs_fs_info *fs_info); >>> -int btrfs_quota_rescan(struct btrfs_fs_info *fs_info); >>> +int btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info); >>> int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, >>> struct btrfs_fs_info *fs_info, u64 src, u64 dst); >>> int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, >>> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c >>> index 7717363..63e9348 100644 >>> --- a/fs/btrfs/disk-io.c >>> +++ b/fs/btrfs/disk-io.c >>> @@ -2010,6 +2010,7 @@ static void btrfs_stop_all_workers(struct >>> btrfs_fs_info *fs_info) >>> btrfs_stop_workers(&fs_info->caching_workers); >>> btrfs_stop_workers(&fs_info->readahead_workers); >>> btrfs_stop_workers(&fs_info->flush_workers); >>> + btrfs_stop_workers(&fs_info->qgroup_rescan_workers); >>> } >>> >>> /* helper to cleanup tree roots */ >>> @@ -2301,6 +2302,7 @@ int open_ctree(struct super_block *sb, >>> fs_info->qgroup_seq = 1; >>> fs_info->quota_enabled = 0; >>> fs_info->pending_quota_state = 0; >>> + mutex_init(&fs_info->qgroup_rescan_lock); >>> >>> btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); >>> btrfs_init_free_cluster(&fs_info->data_alloc_cluster); >>> @@ -2529,6 +2531,8 @@ int open_ctree(struct super_block *sb, >>> btrfs_init_workers(&fs_info->readahead_workers, "readahead", >>>fs_info->thread_pool_size, >>>&fs_info->generic_worker); >>> + btrfs_init_workers(&fs_info->qgroup_rescan_workers, "qgroup-rescan", 1, >>> + &fs_info->generic_worker); >>> >>> /* >>> * endios are largely parallel and should have a very >>> @@ -2563,6 +2567,7 @@ int open_ctree(struct super_block *sb, >>> ret |= btrfs_start_workers(&fs_info->caching_workers); >>> ret |= btrfs_start_workers(&fs_info->readahead_workers); >>> ret |=
Re: [PATCH v4 2/3] Btrfs: rescan for qgroups
Hi Wang, On 01.05.2013 09:29, Wang Shilong wrote: > Hello Jan, > >> If qgroup tracking is out of sync, a rescan operation can be started. It >> iterates the complete extent tree and recalculates all qgroup tracking data. >> This is an expensive operation and should not be used unless required. >> >> A filesystem under rescan can still be umounted. The rescan continues on the >> next mount. Status information is provided with a separate ioctl while a >> rescan operation is in progress. >> >> Signed-off-by: Jan Schmidt >> --- >> fs/btrfs/ctree.h | 17 ++- >> fs/btrfs/disk-io.c |5 + >> fs/btrfs/ioctl.c | 83 ++-- >> fs/btrfs/qgroup.c | 318 >> ++-- >> include/uapi/linux/btrfs.h | 12 ++- >> 5 files changed, 400 insertions(+), 35 deletions(-) >> >> diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h >> index 412c306..e4f28a6 100644 >> --- a/fs/btrfs/ctree.h >> +++ b/fs/btrfs/ctree.h >> @@ -1021,9 +1021,9 @@ struct btrfs_block_group_item { >> */ >> #define BTRFS_QGROUP_STATUS_FLAG_ON (1ULL << 0) >> /* >> - * SCANNING is set during the initialization phase >> + * RESCAN is set during the initialization phase >> */ >> -#define BTRFS_QGROUP_STATUS_FLAG_SCANNING (1ULL << 1) >> +#define BTRFS_QGROUP_STATUS_FLAG_RESCAN (1ULL << 1) >> /* >> * Some qgroup entries are known to be out of date, >> * either because the configuration has changed in a way that >> @@ -1052,7 +1052,7 @@ struct btrfs_qgroup_status_item { >> * only used during scanning to record the progress >> * of the scan. It contains a logical address >> */ >> -__le64 scan; >> +__le64 rescan; >> } __attribute__ ((__packed__)); >> >> struct btrfs_qgroup_info_item { >> @@ -1603,6 +1603,11 @@ struct btrfs_fs_info { >> /* used by btrfs_qgroup_record_ref for an efficient tree traversal */ >> u64 qgroup_seq; >> >> +/* qgroup rescan items */ >> +struct mutex qgroup_rescan_lock; /* protects the progress item */ >> +struct btrfs_key qgroup_rescan_progress; >> +struct btrfs_workers qgroup_rescan_workers; >> + >> /* filesystem state */ >> unsigned long fs_state; >> >> @@ -2888,8 +2893,8 @@ BTRFS_SETGET_FUNCS(qgroup_status_version, struct >> btrfs_qgroup_status_item, >> version, 64); >> BTRFS_SETGET_FUNCS(qgroup_status_flags, struct btrfs_qgroup_status_item, >> flags, 64); >> -BTRFS_SETGET_FUNCS(qgroup_status_scan, struct btrfs_qgroup_status_item, >> - scan, 64); >> +BTRFS_SETGET_FUNCS(qgroup_status_rescan, struct btrfs_qgroup_status_item, >> + rescan, 64); >> >> /* btrfs_qgroup_info_item */ >> BTRFS_SETGET_FUNCS(qgroup_info_generation, struct btrfs_qgroup_info_item, >> @@ -3834,7 +3839,7 @@ int btrfs_quota_enable(struct btrfs_trans_handle >> *trans, >> struct btrfs_fs_info *fs_info); >> int btrfs_quota_disable(struct btrfs_trans_handle *trans, >> struct btrfs_fs_info *fs_info); >> -int btrfs_quota_rescan(struct btrfs_fs_info *fs_info); >> +int btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info); >> int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, >>struct btrfs_fs_info *fs_info, u64 src, u64 dst); >> int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, >> diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c >> index 7717363..63e9348 100644 >> --- a/fs/btrfs/disk-io.c >> +++ b/fs/btrfs/disk-io.c >> @@ -2010,6 +2010,7 @@ static void btrfs_stop_all_workers(struct >> btrfs_fs_info *fs_info) >> btrfs_stop_workers(&fs_info->caching_workers); >> btrfs_stop_workers(&fs_info->readahead_workers); >> btrfs_stop_workers(&fs_info->flush_workers); >> +btrfs_stop_workers(&fs_info->qgroup_rescan_workers); >> } >> >> /* helper to cleanup tree roots */ >> @@ -2301,6 +2302,7 @@ int open_ctree(struct super_block *sb, >> fs_info->qgroup_seq = 1; >> fs_info->quota_enabled = 0; >> fs_info->pending_quota_state = 0; >> +mutex_init(&fs_info->qgroup_rescan_lock); >> >> btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); >> btrfs_init_free_cluster(&fs_info->data_alloc_cluster); >> @@ -2529,6 +2531,8 @@ int open_ctree(struct super_block *sb, >> btrfs_init_workers(&fs_info->readahead_workers, "readahead", >> fs_info->thread_pool_size, >> &fs_info->generic_worker); >> +btrfs_init_workers(&fs_info->qgroup_rescan_workers, "qgroup-rescan", 1, >> + &fs_info->generic_worker); >> >> /* >> * endios are largely parallel and should have a very >> @@ -2563,6 +2567,7 @@ int open_ctree(struct super_block *sb, >> ret |= btrfs_start_workers(&fs_info->caching_workers); >> ret |= btrfs_start_workers(&fs_info->readahead_workers); >> ret |= btrfs_start_workers(&fs_info->flush_workers); >> +ret |= btrfs_start_workers(&fs_info->
Re: [PATCH v4 2/3] Btrfs: rescan for qgroups
Hello Jan, > If qgroup tracking is out of sync, a rescan operation can be started. It > iterates the complete extent tree and recalculates all qgroup tracking data. > This is an expensive operation and should not be used unless required. > > A filesystem under rescan can still be umounted. The rescan continues on the > next mount. Status information is provided with a separate ioctl while a > rescan operation is in progress. > > Signed-off-by: Jan Schmidt > --- > fs/btrfs/ctree.h | 17 ++- > fs/btrfs/disk-io.c |5 + > fs/btrfs/ioctl.c | 83 ++-- > fs/btrfs/qgroup.c | 318 ++-- > include/uapi/linux/btrfs.h | 12 ++- > 5 files changed, 400 insertions(+), 35 deletions(-) > > diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h > index 412c306..e4f28a6 100644 > --- a/fs/btrfs/ctree.h > +++ b/fs/btrfs/ctree.h > @@ -1021,9 +1021,9 @@ struct btrfs_block_group_item { > */ > #define BTRFS_QGROUP_STATUS_FLAG_ON (1ULL << 0) > /* > - * SCANNING is set during the initialization phase > + * RESCAN is set during the initialization phase > */ > -#define BTRFS_QGROUP_STATUS_FLAG_SCANNING(1ULL << 1) > +#define BTRFS_QGROUP_STATUS_FLAG_RESCAN (1ULL << 1) > /* > * Some qgroup entries are known to be out of date, > * either because the configuration has changed in a way that > @@ -1052,7 +1052,7 @@ struct btrfs_qgroup_status_item { >* only used during scanning to record the progress >* of the scan. It contains a logical address >*/ > - __le64 scan; > + __le64 rescan; > } __attribute__ ((__packed__)); > > struct btrfs_qgroup_info_item { > @@ -1603,6 +1603,11 @@ struct btrfs_fs_info { > /* used by btrfs_qgroup_record_ref for an efficient tree traversal */ > u64 qgroup_seq; > > + /* qgroup rescan items */ > + struct mutex qgroup_rescan_lock; /* protects the progress item */ > + struct btrfs_key qgroup_rescan_progress; > + struct btrfs_workers qgroup_rescan_workers; > + > /* filesystem state */ > unsigned long fs_state; > > @@ -2888,8 +2893,8 @@ BTRFS_SETGET_FUNCS(qgroup_status_version, struct > btrfs_qgroup_status_item, > version, 64); > BTRFS_SETGET_FUNCS(qgroup_status_flags, struct btrfs_qgroup_status_item, > flags, 64); > -BTRFS_SETGET_FUNCS(qgroup_status_scan, struct btrfs_qgroup_status_item, > -scan, 64); > +BTRFS_SETGET_FUNCS(qgroup_status_rescan, struct btrfs_qgroup_status_item, > +rescan, 64); > > /* btrfs_qgroup_info_item */ > BTRFS_SETGET_FUNCS(qgroup_info_generation, struct btrfs_qgroup_info_item, > @@ -3834,7 +3839,7 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans, > struct btrfs_fs_info *fs_info); > int btrfs_quota_disable(struct btrfs_trans_handle *trans, > struct btrfs_fs_info *fs_info); > -int btrfs_quota_rescan(struct btrfs_fs_info *fs_info); > +int btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info); > int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, > struct btrfs_fs_info *fs_info, u64 src, u64 dst); > int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, > diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c > index 7717363..63e9348 100644 > --- a/fs/btrfs/disk-io.c > +++ b/fs/btrfs/disk-io.c > @@ -2010,6 +2010,7 @@ static void btrfs_stop_all_workers(struct btrfs_fs_info > *fs_info) > btrfs_stop_workers(&fs_info->caching_workers); > btrfs_stop_workers(&fs_info->readahead_workers); > btrfs_stop_workers(&fs_info->flush_workers); > + btrfs_stop_workers(&fs_info->qgroup_rescan_workers); > } > > /* helper to cleanup tree roots */ > @@ -2301,6 +2302,7 @@ int open_ctree(struct super_block *sb, > fs_info->qgroup_seq = 1; > fs_info->quota_enabled = 0; > fs_info->pending_quota_state = 0; > + mutex_init(&fs_info->qgroup_rescan_lock); > > btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); > btrfs_init_free_cluster(&fs_info->data_alloc_cluster); > @@ -2529,6 +2531,8 @@ int open_ctree(struct super_block *sb, > btrfs_init_workers(&fs_info->readahead_workers, "readahead", > fs_info->thread_pool_size, > &fs_info->generic_worker); > + btrfs_init_workers(&fs_info->qgroup_rescan_workers, "qgroup-rescan", 1, > +&fs_info->generic_worker); > > /* >* endios are largely parallel and should have a very > @@ -2563,6 +2567,7 @@ int open_ctree(struct super_block *sb, > ret |= btrfs_start_workers(&fs_info->caching_workers); > ret |= btrfs_start_workers(&fs_info->readahead_workers); > ret |= btrfs_start_workers(&fs_info->flush_workers); > + ret |= btrfs_start_workers(&fs_info->qgroup_rescan_workers); > if (ret) { > err = -ENOMEM; > goto fail_sb_buffer; > diff -
Re: [PATCH v4 2/3] Btrfs: rescan for qgroups
> If qgroup tracking is out of sync, a rescan operation can be started. It > iterates the complete extent tree and recalculates all qgroup tracking data. > This is an expensive operation and should not be used unless required. > > A filesystem under rescan can still be umounted. The rescan continues on the > next mount. Status information is provided with a separate ioctl while a > rescan operation is in progress. > > Signed-off-by: Jan Schmidt Now it looks good to me. Reviewed-by: Wang Shilong Thanks, Wang > --- > fs/btrfs/ctree.h | 17 ++- > fs/btrfs/disk-io.c |5 + > fs/btrfs/ioctl.c | 83 ++-- > fs/btrfs/qgroup.c | 318 > ++-- > include/uapi/linux/btrfs.h | 12 ++- > 5 files changed, 400 insertions(+), 35 deletions(-) > > diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h > index 412c306..e4f28a6 100644 > --- a/fs/btrfs/ctree.h > +++ b/fs/btrfs/ctree.h > @@ -1021,9 +1021,9 @@ struct btrfs_block_group_item { > */ > #define BTRFS_QGROUP_STATUS_FLAG_ON (1ULL << 0) > /* > - * SCANNING is set during the initialization phase > + * RESCAN is set during the initialization phase > */ > -#define BTRFS_QGROUP_STATUS_FLAG_SCANNING(1ULL << 1) > +#define BTRFS_QGROUP_STATUS_FLAG_RESCAN (1ULL << 1) > /* > * Some qgroup entries are known to be out of date, > * either because the configuration has changed in a way that > @@ -1052,7 +1052,7 @@ struct btrfs_qgroup_status_item { >* only used during scanning to record the progress >* of the scan. It contains a logical address >*/ > - __le64 scan; > + __le64 rescan; > } __attribute__ ((__packed__)); > > struct btrfs_qgroup_info_item { > @@ -1603,6 +1603,11 @@ struct btrfs_fs_info { > /* used by btrfs_qgroup_record_ref for an efficient tree traversal */ > u64 qgroup_seq; > > + /* qgroup rescan items */ > + struct mutex qgroup_rescan_lock; /* protects the progress item */ > + struct btrfs_key qgroup_rescan_progress; > + struct btrfs_workers qgroup_rescan_workers; > + > /* filesystem state */ > unsigned long fs_state; > > @@ -2888,8 +2893,8 @@ BTRFS_SETGET_FUNCS(qgroup_status_version, struct > btrfs_qgroup_status_item, > version, 64); > BTRFS_SETGET_FUNCS(qgroup_status_flags, struct btrfs_qgroup_status_item, > flags, 64); > -BTRFS_SETGET_FUNCS(qgroup_status_scan, struct btrfs_qgroup_status_item, > -scan, 64); > +BTRFS_SETGET_FUNCS(qgroup_status_rescan, struct btrfs_qgroup_status_item, > +rescan, 64); > > /* btrfs_qgroup_info_item */ > BTRFS_SETGET_FUNCS(qgroup_info_generation, struct btrfs_qgroup_info_item, > @@ -3834,7 +3839,7 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans, > struct btrfs_fs_info *fs_info); > int btrfs_quota_disable(struct btrfs_trans_handle *trans, > struct btrfs_fs_info *fs_info); > -int btrfs_quota_rescan(struct btrfs_fs_info *fs_info); > +int btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info); > int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, > struct btrfs_fs_info *fs_info, u64 src, u64 dst); > int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, > diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c > index 7717363..63e9348 100644 > --- a/fs/btrfs/disk-io.c > +++ b/fs/btrfs/disk-io.c > @@ -2010,6 +2010,7 @@ static void btrfs_stop_all_workers(struct btrfs_fs_info > *fs_info) > btrfs_stop_workers(&fs_info->caching_workers); > btrfs_stop_workers(&fs_info->readahead_workers); > btrfs_stop_workers(&fs_info->flush_workers); > + btrfs_stop_workers(&fs_info->qgroup_rescan_workers); > } > > /* helper to cleanup tree roots */ > @@ -2301,6 +2302,7 @@ int open_ctree(struct super_block *sb, > fs_info->qgroup_seq = 1; > fs_info->quota_enabled = 0; > fs_info->pending_quota_state = 0; > + mutex_init(&fs_info->qgroup_rescan_lock); > > btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); > btrfs_init_free_cluster(&fs_info->data_alloc_cluster); > @@ -2529,6 +2531,8 @@ int open_ctree(struct super_block *sb, > btrfs_init_workers(&fs_info->readahead_workers, "readahead", > fs_info->thread_pool_size, > &fs_info->generic_worker); > + btrfs_init_workers(&fs_info->qgroup_rescan_workers, "qgroup-rescan", 1, > +&fs_info->generic_worker); > > /* >* endios are largely parallel and should have a very > @@ -2563,6 +2567,7 @@ int open_ctree(struct super_block *sb, > ret |= btrfs_start_workers(&fs_info->caching_workers); > ret |= btrfs_start_workers(&fs_info->readahead_workers); > ret |= btrfs_start_workers(&fs_info->flush_workers); > + ret |= btrfs_start_workers(&fs_info->qgroup_rescan_workers); >
[PATCH v4 2/3] Btrfs: rescan for qgroups
If qgroup tracking is out of sync, a rescan operation can be started. It iterates the complete extent tree and recalculates all qgroup tracking data. This is an expensive operation and should not be used unless required. A filesystem under rescan can still be umounted. The rescan continues on the next mount. Status information is provided with a separate ioctl while a rescan operation is in progress. Signed-off-by: Jan Schmidt --- fs/btrfs/ctree.h | 17 ++- fs/btrfs/disk-io.c |5 + fs/btrfs/ioctl.c | 83 ++-- fs/btrfs/qgroup.c | 318 ++-- include/uapi/linux/btrfs.h | 12 ++- 5 files changed, 400 insertions(+), 35 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 412c306..e4f28a6 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -1021,9 +1021,9 @@ struct btrfs_block_group_item { */ #define BTRFS_QGROUP_STATUS_FLAG_ON(1ULL << 0) /* - * SCANNING is set during the initialization phase + * RESCAN is set during the initialization phase */ -#define BTRFS_QGROUP_STATUS_FLAG_SCANNING (1ULL << 1) +#define BTRFS_QGROUP_STATUS_FLAG_RESCAN(1ULL << 1) /* * Some qgroup entries are known to be out of date, * either because the configuration has changed in a way that @@ -1052,7 +1052,7 @@ struct btrfs_qgroup_status_item { * only used during scanning to record the progress * of the scan. It contains a logical address */ - __le64 scan; + __le64 rescan; } __attribute__ ((__packed__)); struct btrfs_qgroup_info_item { @@ -1603,6 +1603,11 @@ struct btrfs_fs_info { /* used by btrfs_qgroup_record_ref for an efficient tree traversal */ u64 qgroup_seq; + /* qgroup rescan items */ + struct mutex qgroup_rescan_lock; /* protects the progress item */ + struct btrfs_key qgroup_rescan_progress; + struct btrfs_workers qgroup_rescan_workers; + /* filesystem state */ unsigned long fs_state; @@ -2888,8 +2893,8 @@ BTRFS_SETGET_FUNCS(qgroup_status_version, struct btrfs_qgroup_status_item, version, 64); BTRFS_SETGET_FUNCS(qgroup_status_flags, struct btrfs_qgroup_status_item, flags, 64); -BTRFS_SETGET_FUNCS(qgroup_status_scan, struct btrfs_qgroup_status_item, - scan, 64); +BTRFS_SETGET_FUNCS(qgroup_status_rescan, struct btrfs_qgroup_status_item, + rescan, 64); /* btrfs_qgroup_info_item */ BTRFS_SETGET_FUNCS(qgroup_info_generation, struct btrfs_qgroup_info_item, @@ -3834,7 +3839,7 @@ int btrfs_quota_enable(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); int btrfs_quota_disable(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); -int btrfs_quota_rescan(struct btrfs_fs_info *fs_info); +int btrfs_qgroup_rescan(struct btrfs_fs_info *fs_info); int btrfs_add_qgroup_relation(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, u64 src, u64 dst); int btrfs_del_qgroup_relation(struct btrfs_trans_handle *trans, diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 7717363..63e9348 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -2010,6 +2010,7 @@ static void btrfs_stop_all_workers(struct btrfs_fs_info *fs_info) btrfs_stop_workers(&fs_info->caching_workers); btrfs_stop_workers(&fs_info->readahead_workers); btrfs_stop_workers(&fs_info->flush_workers); + btrfs_stop_workers(&fs_info->qgroup_rescan_workers); } /* helper to cleanup tree roots */ @@ -2301,6 +2302,7 @@ int open_ctree(struct super_block *sb, fs_info->qgroup_seq = 1; fs_info->quota_enabled = 0; fs_info->pending_quota_state = 0; + mutex_init(&fs_info->qgroup_rescan_lock); btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); btrfs_init_free_cluster(&fs_info->data_alloc_cluster); @@ -2529,6 +2531,8 @@ int open_ctree(struct super_block *sb, btrfs_init_workers(&fs_info->readahead_workers, "readahead", fs_info->thread_pool_size, &fs_info->generic_worker); + btrfs_init_workers(&fs_info->qgroup_rescan_workers, "qgroup-rescan", 1, + &fs_info->generic_worker); /* * endios are largely parallel and should have a very @@ -2563,6 +2567,7 @@ int open_ctree(struct super_block *sb, ret |= btrfs_start_workers(&fs_info->caching_workers); ret |= btrfs_start_workers(&fs_info->readahead_workers); ret |= btrfs_start_workers(&fs_info->flush_workers); + ret |= btrfs_start_workers(&fs_info->qgroup_rescan_workers); if (ret) { err = -ENOMEM; goto fail_sb_buffer; diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index d0af96a..5e93bb8 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.