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;
3056 Vcb->balance.balance_num++;
3058 Vcb->balance.stopping =
false;
3062 old_data_flags =
Vcb->data_flags;
3069 old_metadata_flags =
Vcb->metadata_flags;
3074 old_system_flags =
Vcb->system_flags;
3085 num_chunks[0] = num_chunks[1] = num_chunks[2] = 0;
3086 Vcb->balance.total_chunks =
Vcb->balance.chunks_left = 0;
3092 if (!
Vcb->readonly) {
3093 if (!
Vcb->balance.removing && !
Vcb->balance.shrinking) {
3096 ERR(
"add_balance_item returned %08lx\n",
Status);
3101 if (
Vcb->need_write) {
3107 ERR(
"do_write returned %08lx\n",
Status);
3117 if (
Vcb->balance.stopping)
3122 le =
Vcb->chunks.Flink;
3123 while (le != &
Vcb->chunks) {
3136 ERR(
"unexpected chunk type %I64x\n",
c->chunk_item->type);
3146 Vcb->balance.total_chunks++;
3147 Vcb->balance.chunks_left++;
3149 okay_metadata_chunks++;
3153 okay_system_chunks++;
3155 if (!
c->cache_loaded) {
3159 ERR(
"load_cache_chunk returned %08lx\n",
Status);
3175 if (okay_metadata_chunks == 0 || okay_data_chunks == 0 || okay_system_chunks == 0) {
3176 bool consolidated =
false;
3179 if (okay_metadata_chunks == 0) {
3184 c->balance_num =
Vcb->balance.balance_num;
3186 ERR(
"alloc_chunk returned %08lx\n",
Status);
3197 ERR(
"try_consolidation returned %08lx\n",
Status);
3201 c->balance_num =
Vcb->balance.balance_num;
3203 consolidated =
true;
3205 if (
Vcb->balance.stopping)
3210 if (okay_data_chunks == 0) {
3215 c->balance_num =
Vcb->balance.balance_num;
3217 ERR(
"alloc_chunk returned %08lx\n",
Status);
3228 ERR(
"try_consolidation returned %08lx\n",
Status);
3232 c->balance_num =
Vcb->balance.balance_num;
3234 consolidated =
true;
3236 if (
Vcb->balance.stopping)
3241 if (okay_system_chunks == 0) {
3246 c->balance_num =
Vcb->balance.balance_num;
3248 ERR(
"alloc_chunk returned %08lx\n",
Status);
3259 ERR(
"try_consolidation returned %08lx\n",
Status);
3263 c->balance_num =
Vcb->balance.balance_num;
3265 consolidated =
true;
3267 if (
Vcb->balance.stopping)
3276 while (le != &chunks) {
3288 while (le != &chunks) {
3300 ERR(
"balance_data_chunk returned %08lx\n",
Status);
3308 Vcb->balance.stopping =
true;
3310 if (
Vcb->balance.stopping)
3315 c->space_changed =
true;
3318 if (
Vcb->balance.stopping)
3324 c->list_entry_balance.Flink =
NULL;
3326 Vcb->balance.chunks_left--;
3344 ERR(
"balance_metadata_chunk returned %08lx\n",
Status);
3352 Vcb->balance.stopping =
true;
3354 if (
Vcb->balance.stopping)
3359 c->space_changed =
true;
3362 if (
Vcb->balance.stopping)
3365 c->list_entry_balance.Flink =
NULL;
3367 Vcb->balance.chunks_left--;
3371 if (!
Vcb->readonly) {
3374 while (le != &chunks) {
3379 c->list_entry_balance.Flink =
NULL;
3382 if (old_data_flags != 0)
3383 Vcb->data_flags = old_data_flags;
3385 if (old_metadata_flags != 0)
3386 Vcb->metadata_flags = old_metadata_flags;
3388 if (old_system_flags != 0)
3389 Vcb->system_flags = old_system_flags;
3392 if (
Vcb->balance.removing) {
3397 le =
Vcb->devices.Flink;
3398 while (le != &
Vcb->devices) {
3410 if (
Vcb->balance.chunks_left == 0) {
3414 ERR(
"finish_removing_device returned %08lx\n",
Status);
3422 }
else if (
Vcb->balance.shrinking) {
3427 le =
Vcb->devices.Flink;
3428 while (le != &
Vcb->devices) {
3440 ERR(
"could not find device %I64x\n",
Vcb->balance.opts[0].devid);
3448 WARN(
"regenerate_space_list returned %08lx\n",
Status);
3453 old_size =
dev->devitem.num_bytes;
3454 dev->devitem.num_bytes =
Vcb->balance.opts[0].drange_start;
3458 ERR(
"update_dev_item returned %08lx\n",
Status);
3459 dev->devitem.num_bytes = old_size;
3464 WARN(
"regenerate_space_list returned %08lx\n",
Status);
3466 Vcb->superblock.total_bytes -= old_size -
dev->devitem.num_bytes;
3470 ERR(
"do_write returned %08lx\n",
Status);
3483 ERR(
"remove_balance_item returned %08lx\n",
Status);
3488 if (
Vcb->trim && !
Vcb->options.no_trim) {
3491 le =
Vcb->devices.Flink;
3492 while (le != &
Vcb->devices) {
static bool should_balance_chunk(device_extension *Vcb, uint8_t sort, chunk *c)
#define BALANCE_OPTS_SYSTEM
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
_STLP_MOVE_TO_STD_NAMESPACE void sort(_RandomAccessIter __first, _RandomAccessIter __last)
NTSTATUS do_write(device_extension *Vcb, PIRP Irp)
#define InsertTailList(ListHead, Entry)
static NTSTATUS balance_metadata_chunk(device_extension *Vcb, chunk *c, bool *changed)
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
#define BLOCK_FLAG_SINGLE
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
#define STATUS_INTERNAL_ERROR
static NTSTATUS try_consolidation(device_extension *Vcb, uint64_t flags, chunk **newchunk)
#define BTRFS_BALANCE_OPTS_CONVERT
#define BTRFS_INCOMPAT_FLAGS_MIXED_GROUPS
#define BLOCK_FLAG_SYSTEM
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
#define release_chunk_lock(c, Vcb)
NTSTATUS alloc_chunk(device_extension *Vcb, uint64_t flags, chunk **pc, bool full_size) __attribute__((nonnull(1
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
#define FSRTL_VOLUME_CHANGE_SIZE
static NTSTATUS add_balance_item(device_extension *Vcb)
struct _LIST_ENTRY * Flink
static NTSTATUS regenerate_space_list(device_extension *Vcb, device *dev)
NTSTATUS NTAPI FsRtlNotifyVolumeEvent(IN PFILE_OBJECT FileObject, IN ULONG EventCode)
#define NT_SUCCESS(StatCode)
#define BTRFS_BALANCE_OPTS_LIMIT
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
NTSTATUS update_dev_item(device_extension *Vcb, device *device, PIRP Irp)
#define BTRFS_BALANCE_OPTS_ENABLED
#define BLOCK_FLAG_METADATA
NTSTATUS NTSTATUS bool bool void free_trees(device_extension *Vcb) __attribute__((nonnull(1)))
NTSTATUS load_cache_chunk(device_extension *Vcb, chunk *c, PIRP Irp)
static NTSTATUS remove_balance_item(device_extension *Vcb)
static NTSTATUS balance_data_chunk(device_extension *Vcb, chunk *c, bool *changed)
#define KeInitializeEvent(pEvt, foo, foo2)
#define acquire_chunk_lock(c, Vcb)
#define InitializeListHead(ListHead)
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
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)
#define RtlCopyMemory(Destination, Source, Length)
#define BALANCE_OPTS_METADATA
#define BALANCE_OPTS_DATA