50_디스크 자유 공간 관리(Free-Space Management)

 

디스크의 공간은 제한되어 있기 때문에 삭제된 파일들일 차지하던 공간을 새로운 파일들을 위하여 다시 재사용하여야 한다. 시스템은 이러한 자유 공간을 리스트로 유지하고 관리한다.

 

디스크는 자유 공간 리스트에 디스크의 모든 자유 블록들을 등록 한다. 새로운 파일을 만들려면 자유 공간 리스트를 탐색하여 새로운 파일을 위한 공간을 할당 받아야 한다. 할당 된 공간은 자유 리스트로부터 삭제 된다.

 

자유 공간 관리를 위해서 꼭 리스트 형태로만 구현될 필요는 없다. 관리를 위해 사용되는 다양한 방법을 알아 보자.

 

[비트 벡터(Bit Vector)]

자유 공간 리스트는 흔히 비트 맵(bit map) 또는 비트 벡터(bit vector)로써 구현 된다. 여기서 각 블록은 1비트로 표현된다. 만약에 블록이 자유로우면 그 비트는 1이 되고 만약 블록이 할당되어 있다면 그 비트는 0이 된다.

 

예를 들어 디스크의 블록들 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 17, 18, 25, 26, 27이 비어 있고 나머지 블록은 할당되어 있다고 가정 할 때 그 자유 공간 비트맵은 다음과 같다.

 

001111001111110001100000011100000…

 

이 방법의 큰 이점은 첫 번째 자유 블록 또는 n개의 연속된 자유 블록들을 찾는 일이 간편하고 효율적이다. Apple Macintosh 운영체제는 디스크 공간 할당을 위해 비트 벡터 기법을 사용한다. Macintosh 운영체제는 비트 맵의 각 워드를 순차적으로 검사하여 0이 아닌 워드를 찾고 그 워드에서 첫 번째 1비트를 찾는다. 블록번호는 다음과 같이 계산 한다.

 

(워드의 비트 수) * (값이 0인 워드 수) + 첫 번째 1비트의 오프셋

 

비트 벡터는 그 전체가 주 메모리 내에 존재하지 않으면 비효율적이 된다.

 

[연결 리스트 (Linked List)]

모든 자유 디스크 블록들을 함께 연결시키는 것인데 첫 번째 자유 블록은 다음 자유 블록을 가리키는 포인터를 가진다. 두 번째 자유 블록은 다음 자유 블록의 포인터를 가지고 계속 그런 방법으로 구현 된다.

 

 

시스템은 첫 번째 자유 블록에 대한 포인터를 디스크의 특정 위치에 두고 메모리에 캐싱하여 사용 한다.

 

자유 리스트를 순회 하려면 매번 디스크를 접근해야 하므로 효율적이지 못하나 자유 리스트는 순회는 자주 발생하지 않는다. 통상 운영체제는 단순히 파일에 할당할 하나의 자유 블록이 필요하며 자유 리스트의 첫 블록을 사용할 수 있다.

 

 

 

[그룹핑(Grouping)]

자유 리스트 방식의 변형으로 첫 번째 자유 블록 내에 n 개의 블록 주소를 저장하는 방법이다. 이 중 처음 n -1 개는 실제로 비어 있는 블록의 주소이다. 그러나 마지막 1개는 자신과 마찬가지로 n-1 개의 빈 블록 주소를 가지고 있는 자유 블록을 가리킨다.

 

이 방법은 연결 리스트 방법과는 달리 다수 개의 자유 블록 주소들을 쉽게 찾을 수 있다는 점이 장점이다.

 

[계수 (Counting)]

프로그램들이 매우 자주(여러 연속된) 블록들을 할당하고(여러 연속된) 블록들을 반환 한다는 사실에 착안한 것으로 특히 연속 할당 알고리즘이나 클러스터링을 통해 공간을 할당 할 경우 유용하다.

 

모든 블록을 일일이 추적할 필요가 없이 연속된 자유 블록의 첫 번째 블록의 주소와 연속된 블록의 계수(count)만 유지하면 보다 효율적이다. 따라서 자유 공간 리스트의 각 항은 하나의 디스크 주소와 블록의 개수로 구성 된다.

 

[참고자료]

Operating System Concepts / 홍릉과학출판사

 

49_파일 할당 방법 (Allocation Method)

 

