6/30 PintOS Project4 File System(5)

JK·2023년 6월 30일
0

Subdirectories의 구현을 시작해보겠습니다

어제까지 Indexed and Extensible Files의 구현을 끝내고 다음 파트인 Subdirectories의 구현을 시작해보겠습니다

chdir

프로세스의 현재 작업 디렉토리를 상대 또는 절대일 수 있는 dir로 변경합니다. 성공하면 true를, 실패하면 false를 반환합니다.

bool chdir(const char *name)
{
	struct thread *curr = thread_current();

	char *copy_name = (char *)malloc(strlen(name) + 1);
	if (copy_name == NULL)
		return false;

	strlcpy(copy_name, name, strlen(name) + 1);

	if (strlen(copy_name) == 0)
		return false;

	struct dir *dir;

	if (copy_name[0] == '/')
		dir = dir_open_root();
	else
		dir = dir_reopen(curr->curr_dir);

	char *token, *save_ptr;
	token = strtok_r(copy_name, "/", &save_ptr);

	struct inode *inode = NULL;
	while (token != NULL)
	{
		if (!dir_lookup(dir, token, &inode))
			goto fail;

		if (!inode_is_dir(inode))
			goto fail;

		dir_close(dir);
		dir = dir_open(inode);

		token = strtok_r(NULL, "/", &save_ptr);
	}

	dir_close(curr->curr_dir);
	curr->curr_dir = dir;
	free(copy_name);

	return true;

fail:
	dir_close(dir);
	if (inode)
		inode_close(inode);

	return false;
}

위의 코드는 chdir 함수입니다.

1. 함수 시그니처:

주어진 경로를 기반으로 현재 작업 디렉토리를 변경하는 기능을 수행합니다.

2. 함수 동작:

  1. 입력 경로의 복사본 생성: name은 변경할 디렉토리의 경로를 나타냅니다. 이 함수는 입력 경로 name의 길이 + 1 크기의 메모리를 동적으로 할당하여 복사본 copy_name을 생성합니다.

  2. 빈 경로 검사: copy_name의 길이가 0인 경우 false를 반환하여 빈 경로가 주어진 경우를 처리합니다.

  3. 디렉토리 열기: copy_name의 첫 번째 문자가 '/'인 경우 루트 디렉토리를 엽니다. 그렇지 않은 경우 현재 작업 디렉토리인 curr->curr_dir을 재사용하여 디렉토리를 엽니다.

  4. 경로 토큰 분리 및 처리: copy_name을 '/'로 구분하여 토큰으로 분리합니다. 각 토큰은 디렉토리 이름을 나타냅니다. 각 토큰을 순회하면서 해당 디렉토리에서 토큰에 해당하는 inode를 찾습니다.

  5. 디렉토리 업데이트: 각 토큰에 해당하는 inode가 디렉토리인지 확인한 후, 기존의 열린 디렉토리 dir을 닫고 새로운 디렉토리 dir을 엽니다. 이 과정을 경로의 모든 토큰에 대해 반복합니다.

  6. 현재 작업 디렉토리 업데이트: 경로 토큰 처리가 완료되면, 기존의 현재 작업 디렉토리 curr->curr_dir을 닫고 새로운 디렉토리 dir을 현재 작업 디렉토리로 설정합니다.

  7. 메모리 해제 및 성공 반환: 모든 작업이 성공적으로 완료되면, 할당한 메모리를 해제하고 true를 반환합니다.

  8. 실패 처리 및 반환: 중간에 실패한 경우, 열린 디렉토리 dir을 닫고 할당한 메모리를 해제합니다. 만약 inode가 유효한 경우에는 해당 inode도 닫습니다. 그 후 false를 반환합니다.

이 함수는 주어진 경로를 따라 디렉토리를 탐색하고 변경하는 데 사용될 수 있습니다.

mkdir

