// File: /workspace/github_cpp_makefile_star2_O2/ljl0222[P]SecondFileSystem/FileManager.cpp
// Function: FileManager::NameI(FileManager::DirectorySearchMode)
Inode* FileManager::NameI(enum DirectorySearchMode mode) 
{

    int freeEntryOffset;
    unsigned int index = 0, nindex = 0;

    User& u = globalUser;
    Inode* pINode = u.u_cdir;
    BufferManager& bufferManager = globalBufferManager;

    Buf* pBuf;

    /*
     * ������·����'/'��ͷ�ģ��Ӹ�Ŀ¼��ʼ������
     * �����ӽ��̵�ǰ����Ŀ¼��ʼ������
     */
    if ('/' == u.u_dirp[0]) 
    {
        nindex = ++index + 1;
        pINode = this->rootDirInode;
    }


    /* ����ѭ��ÿ�δ���pathname��һ��·������ */
    while (1) 
    {
        /* �����������ͷŵ�ǰ��������Ŀ¼�ļ�Inode�����˳� */
        if (u.u_error != User::myNOERROR) 
        {
            break; /* goto out; */
        }

        /* ����·���������ϣ�������ӦInodeָ�롣Ŀ¼�����ɹ����ء� */
        if (nindex >= u.u_dirp.length()) 
        {
            return pINode;
        }

        /* ����Ҫ���������Ĳ���Ŀ¼�ļ����ͷ�����Inode��Դ���˳� */
        if ((pINode->i_mode & Inode::IFMT) != Inode::IFDIR) 
        {
            u.u_error = User::myENOTDIR;
            break;
        }


        /*
         * ��Pathname�е�ǰ׼������ƥ����·������������u.u_dbuf[]�У�
         * ���ں�Ŀ¼�����бȽϡ�
         */
        nindex = u.u_dirp.find_first_of('/', index);
        memset(u.u_dbuf, 0, sizeof(u.u_dbuf));
        memcpy(u.u_dbuf, u.u_dirp.data() + index, (nindex == (unsigned int)string::npos ? u.u_dirp.length() : nindex) - index);
        index = nindex + 1;

        /* �ڲ�ѭ�����ֶ���u.u_dbuf[]�е�·����������������Ѱƥ����Ŀ¼�� */
        u.u_IOParam.m_Offset = 0;
        /* ����ΪĿ¼������ �����հ׵�Ŀ¼��*/
        u.u_IOParam.m_Count = pINode->i_size / sizeof(DirectoryEntry);
        freeEntryOffset = 0;
        pBuf = NULL;

        while (1) 
        {

            /* ��Ŀ¼���Ѿ��������� */
            if (0 == u.u_IOParam.m_Count) 
            {
                if (NULL != pBuf) 
                {
                    bufferManager.Brelse(pBuf);
                }

                /* �����Ǵ������ļ� */
                if (FileManager::CREATE == mode && nindex >= u.u_dirp.length()) 
                {
                    /* ����Ŀ¼Inodeָ�뱣���������Ժ�дĿ¼��WriteDir()�������õ� */
                    u.u_pdir = pINode;

                    if (freeEntryOffset)  /* �˱��������˿���Ŀ¼��λ��Ŀ¼�ļ��е�ƫ���� */
                    {   
                        /* ������Ŀ¼��ƫ��������u���У�дĿ¼��WriteDir()���õ� */
                        u.u_IOParam.m_Offset = freeEntryOffset - sizeof(DirectoryEntry);
                    }

                    else  /*���⣺Ϊ��if��֧û����IUPD��־��  ������Ϊ�ļ��ĳ���û�б�ѽ*/ 
                    { 
                        pINode->i_flag |= Inode::IUPD;
                    }

                    /* �ҵ�����д���Ŀ���Ŀ¼��λ�ã�NameI()�������� */
                    return NULL;
                }
                u.u_error = User::myENOENT;
                goto out;
            }

            /* �Ѷ���Ŀ¼�ļ��ĵ�ǰ�̿飬��Ҫ������һĿ¼�������̿� */
            if (0 == u.u_IOParam.m_Offset % Inode::BLOCK_SIZE) 
            {
                if (pBuf) 
                {
                    bufferManager.Brelse(pBuf);
                }

                /* ����Ҫ���������̿��� */
                int phyBlkno = pINode->Bmap(u.u_IOParam.m_Offset / Inode::BLOCK_SIZE);
                pBuf = bufferManager.Bread(phyBlkno);
                //pBuffer->debug();
            }

            /* û�ж��굱ǰĿ¼���̿飬����ȡ��һĿ¼����u.u_dent */
            memcpy(&u.u_dent, pBuf->b_addr + (u.u_IOParam.m_Offset % Inode::BLOCK_SIZE), sizeof(u.u_dent));

            u.u_IOParam.m_Offset += sizeof(DirectoryEntry);
            u.u_IOParam.m_Count--;

            /* �����ǿ���Ŀ¼���¼����λ��Ŀ¼�ļ���ƫ���� */
            if (0 == u.u_dent.m_ino) 
            {
                if (0 == freeEntryOffset) 
                {
                    freeEntryOffset = u.u_IOParam.m_Offset;
                }
                /* ��������Ŀ¼������Ƚ���һĿ¼�� */
                continue;
            }

            if (!memcmp(u.u_dbuf, &u.u_dent.name, sizeof(DirectoryEntry) - 4)) 
            {
                break;
            }
        }

        /*
         * ���ڲ�Ŀ¼��ƥ��ѭ�������˴���˵��pathname��
         * ��ǰ·������ƥ���ɹ��ˣ�����ƥ��pathname����һ·��
         * ������ֱ������'\0'������
         */
        if (NULL != pBuf) 
        {
            bufferManager.Brelse(pBuf);
        }

        /* ������ɾ���������򷵻ظ�Ŀ¼Inode����Ҫɾ���ļ���Inode����u.u_dent.m_ino�� */
        if (FileManager::DELETE == mode && nindex >= u.u_dirp.length()) 
        {
            return pINode;
        }

        /*
         * ƥ��Ŀ¼���ɹ������ͷŵ�ǰĿ¼Inode������ƥ���ɹ���
         * Ŀ¼��m_ino�ֶλ�ȡ��Ӧ��һ��Ŀ¼���ļ���Inode��
         */
        this->m_InodeTable->IPut(pINode);
        pINode = this->m_InodeTable->IGet(u.u_dent.m_ino);
        /* �ص�����While(true)ѭ��������ƥ��Pathname����һ·������ */

        if (NULL == pINode) 
        { /* ��ȡʧ�� */
            return NULL;
        }
    }

out:
    this->m_InodeTable->IPut(pINode);
    return NULL;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movl %esi, -0x30(%rbp)
leaq 0x186a9(%rip), %r12     # 0x1cbd8
movq 0x1038(%r12), %rax
xorl %r8d, %r8d
cmpb $0x2f, (%rax)
leaq 0x1058(%r12), %rax
sete %r8b
movq %rdi, -0x40(%rbp)
cmoveq %rdi, %rax
leal (%r8,%r8), %edx
movq (%rax), %rbx
movl $0x6000, %ecx           # imm = 0x6000
leaq 0x1038(%r12), %rdi
pushq $0x2f
popq %rsi
leaq 0x1088(%r12), %r13
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
movq %rdi, -0x58(%rbp)
cmpl $0x0, 0x10c8(%r12)
jne 0x47dd
movl %edx, %eax
cmpq 0x1040(%r12), %rax
jae 0x47ef
movl 0x4(%rbx), %eax
andl %ecx, %eax
cmpl $0x4000, %eax           # imm = 0x4000
jne 0x47d2
movl %r8d, %r14d
movq %r14, %rdx
callq 0x32e0
xorps %xmm0, %xmm0
movups %xmm0, 0x1088(%r12)
movups %xmm0, 0x1094(%r12)
movq %rax, -0x50(%rbp)
movl %eax, %eax
movq %rax, %rdx
movq %rax, -0x48(%rbp)
cmpq %r15, %rax
jne 0x45e3
movq 0x1040(%r12), %rdx
subq %r14, %rdx
addq 0x1038(%r12), %r14
movq %r13, %rdi
movq %r14, %rsi
callq 0x3190
andl $0x0, 0x13f8(%r12)
movq -0x50(%rbp), %rax
incq %rax
movq %rax, -0x60(%rbp)
movq %rbx, -0x38(%rbp)
movl 0x1c(%rbx), %ebx
sarl $0x5, %ebx
movl %ebx, 0x13fc(%r12)
xorl %r15d, %r15d
movl $0x0, -0x2c(%rbp)
xorl %r14d, %r14d
testl %ebx, %ebx
je 0x4782
testw $0x1ff, %r15w           # imm = 0x1FF
je 0x4643
movl $0x200, %esi            # imm = 0x200
jmp 0x469a
testq %r14, %r14
leaq 0x7c13(%rip), %rbx      # 0xc260
je 0x4662
movq %rbx, %rdi
movq %r14, %rsi
callq 0x3a16
movl 0x13f8(%r12), %r15d
movl %r15d, %eax
cltd
movl $0x200, %ecx            # imm = 0x200
idivl %ecx
movq -0x38(%rbp), %rdi
movl %eax, %esi
callq 0x5608
movq %rbx, %rdi
movl %eax, %esi
callq 0x3a46
movl $0x200, %esi            # imm = 0x200
movq %rax, %r14
movl 0x13f8(%r12), %r15d
movl 0x13fc(%r12), %ebx
movq 0x20(%r14), %rcx
movl %r15d, %eax
cltd
idivl %esi
movslq %edx, %rax
movups (%rcx,%rax), %xmm0
movups 0x10(%rcx,%rax), %xmm1
movups %xmm0, 0x1068(%r12)
movups %xmm1, 0x1078(%r12)
addl $0x20, %r15d
movl %r15d, 0x13f8(%r12)
decl %ebx
movl %ebx, 0x13fc(%r12)
cmpl $0x0, 0x1068(%r12)
je 0x4700
leaq 0x106c(%r12), %rsi
movq %r13, %rdi
pushq $0x1c
popq %rdx
callq 0x3220
testl %eax, %eax
jne 0x462c
jmp 0x4711
movl -0x2c(%rbp), %eax
testl %eax, %eax
cmovel %r15d, %eax
movl %eax, -0x2c(%rbp)
jmp 0x462c
leaq 0x7b48(%rip), %rdi      # 0xc260
movq %r14, %rsi
callq 0x3a16
cmpl $0x2, -0x30(%rbp)
jne 0x4738
movq -0x48(%rbp), %rax
cmpq 0x1040(%r12), %rax
jae 0x4801
movq -0x40(%rbp), %rbx
movq 0x10(%rbx), %rdi
movq -0x38(%rbp), %rsi
callq 0x5d14
movq 0x10(%rbx), %rdi
movl 0x1068(%r12), %esi
callq 0x5dfa
movq %rax, %rbx
testq %rax, %rax
movl $0x6000, %ecx           # imm = 0x6000
movq -0x58(%rbp), %rdi
pushq $0x2f
popq %rsi
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
movq -0x50(%rbp), %rdx
movq -0x60(%rbp), %r8
jne 0x457a
jmp 0x47ed
testq %r14, %r14
je 0x4796
leaq 0x7ad2(%rip), %rdi      # 0xc260
movq %r14, %rsi
callq 0x3a16
pushq $0x2
popq %rax
cmpl $0x1, -0x30(%rbp)
movq -0x38(%rbp), %rbx
jne 0x47d5
movq -0x48(%rbp), %rcx
cmpq 0x1040(%r12), %rcx
jb 0x47d5
movq %rbx, 0x1060(%r12)
movl -0x2c(%rbp), %eax
testl %eax, %eax
je 0x47cd
addl $-0x20, %eax
movl %eax, 0x13f8(%r12)
jmp 0x47ed
orb $0x2, (%rbx)
jmp 0x47ed
pushq $0x14
popq %rax
movl %eax, 0x10c8(%r12)
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdi
movq %rbx, %rsi
callq 0x5d14
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq -0x38(%rbp), %rbx
jmp 0x47ef
nop