파일 시스템의 개념
파일을 보관/관리하는 파일 관리자를 두어 저장장치의 전체 관리를 맡기는 것
파일 관리자는 파일 테이블을 사용하여 파일 관리
사용자가 특정 파일에 접근하려면 파일 관리자로부터 파일에 접근할 수 있는 권한(키)를 획득해야함.
파일 접근 권한을 파일 디스크립터 라고 함

파일 시스템의 기능

블록과 파일 테이블
블록 - 저장창치에서 사용하는 가장 작은 단위, 한 블록에 주소 하나 할당
파일 테이블에는 각 파일이 어떤 블록에 저장되어 있는지에 대한 정보 저장

저장장치의 그림은 실제 디스크 블록 구조를 보여주는것으로 각 칸은 하나의 블록을 나타낸다
여기서 잠깐
이 저장장치는 RAM(주기억장치)가 아니라 디스크임을 기억하자
실행 중인 프로그램의 메모리와는 다른 계층임을 기억합시다
파일 종류와 확장자
실행 파일 - 운영체제가 메모리로 가져와 CPU를 이용하여 작업하는 파일
데이터 파일 - 실행 파일이 작업하는데 필요한 데이터를 모아놓은 파일

위의 표를 보면 어떤 확장자인지를 통해 어떤 파일이 실행 파일인지 어떤 파일이 데이터 파일인지 구분할 수 있다는 것을 보여준다
실행,소스코드,라이브러리,배치 는 실행파일이며
그 아래부터는 데이터파일임을 확인 할 수 있다.
구분 예시 파일명 용도
| 실행 파일 | calc.exe, run.sh | CPU가 직접 실행 |
| 데이터 파일 | report.pdf, image.jpg | 프로그램이 불러서 사용함 |
실행파일이 PCB를 가지고 수행되면 프로세스가 되고 그 이후 위의 데이터 파일을 사용한다라는 일련의 과정을 기억하자
파일 연결 프로그램
우리가 테이터 파일을 더블클릭 하면 해당 파일을 사용하는 응용 프로그램이 실행되는것 이것을 연결 프로그램이라고 한다


파일작업

위에서 설명했듯이 파일들은 디스크상에 저장되어있다
그렇다면 이 파일작업은 CPU가 직접 디스크를 다루는것이 아니라 OS의 파일 시스템이 대신 수행해준다
즉 프로세스가 파일 작업을 요청하면 운영체제가 디스크I/O를 관리하면서 대신 수행하고 CPU는 명령을 내려주기만 한다.
조금 더 자세히 살펴보자
- 사용자 프로그램이 파일 작업 요청 → 시스템 콜 호출(인터페이스 함수 호출)
- 예: open("data.txt") 라는 코드가 실행되면,
- 사용자 공간 → 커널 공간으로 전환됨 (시스템 콜 발생)
- 운영체제의 파일 시스템이 개입
- 운영체제는 해당 파일이 디스크에 있는지 확인하고,
- 디스크 컨트롤러에 명령을 내려서 해당 작업을 수행하게 함
- 디스크 I/O는 하드웨어가 처리
- 디스크 컨트롤러가 실제로 디스크에 접근해 데이터를 읽거나 씀
- 읽은 데이터는 메모리로 복사되고, CPU는 그 메모리를 사용함
- 예시로 보자: read("text.txt")
- 사용자 프로세스가 read() 호출 (시스템콜)
- 운영체제는 파일 시스템을 통해 "text.txt"가 저장된 블록을 디스크에서 찾음
- 디스크 컨트롤러가 해당 블록을 메모리로 로딩
- CPU는 메모리에 올라온 데이터를 읽어서 처리
파일 헤더
파일헤더에는 파일의 버전 번호, 크기, 특수 정보 등 응용 프로그램이 필요한 정보가 담겨있다
모든 파일에 공통으로 적용되는 정보인 파일 속성은 파일 테이블에 위치, 해당 파일에 필요한 정보를 가지고 있는 파일 헤더는 파일의 맨 앞에 위치한다.

