파일 시스템
사용자가 파일이나 디렉토리에 접근한다는 것은, 사용자는 하드웨어 장치의 데이터에 실제로 접근한다는 것이다. 파일 시스템은 사용자 수준에서 하드디스크 파티션의 물리적인 구조를 볼 수 있게 해준다. 사용자 모드에서 파일 시스템을 통해 파일을 다루고자 하면 실제 파일을 다루는 작업은 커널 모드에서 수행하게 된다. 이를 위해 유닉스 시스템에서는 여러 시스템 콜을 정의하였다.
파일 열기
fd = open(path, flag, mode)
프로세스는 열린 파일에만 접근할 수 있다. 파일을 열기 위해서, 프로세스는 위 시스템 콜을 호출한다. 세 매개변수는 각각 열 파일의 경로, 파일을 어떻게 열 것인지(읽기 쓰기 등), 새로 생성할 파일의 접근 권한을 의미한다.
이 시스템 콜은 open file 객체를 생성하고, 파일 디스크립터 식별자를 돌려준다. open file 객체는 파일 데이터를 복사할 커널의 버퍼 메모리 영역을 나타내는 포인터와 같은 파일을 다루는 몇 가지 자료 구조와 다음 연산이 수행되는 곳에서부터 그 파일의 현재 위치를 나타내는 파일 포인터, 프로세스가 호출할 수 있는 커널 함수 포인터가 주어진다. 여기서 사용이 허가된 함수의 목록은 flag 매개변수 값에 따라 달라지게 된다.
파일 디스크립터는 프로세스와 열린 파일 사이의 상호 작용을 나타내지만, open file 객체는 이 상호 작용과 관련된 자료를 포함한다. 여러 파일 디스크립터가 open file 객체와 같은 관계를 가질 수도 있다.
여러 프로세스가 동시에 같은 파일을 열 수도 있지만, 유닉스 파일 시스템은 이들 사이의 동기화를 제공하지 않는다. 그러나 프로세스가 스스로 전체 파일이나 파일의 일부분을 동기화할 수 있도록 flock()과 같은 시스템 콜을 제공한다. flock()은 파일의 읽기나 쓰기를 잠그는 시스템 콜이다.
새 파일을 만드는 경우 creat() 시스템 콜을 호출할 수 있고, 이는 커널에서 open()과 똑같이 다룬다.
파일 접근하기
일반 유닉스 파일은 순차 접근 또는 임의 접근이 가능하다. 하지만 장치 파일이나 이름이 있는 파이프는 순차적으로만 접근한다. 커널은 어떤 식으로 접근하든간에 파일 포인터를 open file 객체에 저장한다.
read_cnt = read(fd, buf, count);
read()는 파일 디스크립터 fd가 가리키는 파일에서 열린 파일의 파일 포인터에 있는 현재 값부터 count 바이트만큼 읽어서 buf에 저장한다. 그리고 실제로 읽은 바이트 수를 반환한다. write()도 거의 비슷한 매개변수를 전달하는데, buf에 쓸 데이터를 넣는다.
read()와 write() 시스템 콜은 항상 현재 파일 포인터의 위치를 참조한다. 특별히 지정하지 않으면 순차적인 접근으로 생각하고, 이 값을 바꾸려면 lseek() 시스템 콜을 호출해야 한다. 파일을 열었을 때 파일 포인터는 파일의 첫번째 바이트 위치인 offset 0으로 설정한다.
newoffset = lseek(fd, offset, whence);
fd는 열린 파일의 파일 디스크립터, offset은 파일 포인터의 새로운 위치를 계산하는 데에 사용할 정수 값, whence는 어떤 기준에 offset 값을 더해 새 위치를 계산할 것인지 지정한다. SEEK_SET은 시작 위치(offset 0), SEEK_CUR은 현재 파일 포인터 기준, SEEK_END는 끝 위치를 기준으로 계산한다.
파일 닫기
res = close(fd);
프로세스가 더 이상 파일을 사용하지 않는 경우 프로세스는 위 시스템 콜을 호출해서 파일을 닫을 수 있다. 이는 파일 디스크립터 fd에 해당하는 열린 파일 객체를 해제한다. 만약 프로세스가 종료될 때 파일이 열려 있다면 커널이 닫아준다.
파일명 변경
res = rename(oldpath, newpath);
파일명을 바꾸는 것은 파일에 대한 수정이 아닌 경로에 대한 수정, 다시 말해 디렉토리의 수정이다. 따라서 파일을 열 필요가 없고 위 시스템콜을 통해 경로를 바꿔주면 된다.
파일 삭제
res = unlink(pathname);
이 시스템콜은 pathname에 대한 링크를 제거한다. 즉 파일의 링크 횟수를 줄이고 해당 디렉토리 엔트리를 제거한다. 파일은 링크 횟수가 0일 때 제거된다.
'현생 > 리눅스 커널' 카테고리의 다른 글
유닉스 커널 개요 - 3. 메모리 관리 (0) | 2024.08.23 |
---|---|
유닉스 커널 개요 - 2. 시그널, 프로세스 간 통신, 프로세스 관리 (0) | 2024.08.22 |
유닉스 커널 개요 - 1. 커널, 프로세스와 동기화 (0) | 2024.08.21 |
유닉스 파일 시스템 (0) | 2024.08.19 |
운영체제 기초 개념 (0) | 2024.08.18 |