본문 바로가기

Operating System [OS]

[OS] 09. File System

파일

파일의 기본 개념

  • 사용자나 응용프로그램 관점 : 정보를 저장하고 관리하는 논리적인 단위
  • 컴퓨터 시스템 관점 : 정보를 저장하는 컨테이너 / 0과 1의 데이터
    파일이 저장되는 저장 장치 (HDD, SSD, USB, 테이프 저장 장치, 램 디스크)
  • 파일 관리에서 OS의 역할 : 파일 생성, 기록, 읽기의 모든 과정 관리
  • 응용프로그램이 OS 없이 파일을 다루는 것은 불가능 (저장 매체, 빈 공간 등의 관리는 모두 OS가 수행)

파일 입출력 주소

  • 디스크 장치는 디스크 물리 주소 사용
  • OS는 논리 블록 주소 사용
  • 논리 블록 주소(Logical Block Address, LBA) : 저장 매체를 1차원의 연속된 데이터 블록들로 처리 / 저장 매체의 종류에 관계 없음
  • 모든 블록을 0부터 시작하는 블록 번호를 매김
  • HDD의 경우 바깥 실린더에서 안으로, 위 트랙에서 아래로
  • 응용프로그램은 파일 내 바이트 주소 사용 (바이트 주소 : 파일 내 바이트 위치(offset))

파일 주소 변환

  • 사용자나 응용프로그램 : 파일 데이터가 바이트 단위로 연속하여 저장된다고 생각
  • OS : 파일을 블록 크기로 분할, 각 블록을 디스크에 분할 저장 / 블록은 OS가 입출력하는 단위
  • 파일 주소 변환 과정 : 파일 내 바이트 주소 -> 논리 블록 주소 -> 물리 주소
  • OS는 파일 내 바이트 주소를 논리 블록 주소로 변환 / 디스크 장치의 펌웨어가 논리 블록 주소를 물리 주소로 변환

 


파일 시스템 구조

트리 계층 구조로 파일 시스템 구성 : 디렉토리와 파일의 트리 구조

  • 루트 디렉토리 : 계층 구조의 최상위 디렉토리
  • 서브 디렉토리 : 하부 디렉토리들
  • 디렉토리도 하나의 파일 (서브 디렉토리나 파일들의 목록을 저장한 파일)

 디렉토리

  • 논리적 관점 : 여러 파일 혹은 서브 디렉토리를 포함하는 컨테이너 / 파일에 대한 경로 제공
  • 물리적 관점 : 디렉토리는 파일이나 서브 디렉토리 이름, 이들에 관한 위치 정보, 속성 등을 저장하는 특별한 파일

파일 이름과 경로명

  • 단순 파일 이름 : abc.exe, draw.jpg, main.cpp 등
  • 파일 경로명(pathname) : 루트 디렉토리부터 파일에 이르기까지의 계층 경로 (/Programs/Apps/abc.exe)

운영체제에서 파일 시스템을 다루기 위한 메타 정보

  1. 파일 시스템 메타 정보 – 파일 시스템 전체에 관한 정보
  2. 파일 메타 정보 – 파일에 관한 정보

파일 시스템 메타 정보

  • 파일 시스템 전체 크기와 현재 사용 크기
  • 저장 장치에 구축된 파일 시스템의 비어 있는 크기
  • 저장 장치의 빈 블록 리스트 등

파일 시스템 메타 정보가 저장되는 위치

  • 운영체제마다 다름, 운영체제가 쉽게 읽고 쓸 수 있도록 저장 매체의 특별한 위치에 저장

파일 메타 정보

  • 파일 이름
  • 파일 크기
  • 파일 생성 시간
  • 파일 수정 시간
  • 최근 접근 시간
  • 파일을 만든 사용자
  • 파일 속성(접근 권한)
  • 파일이 저장된 위치 등

파일 메타 정보가 저장되는 위치

  • 파일 시스템마다 다름
  • 특별한 위치(예:i-node)에 저장

파일 시스템 종류

  • FAT(File Allocation Table) 파일 시스템 : MS-DOS에서 사용. NTFS의 근간
  • UFS(Unix File System) : Unix에서 사용
  • ext2, ext3, ext4 : 리눅스에서 사용
  • HFS(Hierarchical File System) : Mac 운영체제에서 사용
  • NTFS(New Technology File System) : Windows3.1부터 지금까지 사용. FAT 개선, 리눅스에서도 지원됨