운영체제의 파일 테이블은 OS가 관리하는 메타데이터이고,
파일 헤더는 파일 내부에 존재하며, 응용 프로그램이 해석하는 포맷 정보다.
둘은 서로 다른 위치, 다른 목적, 다른 주체에 의해 사용되며,
파일 헤더의 내용이 파일 테이블로 복사되거나 연결되지는 않는다.
즉 운영체제는 파일 테이블을 참고해서 디스크에서 파일 A가 있는 블록찾고 필요한 데이터를 메모리에 로딩한다
여기서 우리가 오해하면 안되는것이 헤더는 운영체제가 아니라 응용프로그램이 파일을 해석할때 사용된다!
즉, 운영체제는 파일 A의 위치를 알고 가져오지만,
그 안의 내용을 어떻게 해석할지는 헤더를 보고 응용 프로그램이 결정하는것
저장장치 관리기법
1. 파티션
저장장치를 2개 이상의 묶음으로 나누는 것으로 디스크를 논리적으로 분할
대용량 저장장치를 하나로 사용하기보다 여러 개로 나누면 관리하기 편리

그렇다면 위처럼 파티션을 나눴다면 각각의 차이는 무엇인가??
제일 왼쪽 그림은 디스크마다 파티션을 하나씩 둔 전통적인 방식이다
각각 독립된 저장장치와 파일 시스템을 가진다
장치별 관리가 쉽지만 공간재분배가 유연하지 않다
중간그림은 흔히 우리가 알수있는 로컬디스크C,D의 구조이다
각 파티션은 자체 파일 테이블을 가지며 서로 독립된 파일 시스템이다 디스크 하나를 논리적으로 나눠쓸수있지만
하나의 디스크 고장시 A, B 둘다 영향을 받을 수 있다
오른쪽 그림은 여러디스크를 하나의 파티션으로 논리적으로 묶은 구조이다
내부적으로 운영체제가 논리적으로 묶어서 하나의 큰 저장소 처럼 사용한다
RAID / LVM 등의 기술에서 사용한다
저장공간 확장성, 유연한관리등의 장점이 있지만 구성이 복잡하고 일부 디스크문제시 전체 영향 가능성이 있다.
2. 포맷
포맷은 저장장치의 파일 시스템을 초기화 하는 작업이다.
파일을 삭제하는것과는 다른의미로 파일 테이블을 삭제한다
파일 테이블이 없는 저장장치를 포맷하면 파일 테이블이 새로 탑재, 있는 저장장치를 포맷하면 파일 테이블이 초기화된다
빠른포맷: 데이터는그대로둔채파일테이블만초기화
느린 포맷: 파일테이블을초기화할뿐아니라블록의모든데이터를0으로만 들어포맷시간이많이걸림
3. 조각 모음
파일 저장과 지우기를 반복하면 중간중간 빈 공간이 생김 이를 조각화 또는 단편화라고 부른다
조각이 많이 생기면 저장장치의 성능저하의 원인이 되기에 주기적으로 조각 모음이 필요하다
파일구조
순차파일구조
파일 내용이 하나의 긴 줄로 늘어선 형태
장점
• 모든데이터가 순서대로 기록되기때 문에 저장공간에 낭비되는부분이 없음
• 구조가 단순하여 테이프는 물론 플로피디스크나 메모리를 이용한 저장장치에도 적용가능
• 순서대로 데이터를 읽거나 저장할때 매우 빠르게처리됨
단점
• 파일에 새로운 데이터를 삽입하거나 삭제할때 시간이 많이걸림
• 특정 데이터로이동할때 직접 접근이 어려워 앞에서부터 순서대로 움직여야하므로 데이터검색에 적당하지않음

위 그림은 순차 파일 구조에서 read(), write(), lseek() 함수 호출 시
파일 포인터가 어떻게 이동하는지를 보여준다.
순차 접근은 연속된 읽기/쓰기에는 효율적이지만,
특정 위치로 점프하려는 경우(lseek)는 비효율적이라는 단점을 시각적으로 설명한다.
직접 파일 구조
저장하려는 데이터의 특정 값에 어떤 관계를 정의하여 물리적인 주소로 바로 변환하는 파일 구조 (주소가 필요없음)

장점
- 빠른 접근 속도:
→ 원하는 데이터를 주소 계산을 통해 바로 접근 (lseek처럼 순서대로 찾을 필요 없음) - 검색 효율적:
→ 특정 값을 기준으로 바로 찾아가기 때문에 데이터 검색에 적합
단점 - 공간 낭비 가능성:
→ 주소 계산이 충돌을 일으키면 빈 공간이 생기거나 오버플로우 처리 필요 - 구조 복잡:
→ 주소 계산 공식(해시 함수 등)이 필요하고, 충돌 처리 로직이 있어 구현이 복잡함 - 삽입/삭제 어려움:
→ 충돌 발생 시 삽입/삭제 처리 복잡
인덱스 순차 액세스
순차 파일 구조에 인덱스 테이블을 추가하여 순차 접근과 직접 접근이 가능 B-tree 기반 파일구조

