// File: ljl0222[P]SecondFileSystem/FileSystem.cpp
// Function: FileSystem::IAlloc()
Inode* FileSystem::IAlloc()
{
	Buf* pBuf;
	Inode* pNode;
	User& u = globalUser;
	int ino;	/* ���䵽�Ŀ�������Inode���� */

	/*
	 * SuperBlockֱ�ӹ����Ŀ���Inode�������ѿգ�
	 * ���뵽��������������Inode���ȶ�inode�б�������
	 * ��Ϊ�����³����л����ж��̲������ܻᵼ�½����л���
	 * ���������п��ܷ��ʸ������������ᵼ�²�һ���ԡ�
	 */
	if (m_SuperBlock->s_ninode <= 0)
	{
		/* ����Inode���Ŵ�0��ʼ���ⲻͬ��Unix V6������Inode��1��ʼ���� */
		ino = -1;

		/* ���ζ�������Inode���еĴ��̿飬�������п�������Inode����������Inode������ */
		for (int i = 0; i < m_SuperBlock->s_isize; i++)
		{
			pBuf = this->m_BufferManager->Bread(FileSystem::INODE_ZONE_START_SECTOR + i);

			/* ��ȡ��������ַ */
			int* p = (int*)pBuf->b_addr;

			/* �����û�������ÿ������Inode��i_mode != 0����ʾ�Ѿ���ռ�� */
			for (int j = 0; j < FileSystem::INODE_NUMBER_PER_SECTOR; j++)
			{
				ino++;

				int mode = *(p + j * sizeof(DiskInode) / sizeof(int));

				/* ������Inode�ѱ�ռ�ã����ܼ�������Inode������ */
				if (mode != 0)
				{
					continue;
				}

				/*
				 * ��������inode��i_mode==0����ʱ������ȷ��
				 * ��inode�ǿ��еģ���Ϊ�п������ڴ�inodeû��д��
				 * ������,����Ҫ���������ڴ�inode���Ƿ�����Ӧ����
				 */
				if (globalINodeTable.IsLoaded(ino) == -1)
				{
					/* ������Inodeû�ж�Ӧ���ڴ濽����������������Inode������ */
					m_SuperBlock->s_inode[m_SuperBlock->s_ninode++] = ino;

					/* ���������������Ѿ�װ�����򲻼������� */
					if (m_SuperBlock->s_ninode >= 100)
					{
						break;
					}
				}
			}

			/* �����Ѷ��굱ǰ���̿飬�ͷ���Ӧ�Ļ��� */
			this->m_BufferManager->Brelse(pBuf);

			/* ���������������Ѿ�װ�����򲻼������� */
			if (m_SuperBlock->s_ninode >= 100)
			{
				break;
			}
		}

		/* �����ڴ�����û���������κο�������Inode������NULL */
		if (m_SuperBlock->s_ninode <= 0)
		{
			u.u_error = User::myENOSPC;
			return NULL;
		}
	}
	
	ino = m_SuperBlock->s_inode[--m_SuperBlock->s_ninode];
	pNode = globalINodeTable.IGet(ino);
	if (NULL == pNode) {
		cout << "û�п����ڴ���Inode" << endl;
		return NULL;
	}

	pNode->Clean();
	m_SuperBlock->s_fmod = 1;
	return pNode;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x48(%rbp)
leaq 0x1d43d(%rip), %rcx     # 0x24cc8
movq %rcx, -0x28(%rbp)
movq 0x8(%rax), %rax
cmpl $0x0, 0x19c(%rax)
jg 0x79e1
movl $0xffffffff, -0x2c(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x30(%rbp)
movq -0x48(%rbp), %rcx
movl -0x30(%rbp), %eax
movq 0x8(%rcx), %rcx
cmpl (%rcx), %eax
jge 0x79b0
movq -0x48(%rbp), %rax
movq (%rax), %rdi
movl -0x30(%rbp), %esi
addl $0x2, %esi
callq 0x3f10
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x38(%rbp)
movl $0x0, -0x3c(%rbp)
cmpl $0x8, -0x3c(%rbp)
jge 0x797d
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
movq -0x38(%rbp), %rax
movslq -0x3c(%rbp), %rcx
shlq $0x6, %rcx
shrq $0x2, %rcx
movl (%rax,%rcx,4), %eax
movl %eax, -0x40(%rbp)
cmpl $0x0, -0x40(%rbp)
je 0x791b
jmp 0x796f
movl -0x2c(%rbp), %esi
leaq 0x1b5cb(%rip), %rdi     # 0x22ef0
callq 0x8fe0
cmpl $-0x1, %eax
jne 0x796d
movq -0x48(%rbp), %rax
movl -0x2c(%rbp), %esi
movq 0x8(%rax), %rcx
movq 0x8(%rax), %rdi
movl 0x19c(%rdi), %edx
movl %edx, %r8d
addl $0x1, %r8d
movl %r8d, 0x19c(%rdi)
movslq %edx, %rdx
movl %esi, 0x1a0(%rcx,%rdx,4)
movq 0x8(%rax), %rax
cmpl $0x64, 0x19c(%rax)
jl 0x796b
jmp 0x797d
jmp 0x796d
jmp 0x796f
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x78ea
movq -0x48(%rbp), %rax
movq (%rax), %rdi
movq -0x18(%rbp), %rsi
callq 0x3e80
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0x64, 0x19c(%rax)
jl 0x79a0
jmp 0x79b0
jmp 0x79a2
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x78ae
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
cmpl $0x0, 0x19c(%rax)
jg 0x79df
leaq 0x1d300(%rip), %rax     # 0x24cc8
movl $0x1c, 0x10c8(%rax)
movq $0x0, -0x8(%rbp)
jmp 0x7a73
jmp 0x79e1
movq -0x48(%rbp), %rcx
movq 0x8(%rcx), %rax
movq 0x8(%rcx), %rdx
movl 0x19c(%rdx), %ecx
addl $-0x1, %ecx
movl %ecx, 0x19c(%rdx)
movslq %ecx, %rcx
movl 0x1a0(%rax,%rcx,4), %eax
movl %eax, -0x2c(%rbp)
movl -0x2c(%rbp), %esi
leaq 0x1b4dd(%rip), %rdi     # 0x22ef0
callq 0x8ec0
movq %rax, -0x20(%rbp)
xorl %eax, %eax
cmpq -0x20(%rbp), %rax
jne 0x7a50
movq 0xc59d(%rip), %rdi      # 0x13fc8
leaq 0x6615(%rip), %rsi      # 0xe047
callq 0x32e0
movq %rax, %rdi
movq 0xc56f(%rip), %rsi      # 0x13fb0
callq 0x3330
movq $0x0, -0x8(%rbp)
jmp 0x7a73
movq -0x20(%rbp), %rdi
callq 0x88d0
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movl $0x1, 0x338(%rax)
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax)