PintOS-jungle) Indexed and Extensible Files 구조 파악

Mongle·2021년 3월 5일
2

OS프로젝트

목록 보기
7/8

pintos - project04) filesys 구조 파악하기

Root Directory

  • filename
  • start_cluster = 2
  • length = 1400 bytes

start clust는 cluster_chain이 시작되는 시작 클러스터 번호를 가지고 있음.

하나의 클러스터 당 512bytes를 수용할 수 있음. 따라서 3개의 클러스터가 필요하고 마지막 클러스터는 136bytes의 zero space가 들어간다는 사실을 유추할 수 있음.

🤔 클러스터당 512 bytes를 수용할 수 있음. 그러면 클러스터 당 하나의 섹터와 대응되고 그 섹터가 512 bytes를 수용? [✔]

🧐 fat_fs->fat_length
fat를 관리하는 단위는 cluster이다. 따라서 at_length는 결국 FAT에 들어갈 클러스터의 개수를 구해야한다.
하나의 FAT에 총 157개의 섹터가 들어있는데 섹터는 총 512btytes를 수용할 수 있기 때문에 157 * 512 = 80384 bytes를 수용할 수 있다. 하지만 우리는 fat를 클러스터 단위로 관리할 것이고 클러스터는 하나당 4 bytes이기 때문에 총 20096개의 클러스터를 가지고 있게 된다.

🧐 fat_fs->data_start
FAT는 157개의 섹터이고 158번째 섹터부터 data가 시작된다.

FAT(File Allocation Table)
fat는 인덱스를 통해 접근할 수 있는 배열이라고 생각하면 됨. chain형식으로 다음에 이어지는 섹터번호를 가지고 있음.
2 - 5 - 3 - 1 네 개의 섹터가 연결되어있다고 가정했을 때,
fat[2] = 5,
fat[5] = 3,
fat[3] = 1,
fat[1] = EOC(0xfffff) 이렇게 연결되어있다.


inode_disk

  • start_sector
  • length

inode_disk에는 파일의 정보를 담고있는 섹터 중 시작 섹터와 파일의 길이를 저장하고있다. 섹터는 클러스터와 연결되어있고 클러스터에 연결된 체인을 따라가면 파일의 정보를 담고있는 모든 섹터에 순차적으로 접근할 수 있다.


fat_init
struct fat_fs만큼의 공간을 할당받는다.
FAT_BOOT_SECTOR를 임시로 복사해놓기 위해 한 섹터의 크기만큼의 공간을 할당받는다.(512 bytes)
FAT_BOOT_SECTOR를 disk에서 복사해온다.
memcpy로 디스크에서 복사해온 것을 fat_fs->bs로 카피한다.

이 과정을 통해 디스크에 저장되어있던 boot_sector를 메모리에 올려놓았다.

FAT_BOOT_SECTOR를 가져와서 fat_fs->bs를 만들었다면 이제 부트 섹터의 정보를 이용해 fat_fs를 init한다.

fat_fs_init
fat_fs->data_start는 클러스터번호가 담겨있는 FAT가 끝나고 DATA가 시작되는 지점을 저장해주는 멤버변수이다.

fat_fs->bs.fat_start + fat_fs->bs.fat_sectors;

fat_start는 1이고 fat_sectors는 157이다. 따라서 158번째 섹터부터 DATA가 시작된다.

🤔 fat의 0번째에는 boot_sector가 있어서 1번째 부터 시작하는 것 같다. []

do_format

#define ROOT_DIR_CLUSTER 1    /* Cluster for the root directory */

1번째 클러스터는 항상 root_directory를 가리키고있다.

dir_create을 하는데 루트 디렉터리의 클러스터는 항상 1번이기 때문에 1번 클러스터를 섹터로 바꿔서 섹터넘버를 인자로 넣어주고 디렉터리 엔트리의 개수를 16으로 넣어준다.

🤔 왜 엔트리 개수를 16으로 넣어주는지는 더 찾아봐야겠다.

루트 디렉터리를 만들어줬으니 fat에 정보를 넣어줘야 나중에 찾아갈 수 있다. fat_put에

#define ROOT_DIR_SECTOR 1       /* Root directory file inode sector. */

