// File: /workspace/github_cpp_makefile_star2_O3/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, -0x2c(%rbp)
leaq 0x1971d(%rip), %r14     # 0x1dbd8
movq 0x1038(%r14), %rax
xorl %r13d, %r13d
cmpb $0x2f, (%rax)
leaq 0x1058(%r14), %rax
sete %r13b
movq %rdi, -0x40(%rbp)
cmoveq %rdi, %rax
leal (%r13,%r13), %edx
movq (%rax), %rbx
movl $0x6000, %ecx           # imm = 0x6000
leaq 0x1038(%r14), %r12
leaq 0x1088(%r14), %rax
movq %rax, -0x58(%rbp)
leaq 0x8d5f(%rip), %r15      # 0xd260
movq %r12, -0x50(%rbp)
cmpl $0x0, 0x10c8(%r14)
jne 0x475f
movl %edx, %eax
cmpq 0x1040(%r14), %rax
jae 0x4795
movl 0x4(%rbx), %eax
andl %ecx, %eax
cmpl $0x4000, %eax           # imm = 0x4000
jne 0x4753
movl %r13d, %r13d
movq %r12, %rdi
movl $0x2f, %esi
movq %r13, %rdx
callq 0x32e0
xorps %xmm0, %xmm0
movups %xmm0, 0x1088(%r14)
movups %xmm0, 0x1094(%r14)
movq %rax, -0x48(%rbp)
movl %eax, %ecx
movq %rcx, %rdx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movq %rcx, -0x38(%rbp)
cmpq %rax, %rcx
jne 0x4576
movq 0x1040(%r14), %rdx
subq %r13, %rdx
addq 0x1038(%r14), %r13
movq -0x58(%rbp), %rdi
movq %r13, %rsi
callq 0x31b0
movl $0x0, 0x13f8(%r14)
movl 0x1c(%rbx), %eax
movl %eax, %edx
sarl $0x5, %edx
movl %edx, 0x13fc(%r14)
cmpl $0x20, %eax
jb 0x4771
movq -0x48(%rbp), %r13
incq %r13
xorl %ecx, %ecx
xorl %eax, %eax
xorl %r12d, %r12d
testl $0x1ff, %ecx            # imm = 0x1FF
jne 0x460a
testq %rax, %rax
je 0x45dc
movq %r15, %rdi
movq %rax, %rsi
callq 0x3a58
movl 0x13f8(%r14), %ecx
leal 0x1ff(%rcx), %esi
testl %ecx, %ecx
cmovnsl %ecx, %esi
sarl $0x9, %esi
movq %rbx, %rdi
callq 0x5684
movq %r15, %rdi
movl %eax, %esi
callq 0x3aa4
movl 0x13f8(%r14), %ecx
movl 0x13fc(%r14), %edx
movq 0x20(%rax), %rsi
leal 0x1ff(%rcx), %edi
testl %ecx, %ecx
cmovnsl %ecx, %edi
andl $0xfffffe00, %edi       # imm = 0xFFFFFE00
movl %ecx, %r8d
subl %edi, %r8d
movslq %r8d, %rdi
movdqu (%rsi,%rdi), %xmm0
movdqu 0x10(%rsi,%rdi), %xmm1
movdqu %xmm0, 0x1068(%r14)
movdqu %xmm1, 0x1078(%r14)
addl $0x20, %ecx
movl %ecx, 0x13f8(%r14)
decl %edx
movl %edx, 0x13fc(%r14)
cmpl $0x0, 0x1068(%r14)
je 0x46a0
movdqu 0x106c(%r14), %xmm0
movdqu 0x1078(%r14), %xmm1
movdqu 0x1088(%r14), %xmm2
pcmpeqb %xmm0, %xmm2
movdqu 0x1094(%r14), %xmm0
pcmpeqb %xmm1, %xmm0
pand %xmm2, %xmm0
pmovmskb %xmm0, %esi
cmpl $0xffff, %esi           # imm = 0xFFFF
jne 0x46a7
jmp 0x46b1
testl %r12d, %r12d
cmovel %ecx, %r12d
testl %edx, %edx
jne 0x45bd
jmp 0x4713
movq %r15, %rdi
movq %rax, %rsi
callq 0x3a58
cmpl $0x2, -0x2c(%rbp)
jne 0x46d3
movq -0x38(%rbp), %rax
cmpq 0x1040(%r14), %rax
jae 0x4795
movq -0x40(%rbp), %r12
movq 0x10(%r12), %rdi
movq %rbx, %rsi
callq 0x5dc0
movq 0x10(%r12), %rdi
movl 0x1068(%r14), %esi
callq 0x5eae
movq %rax, %rbx
testq %rax, %rax
movl $0x6000, %ecx           # imm = 0x6000
movq -0x50(%rbp), %r12
movq -0x48(%rbp), %rdx
jne 0x4505
jmp 0x4793
leaq 0x8b46(%rip), %rdi      # 0xd260
movq %rax, %rsi
callq 0x3a58
movl $0x2, %eax
cmpl $0x1, -0x2c(%rbp)
jne 0x4758
movq -0x38(%rbp), %rcx
cmpq 0x1040(%r14), %rcx
jb 0x4758
movq %rbx, 0x1060(%r14)
testl %r12d, %r12d
je 0x4790
addl $-0x20, %r12d
movl %r12d, 0x13f8(%r14)
jmp 0x4793
movl $0x14, %eax
movl %eax, 0x10c8(%r14)
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rdi
movq %rbx, %rsi
callq 0x5dc0
jmp 0x4793
movl $0x2, %eax
cmpl $0x1, -0x2c(%rbp)
jne 0x4758
movq -0x38(%rbp), %rcx
cmpq 0x1040(%r14), %rcx
jb 0x4758
movq %rbx, 0x1060(%r14)
orb $0x2, (%rbx)
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop