// File: /workspace/github_c_makefile_star2_O1/j-hoppe[P]tu58fs/rt11.c
// Function: rt11_filesystem_calc_block_use
static int rt11_filesystem_calc_block_use(rt11_filesystem_t *_this, int test_data_size) {
	int i;
	int dir_max_seg_nr;
	int used_file_blocks;
	int available_blocks;

	if (_this->dir_entry_extra_bytes > 16)
		fatal("Extra bytes in directory %d is > 16 ... how much is allowed?", _this->dir_entry_extra_bytes);

	// 1) calc segments & blocks needed for existing files
	used_file_blocks = 0;
	for (i = 0; i < _this->file_count; i++) {
		// round file sizes up to blocks
		// prefix size and data size already sum'd up to file->block_count
		used_file_blocks += _this->file[i]->block_count;
	}
	if (test_data_size)
		used_file_blocks += NEEDED_BLOCKS(RT11_BLOCKSIZE, test_data_size);

	// total blocks available for dir and data
	// On disk supporting STd144 bad secotr info,
	// "available blocks" should not be calculated from total disk size,
	// but from usable blockcount of "rt11_radi".
	// Difficulties in case of enlarged images!
	available_blocks = _this->blockcount - _this->first_dir_blocknr; // boot, home, 2..5 used
	if (test_data_size)
		dir_max_seg_nr = rt11_dir_needed_segments(_this, _this->file_count + 1);
	else
		dir_max_seg_nr = rt11_dir_needed_segments(_this, _this->file_count);
	if (available_blocks < used_file_blocks + 2 * dir_max_seg_nr) {
		// files do not fit on volume
		if (!test_data_size)
			_this->free_blocks = 0; // can't be negative
		return error_set(ERROR_FILESYSTEM_OVERFLOW, "rt11_filesystem_calc_block_use");
	}
	if (test_data_size)
		return ERROR_OK;

	/* end of test mode */
	// now modify file system
	_this->dir_max_seg_nr = dir_max_seg_nr;
	_this->used_file_blocks = used_file_blocks;

	_this->free_blocks = available_blocks - _this->used_file_blocks - 2 * _this->dir_max_seg_nr;
	// now used_blocks,free_blocks, dir_total_seg_num valid.

	/* Plan use of remaining free_space
	 * how many files would be allocated in the remaining free space?
	 * derive from average file size, but allow 1.5 * as much
	 * Most critical test situations:
	 * All dir segments full, and only 2 block in file area left.
	 * assigned these blocks to 1 more file would need a new dir segment,
	 * which would need these 2 blocks too.
	 * If 3 blocks are left: 2 can be used for additional dir segmetn,
	 * and 1 for new file.
	 */
	if (_this->file_count == 0) {
		// if disk empty: start with only 1 segment
		_this->dir_max_seg_nr = 1;
		_this->dir_total_seg_num = 1;
	} else {
		// planning params have prefix "_"
		int avg_file_blocks; // average filesize in blocks
		int _new_file_count; // planned count of additional files
		int _used_file_blocks; // planned block requirement for all files (existing + planned)
		int _dir_total_seg_num; // planned dir segment requirement for all files (existing + planned)
		avg_file_blocks = _this->used_file_blocks / _this->file_count;
		if (avg_file_blocks < 1)
			avg_file_blocks = 1;
		// 1st estimate for possible new files.
		// Assume they have average size.
		// too big, since additional dir segments reduce free space
		_new_file_count = _this->free_blocks / avg_file_blocks + 1;
		// reduce amount of planned files, until files+dir fit on disk
		do {
			_new_file_count--;
			_used_file_blocks = _this->used_file_blocks + _new_file_count * avg_file_blocks;
			// plan for 50% more file count
			_dir_total_seg_num = rt11_dir_needed_segments(_this,
					_this->file_count + (_new_file_count * 3) / 2);
		} while (_new_file_count
				&& available_blocks < _used_file_blocks + 2 * _dir_total_seg_num);
		// solution found: save
		if (_dir_total_seg_num > 31)
			_dir_total_seg_num = 31;
		_this->dir_total_seg_num = _dir_total_seg_num;
	}
	// calculate free blocks again
	assert(available_blocks >= _this->used_file_blocks + 2 * _this->dir_total_seg_num);
	_this->free_blocks = available_blocks - _this->used_file_blocks
			- 2 * _this->dir_total_seg_num;

	return ERROR_OK;
}

