. [PintOS, Project 4] Filesys.c 구현
본문 바로가기
Pintos Project/Project 4

[PintOS, Project 4] Filesys.c 구현

by 불냥이_ 2021. 3. 4.

이번에는 좀 나대보도록 하겠다.

공부와 동시에 바로 구현에 들어간다.

 

 

/* 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에서는 해주지 않았다. 이것도 추가해주자.

 

댓글