// File: 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
subq $0x80, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x50(%rbp)
movl $0x0, -0x1c(%rbp)
movl $0x0, -0x20(%rbp)
leaq 0x1e819(%rip), %rax     # 0x24cc8
movq %rax, -0x28(%rbp)
leaq 0x1e80e(%rip), %rax     # 0x24cc8
movq 0x1058(%rax), %rax
movq %rax, -0x30(%rbp)
leaq 0xde84(%rip), %rax      # 0x14350
movq %rax, -0x38(%rbp)
leaq 0x1e7f1(%rip), %rdi     # 0x24cc8
addq $0x1038, %rdi           # imm = 0x1038
xorl %eax, %eax
movl %eax, %esi
callq 0x3610
movsbl (%rax), %ecx
movl $0x2f, %eax
cmpl %ecx, %eax
jne 0x650d
movq -0x50(%rbp), %rax
movl -0x1c(%rbp), %ecx
addl $0x1, %ecx
movl %ecx, -0x1c(%rbp)
addl $0x1, %ecx
movl %ecx, -0x20(%rbp)
movq (%rax), %rax
movq %rax, -0x30(%rbp)
jmp 0x650f
leaq 0x1e7b2(%rip), %rax     # 0x24cc8
cmpl $0x0, 0x10c8(%rax)
je 0x6524
jmp 0x690d
movl -0x20(%rbp), %eax
movq %rax, -0x58(%rbp)
leaq 0x1e796(%rip), %rdi     # 0x24cc8
addq $0x1038, %rdi           # imm = 0x1038
callq 0x34e0
movq %rax, %rcx
movq -0x58(%rbp), %rax
cmpq %rcx, %rax
jb 0x6557
movq -0x30(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x6928
movq -0x30(%rbp), %rax
movl 0x4(%rax), %eax
andl $0x6000, %eax           # imm = 0x6000
cmpl $0x4000, %eax           # imm = 0x4000
je 0x6580
leaq 0x1e757(%rip), %rax     # 0x24cc8
movl $0x14, 0x10c8(%rax)
jmp 0x690d
movl -0x1c(%rbp), %eax
movl %eax, %edx
leaq 0x1e73c(%rip), %rdi     # 0x24cc8
addq $0x1038, %rdi           # imm = 0x1038
movl $0x2f, %esi
callq 0x31e0
movl %eax, -0x20(%rbp)
leaq 0x1e721(%rip), %rdi     # 0x24cc8
addq $0x1088, %rdi           # imm = 0x1088
xorl %esi, %esi
movl $0x1c, %edx
callq 0x3190
leaq 0x1e707(%rip), %rdi     # 0x24cc8
addq $0x1038, %rdi           # imm = 0x1038
callq 0x31b0
movl -0x1c(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0x60(%rbp)
cmpl $-0x1, -0x20(%rbp)
jne 0x65f6
leaq 0x1e6e4(%rip), %rdi     # 0x24cc8
addq $0x1038, %rdi           # imm = 0x1038
callq 0x34e0
movq %rax, -0x68(%rbp)
jmp 0x65fd
movl -0x20(%rbp), %eax
movq %rax, -0x68(%rbp)
movq -0x60(%rbp), %rsi
movq -0x68(%rbp), %rdx
movl -0x1c(%rbp), %eax
subq %rax, %rdx
leaq 0x1e6b6(%rip), %rdi     # 0x24cc8
addq $0x1088, %rdi           # imm = 0x1088
callq 0x3260
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1c(%rbp)
leaq 0x1e69a(%rip), %rax     # 0x24cc8
movl $0x0, 0x13f8(%rax)
movq -0x30(%rbp), %rax
movslq 0x1c(%rax), %rax
shrq $0x5, %rax
movl %eax, %ecx
leaq 0x1e67b(%rip), %rax     # 0x24cc8
movl %ecx, 0x13fc(%rax)
movl $0x0, -0x18(%rbp)
movq $0x0, -0x40(%rbp)
xorl %eax, %eax
leaq 0x1e65d(%rip), %rcx     # 0x24cc8
cmpl 0x13fc(%rcx), %eax
jne 0x671e
xorl %eax, %eax
cmpq -0x40(%rbp), %rax
je 0x668f
movq -0x40(%rbp), %rsi
leaq 0xdcc6(%rip), %rdi      # 0x14350
callq 0x3e80
movl $0x1, %eax
cmpl -0x14(%rbp), %eax
jne 0x6708
movl -0x20(%rbp), %eax
movq %rax, -0x70(%rbp)
leaq 0x1e621(%rip), %rdi     # 0x24cc8
addq $0x1038, %rdi           # imm = 0x1038
callq 0x34e0
movq %rax, %rcx
movq -0x70(%rbp), %rax
cmpq %rcx, %rax
jb 0x6708
movq -0x30(%rbp), %rcx
leaq 0x1e5fe(%rip), %rax     # 0x24cc8
movq %rcx, 0x1060(%rax)
cmpl $0x0, -0x18(%rbp)
je 0x66f0
movslq -0x18(%rbp), %rax
subq $0x20, %rax
movl %eax, %ecx
leaq 0x1e5e0(%rip), %rax     # 0x24cc8
movl %ecx, 0x13f8(%rax)
jmp 0x66fb
movq -0x30(%rbp), %rax
movl (%rax), %ecx
orl $0x2, %ecx
movl %ecx, (%rax)
movq $0x0, -0x8(%rbp)
jmp 0x6928
leaq 0x1e5b9(%rip), %rax     # 0x24cc8
movl $0x2, 0x10c8(%rax)
jmp 0x690f
leaq 0x1e5a3(%rip), %rax     # 0x24cc8
movl 0x13f8(%rax), %eax
movl $0x200, %ecx            # imm = 0x200
cltd
idivl %ecx
xorl %eax, %eax
cmpl %edx, %eax
jne 0x6786
cmpq $0x0, -0x40(%rbp)
je 0x6750
movq -0x40(%rbp), %rsi
leaq 0xdc05(%rip), %rdi      # 0x14350
callq 0x3e80
movq -0x30(%rbp), %rdi
leaq 0x1e56d(%rip), %rax     # 0x24cc8
movl 0x13f8(%rax), %eax
movl $0x200, %ecx            # imm = 0x200
cltd
idivl %ecx
movl %eax, %esi
callq 0x8020
movl %eax, -0x44(%rbp)
movl -0x44(%rbp), %esi
leaq 0xdbd3(%rip), %rdi      # 0x14350
callq 0x3f10
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq 0x20(%rax), %rcx
leaq 0x1e533(%rip), %rax     # 0x24cc8
movl 0x13f8(%rax), %eax
movl $0x200, %esi            # imm = 0x200
cltd
idivl %esi
movslq %edx, %rdx
leaq 0x1e51b(%rip), %rax     # 0x24cc8
movq (%rcx,%rdx), %rsi
movq %rsi, 0x1068(%rax)
movq 0x8(%rcx,%rdx), %rsi
movq %rsi, 0x1070(%rax)
movq 0x10(%rcx,%rdx), %rsi
movq %rsi, 0x1078(%rax)
movq 0x18(%rcx,%rdx), %rcx
movq %rcx, 0x1080(%rax)
leaq 0x1e4e5(%rip), %rax     # 0x24cc8
movslq 0x13f8(%rax), %rax
addq $0x20, %rax
movl %eax, %ecx
leaq 0x1e4d1(%rip), %rax     # 0x24cc8
movl %ecx, 0x13f8(%rax)
leaq 0x1e4c4(%rip), %rax     # 0x24cc8
movl 0x13fc(%rax), %ecx
addl $-0x1, %ecx
leaq 0x1e4b4(%rip), %rax     # 0x24cc8
movl %ecx, 0x13fc(%rax)
xorl %eax, %eax
leaq 0x1e4a5(%rip), %rcx     # 0x24cc8
cmpl 0x1068(%rcx), %eax
jne 0x6847
xorl %eax, %eax
cmpl -0x18(%rbp), %eax
jne 0x6842
leaq 0x1e48f(%rip), %rax     # 0x24cc8
movl 0x13f8(%rax), %eax
movl %eax, -0x18(%rbp)
jmp 0x6662
leaq 0x1e47a(%rip), %rsi     # 0x24cc8
movq %rsi, %rdi
addq $0x1088, %rdi           # imm = 0x1088
addq $0x106c, %rsi           # imm = 0x106C
movl $0x1c, %edx
callq 0x3160
cmpl $0x0, %eax
jne 0x6870
jmp 0x6875
jmp 0x6662
xorl %eax, %eax
cmpq -0x40(%rbp), %rax
je 0x688d
movq -0x40(%rbp), %rsi
leaq 0xdac8(%rip), %rdi      # 0x14350
callq 0x3e80
movl $0x2, %eax
cmpl -0x14(%rbp), %eax
jne 0x68c7
movl -0x20(%rbp), %eax
movq %rax, -0x78(%rbp)
leaq 0x1e423(%rip), %rdi     # 0x24cc8
addq $0x1038, %rdi           # imm = 0x1038
callq 0x34e0
movq %rax, %rcx
movq -0x78(%rbp), %rax
cmpq %rcx, %rax
jb 0x68c7
movq -0x30(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x6928
movq -0x50(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x30(%rbp), %rsi
callq 0x8d20
movq -0x50(%rbp), %rax
movq 0x10(%rax), %rdi
leaq 0x1e3e1(%rip), %rax     # 0x24cc8
movl 0x1068(%rax), %esi
callq 0x8ec0
movq %rax, -0x30(%rbp)
xorl %eax, %eax
cmpq -0x30(%rbp), %rax
jne 0x6908
movq $0x0, -0x8(%rbp)
jmp 0x6928
jmp 0x650f
jmp 0x690f
movq -0x50(%rbp), %rax
movq 0x10(%rax), %rdi
movq -0x30(%rbp), %rsi
callq 0x8d20
movq $0x0, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x80, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)