파일 시스템 구현 이슈

  • 디스크에 파일 시스템 포맷 : 디스크 장치에 비어 있는 블록들의 리스트를 어떻게 관리할 것인가?
  • 파일 블록 할당/배치 관리 : 파일 블록들을 디스크의 어느 영역에 분산 배치할 것인가?
  • 파일 블록 위치 관리 : 파일 블록들이 저장된 디스크 내 위치들을 어떻게 관리할 것인가?

FAT 파일 시스템

파일 시스템 구조

  • 부트 섹터(boot sector) : 섹터 1개, 운영체제 초기 코드를 적재하고 실행시키는 코드
  • FAT1, FAT2 : FAT(File Allocation Table)는 파일 블록들의 할당 테이블 / FAT2는 FAT1의 복사본
  • 루트 디렉토리 : 고정 크기이므로 루트 디렉토리에 생성되는 파일이나 서브디렉토리의 개수는 유한
  • 데이터 블록들 : 파일 블록들이 저장되는 곳. 파일은 블록들로 분할되어 분산 저장

디렉토리

  • 파일이나 서브 디렉토리의 목록을 담은 특수 파일 / 파일 이름은 8.3형식 – 이름 최대 8글자, 확장자 3글자
  • 디렉토리 항목 : 32바이트 크기로 한 파일에 대한 메타 정보 저장
  • 루트 디렉토리나 서브 디렉토리의 구조 동일

 

FAT 파일 시스템의 파일 블록 저장

  • 파일 데이터를 블록 단위로 디스크에 분산 저장
  • 파일 메타 데이터는 디렉토리에 저장
  • 저장된 파일 블록들의 위치는 FAT 테이블에 기록

FAT 테이블

파일 시스템에 생성된 모든 파일에 대해,  저장된 파일 블록 번호들이 담겨 있는 테이블

 

FAT 테이블 항목

  • 디스크 블록 번호는 FAT 항목 번호와 동일
  • FAT 항목에는 다음 디스크 블록 번호 저장 (다음 FAT 항목을 가리킴)
  • FAT 항목에 저장된 번호가 -1이면 파일 끝을 나타냄
  • FAT 항목에 저장된 번호가 0이면 빈 블록을 나타냄
  • FAT 항목들은 연결 리스트로 연결됨
  • FAT가 손상되면 심각한 문제 (FAT2 백업으로 해결)

파일이 저장된 모든 블록 알아내기

  1. 먼저 파일이 포함된 디렉토리 항목 검색
  2. 디렉토리 항목에는 해당 파일이 시작되는 FAT 항목 번호가 저장
  3. 디렉토리 항목에는 해당 파일의 크기가 저장되어 있음
  4. 디렉토리 항목(파일 크기와 파일 시작 블록 번호)을 이용하여 FAT 테이블을 연결 리스트 방식으로 검색하여 파일이 저장된 블록들을 알아냄

하나의 파일을 읽는 데 여러 번의 디스크 탐색(seek) 필요

파일이 여러 개의 블록으로 나뉘어 분산 저장되기 때문

 

예시

FAT 한 항목의 크기가 16비트, 블록이 4KB라면, FAT 파일 시스템이 저장할 수 있는 최대 데이터양

접근 가능한 총 블록 수  -> 2^16 - 2개=대략 2^16개 -> 216x4KB = 216x212 바이트  -> 256MB

 

2^16에서 2를 빼는 이유

  • 0번과 1번을 제외
  • 0번은 비어있는지 여부를 나타냄
  • 1번은 혹시 모를 상황을 위해예약해 둔 번호
  • 실제로는 2번부터 사용됨

UNIX 파일 시스템