상대 또는 절대일 수 있는 dir이라는 디렉토리를 생성합니다. 성공하면 true를, 실패하면 false를 반환합니다. dir이 이미 존재하거나 dir에 마지막 디렉터리 이름 외에 이미 존재하지 않는 디렉터리 이름이 있는 경우 실패합니다. 즉, 이미 존재하는 경우에만 성공하고 그렇지 않은 mkdir("/a/b/c")경우에만 성공합니다 ./a/b/a/b/c

bool mkdir(const char *dir)
{
	char *copy_dir = (char *)malloc(strlen(dir) + 1);
	if (copy_dir == NULL)
		return false;

	strlcpy(copy_dir, dir, strlen(dir) + 1);

	lock_acquire(&filesys_lock);
	bool succ = filesys_create_dir(copy_dir);
	lock_release(&filesys_lock);

	free(copy_dir);

	return succ;
}

위의 코드는 mkdir 함수입니다.

1. 함수 시그니처:

주어진 디렉토리를 생성하는 기능을 수행합니다.

2. 함수 동작:

  1. 입력 디렉토리의 복사본 생성: dir은 생성할 디렉토리의 경로를 나타냅니다. 이 함수는 입력 경로 dir의 길이 + 1 크기의 메모리를 동적으로 할당하여 복사본 copy_dir을 생성합니다.

  2. 메모리 할당 실패 검사: copy_dir이 NULL인 경우 메모리 할당 실패로 간주하고 false를 반환합니다.

  3. 파일 시스템 잠금 획득: 다른 스레드와의 동시 접근을 방지하기 위해 filesys_lock을 잠급니다.

  4. 디렉토리 생성 시스템 호출: filesys_create_dir 함수를 호출하여 실제 디스크에 새 디렉토리를 생성합니다. 해당 함수의 반환값인 succ는 디렉토리 생성의 성공 여부를 나타냅니다.

  5. 파일 시스템 잠금 해제: 디렉토리 생성 작업이 완료되면 filesys_lock을 해제합니다.

  6. 메모리 해제 및 결과 반환: 할당한 메모리를 해제하고 succ 값을 반환합니다. 이 값은 디렉토리 생성의 성공 여부를 나타냅니다.

해당 함수는 주어진 경로에 디렉토리를 생성하는 데 사용될 수 있습니다. 파일 시스템 접근을 보호하기 위해 잠금 메커니즘이 사용되며, 디렉토리 생성 결과를 반환합니다.

readdir

디렉토리를 나타내야 하는 파일 설명자 fd에서 디렉토리 항목을 읽습니다. 성공하면 null로 끝나는 파일 이름을 바이트 공간이 있어야 하는 name에 저장 READDIR_MAX_LEN + 1하고 true를 반환합니다. 디렉토리에 항목이 남아 있지 않으면 false를 반환합니다.

. 그리고 ..는 에 의해 반환되어서는 안 됩니다 readdir. 디렉토리가 열려 있는 동안 디렉토리가 변경되면 일부 항목이 전혀 읽히지 않거나 여러 번 읽힐 수 있습니다. 그렇지 않으면 각 디렉토리 항목을 순서에 관계없이 한 번 읽어야 합니다.

READDIR_MAX_LEN에 정의되어 있습니다 lib/user/syscall.h. 파일 시스템이 기본 파일 시스템보다 긴 파일 이름을 지원하는 경우 이 값을 기본값인 14에서 늘려야 합니다.

bool readdir(int fd, char *name)
{
	if (name == NULL)
		return false;

	struct file *f = process_get_file(fd);
	if (f == NULL)
		return false;

	if (inode_is_dir(f->inode) == INODE_FILE)
		return false;

	struct dir *dir = f;

	bool succ = dir_readdir(dir, name);

	return succ;
}

위의 코드는 readdir 함수입니다.

1. 함수 시그니처:

파일 디스크립터 fd에 연결된 디렉토리에서 다음 엔트리의 이름을 읽어옵니다.

2. 함수 동작:

  1. 입력 이름의 유효성 검사: 입력으로 받은 name이 NULL인 경우 false를 반환합니다.

  2. 파일 디스크립터 확인: 주어진 fd를 사용하여 현재 파일 시스템에서 해당 파일을 가져옵니다. 가져온 파일을 f에 저장합니다.

  3. 파일 유형 검사: 가져온 파일이 디렉토리가 아닌 경우(즉, 파일인 경우) false를 반환합니다.

  4. 디렉토리 파일 처리: f가 디렉토리 파일인 경우, 해당 디렉토리에 대한 디렉토리 구조체 dir로 캐스팅합니다.

  5. 디렉토리 읽기 시스템 호출: dir_readdir 함수를 호출하여 다음 엔트리의 이름을 읽어옵니다. 읽어온 이름은 name 버퍼에 저장됩니다.

  6. 결과 반환: dir_readdir 함수의 반환값인 succ를 반환합니다. 이 값은 디렉토리 읽기 작업의 성공 여부를 나타냅니다.

해당 함수는 주어진 파일 디스크립터에 연결된 디렉토리에서 다음 엔트리의 이름을 읽어오는 기능을 수행합니다. 파일 시스템 접근을 보호하기 위해 파일 디스크립터를 사용하며, 읽어온 결과를 반환합니다.

isdir

fd가 디렉토리를 나타내는 경우 true를 반환하고 일반 파일을 나타내는 경우 false를 반환합니다.

int inumber(int fd)
{
	struct file *f = process_get_file(fd);
	if (f == NULL)
		return false;

	return inode_get_inumber(f->inode);
}

위의 코드는 isdir 함수입니다.

1. 함수 시그니처:

파일 디스크립터 fd에 연결된 파일의 i-node 번호를 반환합니다.

2. 함수 동작:

  1. 파일 디스크립터 확인: 주어진 fd를 사용하여 현재 파일 시스템에서 해당 파일을 가져옵니다. 가져온 파일을 f에 저장합니다.

  2. 파일 존재 여부 확인: 가져온 파일 f가 NULL인 경우, 즉 파일이 존재하지 않는 경우 false를 반환합니다.

  3. i-node 번호 반환: f->inode를 사용하여 파일의 i-node 구조체를 가져온 후, 해당 i-node의 번호를 반환합니다. 이는 파일을 유일하게 식별하는 번호입니다.

해당 함수는 파일 디스크립터에 연결된 파일의 i-node 번호를 반환합니다. 이를 통해 파일을 고유하게 식별할 수 있습니다.

inumber

일반 파일이나 디렉토리를 나타낼 수 있는 fd와 관련된 inode의 inode 번호를 반환합니다.

inode 번호는 파일이나 디렉토리를 지속적으로 식별합니다. 파일이 존재하는 동안 고유합니다. Pintos에서는 inode의 섹터 번호가 inode 번호로 사용하기에 적합합니다.

int inumber(int fd)
{
	struct file *f = process_get_file(fd);
	if (f == NULL)
		return false;

	return inode_get_inumber(f->inode);
}

위의 코드는 inumber 함수입니다.

1. 함수 시그니처:

파일 디스크립터 fd에 연결된 파일의 i-node 번호를 반환합니다.

2. 함수 동작:

  1. 파일 디스크립터 확인: process_get_file(fd)를 호출하여 주어진 fd를 사용하여 현재 프로세스의 파일 테이블에서 해당 파일을 가져옵니다. 가져온 파일을 f에 저장합니다.

  2. 파일 존재 여부 확인: 가져온 파일 f가 NULL인 경우, 즉 파일이 존재하지 않는 경우 false를 반환합니다.

  3. i-node 번호 반환: f->inode를 사용하여 파일의 i-node 구조체를 가져온 후, 해당 i-node의 번호를 반환합니다. i-node 번호는 파일을 고유하게 식별하는 값으로 사용됩니다.

따라서, 해당 함수는 파일 디스크립터에 연결된 파일의 i-node 번호를 반환하여 파일을 고유하게 식별할 수 있습니다.

profile
^^

0개의 댓글

관련 채용 정보