이번에는 좀 나대보도록 하겠다.
공부와 동시에 바로 구현에 들어간다.
/* Initializes the file system module.
* If FORMAT is true, reformats the file system. */
void
filesys_init (bool format) {
filesys_disk = disk_get (0, 1);
if (filesys_disk == NULL)
PANIC ("hd0:1 (hdb) not present, file system initialization failed");
inode_init ();
#ifdef EFILESYS
fat_init ();
if (format)
do_format ();
fat_open ();
#else
/* Original FS */
free_map_init ();
if (format)
do_format ();
free_map_open ();
#endif
}
init은 초기화하는 함수이다. 딱히 볼 것은 없는 것 같다.
/* Shuts down the file system module, writing any unwritten data
* to disk. */
void
filesys_done (void) {
/* Original FS */
#ifdef EFILESYS
fat_close ();
#else
free_map_close ();
#endif
}
이 친구 또한 끌 때 필요한 친구들이다. 볼 필요는 없는 것 같다.
/* Creates a file named NAME with the given INITIAL_SIZE.
* Returns true if successful, false otherwise.
* Fails if a file named NAME already exists,
* or if internal memory allocation fails. */
bool
filesys_create (const char *name, off_t initial_size) {
disk_sector_t inode_sector = 0;
struct dir *dir = dir_open_root ();
bool success = (dir != NULL
&& free_map_allocate (1, &inode_sector)
&& inode_create (inode_sector, initial_size)
&& dir_add (dir, name, inode_sector));
if (!success && inode_sector != 0)
free_map_release (inode_sector, 1);
dir_close (dir);
return success;
}
오. 이 친구는 바꿀게 보인다.
일단 free_map만 바꿔주고, 나머지 함수는 안에서 제 역할을 다 하고 있다고 생각하자.
(실제로 directory에는 바꿀 것이 딱히 보이지 않는다.)
이 함수는 name와 initial_size로 file을 만드는 것이다.
그러면 free-map함수들이 어떻게 사용되나를 보자.
우선 inode_sector를 0으로 시작하는데, free_map_allocate로 받아온다. 즉, 신생 inode_disk를 넣을 disk sector를 검색한다는 뜻인 것 같다. 그러면 fat_create_chain()으로 대체하면 될 것 같다.
그 다음은 inode_create()로 data들을 넣을 disk sector할당받고, 이 정보를 inode에 넣어준다.
이 또한, 이미 구현되어있다. 우리는 인자만 제대로 넣어주면 된다.
만약 실 data 를 넣은 sector 할당에 실패한다면, inode_sector 를 free한다.
free_map_release()는 sector와 해제할 sector의 갯수를 받는데 여기서는 inode_disk의 sector만 해제할 것이니, fat_remove_chain(inode_sector, 0) 로 해제한다.
오케이. 감 잡았다.
/* Creates a file named NAME with the given INITIAL_SIZE.
* Returns true if successful, false otherwise.
* Fails if a file named NAME already exists,
* or if internal memory allocation fails. */
bool
filesys_create (const char *name, off_t initial_size) {
#ifdef EFILESYS
disk_sector_t inode_sector = fat_create_chain(0);
struct dir *dir = dir_open_root ();
bool success = (dir != NULL
&& !inode_sector
&& inode_create (inode_sector, initial_size)
&& dir_add (dir, name, inode_sector));
if (!success && inode_sector != 0)
fat_remove_chain(inode_sector, 0);
dir_close (dir);
return success;
#else
disk_sector_t inode_sector = 0;
struct dir *dir = dir_open_root ();
bool success = (dir != NULL
&& free_map_allocate (1, &inode_sector)
&& inode_create (inode_sector, initial_size)
&& dir_add (dir, name, inode_sector));
if (!success && inode_sector != 0)
free_map_release (inode_sector, 1);
dir_close (dir);
return success;
#endif
}
여기서는 문제가 없으나, sector를 시작부터 몇개 정도만 해제하고 싶을 때, fat_remove_chain()을 적용하기가 어렵겠다라는 생각이 든다.
그런데 또 생각해보면, 그럴일이 드물기도 하고, 어차피 그 위치를 offset으로 받을테니, byte_to_sector()를 사용하면 오히려 더 쉽게 할 수도 있다는 생각이 든다.
/* Opens the file with the given NAME.
* Returns the new file if successful or a null pointer
* otherwise.
* Fails if no file named NAME exists,
* or if an internal memory allocation fails. */
struct file *
filesys_open (const char *name) {
struct dir *dir = dir_open_root ();
struct inode *inode = NULL;
if (dir != NULL)
dir_lookup (dir, name, &inode);
dir_close (dir);
return file_open (inode);
}
filesys_open()과 filesys_remove()는 딱히 바꿀 곳이 보이지 않는다. 공부만 하고 넘어가자.
주어진 file의 이름 (name) 으로 file을 찾는다. 이는 directory.c 의 파일을 사용하는 것 같다.
그렇다면 directory.c에는 name만으로도 inode를 찾을 수 있는 방법이 있겠지.
inode_disk나 inode에는 딱히 이름을 저장하고 있는 변수가 없으니, directory에서 변환을 할 것이다.
/* Deletes the file named NAME.
* Returns true if successful, false on failure.
* Fails if no file named NAME exists,
* or if an internal memory allocation fails. */
bool
filesys_remove (const char *name) {
struct dir *dir = dir_open_root ();
bool success = dir != NULL && dir_remove (dir, name);
dir_close (dir);
return success;
}
filesys_remove() 도 특별한 것은 보이지 않는다.
filesys라는 것이 file name과 directory를 연결해주는 것 같다.
그럼 directory로 가보자.
+++ 3/5 추가사항 +++
/* Formats the file system. */
static void
do_format (void) {
printf ("Formatting file system...");
#ifdef EFILESYS
/* Create FAT and save it to the disk. */
fat_create ();
/* ---------------------------- >> Project.4 FAT >> ---------------------------- */
if (!dir_create (ROOT_DIR_SECTOR, 16))
PANIC ("---ERROR // do_format // ROOT_DIR CREATION FAILED\n");
/* ---------------------------- << Project.4 FAT << ---------------------------- */
fat_close ();
#else
free_map_create ();
if (!dir_create (ROOT_DIR_SECTOR, 16))
PANIC ("root directory creation failed");
free_map_close ();
#endif
printf ("done.\n");
}
방심했다.
do_format에서 root_dir_sector에 entry를 만들어주는데, fat_sys에서는 해주지 않았다. 이것도 추가해주자.
'Pintos Project > Project 4' 카테고리의 다른 글
[PintOS, Project 4] File Growth 구현 (1) | 2021.03.05 |
---|---|
[PintOS, Project 4] Directory.c 공부 (0) | 2021.03.05 |
[PintOS, Project 4] inode.c 구현 (0) | 2021.03.04 |
[PintOS, Project 4] fat.c 구현 (0) | 2021.03.04 |
[PintOS, Project 4] inode.c 공부 (2) | 2021.03.04 |
댓글