파일 시스템 구조

  • 부트 블록(boot block) : 부팅 시 메모리에 적재되어 실행되는 코드로, 운영체제를 적재하는 기능
  • 수퍼 블록(super block) : 파일 시스템 메타 정보 저장
  • i-node
     - i-node : 파일 하나당 1개의 i-node 필요, 파일 메타 정보 저장
  • i-node 리스트
     - i-node 리스트 : i-node들의 테이블
     - i-node 리스트의 크기는 포맷 시 결정. 포맷 후 i-node 개수는 고정
     - 파일이 생성될 때마다 빈 i-node 할당, 파일 메타 정보 기록
     - i-node 번호는 0부터 시작. 운영체제마다 첫 i-node 번호가 조금씩 다름
     - 루트 디렉토리의 i-node 번호는 수퍼 블록에 기록. 리눅스의 경우 2, 유닉스의 경우 1
     - 0번 i-node는 오류 처리를 위해 예약
  • 데이터 블록 : 파일과 디렉토리가 저장되는 공간

 

수퍼 블록

  • 파일 시스템의 크기와 상태 정보 (수퍼 블록의 수정 여부 등) - 파일 시스템 내의 자유 블록 수 / 자유 블록들의 리스트
  • 자유 블록 리스트에서 요청 시 할당할 다음 블록 인덱스 / 파일 시스템 내의 i-node 리스트의 크기
  • 파일 시스템 내의 자유 i-node 수 / 파일 시스템 내의 자유 i-node들의 리스트
  • 파일 시스템 내의 자유 i-node 리스트에서 요청 시 할당할 다음 자유 inode 인덱스
  • 파일 시스템의 논리 블록 크기 / 루트 디렉토리의 i-node 번호 / 수퍼 블록이 갱신된 최근 시간

i-node에 저장된 정보

 

  • 디렉토리 항목 (16바이트)

  • 디렉토리 블록과 디렉토리 항목, 그리고 i-node

 

Unix 파일 시스템의 파일 블록 배치

  • Unix 파일 시스템은 파일을 블록 단위로 분산 배치
  • i-node에 15개 인덱스를 두고 파일 블록들의 위치 정보 저장
  • 12개의 직접 인덱스: 12개의 파일 블록 번호, 파일의 앞부분 12개 블록 가리킴
     - 12개의 직접 인덱스로 가리킬 수 있는 파일 크기: 12x4KB = 48KB
  • 1개의 간접 인덱스: 파일 크기가 12개의 블록을 넘어갈 때 사용
     - 인덱스가 가리키는 한 개의 디스크 블록에 파일 블록 번호들이 들어 있음
     - 한 블록이 4KB이고, 블록 번호가 32비트(4바이트)일 때
     - 간접 인덱스로 가리킬 수 있는 파일 블록 수 : 4KB/4B = 1024블록, 파일 크기는 1024 x 4KB = 4MB
  • 1개의 2중 간접 인덱스
     - 2중 간접 인덱스로 가리킬 수 있는 파일 블록 수 : (1024 x 1024)블록
     - 2중 간접 인덱스로 가리킬 수 있는 파일 크기 : 1024 x 1024 x 4KB = 4GB
  • 1개의 3중 간접 인덱스
     - 3중 간접 인덱스로 가리킬 수 있는 파일 블록 수 : (1024 x 1024 x 1024)블록
     - 3중 간접 인덱스로 가리킬 수 있는 파일 크기 : 1024 x 1024 x 1024 x 4KB = 4TB
  • Unix 파일 시스템에서의 파일 최대 크기
     - 48KB + 4MB + 4GB+ 4TB

 

파일의 i-node 찾기

파일을 읽고 쓰기 위해 파일 블록들의 위치 파악 필요
파일 블록들의 위치는 i-node의 15개 인덱스를 통해 알 수 있음
그러므로 파일의 i-node를 먼저 찾아야 함

/usr/source/main.c 파일 찾는 과정

  1. 루트 디렉토리(/)의 i-node 번호 알아내기 : 루트 디렉토리의 i-node 번호는 수퍼 블록에 있음
  2. 루트 디렉토리(/)의 i-node 읽기 : 수퍼 블록에 적힌 루트 디렉토리의 i-node 번호로부터 i-node 읽기
  3. /usr의 i-node 알아내기
  4. /usr 디렉토리를 읽고 /usr/source 파일의 i-node 번호 알아내기
  5. /usr/source 디렉토리 읽고 /usr/source/main.c 파일의 i-node 번호 알아내기
  6. /usr/source/main.c 파일 읽기

파일 입출력 연산