디렉터리
관련 있는 파일을 하나로 모아놓은 곳
1개 이상의 자식 디렉터리와 1개 이상의 파일을 가질 수 있음
하나의 디렉터리에는 여러개의 파일과 자식 디렉터리가 존재


디렉터리 파일
디렉터리도 파일이다
일반 파일에는 데이터가 담기고 디렉터리에는 파일 정보가 담긴다
디렉터리 헤더에는 디렉터리 이름, 만든 시간, 접근 권한 등의 정보가 기록된다

우리가 윈도우에서 폴더를 열고 파일을 더블클릭하거나,
터미널에서 cd로 이동하고 cat으로 파일을 보는 모든 행동은,
운영체제 내부에서는 디렉터리 파일에서 이름 → inode(헤더) 번호 → 데이터 블록의 순서로 해석되고 처리되는 것이다.
자 그러면 inode라는건 또 무엇이냐?
inode는 리눅스 파일 시스템에서 특정 파일이나 디렉토리에 대한 정보를 저장하는 데이터 구조이다
간단히 말해 파일에 대한 식별 정보를 담고 있는것
Disk는 한정된 수의 inode를 가지는데 많은 양의 작은 파일들이 생성되면 inode가 소진되어 실제로 디스크에는 여유공간이 있지만 새로운 파일을 생성하지 못하게 된다 그렇기에 inode의 사용량도 주기적으로 체크해야함


File Descriptor (FD, 파일 디스크립터)
- 프로세스가 파일을 open() 했을 때 받는 정수 번호
- 프로세스가 사용하는 파일 핸들
- 예:
- 0: 표준 입력 (stdin)
- 1: 표준 출력 (stdout)
- 2: 표준 에러 (stderr)
- 3: 일반 파일 (file.txt 등)
File Table (파일 테이블, 운영체제 커널 내부)
- OS가 관리하는 전체 열린 파일 정보 목록
- 각 항목은 다음을 포함함:
- 접근 모드 (읽기, 쓰기, 읽기-쓰기 등)
- 현재 읽기/쓰기 위치 (파일 오프셋)
- inode 번호 (→ 실제 파일 위치)
- 참조 횟수 (여러 FD가 같은 파일을 공유 가능)
Inode Table (아이노드 테이블)
- 실제 파일의 메타데이터와 데이터 위치 정보 저장
- 예:
- 파일 크기, 생성/수정 시간, 권한 정보
- 디스크의 데이터 블록 위치 등
- 파일 이름은 없음. 이름은 디렉터리에서 inode 번호로 매핑될 뿐.
프로세스는 시스템콜로 파일 디스크립터를 요청하고,
운영체제는 디렉터리 → inode → file table을 거쳐 파일의 실제 데이터를 디스크에서 읽어 메모리에 올린다.
컴퓨터를 사용하는 사람은 파일 이름으로만 인식하지만, 실제 컴퓨터는 파일이름:inode로 파일과 inode 번호를 매칭시켜 인식한다
1. 파일이 생성되자마자 inode 번호가 부여
2. inode 블록이 생성되어 상세 정보Meta-data가 기입
3. 이를 기반으로 파일을 접근
경로
파일이 전체 디렉터리 중 어디에 있는지를 나타내는 정보
한 디렉터리에는 같은 이름을 가진 파일이 존재할 수 없지만 서로 다른 디렉터리에는 같은 이름의 파일이 존재할 수있다

1단계 디렉터리 구조
루트 디렉터리에 새로운 디렉터리를 만들 수 있지만 디렉터리안에 자식 디렉터리를 만들수 없는 구조

다단계 디렉터리 구조
루트 디렉터리를 시작점으로여러 단계의 디렉터리가 가지처럼 뻗음 트리 디렉터리 구조라고도 함

바로가기 링크를 포함한 디렉터리 구조
기본적으로는 트리 구조이나 바로가기 링크로 인하여 현재의 디렉터리 구조는 그래프 구조로 바뀜