디스크의 직접 접근 특성이 파일의 구현에 융통성을 허용한다. 거의 모든 경우에 하나의 디스크에 여러 파일이 저장되며 이 파일들을 어떻게 디스크 공간에 배치해야 효율적으로 사용할 수 있을지 고민하게 된다. 디스크 공간을 할당 방법과 특성을 살펴 보자.

 

[연속 할당 (Contiguous Allocation)]

연속 할당은 각 파일이 디스크 내에서 연속적인 공간을 차지하도록 요구 한다. 디스크 주소들은 디스크 상에서 선형 순서를 정의 한다. 이러한 순서를 따를 경우 단지 한 작업(job)이 디스크에 접근 한다고 가정하고 블록 b 다음에 블록 b+1을 접근 한다면 통상 헤드의 이동을 요하지 않는다. 헤드의 이동이 필요한 경우는 다음 섹터의 이동할 경우 이다.

 

한 파일의 연속 할당은 디스크 주소와(블록 단위의) 길이로 정의 된다. 파일의 길이가 n블록이고 블록 b에서 시작한다면 이 파일은 블록 b, b+1, b+2 … b+n-1을 차지한다. 각 파일을 위한 디렉토리 항목은 이 파일의 디스크 내 시작 블록 주소와 이 파일의 크기만 표시하면 된다.

 

 

연속적으로 할당된 파일의 접근은 쉽다. 가장 최근 참조된 주소를 기억하고 있다가 필요할 때 다음 블록을 읽어 들이면 된다. 그러나 연속 할당 기법에서 가장 큰 문제는 새로운 파일을 위한 가용 공간을 찾는 일이다. 자유 공간(free space)을 관리하기 위해 선택된 시스템이 이 작업을 담당한다.

 

연속 할당 문제는 일반적인 동적 공간 할당 문제(dynamic storage allocation problem)의 특정 응용으로 볼 수 있다. 이 문제는 자유 공간 (free hole)의 리스트에서 크기 n의 공간을 할당하는 방법에 관한 것이다. 최초 적합(first fit)과 최적 적합(best fit)이 가용 공간 중에서 할당할 공간을 선택하는 가장 일반적인 전략이다. 연속 할당 방법은 모두 외부 단편화(external fragmentation)문제가 발생 한다.

 

연속 할당의 또 다른 문제점은 파일을 위해서 얼마나 많은 공간을 주어야 할지를 결정하는 것이다. 파일이 생성될 때 필요한 공간의 크기를 알아야만 할당 가능하다. 기존의 파일을 복사하는 경우를 제외하곤 파일의 크기를 예측하는 것은 어렵다.

공간을 너무 작게 예약하여 사용하는 경우 파일이 커졌을 때 앞뒤로 다른 데이터로 인해 확장 할 수가 없다. 한 파일에 대한 공간을 미리 알 수 있다고 해도 선할당은 비효율 적이다. 내부 단편화가로 낭비 될 수 있기 때문이다.

 

이러한 단점을 보완하기 위해 많은 운영체제는 어느 정도의 연속된 공간만 초기에 할당하고 그 양이 충분히 크지 않을 때는 추후 n개의 연속된 공간을 단위(extent)로 할당한다. 파일 블록들의 위치는 위치와 블록 수, 다음 단위의 첫 블록에 대한 포인터로 기록된다.

 

 

[연결 할당 (Linked Allocation)]

연결 할당은 연속 할당의 모든 문제를 해결 한다. 연결 할당에서 각 파일은 디스크 블록의 연결 리스트이다. 파일의 디스크 블록들이 디스크 내에 흩어져 있다. 그리고 디렉토리는 파일의 첫 번째와 마지막 블록에 대한 포인터를 가지고 있다.

 

새 파일을 생성하려면 단순히 디렉토리 내의 새로운 항목(entry)을 만든다. 연결 할당의 경우 각 디렉토리 항목은 파일의 첫 디스크 블록에 대한 포인터를 갖고 있다. 이 포인터는 처음에는 빈 파일을 표시하기 위해 nil(연결의 끝에 해당하는 포인터 값) 값으로 초기화된다. 파일 쓰기가 일어나면 자유 공간 관리 시스템은 자유 블록을 할당받아 쓰기를 실행 한 후 파일의 끝에 연결 한다.

 

 

