>source

학교 프로젝트 (구현 ls, mkdir, 그런 종류)를 위해 ext2 파일 시스템 작업을하고 있으며 inode의 i_block을 통과 해야하는 작업을 위해 많은 중복 코드를 생성하고 있음을 발견했습니다. dir 항목 수를 계산하고 strcmp 이름 일치, dir 데이터 검색, 데이터 쓰기 ... i_block 통과는 많은 문제에 공통적 인 것으로 보입니다. i_block 이이 중복성을 제거하기 위해 반복자와 비슷한 것을 쓰려고합니다.

이 작업을 수행하는 좋은 방법이 무엇인지 궁금합니다. 리눅스 시스템 코드에서 이것 또는 비슷한 것이 수행되는 예가 있습니까? 아니면 이것은 단지 나쁜 생각입니다.

지금까지 내가 만든 코드 :

   // returns block number located at iter position
    // accepts a minode which is a struct wrapping an inode (in memory inode)
    // accepts an iter which will self mutate and should start at 0
    int iter_i_block(minode *mip, int *iter) {
      static char buf[BLKSIZE]; // static buffer
      // buffer number used to check if a new block needs to be read in
      static int bufno;
      // inode number used to determine if we are working on a new inode
      static int ino; 
      // block number to return
      int bno;
      // flag for if this a different inode than last time
      int new_ino = 0;
      if (ino != mip->ino) {
        ino = mip->ino;
        new_ino = 1;
      }
      // direct blocks
      if (*iter < 12) {
        bno = mip->inode.i_block[*iter];
        (*iter)++;
        bufno = bno;
        return bno;
      }
      // indirect blocks
      if (*iter < 12 + BLKSIZE_1024 / sizeof(int)) {
        if (!mip->inode.i_block[12])
          return 0;
        if (new_ino || bufno != 12)
          get_block(mip->mount_entry, mip->inode.i_block[12], buf);
        bufno = 12;
        bno = *((int *)buf + (*iter - 12));
        (*iter)++;
        return bno;
      }
      // double indirect blocks (not shown)
      // triple indirect blocks (not shown)
      return 0;
    }

어떤 조언을 부탁드립니다! 감사합니다


  • 답변 # 1

    지금 내가 겪고있는 일은

    길 해밀턴에게 구조체 사용을 제안 해 주셔서 감사합니다

    typedef struct blk_iter {
      struct minode *mip;
      // buf contains the nth block
      unsigned int nth;
      // direct block (buf), indirection block(map1),
      // double indirection(map2), triple indirection(map3);
      char buf[BLKSIZE_1024], map1[BLKSIZE_1024], map2[BLKSIZE_1024],
          map3[BLKSIZE_1024];
    } blk_iter;
    // returns a char* buffer of BLKSIZE on success
    // null on failure (nothing more to read)
    // must start from nth = -1
    char *get_blk(blk_iter *it, int lbk) {
      // calculations for convience, could be macros
      int blks_per = BLKSIZE_1024 / sizeof(int);
      int direct_start = 0, direct_end = 12, indirect_start = direct_end,
          indirect_end = direct_end + blks_per, double_start = indirect_end,
          double_end = indirect_end + blks_per * blks_per,
          triple_start = double_end,
          triple_end = double_end + blks_per * blks_per * blks_per;
      // pointers for shorter names
      unsigned int *i_block = it->mip->inode.i_block;
      mount_entry *me = it->mip->mount_entry;
      // null check
      if (!it || !it->mip)
        return 0;
      // get blocks based on lbk
      if (lbk < direct_end) {
        // get direct block
        get_block(me, i_block[lbk], it->buf);
      } else if (lbk < indirect_end) {
        // get indirect block
        if (!(it->nth >= indirect_start && it->nth < indirect_end))
          // check if map1 cached
          get_block(me, i_block[12], it->map1);
        get_block(me, it->map1[lbk - indirect_start], it->buf);
      } else if (lbk < double_end) {
        // get double indirect block
        if (!(it->nth >= double_start && it->nth < double_end))
          // check if map2 cached
          get_block(me, i_block[13], it->map2);
        if (!((lbk - double_start) / blks_per ==
              (it->nth - double_start) / blks_per))
          // check if map1 cached
          get_block(me, it->map2[(lbk - double_start) / blks_per], it->map1);
        get_block(me, it->map1[(lbk - double_start) % blks_per], it->buf);
      } else if (lbk < triple_end) {
        // triple  indirect blocks
        if (!(it->nth >= triple_start && it->nth < triple_end))
          // check if map3 cached
          get_block(me, i_block[12], it->map3);
        if (!((lbk - triple_start) / (blks_per * blks_per) ==
              (it->nth - triple_start) / (blks_per * blks_per)))
          // check if map2 cached
          get_block(me, it->map3[(lbk - triple_start) / (blks_per * blks_per)],
                    it->map2);
        if (!((lbk - triple_start) / blks_per ==
              (it->nth - triple_start) / blks_per))
          // check if map1 cached
          get_block(me, it->map2[(lbk - triple_start) / blks_per], it->map1);
        get_block(me, it->map1[(lbk - triple_start) % blks_per], it->buf);
      }
      it->nth = lbk;
      return it->buf;
    }
    
    

관련 자료

  • 이전 jquery - 콘솔의 여러 줄을 배열에 병합하려고합니다
  • 다음 javautilHashMapcontainsValue ()는 어떻게 작동합니까? 시간 복잡성이란 무엇입니까?