// Assembly:
pushq %r14
pushq %rbx
pushq %rax
movl %esi, %r14d
movq %rdi, %rbx
movzwl 0x68(%rdi), %esi
cmpl $0x11, %esi
jb 0xfcc4
leaq 0x6f5d(%rip), %rdi      # 0x16c1a
xorl %eax, %eax
callq 0xa2ef
movslq 0x8c(%rbx), %r9
testq %r9, %r9
jle 0xfcee
xorl %eax, %eax
xorl %r8d, %r8d
movq 0x90(%rbx,%rax,8), %rcx
movzwl 0x7c(%rcx), %ecx
addl %ecx, %r8d
incq %rax
cmpq %rax, %r9
jne 0xfcd5
jmp 0xfcf1
xorl %r8d, %r8d
testl %r14d, %r14d
je 0xfd0f
leal 0x1ff(%r14), %eax
leal 0x3fe(%r14), %ecx
testl %eax, %eax
cmovnsl %eax, %ecx
sarl $0x9, %ecx
addl %ecx, %r8d
movl 0x6c(%rbx), %r10d
movzwl 0x34(%rbx), %eax
subl %eax, %r10d
testl %r14d, %r14d
je 0xfd38
movzwl 0x68(%rbx), %ecx
addl $0xe, %ecx
movl $0x3f6, %eax            # imm = 0x3F6
xorl %edx, %edx
divl %ecx
leal (%r9,%rax), %ecx
addl $-0x2, %ecx
jmp 0xfd4f
movzwl 0x68(%rbx), %ecx
addl $0xe, %ecx
movl $0x3f6, %eax            # imm = 0x3F6
xorl %edx, %edx
divl %ecx
leal (%rax,%r9), %ecx
addl $-0x3, %ecx
movl %eax, %esi
addl $-0x3, %esi
movl %ecx, %eax
cltd
idivl %esi
leal (%r8,%rax,2), %edx
movl %r10d, %ecx
subl %edx, %ecx
jge 0xfd8c
testl %r14d, %r14d
jne 0xfd72
movw $0x0, 0x1fd2(%rbx)
leaq 0x6ede(%rip), %rsi      # 0x16c57
movl $0xfffffffe, %edi       # imm = 0xFFFFFFFE
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
jmp 0x9f8f
testl %r14d, %r14d
jne 0xfe51
movw %ax, 0x66(%rbx)
movw %r8w, 0x1fd0(%rbx)
movw %cx, 0x1fd2(%rbx)
testl %r9d, %r9d
je 0xfe2c
movl $0xffff, %edi           # imm = 0xFFFF
movl %r8d, %esi
andl %edi, %esi
movl %esi, %eax
xorl %edx, %edx
idivl %r9d
cmpl $0x2, %eax
movl $0x1, %r11d
cmovgel %eax, %r11d
andl %edi, %ecx
movl %ecx, %eax
xorl %edx, %edx
divl %r11d
movl %eax, %edi
leal 0x1(%rdi), %r14d
movzwl 0x68(%rbx), %ecx
addl $0xe, %ecx
movl $0x3f6, %eax            # imm = 0x3F6
xorl %edx, %edx
divl %ecx
movl %eax, %ecx
addl $-0x3, %ecx
leal (%rdi,%rdi,2), %edi
imull %r11d, %r14d
addl %esi, %r14d
addl %ecx, %r9d
movl %edi, %eax
shrl $0x1f, %eax
addl %edi, %eax
sarl %eax
addl %r9d, %eax
cltd
idivl %ecx
addl $-0x3, %edi
cmpl $-0x3, %edi
je 0xfe1f
subl %r11d, %r14d
leal (%r14,%rax,2), %edx
cmpl %edx, %r10d
jl 0xfdfc
cmpl $0x1f, %eax
movl $0x1f, %ecx
cmovll %eax, %ecx
jmp 0xfe36
movw $0x1, 0x66(%rbx)
movw $0x1, %cx
movw %cx, 0x64(%rbx)
movzwl %r8w, %eax
movzwl %cx, %ecx
leal (%rax,%rcx,2), %eax
subl %eax, %r10d
jl 0xfe5b
movw %r10w, 0x1fd2(%rbx)
xorl %eax, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
retq
leaq 0x6e14(%rip), %rdi      # 0x16c76
leaq 0x687f(%rip), %rsi      # 0x166e8
leaq 0x6e51(%rip), %rcx      # 0x16cc1
movl $0x1c9, %edx            # imm = 0x1C9
callq 0x3210