커널은 파일 입출력을 위한 시스템 호출 함수 제공

  • open( ), read( ), write( ), close( ), chmod( ), create( ), mount( ), unmount( ) 등

파일 찾기

  • 파일의 경로명으로부터 파일의 i-node 찾기
  • i-node에 파일 타입, 접근 권한, 파일 데이터가 담겨 있는 블록 번호 등이 저장되어 있기 때문
  • 파일 입출력을 위한 시스템 호출은 커널에 의해 수행

파일 열기 과정

  1. 파일 이름으로 i-node 번호 알아내기 : 파일이 존재하지 않거나 접근 권한이 허용되지 않으면 오류 리턴
  2. 디스크 i-node를 커널 메모리의 i-node 테이블에 적재
  3. 오픈 파일 테이블에 새 항목 만들기 : i-node 주소 기록
  4. 프로세스별 오픈 파일 테이블에 새 항목 만들기 : 프로세스별 오픈 파일 테이블에 항목 할당
     파일 테이블의 주소 기록
  5. open()은 프로세스별 오픈 파일 테이블 항목 번호 리턴
     - 프로세스별 오픈 파일 테이블의 항목 번호(정수) 리턴
     - 응용프로그램이 open()으로부터 리턴 받은 정수는 프로세스별 오픈 파일 테이블 항목 번호임
     (이 정수를 파일 디스크립터(file descriptor)라고 부름) - 응용프로그램은 파일 입출력 시 파일 디스크립터를 사용

파일 열기 후 형성되는 커널 내 구조

 

파일 읽기 과정

  1. read(fd,...)는 fd 번호의 프로세스별 오픈 파일 테이블 참조
  2. 파일 테이블 참조 : R 모드(읽기 허용)가 아닌 경우 오류로 리턴
  3. i-node 참조 : i-node에서 파일 블록들의 리스트 확보
     파일 테이블 항목에 적힌 offset 확인 / offset을 파일 블록 번호로 변환
  4. 해당 블록이 버퍼 캐시에 있는지 확인
     - 해당 블록이 버퍼 캐시에 없으면, 버퍼 캐시를 할당받고 디스크에서 버퍼 캐시로 읽기
     - 할당받은 버퍼 캐시가 dirty이면 버퍼 캐시에 들어 있는 블록을 디스크에 쓰기
  5. 버퍼 캐시로부터 사용자 영역으로 블록 복사

 

파일 쓰기 과정

  1. write(fd,...)는 fd 번호의 프로세스별 파일 테이블을 참조
  2. 파일 테이블 참조 : W 모드(쓰기 허용)가 아니면 오류로 리턴
  3. i-node 참조 : i-node에서 파일 블록들의 리스트 확보
    파일 테이블 항목에 적힌 offset 확인 / offset을 파일 블록 번호로 변환
  4. 해당 블록이 버퍼 캐시에 있는지 확인
     - 해당 블록이 버퍼 캐시에 있으면, 사용자 영역에서 버퍼 캐시에 쓰기
     - 해당 블록이 버퍼 캐시에 없으면, 버퍼 캐시를 할당받고 디스크 블록을 버퍼 캐시로 읽어 들이기
  5. 사용자 공간의 버퍼에서 버퍼 캐시로 쓰기
  6. 추후 버퍼 캐시가 교체되거나 플러시 될 때, 버퍼 캐시의 내용이 저장 장치에 기록

 

파일 닫기 과정

  1. 프로세스의 오픈 파일 테이블 항목에 기록된 내용 지우기
  2. 프로세스의 오픈 파일 테이블 항목을 지우기 전, 파일 테이블의 항목을 찾고 (지우고) 반환하기
  3. 파일 테이블 항목을 반환하기 전, 메모리 i-node의 사용 해제
  4. 버퍼 캐시에 있는 이 파일의 블록들이 수정되었거나 새로 만든 블록인 경우 디스크에 기록

 

 

'Operating System [OS]' 카테고리의 다른 글

[OS] 11.Mass-Storage Systems  (1) 2024.01.03
[OS] 10. File System Implementation  (1) 2024.01.03
[OS] 08. Deadlocks  (1) 2024.01.02
[OS] 07. Synchronization Tools  (1) 2024.01.02
[OS] 06. Threads & Concurrency  (2) 2024.01.02