연결 할당의 경우 외부 단편화가 없고 모든 블록들은 크기가 같기 때문에 자유 공간 리스트의 어떠한 자유 블록들을 이용하여도 무방하다. 파일의 크기가 미리 고정될 필요도 없다. 파일은 계속해서 커질 수 있으며 주기적으로 밀집화 할 필요도 없다.

 

하지만 단점도 존재한다. 가장 중요한 단점은 순차적 접근 파일에만 효과적이다. 포인터를 접근할 때마다 디스크 읽기와 몇 번의 탐색이 필요하므로 직접 접근에는 비효율 적이다. 그리고 포인터를 관리하기 위한 추가 공간이 필요하다. 이 문제를 일반적인 해결방법은 블록들을 클러스터(cluster)로 구성하여 클러스터 단위로 할당하는 것이다.

 

또 다른 문제는 신뢰성의 문제인데 포인터를 이용하여 관리하다 보니 포인터를 잃어버리거나 잘못된 포인터 주소를 가지게 되면 결국 모든 자료를 잃게 된다. 이 경우 이중 연결 리스트를 사용하거나 각 블록마다 파일 이름과 상대 블록 번호 등을 저장하는 방법을 같이 쓸 수도 있겠으나 이 기법들은 더 많은 오버헤드를 유발한다.

 

연결 할당의 변형으로 파일 할당 테이블(file Allocation Table, FAT)을 사용하는 것이다. FAT 테이블은 각 디스크 블록마다 한 개의 항목을 가지고 있고 이 항목은 디스크 블록 번호를 색인으로 찾는다.

 

FAT 할당 기법은 FAT가 캐시되지 않으면 상당한 수의 디스크 찾기를 유발 할 수 있다. FAT를 읽기 위해 디스크 헤드를 반드시 파티션의 시작 부분으로 움직여 찾고자 하는 블록의 주소를 알아내야 하고 이어 그 블록이 있는 곳으로 다시 이동해야 한다. 최악의 경우 각 블록을 찾을 때마다 두 번의 이동이 일어나야 한다. 장점은 디스크헤드가 FAT의 정보를 읽어 임의의 블록의 위치를 알아 낼 수 있기 때문에 임의(random) 접근 시간이 개선된다.

 

 

[색인 할당 (Indexed Allocation)]

연결 할당은 연속 할당의 외부 단편화 문제와 파일 크기 문제를 해결하였지만 FAT가 없으면 직접 접근 방식을 지원 할 수가 없다. 색인 할당은 모든 포인터들을 하나의 장소 즉, 색인 블록으로 관리함으로써 이 문제를 해결 한다.

 

각 파일들은 디스크 블록 주소를 모아 놓은 배열인 색인(index) 블록을 가진다. 색인 블록의 i번째 항목은 파일의 i번째 블록을 가리킨다. 디렉토리는 색인 블록의 주소를 가지고 있다. i번째 블록을 읽기 위해서는 색인 블록 항목에 있는 i번째 항목에서 포인터를 얻어서 그 블록을 읽는다. 이 기법은 페이징과 유사하다.

 

 

색인 할당은 추가 공간 요구가 있을 경우 디스크 상의 임의의 자유 공간을 사용할 수 있기 때문에 외부 단편화 없이 직접 접근을 제공 한다. 그러나 색인 할당은 공간의 낭비가 문제이다. 색인 블록의 포인터 오버헤드는 일반적으로 연결 할당의 포인터 오버헤드 보다 크다. 대부분의 파일들은 작으므로 파일들이 대부분 하나 또는 두 개의 블록만으로 구성되어 있는 것이 일반적이다. 이 경우 단지 한 두개의 포인터만 사용되지만 색인을 위해 한 블록이 할당되어야 한다.

 

여기에서는 색인 블록이 얼마나 커야 하는지가 문제 된다. 각 파일들은 하나의 색인 블록을 가지므로 색인 블록의 크기는 가능한 작은 것이 좋다. 만약 색인 블록이 너무 작다면 큰 파일들에 대해서 충분한 공간을 가질 수가 없을 것이다.

 