무슨말이냐면 현대 운영체제의 디렉터리 구조는 논리적으로는 트리(Tree) 구조지만,
실제로는 "그래프(Graph)" 구조로 동작한다.
마운트
유닉스에서 여러 개의 파티션을 통합하는 명령어

여러 개의 파티션을 각각 디렉터리에 mount 명령어로 붙여서,
마치 하나의 통합된 파일 시스템처럼 사용할 수 있게 만든다.

할당방식
연속 할당과 불연속 할당
연속 할당 방식
- 파일을 구성하는 데이터를 디스크상에 연속 배열하는 간단한 방식
- 파일을 저장하거나 삭제하면 빈 공간이 생기는데 디스크에 남은 공간 중 파일 크기와 맞는 연속 공간이 없으면 연속 할당이 불간으하므로 실제로는 사용되지 않음
불연속 할당
비어있는 블록에 데이터를 분산 저장하고 이에 관한 정보를 파일 시스템이 관리하는 방식
연결 리스트를 이용한 연결 할당과 인덱스를 이용한 인덱스 할당이 대표적
그러면 불연속 할당의 종류인 연결할당과 인덱스 할당을 알아보자
연결할당
파일에 속한 데이터를 연결 리스트로 관리하는 방식
파일 테이블에는 시작 블록에 대한 정보만 저장 나머지 데이터는 시작 블록 부터 연결하여 저장
체인으로 연결한 것처럼 보여서 체인 할당이라고도함
연결할당 방식의 ex) 윈도우의 FAT

FAT 방식

파일의 저장 위치를 추적하기 위한 테이블 방식의 파일 시스템
각 파일은 여러 조각(블록)에 나뉘어 저장되고, FAT는 이 조각들이 어디에 있는지를 연결 리스트처럼 관리
왼쪽: 파일 제어 테이블
- 각 파일(A, B, C, D)의 시작 블록 위치를 기록함.
- 예: 파일 B는 위치 2부터 시작
오른쪽: 파일 할당 테이블 (FAT)
- 인덱스는 디스크 블록 번호를 의미
- 각 칸의 값은 다음 블록 번호를 의미함
- null은 해당 블록이 파일의 마지막 블록이라는 뜻
예: 파일 B가 저장된 순서
- 파일 B는 2번 블록에서 시작
- FAT[2] → 4번 블록
- FAT[4] → 12번 블록
- FAT[12] → 8번 블록
- FAT[8] → null
→ 따라서: 2 → 4 → 12 → 8 순으로 디스크에 저장됨
FAT의 장점
- 구현이 간단하고, 연속된 공간이 없어도 파일 저장 가능 (단편화 회피)
- 파일 조각 정보를 테이블만 따라가면 됨
FAT의 단점
- 큰 테이블이 필요함 (파일이 많을수록 FAT도 커짐)
- 연속 접근이 느림 (중간 블록 접근 시 앞에서부터 따라가야 함)
- 고장이 나면 FAT 자체가 손상되어 전체 파일 정보 유실 위험
파일 제어 테이블이란?
파일 제어 테이블이란, 운영체제가 디스크 상의 파일을 관리하기 위해 유지하는 메타데이터 구조이다.
- 파일의 논리적 정보와 물리적 위치를 기록
- 파일 할당 방식(FAT, 인덱스 할당 등)과 연동되어 사용됨
- 파일이 어떤 블록에 저장되어 있는지 추적 가능하게 해줌
- 파일이 생성되면 FCB가 생성되고, 메타데이터가 기록됨
- 사용자가 open(), read() 등을 호출하면 운영체제는 FCB를 참고하여 디스크 접근 수행
구분 파일 제어 테이블 (FCB) 파일 테이블 (File Table) inode
| 소유 주체 | 운영체제 | 운영체제 (커널 영역) | 디스크 내부 (파일시스템) |
| 위치 | 디스크 (파일시스템 내) | 메모리 (RAM, 프로세스 실행 중) | 디스크 (유닉스계) |
| 생성 시점 | 파일 생성 시 | 파일 open 시 | 파일 생성 시 |
| 목적 | 파일 자체 메타데이터 관리 | 열린 파일에 대한 상태 추적 | 파일의 물리 위치 및 메타데이터 추적 |
| 포함 정보 | 파일 이름, 크기, 시작 블록 등 | 파일 오프셋, 접근 모드, 참조 수 등 | 파일 크기, 권한, 블록 위치 등 |
| 대표 시스템 | FAT, 인덱스 할당 계열 | 유닉스, 리눅스 등 전반 | 유닉스, 리눅스 |
인덱스 할당
테이블의 블록 포인터가 데이터 블록을 연결하는 것이 아니라 데이터의 인덱스를 담고있는 인덱스 블록을 연결(인덱스 블록을 따로 생성해서 가지고 있음)
인덱스 블록은 실제 데이터의 위치에 관한 정보를 순서대로 보관
테이블이 꽉 차서 더 이상 데이터를 연결할 수 없을 때는 인덱스 블록을 연결하는
간접 인덱스 블록으로 테이블을 무한 확장 ( 데이터 손실이 발생해도 뒤에 있는 데이터로 복구 가능)

