3048 {
3052 uint64_t num_chunks[3], okay_metadata_chunks = 0, okay_data_chunks = 0, okay_system_chunks = 0;
3053 uint64_t old_data_flags = 0, old_metadata_flags = 0, old_system_flags = 0;
3055
3056 Vcb->balance.balance_num++;
3057
3058 Vcb->balance.stopping =
false;
3060
3062 old_data_flags =
Vcb->data_flags;
3064
3066 }
3067
3069 old_metadata_flags =
Vcb->metadata_flags;
3071 }
3072
3074 old_system_flags =
Vcb->system_flags;
3076 }
3077
3083 }
3084
3085 num_chunks[0] = num_chunks[1] = num_chunks[2] = 0;
3086 Vcb->balance.total_chunks =
Vcb->balance.chunks_left = 0;
3087
3089
3090
3091
3092 if (!
Vcb->readonly) {
3093 if (!
Vcb->balance.removing && !
Vcb->balance.shrinking) {
3096 ERR(
"add_balance_item returned %08lx\n",
Status);
3099 }
3100 } else {
3101 if (
Vcb->need_write) {
3103
3105
3107 ERR(
"do_write returned %08lx\n",
Status);
3110 }
3111 }
3112 }
3113 }
3114
3116
3117 if (
Vcb->balance.stopping)
3119
3121
3122 le =
Vcb->chunks.Flink;
3123 while (le != &
Vcb->chunks) {
3126
3128
3135 else {
3136 ERR(
"unexpected chunk type %I64x\n",
c->chunk_item->type);
3138 break;
3139 }
3140
3144
3146 Vcb->balance.total_chunks++;
3147 Vcb->balance.chunks_left++;
3149 okay_metadata_chunks++;
3151 okay_data_chunks++;
3153 okay_system_chunks++;
3154
3155 if (!
c->cache_loaded) {
3157
3159 ERR(
"load_cache_chunk returned %08lx\n",
Status);
3164 }
3165 }
3166
3168
3170 }
3171
3173
3174
3175 if (okay_metadata_chunks == 0 || okay_data_chunks == 0 || okay_system_chunks == 0) {
3176 bool consolidated = false;
3178
3179 if (okay_metadata_chunks == 0) {
3181
3184 c->balance_num =
Vcb->balance.balance_num;
3186 ERR(
"alloc_chunk returned %08lx\n",
Status);
3190 }
3191
3193
3197 ERR(
"try_consolidation returned %08lx\n",
Status);
3200 } else
3201 c->balance_num =
Vcb->balance.balance_num;
3202
3203 consolidated = true;
3204
3205 if (
Vcb->balance.stopping)
3207 }
3208 }
3209
3210 if (okay_data_chunks == 0) {
3212
3215 c->balance_num =
Vcb->balance.balance_num;
3217 ERR(
"alloc_chunk returned %08lx\n",
Status);
3221 }
3222
3224
3228 ERR(
"try_consolidation returned %08lx\n",
Status);
3231 } else
3232 c->balance_num =
Vcb->balance.balance_num;
3233
3234 consolidated = true;
3235
3236 if (
Vcb->balance.stopping)
3238 }
3239 }
3240
3241 if (okay_system_chunks == 0) {
3243
3246 c->balance_num =
Vcb->balance.balance_num;
3248 ERR(
"alloc_chunk returned %08lx\n",
Status);
3252 }
3253
3255
3259 ERR(
"try_consolidation returned %08lx\n",
Status);
3262 } else
3263 c->balance_num =
Vcb->balance.balance_num;
3264
3265 consolidated = true;
3266
3267 if (
Vcb->balance.stopping)
3269 }
3270 }
3271 }
3272
3274
3276 while (le != &chunks) {
3278
3280
3282 }
3283
3285
3286
3288 while (le != &chunks) {
3291
3293 bool changed;
3294
3295 do {
3296 changed = false;
3297
3300 ERR(
"balance_data_chunk returned %08lx\n",
Status);
3303 }
3304
3306
3308 Vcb->balance.stopping =
true;
3309
3310 if (
Vcb->balance.stopping)
3311 break;
3312 } while (changed);
3313
3315 c->space_changed =
true;
3316 }
3317
3318 if (
Vcb->balance.stopping)
3320
3324 c->list_entry_balance.Flink =
NULL;
3325
3326 Vcb->balance.chunks_left--;
3327 }
3328
3329 le = le2;
3330 }
3331
3332
3335 bool changed;
3336
3339
3341 do {
3344 ERR(
"balance_metadata_chunk returned %08lx\n",
Status);
3347 }
3348
3350
3352 Vcb->balance.stopping =
true;
3353
3354 if (
Vcb->balance.stopping)
3355 break;
3356 } while (changed);
3357
3359 c->space_changed =
true;
3360 }
3361
3362 if (
Vcb->balance.stopping)
3363 break;
3364
3365 c->list_entry_balance.Flink =
NULL;
3366
3367 Vcb->balance.chunks_left--;
3368 }
3369
3371 if (!
Vcb->readonly) {
3374 while (le != &chunks) {
3377
3379 c->list_entry_balance.Flink =
NULL;
3380 }
3381
3382 if (old_data_flags != 0)
3383 Vcb->data_flags = old_data_flags;
3384
3385 if (old_metadata_flags != 0)
3386 Vcb->metadata_flags = old_metadata_flags;
3387
3388 if (old_system_flags != 0)
3389 Vcb->system_flags = old_system_flags;
3390 }
3391
3392 if (
Vcb->balance.removing) {
3394
3396
3397 le =
Vcb->devices.Flink;
3398 while (le != &
Vcb->devices) {
3400
3403 break;
3404 }
3405
3407 }
3408
3410 if (
Vcb->balance.chunks_left == 0) {
3412
3414 ERR(
"finish_removing_device returned %08lx\n",
Status);
3416 }
3417 } else
3419 }
3420
3422 }
else if (
Vcb->balance.shrinking) {
3424
3426
3427 le =
Vcb->devices.Flink;
3428 while (le != &
Vcb->devices) {
3430
3433 break;
3434 }
3435
3437 }
3438
3440 ERR(
"could not find device %I64x\n",
Vcb->balance.opts[0].devid);
3442 }
3443
3448 WARN(
"regenerate_space_list returned %08lx\n",
Status);
3449 }
3450 } else {
3452
3454 dev->devitem.num_bytes =
Vcb->balance.opts[0].drange_start;
3455
3458 ERR(
"update_dev_item returned %08lx\n",
Status);
3461
3464 WARN(
"regenerate_space_list returned %08lx\n",
Status);
3465 } else {
3466 Vcb->superblock.total_bytes -=
old_size -
dev->devitem.num_bytes;
3467
3470 ERR(
"do_write returned %08lx\n",
Status);
3471
3473 }
3474 }
3475
3477
3480 } else {
3483 ERR(
"remove_balance_item returned %08lx\n",
Status);
3485 }
3486 }
3487
3488 if (
Vcb->trim && !
Vcb->options.no_trim) {
3490
3491 le =
Vcb->devices.Flink;
3492 while (le != &
Vcb->devices) {
3494
3497
3499 }
3500
3502 }
3503 }
3504
3507
3509}
_STLP_MOVE_TO_STD_NAMESPACE void sort(_RandomAccessIter __first, _RandomAccessIter __last)
#define acquire_chunk_lock(c, Vcb)
NTSTATUS load_cache_chunk(device_extension *Vcb, chunk *c, PIRP Irp)
NTSTATUS alloc_chunk(device_extension *Vcb, uint64_t flags, chunk **pc, bool full_size) __attribute__((nonnull(1
NTSTATUS update_dev_item(device_extension *Vcb, device *device, PIRP Irp)
#define BALANCE_OPTS_METADATA
NTSTATUS do_write(device_extension *Vcb, PIRP Irp)
#define BALANCE_OPTS_DATA
NTSTATUS NTSTATUS bool bool void free_trees(device_extension *Vcb) __attribute__((nonnull(1)))
#define BALANCE_OPTS_SYSTEM
#define release_chunk_lock(c, Vcb)
#define BTRFS_BALANCE_OPTS_ENABLED
#define BTRFS_BALANCE_OPTS_CONVERT
#define BLOCK_FLAG_SINGLE
#define BTRFS_BALANCE_OPTS_LIMIT
#define NT_SUCCESS(StatCode)
static NTSTATUS remove_balance_item(device_extension *Vcb)
static NTSTATUS finish_removing_device(_Requires_exclusive_lock_held_(_Curr_->tree_lock) device_extension *Vcb, device *dev)
static void trim_unalloc_space(_Requires_lock_held_(_Curr_->tree_lock) device_extension *Vcb, device *dev)
static bool should_balance_chunk(device_extension *Vcb, uint8_t sort, chunk *c)
static NTSTATUS try_consolidation(device_extension *Vcb, uint64_t flags, chunk **newchunk)
static NTSTATUS balance_data_chunk(device_extension *Vcb, chunk *c, bool *changed)
static NTSTATUS balance_metadata_chunk(device_extension *Vcb, chunk *c, bool *changed)
static NTSTATUS add_balance_item(device_extension *Vcb)
static NTSTATUS regenerate_space_list(device_extension *Vcb, device *dev)
#define BTRFS_INCOMPAT_FLAGS_MIXED_GROUPS
#define RemoveEntryList(Entry)
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
#define KeInitializeEvent(pEvt, foo, foo2)
#define KeSetEvent(pEvt, foo, foo2)
#define ExAcquireResourceExclusiveLite(res, wait)
#define RemoveHeadList(ListHead)
#define InitializeListHead(ListHead)
#define ExAcquireResourceSharedLite(res, wait)
#define FSRTL_VOLUME_CHANGE_SIZE
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
NTSTATUS NTAPI FsRtlNotifyVolumeEvent(IN PFILE_OBJECT FileObject, IN ULONG EventCode)
#define STATUS_INTERNAL_ERROR
#define BLOCK_FLAG_SYSTEM
#define BLOCK_FLAG_METADATA
struct _LIST_ENTRY * Flink
#define RtlCopyMemory(Destination, Source, Length)
#define CONTAINING_RECORD(address, type, field)