이러한 문제점을 보완하는 기법은 다음과 같다.

  • 연결 기법(Linked scheme) : 하나의 색인 블록은 통상 한 디스크 블록이다. 파일의 크기가 크면 여러 개의 색인 블록들을 연결 시킨다.
  • 다단계 색인(Multilevel index) : 첫 번째 수준의 색인 블록은 여러 개의 두 번째 수준 색인 블록들에 대한 포인터들을 가진다. 두 번째 수준의 색인 블록은 실제 자료 블록들을 가리킨다. 이러한 방법은 파일의 크기에 따라 세 번째 또는 네 번째 수준으로까지 계속 된다. 한 블록의 크기가 4096 바이트라면 1024개의 4바이트 포인터를 한 색인 블록에서 저장할 수 있다, 2단계 색인 기법을 쓰면 1048576개의 자료 블록을 가질 수 있으며 이는 파일 크기 4GB까지 저장 가능하다.
  • 결합 기법(Combined scheme) : 디렉토리 내의 색인 블록이 15개의 포인터를 갖는다. 이 포인터들의 처음 12개는 직접 블록(direct block)을 가리킨다. 그 다음 3개의 포인터는 간접 블록(indirect block)의 주소로서 첫 번째 포인터는 단일 간접 블록(single-level indirect block)을 통하여 간접적으로 파일의 블록을 찾을 수 있으며 두 번째 포인터는 이중 간접 블록 (double-level indirect block), 마지막 포인터는 삼중 간접 블록(triple indirect block)을 통하여 간접적으로 파일의 블록을 찾는 형식이다. 이는 다단계 색인 기법을 확장한 것이다.

 

색인 할당 기법은 연결 할당과 동일한 성능 문제를 갖는다. 특히 색인 블록은 메모리에 캐시될 수 있지만 자료 블록은 전체 볼륨 파티션 전체에 널리 퍼져 있을 수 있다.

 

 

[참고자료]

Operating System Concepts / 홍릉과학출판사

 

 

48_디렉토리 구현 (Directory Implementation)

 

디렉토리를 구현하는 공간을 어떻게 할당하고 관리하는가? 파일 시스템의 효율, 성능과 이들 알고리즘 장단점을 알아 보자.

 

[선형 리스트 (Linear List)]

디렉토리를 구현하는 가장 간단한 방법은 파일 이름과 자료 블록에 대한 포인터들의 선형 리스트를 디렉토리에 사용하는 것이다.

 

선형 리스트는 프로그래밍이 쉽지만 실행 시간이 길다. 새로운 파일을 생성하기 위해 먼저 디렉토리를 탐색하여 같은 이름의 존재 여부 확인 후 끝 부분에 새로운 항목을 첨가한다. 파일을 삭제 하려면 디렉토리에서 이름을 찾아 그 파일에 할당된 공간을 방출 한다. 파일 삭제 시간을 줄이기 위해 연결리스트를 사용할 수도 있다.

 

 

디렉토리 항목을 다시 사용하기 위해서는 몇 가지 방법이 있다.

  • 비어있는 항목에 특별한 이름을 부여하거나 각 항목에서 사용되지 않는 비트를 이용하여 비었음이라고 표시
  • 비어 있는 항목을 자유 디렉토리 항목의 리스트에 기록
  • 자유화된 항목에 제일 마지막 항목을 복사해 넣고 디렉토리의 길이를 하나 줄이는 방법

 

선형 리스트로 구성된 가장 큰 단점은 파일을 찾기 위해 선형 탐색을 해야 한다는 것이다. 이는 빈번한 사용으로 인하여 사용자가 체감으로 느낄 정도로 오버헤드가 많다. 최근 많은 운영체제들은 가장 최근에 사용된 디렉토리 정보를 저장하기 위해 소프트웨어 캐시를 구현하여 사용하여 매번 디스크로부터 읽어오는 오버헤드를 감소 시킨다.

 

정렬된 리스트는 이진 탐색을 가능하게 하며 평균 탐색 시간을 줄인다. 그렇지만 리스트가 정렬 상태를 유지하려면 파일을 생성하거나 삭제하는 일이 복잡해 질 수 있다. 정렬을 위해 많은 데이터가 이동할 수도 있기 때문이다. 하지만 정렬된 리스트는 별도의 정렬 작업 없이 정렬된 리스트를 생산할 수 있다.

 

 

[해시 테이블 (Hash Table)]

디렉토리 구조로 해싱 테이블을 사용하기도 한다. 선형 리스트에 디렉토리 항목들이 저장되기는 하지만 해싱(hashing)도 함께 사용한다. 파일 이름을 제시하면 해시로부터 값을 얻어서 그것을 포인터로 활용하여 리스트에 직접 접근할 수 있다. 따라서 디렉토리 탐색 시간을 상당히 개선할 수 있다.

 

 