1번 블록은 인덱스 블록 그 자체 애초에 인덱스 블록으로 사용하려고 만듬
- 0 → 첫 번째 데이터는 0번 블록에 있음
- 2 → 두 번째 데이터는 2번 블록
- 4 → 세 번째 데이터는 4번 블록
- -1 → 끝 표시
어떤 파일이 저장됨 → 총 3블록 필요함
- OS는 블록 0, 2, 4를 사용하고
- 블록 1에 인덱스 블록을 만들어 [0, 2, 4] 정보를 저장
파일 제어 테이블은 **블록 1(인덱스 블록)**만 기억하면 됨
데이터 읽을 때:
- FCT → 블록 1(인덱스 블록) 접근
- 인덱스 블록 안의 번호 읽기
- 순서대로 0, 2, 4번 블록에 접근해서 내용 읽기
장점
- 직접 접근 가능 → 데이터 순서를 알고 있으면 곧장 해당 블록으로 점프 가능
- 단편화 적음 → 연속된 공간이 없어도 됨
- FAT보다 깔끔 → 중간 블록 따라가지 않아도 됨
단점
- 인덱스 블록 크기가 작으면, 저장할 수 있는 블록 수가 제한됨
- 그래서 대형 파일을 저장하려면 간접 인덱스 블록(다른 인덱스 블록을 가리키는 인덱스)이 필요
inode 인덱스 할당 방식의 예

이 그림은 유닉스 계열 파일 시스템의 inode 구조를 나타낸 것으로,
기본 블록 포인터(직접 포인터)로 데이터를 저장하다가 부족해지면 단일/이중/삼중 간접 포인터를 통해 인덱스 블록을 연결해 더 많은 데이터를 저장하는 구조를 보여준다.
즉, 작은 파일은 직접 포인터로 처리하고, 파일이 커질수록 계층적인 인덱스를 활용해 확장한다.
빈 공간 리스트
파일 시스템은 디스크의 내부 단편화를 줄이고 빈 공간을 효율적으로 관리하기 위해 빈 블록의 정보만 모아놓은 빈 공간 리스트를 유지
파일시스템에서는 파일 테이블의 헤더를 삭제하고 사용했던 블록을 빈 공간 리스트에 등록하는 것을 파일 삭제로 간주
어떤 데이터를 지우고 새로운 데티어를 디스크에 넣을 때 방금 지워진 블록에 할당하는 것이 아니라 리스트에 있던 블록 중 맨 앞에 있는 블록에 할당

간단하게 생각해서 빈공간 리스트에 연결하는것이 삭제이다
유닉스 파일 시스템의 접근 패턴
접근 패턴의 맨 앞자리는 파일의 종류
나머지 아홉 자리는 rwx라는 세 덩어리로 구성
1 - 파일의 소유자 권한 부여
2 - 소유자가 속한 그룹 권한 부여
3 - 제삼자의 권한 부여

chmod
유닉스에서 접근 패턴을 변경할 때 사용하는 명령어
접근 패턴에 숫자를 부여하여 변경
- read는 4 write는 2 excute는 1
-chmod 명령을 이용하여 살리고 싶은 숫자를 모두 더하면 됨

'CS > 운영체제' 카테고리의 다른 글
| 8. 입출력 시스템과 저장장 (7) | 2025.08.08 |
|---|---|
| 6. 가상메모리 관리 (0) | 2025.08.08 |
| 5. 페이징 (3) | 2025.08.03 |
| 7. 세그먼테이션 (3) | 2025.07.25 |
| 4. 동기화 및 병행성 제어 (6) | 2025.07.16 |