루트 디렉터리의 inode는 1번째 섹터가 가지고 있다.

void fat_put(cluster_t clst, cluster_t val)은 fat[clst] = val을 해주는 함수이다. 클러스터 체인을 연결해준다.

fat_put 함수를 이용해서 ROOT_DIR_SECTOR에 EOChain 0x0FFFFFFF를 넣어준다. EOChain은 체인의 마지막 클러스터라는 뜻이다.

fat_close에서는 fat에 쓰여진 모든 정보를 디스크에 옮겨준다.
fat_open에서는 반대로 disk에 저장되어있던 fat를 메모리에 올린다. fat_fs->bs.fat_start에 디스크의 어느 섹터부터 data를 가져오면 되는지 저장되어있다.

여기까지하면 test case가 filesystem을 초기 설정하는 부분까지 이해할 수 있다. project4에서는 처음에 init을 하고 format을 하고 다시 init하게해서 총 두 번 init이 실행된다.


fat를 세팅해줬지만 아직 정상적으로 실행되지 않는다. 그 이유는 inode가 파일 정보를 fat이 아니라 기존의 free_bit_map으로 관리하고있기 때문이다.
inode.c 파일로 가서 free_bit_map을 전부 fat으로 바꿔줘야한다.

inode_disk는 inode의 data가 디스크의 어디에 존재하는지에 대한 정보를 가지고있다.

struct inode_disk {
    disk_sector_t start; /* First data sector. */
    off_t length;        /* File size in bytes. */
    unsigned magic;      /* Magic number. */

    //! Indexed and Extensible Files
    disk_sector_t end; /* First data sector. */

    uint32_t unused[124]; /* Not used. */
};

디스크의 시작 섹터넘버를 저장하고 있다. 마지막 섹터넘버를 저장해주는 멤버를 추가해줬다. unused[124]는 멤버변수를 모두 저장하고 남은 데이터의 크기가 124 bytes라는 것을 의미한다. 멤버변수를 추가해줄 때 unused 배열의 크기를 변경해줘야한다.

🤔 unused가 어떻게 사용되는지는 아직 모른다.

inode 구조체에

disk_sector_t sector;   /* Sector number of disk location. */

🤔 sector라는 멤버가 있고 디스크의 섹터 넘버라는 주석이 달려있다.
inode->data.start와 어떤 차이가 있는지 찾아봐야한다.[✔]
🧐 inode->sector 는 inode가 저장되어있는 섹터이고, inode_disk->start는 inode가 가리키는 데이터가 시작하는 섹터이다.

inode_create
앞서 fat_fs_init을 해줄 때 dir_create -> inode_create을 하게된다.
테스트 케이스에 따르면 159번 섹터부터 시작하고 총 길이는 320bytes인 파일(혹은 디렉터리)에 대한 inode를 만들어야한다.

inode_disk struct를 만들어서 받아온 정보들을 넣어준다.
disk_inode->length :: 파일의 크기(bytes)
disk_inode->start :: 시작 섹터 넘버
disk_inode->end :: 마지막 섹터 넘버

인자로 넘어온 섹터넘버(여기에선 159)에 disk_inode를 disk_write해준다.

종종 크기(length)가 0인 파일도 넘어온다. 따로 처리해줘야한다. 이 경우에는 inode 그 자체는 disk_write 해주고 disk_inode->start와 end에는 NULL을 넣어줘서 inode는 있지만 연결된 데이터는 없는 상태가 된다.

먼저 fat에 파일에 대한 섹터 맵핑 정보를 저장해줘야한다.

fat_create_chain(0)은 새로운 chain을 시작한다. 반환된 cluster가 start_cluster가 된다.
파일 데이터를 디스크에 저장하기위해 총 몇 섹터가 필요한지 계산한다. (bytes_to_sectors(length)로 구할 수 있다)

섹터 개수만큼 cluster를 체인으로 연결해놓고 클러스터마다 연결된 섹터에가서 512 bytes를 모두 0으로 채워넣는다. disk_inode->start와 end에 각각 시작 섹터와 끝 섹터 넘버를 저장한다. 이 정보를 inode가 저장된 섹터에 disk_write한다.


profile
https://github.com/Jeongseo21

0개의 댓글