충돌(collision)에 대한 부분만 보완되면 삽입 삭제도 쉽게 할 수 있다. 해싱 테이블의 가장 큰 단점은 해시 테이블이 고정된 크기를 갖는다는 것이다. 이는 해시 테이블의 크기에 따라 해시 기능도 제한을 받는다.

 

예를 들어 64개의 항목을 갖는 선형 탐사(probing) 해시 테이블을 만든다고 하였을 때 나중에 65번째 파일을 생성하려면 디렉토리 해시 테이블을 키워야 한다. 그 경우 파일 이름을 0~127까지 매핑하는 새로운 해시 함수를 필요로 한다. 이때 기존 디렉토리를 새로운 해시 값에 맞게 다시 매핑 해야 하는 문제가 발생한다.

 

해시테이블의 제한을 개선하기 위하여 체인 오버플로우 해시 함수 테이블을 사용할 수 있다. 각 해시 항목은 하나의 값이 아니라 연결 리스트가 되고 새로운 항목을 연결 리스트에 추가함으로써 충돌을 해결한다. 이제 이름을 찾으려면 충돌하는 테이블 항들의 연결 리스트를 살펴보아야 하기 때문에 상대적으로 늦어지겠지만 이러한 연산은 전체 디렉토리를 선형으로 찾는 것보다 훨씬 빠르다.

 

[참고자료]

Operating System Concepts / 홍릉과학출판사

 

 

 

47_파일 시스템 구현 (File System Implementation)

 

운영체제는 파일에 접근을 요구하는 프로세스를 위해 open(), close() 시스템 호출을 구현하며 디스크와 메모리 상에 존재하는 여러 구조가 파일 시스템을 구현하는데 사용된다.

디스크상의 구조는 다음과 같다.

  • 부트 제어 블록(boot control block) : 볼륨 당 하나씩 존재하며 시스템이 그 파티션으로부터 운영체제를 부트 시키는 데 필요한 정보를 가지고 있다. 디스크가 운영체제를 가지고 있지 않다면 부트 제어 블록은 비어 있다. 부트 제어 블록은 일반적으로 한 파티션의 첫 번째 블록이다. UFS에서는 부트 블록, NTFS에서는 파티션 부트 섹터라 불린다.
  • 볼륨 제어 블록 (volume control block) : 볼륨 당 존재하여 볼륨(파티션)의 블록의 수, 블록의 크기, 자유 블록의 수와 포인터, 자유 FCB와 포인터 같은 파티션 정보를 포함 한다. UFS에서는 수퍼블록, NTFS에서는 마스터 파일 테이블에 정보가 저장된다.
  • 디렉토리 구조는 파일을 조직화 하는데 사용된다. UFS에서는 디렉토리 구조에 파일 이름 및 해당 inode 번호가 저장된다. NTFS에서는 마스터 파일 테이블에 이러한 정보가 저장된다.
  • FCB는 파일 허가, 소유, 크기, 자료 블록의 위치 등을 포함하여 자세한 파일 정보를 가지고 있다. UFS에서 이는 inode라 불린다. NTFS에서 이 정보는 실제적으로 마스터 파일 테이블 안에 저장되며 파일마다 한 행을 가지고 관계 데이터베이스 구조를 사용한다.

 

메모리 내의 정보는 파일 시스템 관리와 캐싱을 통한 성능 향상을 위해 사용된다.

  • 메모리 내 파티션 테이블은 각 장착된 파티션 정보를 포함한다.
  • 메모리 내 디렉토리 구조는 최근 접근된 디렉토리 정보를 가진다.(파티션이 장착된 디렉토리의 경우는 파티션 테이블에 대한 포인터를 포함할 수 있다.)
  • 범 시스템 오픈 파일 테이블(system wide open file table)은 다른 정보와 더불어 열려진 각 파일의 FCB의 복사본을 가진다.
  • 프로세스 별 오픈 파일 테이블(per-process open file table)은 다른 정보 뿐만 아니라 범 시스템 오픈 파일 테이블 내의 해당 항목에 대한 포인터를 포함한다.

 

새로운 파일을 생성하기 위해서는 논리 파일 시스템을 호출 한다. 논리 파일 시스템은 디렉토리 구조의 포맷을 알고 있으며 일단 새로운 파일이 생성되면 입/출력을 위해 사용된다.

 

파일을 사용하려면 파일이 반드시 열려야 하며 open() 호출은 파일 시스템에 파일 이름을 넘겨준다. open() 시스템 호출은 먼저 그 파일이 다른 프로세스에 사용중인지 범 시스템 오픈 파일 테이블을 찾으며 이 알고리즘은 오버헤드를 줄이는데 도움이 된다. 또한 디렉토리 연산의 속도를 향상 시키기 위해 통상 디렉토리 구조의 일부는 메모리에 캐싱한다.

 

파일이 발견되면 FCB가 메모리 내의 범 시스템 오픈 파일 테이블에 복사된다. 이 테이블은 FCB와 프로세스의 수도 저장한다. 범 시스템 오픈 파일 테이블 안에는 테이블의 항목에 대한 포인터와 몇 개의 다른 필드를 갖는 프로세스별 항목이 만들어 진다. 이 필드들은 파일 안의 현재 위치(다음 read() 또는 write() 연산이 시작되는 위치)를 가리키는 포인터와 파일이 열린 접근 모드 등을 포함 한다.

 

Open() 호출은 프로세스 별 파일 시스템 테이블 내의 해당 항목에 대한 포인터를 찾아 돌려준다. 그 후 모든 파일 연산은 이 포인터를 통해 실행 된다. 일단 해당 FCB를 디스크에서 찾으면 시스템은 파일 이름을 더 이상 사용하지 않기 때문에 파일 이름은 오픈 파일 테이블의 한 부분이 아니다. 그러나 같은 파일에 대한 차후 open() 연산을 빠르게 하기 위해 캐시될 수 있다. 유닉스에서는 파일 기술자라 부르고 Windows에서는 파일 핸들이라 부른다.

 

파일을 닫지 않는 이상 모든 파일 연산은 오픈 파일 테이블에서 이루어진다. 프로세스가 파일을 닫을 때 프로세스 별 테이블 항목이 삭제되며 범 시스템 항목의 오픈 계수는 감소 된다. 사용자가 열었던 모든 파일을 닫으면 갱신된 메타데이터 정보가 디스크 기반 디렉토리 구조에 복사되며 범 시스템 오픈 파일 테이블에서 그 항목이 삭제 된다.

 

이런 구조들은 캐싱 기법을 사용함으로써 실제 자료 블록을 제외한 오픈 파일에 대한 모든 정보는 메모리 내에 존재 한다. 디스크 입/출력 작업을 줄일 수 있다.

 

 

사용자는 지역 디스크의 여러 파일 시스템이나 네트워크를 통하여 이용 가능한 파일 시스템에 접근할 수 있다. 구현 세부 사항으로부터 기본 시스템 호출 기능을 격리시키기 위해 자료 구조와 프로시저가 사용 된다. 일반적으로 파일 시스템 인터페이스, VFS 인터페이스, 지역 파일 시스템 으로 세 가지 주요한 계층으로 구성되어 있다.

 

파일 시스템 인터페이스는 open(), read(), write(), close() 호출과 파일 기술자에 기반을 둔 인터페이스이다.

가상 파일 시스템(VFS, Virtual File System)은 VFS 인터페이스를 명확하게 정의함으로써 파일 시스템의 일반적 연산을 구현과 분리 시킨다. VFS 인터페이스에 대한 다른 구현들이 같은 기계 상에 공존할 수 있으므로 다른 형태의 파일 시스템을 지역적으로 장착함으로써 투명한 접근을 가능하게 한다. 또한 전체 네트워크에 걸쳐 파일을 유일하게 표시할 수 있는 기법을 제공한다. vnode라는 전체 네트워크에서 파일을 유일하게 만들어주는 수치 지정자(designator)를 포함하고고 있다. VFS는 특정 파일 시스템 고유의 연산을 활성화시킴으로써 파일 시스템 유형에 따른 지역 요청들을 처리하며 원격 요청에 대해서는 NFS 프로토콜 프로시저를 호출 한다. 파일 핸들은 연관된 vnode들로부터 구성되며 이들 프로시저에 매개변수로 전달 된다.

 

 

 

[참고자료]

Operating System Concepts / 홍릉과학출판사

 

 

 

+ Recent posts