Download presentation
Presentation is loading. Please wait.
1
15. 정규 파일 접근 네트워크 실험실 박사 1학기 김성준
2
목차 정규 파일 읽기 정규 파일 쓰기 메모리 매핑
3
정규 파일 접근 정규 파일(Regular File)? 읽기/쓰기->파일 객체의 read와 write 메소드 호출
리눅스는 모든 장치, 소켓, 디렉토리등을 파일로 취급(특수 파일) 일반적인 파일 (/etc/passwd..) 읽기/쓰기->파일 객체의 read와 write 메소드 호출 파일 시스템(ext2,nfs등)에 의존적 디스크 기반-> 데이터를 포함하는 물리적 블록 위치를 찾아서 데이터 전송을 시작하도록 장치 드라이버 활성화
4
i. 정규 파일 읽기
5
정규 파일 읽기와 쓰기 커널 주소 공간 버퍼(페이지) Data 1 2 사용자 주소 공간 버퍼 Data Disk
6
정규 파일 읽기와 쓰기 정규 파일 읽기 페이지 기반 -> 페이지 단위로 작업이 수행됨 전체 페이지 데이터를 한번에 전송
1. 페이지 안에 데이터가 없다면 2. 새로운 페이지 프레임 생성 3. 새로운 페이지에 데이터를 읽어 들임 4. 페이지 캐시에 추가 5. 프로세스 주소 공간(사용자 주소공간)으로 복사 커널 주소 공간
7
정규 파일 읽기와 쓰기 정규 파일에서 읽기 read 메소드 ->generic_file_read()-filemap.c
매개변수 file : 파일 객체 주소 buf : 파일에서 읽은 문자를 저장하기 위한 사용자 모드 메모리 영역의 선형 주소 count : 읽고자 하는 문자 수 ppos : 읽기를 시작할 파일 오프셋을 포함하는 변수를 가리키는 포인터
8
i_atime<-update_atime()
정규 파일 읽기와 쓰기 do_generic_file_read()-기본 흐름 out 미리 읽기 윈도우 ppos의 offset fd.f_reada를 1로 설정 in 미리읽기 i_atime<-update_atime() i_node를 더티로 표시 count만큼 읽음 pos<-ppos n pos < 파일크기 반복 1 f_reada : 미리 읽기 플래그 i_atime : 최종 파일 접근 시간 y ppos<-pos 다음 offset 결정
9
generic_file_readahead()
정규 파일 읽기와 쓰기 반복 1 : 요청한 개수의 문자를 포함하는 모든 페이지를 읽는다. n findpage() new page frame 할당 y generic_readpage() generic_file_readahead() findpage() : 요청한 페이지가 이미 페이지 캐시 안에 존재하는지 검사 generic_file_readpage() : 새로 생성한 페이지를 데이터로 채워주는 함수 페이지 락? y wait_on_page n 페이지-> 주소 공간 복사
10
정규 파일 읽기와 쓰기 generic_readpage() 페이지 캐시를 추가하고 이를 채우기 위한 i-노드 객체의 메소드
PG_locked = 1 다른 커널 제어 경로가 페이지 내용에 접근 못하도록 함 PG_free_after = 1 페이지 입출력 연산 후 페이지 디스크립터의 카운터 감소 블록 수 계산 페이지를 채우기 위한 블록 수 계산 bmap() 대응하는 논리 블록 번호를 얻기 위해서 각 블록 번호에 대해 bmap() 호출 PG_locked PG_free_after : 연산후에 페이지 디스크립터의 사용 카운터를 감소시키도록 하는 Flag brw_page() 페이지의 블록 전송을 위해 brw_page() 호출
11
정규 파일 읽기와 쓰기 미리 읽기 알고리즘 연속된 파일에 대응하는 페이지 집합을 미리 읽기 윈도우로 인식
프로세스가 요청한 다음 읽기 연산이 이 페이지 집합(미리 읽기 윈도우) 안에 있으면, 순차적(sequential)으로 판단 미리 읽기 윈도우 프로세스가 요청한 페이지나 커널이 미리 읽은 페이지 로 구성됨 페이지 캐시 안에 존재 바로 이전에 수행한 미리 읽기 연산에서 요청한 페이지(미리 읽기 그룹)를 포함
12
정규 파일 읽기와 쓰기 파일 객체가 지원하는 미리 읽기와 관련된 필드
f_raend : 미리 읽기 그룹과 윈도우 다음의 첫째 바이트 위치 f_rawin : 현재 미리 읽기 윈도우의 길이 (바이트 단위) f_ralen : 현재 미리 읽기 그룹의 길이 (바이트 단위) f_ramax : 다음 미리 읽기 연산의 최대 길이(문자 단위) f_reada : 파일에 순차적으로 접근하였는지를 나타내는 필드 f_rawin f_ralen f_raend 미리 읽기 윈도우 안에 있는 페이지 미리 읽기 윈도우/그룹 모두에 있는 페이지
13
정규 파일 읽기와 쓰기 미리 읽기 연산 윈도우 (a) 미리 읽기 연산 이전 그룹 윈도우 (b) 짧은 윈도우로 미리 읽은 직후
짧은 윈도우 : 가장 최근의 미리 읽기 그룹만으로 이루어짐 긴 윈도우 : 최근의 미리 읽기 그룹과 미리 읽기 윈도우로 구성됨 윈도우 (c) 긴 윈도우로 미리 읽은 직후 이전 사용 자료 그룹
14
정규 파일 읽기와 쓰기 미리 읽기 알고리즘 개요 - generic_file_readahead() 순차적 접근 미리 읽기 실행
긴 미리 읽기 윈도우 사용 저수준 장치 드라이버 시작 y 페이지가 미리 읽기 그룹에 들어 있는가? n n 페이지 락이 걸려있는가? 아무 일도 하지 않음 y y y 페이지가 미리 읽기 그룹에 들어 있는가? n 미리 읽기 실행 짧은 미리 읽기 윈도우 사용 미리 읽기 윈도우 안에서의 접근인가? n 아무 일도 하지 않음 n 페이지 락이 걸려있는가? y 최소 크기의 미리 읽기 실행 짧은 미리 읽기 윈도우 사용 비순차적 접근
15
정규 파일 읽기와 쓰기 비순차적 접근(미리 읽기 윈도우 밖) 프로세스가 파일에 접근한적이 없거나,
현재 파일의 포인터 위치를 바꾸기 위해 lseek() 호출 페이지에 락이 걸려 있는 경우 해당 페이지에 대한 데이터 전송이 아직 끝나지 않은 경우 최소 크기의 미리 읽기 실행, 짧은 미리 읽기 윈도우 준비 페이지에 락이 걸려 있지 않은 경우 모든 데이터가 페이지 캐시 안에 들어 있는 경우 미리 읽기는 CPU 시간만을 낭비
16
정규 파일 읽기와 쓰기 순차적 접근(미리 읽기 윈도우 안) 페이지 Not 락/in 미리 읽기 그룹
이전 미리 읽기 연산에서 전송된 데이터에 접근(access)했었음 미리 읽기 수행 긴 미리 읽기 윈도우 사용 저수준 장치 드라이브를 활성화 페이지 Not 락/Not in 미리 읽기 그룹 이전 미리 읽기 연산에서 전송된 페이지에 접근(access)하는 중 미리 읽기 수행하지 않음 프로세스가 순차적으로 읽을 페이지가 커널에 충분히 존재하는 상황( 가장 이상적)
17
정규 파일 읽기와 쓰기 순차적 접근(미리 읽기 윈도우 안) 페이지 락/in 미리 읽기 그룹
프로세스가 이전 미리 읽기 연산에서 요청되었던 페이지에 접근(access)하지만, 아직 디스크에서 데이터가 전송되지 않은 경우 미리 읽기를 하는 의미가 없음 페이지 락/Not in 미리 읽기 그룹 프로세스가 이전 미리 읽기 연산에서 요청되었던 페이지에 접근(access) 중 미리 읽기를 추가로 실행, 디스크에 페이지를 기록
18
ii. 정규 파일 쓰기
19
정규 파일 읽기와 쓰기 정규 파일에 쓰기 사용자 모드의 주소 공간->커널 자료 구조->디스크 write() 메소드
디스크 블록을 식별 데이터를 사용자 주소 공간에서 해당 버퍼(커널 주소 공간)로 복사 버퍼를 더티로 표시 디스크 기반 파일 시스템은 직접 페이지 캐시를 사용하지 않음 버퍼 캐시만이 존재하던 이전 버젼의 리눅스와 호환성을 유지하기 위해서 네트워크 기반 파일 시스템은 항상 페이지 캐시를 사용함 리눅스 2.2에서 각 디스크 기반 파일시스템의 write() 메소드는 다음의 동작을 공통적으로 수행 - 디스크 블록을 식별 - 데이터를 사용자 모드 주소 공간에서 해당 버퍼(커널 자료 구조)로 복사 - 버퍼를 더티로 표시 더티(Dirty) 비트 : 메모리 내의 버퍼가 바뀌었으므로 기록해야 한다는 사실을 나타내는 비트
20
정규 파일 읽기와 쓰기 페이지 캐시 변경 하기 update_vm_cache()
현재 기록중인 파일과 관련 페이지 캐시를 페이지 단위로 갱신 매개변수 inode : 쓰기를 수행할 파일의 inode 객체 포인터 pos : 쓰기를 수행할 파일 내의 오프셋 buf : 파일에 써야 할 문자를 가져올 주소 count : 파일에 써야 할 문자 수
21
page_cache_release()
정규 파일 읽기와 쓰기 update_vm_cache() - filemap.c update_vm_cache_conditional() offset <- pos find_page() 페이지를 찾았다면 wait_on_page() 1. 기록할 첫 문자 페이지에 대한 오프셋을 POS로 부터 계산 2. 페이지 캐시에서 페이지 프레임을 검색 memcopy() : 페이지를 프로세스 주소 공간 데이터(사용자 주소 공간의 데이터)로 체움 memcopy() page_cache_release() >0 count - -
22
정규 파일 읽기와 쓰기 정규 파일에 대한 쓰기 연산 generic_file_write() - filemap.c 매개 변수
buf - 파일에 쓸 문자를 가져올 주소 count - 파일에 쓸 문자 수 ppos - 쓰기를 시작할 파일 오프셋을 저장한 변수 주소 페이지 캐시 : 페이지 입출력 연산을 통해 접근하는 데이터에 대한 디스크 캐시. 캐시 갱신은 페이지의 갱신이고 generic_file_write는 캐시의 값을 디스크에 저장하는 것을 다룸.
23
file->flag의 O_APPEND
정규 파일 읽기와 쓰기 파일 객체의 쓰기 메소드 file->flag의 O_APPEND 기록 시작 위치 <= ppos __find page() wait_on_page() copy_from_user() updatepage() wake_up() count -- ppos<=마지막 기록위치 >0 N Y file->flag O_APPEND Page 511p 파일을 열때 추가모드로 열었는지 확인해 주는 플래그 __find_page() : 페이지 캐시에서 페이지를 찾는다. 없다면 새로운 페이지 생성 copy_from_user() : 프로세스 주소공간(사용자 주소공간)에서 받은 데이터(기록할 데이터)로 페이지를 채운다. updatepage() :
24
III. 메모리 매핑
25
메모리 매핑 메모리 영역의 페이지 내부 바이트에 대한 접근을 커널이 그에 대응하는 일반 파일 내부 바이트의 연산으로 변환
메모리 매핑의 종류 공유 (share) 모든 쓰기 연산은 디스크 상의 파일을 변경 어떤 프로세스가 공유 메모리 매핑된 페이지를 변경하면, 이 파일을 매핑하는 다른 모든 프로세스에게도 영향을 미침 비공개(private) 프로세스가 파일에 쓰기가 아닌 읽기 만을 위해 매핑을 생성하는경우에 사용 공유 매핑 보다 효율적임
26
메모리 매핑 mmap()를 이용하여 메모리 매핑 생성 매핑을 생성 후 프로세스는 메모리 영역에서 데이터를 읽을 수 있음
매개변수로 MAP_SHARED/ MAP_PRIVATE 플래그 지정 매핑을 생성 후 프로세스는 메모리 영역에서 데이터를 읽을 수 있음 munmap()을 이용하여 메모리 매핑 제거
27
메모리 매핑 메모리 매핑 자료 구조 매핑된 파일에 대응하는 inode 객체 여러 프로세스가 실행한 각 매핑에 대한 파일 객체
struct inode 여러 프로세스가 실행한 각 매핑에 대한 파일 객체 struct file 각 매핑에 대한 vm_area_struct 디스크립터 struct vm_area_struct 메모리에 할당된 각 페이지 프레임에 대한 페이지 디스크립터 struct page
28
메모리 매핑 struct inode page frame vm_area_struct file i_pages next prev
offset file_image i_mmap vm_offset 메모리 영역 vm_next_share vm_pprev_share vm_file 매핑된 파일에 대응하는 inode 객체 -> struct inode 여러 프로세스가 실행한 각 매핑에 대한 파일 객체 -> struct file 각 매핑에 대한 vm_area_struct 디스크립터 -> struct vm_area_struct 메모리에 할당된 각 페이지 프레임에 대한 페이지 디스크립터 ->struct page
29
메모리 매핑 메모리 영역 관련 연산 open - 영역을 연다 close - 영역을 닫는다
unmap - 선형 주소 공간을 해제한다. protect - 쓰지 않음 sync - 메모리 영역 내용을 flush advise - 쓰지 않음 nopage - 요구 페이징 wppage - 쓰지 않음 swapout - 페이지를 swap out swapin - 페이지를 swap in 메모리 영역은 슈퍼블록, 아이노드, 파일객체와 동일한 객체이다 따라서 자신만의 메소드를 가지고 있다. vm_ops 필드가 구별해줌 메모리 영역 연산은 서로 다른 파일시스템들이 자신의 메모리 매핑 함수를 구현할 수 있도록 한다.
30
메모리 매핑 file_shared_mmap과 file_private_mmap 메소드 메소드 file_shared_mmap
open NULL close unmap filemap_unmap protect sync filemap_sync adivse nopage filemap_nopage wppage swapout filemap_swapout swapin
31
메모리 매핑 메모리 매핑 생성 mmap()에 다음의 매개변수를 전달함으로써 생성 매핑될 파일을 나타내는 파일 디스크립터
매핑될 부분의 첫 문자를 나타내는 파일의 오프셋 매핑될 파일의 부분 길이 플래그 집합 - MAP_SHARED/MAP_PRIVATE 메모리 영역 접근권한에 대한 집합-PROT_READ/PROT_WRITE/PROT_EXEC 선형주소(옵션)- 새로운 메모리 영역에서 시작할 위치를 지정
32
메모리 매핑 메모리 매핑 생성 1. 매핑할 파일에 대해 mmap 연산을 정의했는지를 검사
2. 메모리 매핑 종류/파일 열때 지정한 플래그 비교 3. 새로운 메모리 영역 디스크립터의 vm_flags 값 초기화 4. 매핑된 파일에 대해 mmap 호출 -generic_file_mmap() a. 메모리 디스크립터의 vm_ops 초기화-file_shared(private)_mmap b. i_mode필드로 부터 매핑될 파일이 정규 파일인지 검사 c. i_op 필드로 부터 readpage()의 정의 여부를 검사 d. update_atime() 호출 5. 메모리 영역 디스크립터의 vm_file 필드를 초기화/카운터 증가 6. 메모리 영역 디스크립터를 아이노드의 i_mmap가 가리키는 리스트에 삽입 매핑종류 -> mmap의 매개변수 파일의 열때 지정한 flag는 파일 디스크립터의 f_mode를 통해서 알수 있음. vm_flag는 메모리 영역의 속성을 정의 (VM_READ, VM_WRITE, VM_EXEC등..) 4.a 27쪽의 표에 있는 메소드를 초기화 c. i_op 필드로 부터 readpage()의 정의 여부를 검사 -> 읽을수 있는 파일인지를 검사 d. update_atime() 호출 -> 마지막 접근 시간을 갱신 5. 메모리 영역 디스크립터의 vm_file 필드를 초기화/카운터 증가 -> 메모리 영역 디스크립터와 관련된 파일을 연결 시킴
33
메모리 매핑 메모리 매핑 제거 munmap()에 다음의 매개변수를 전달함으로써 제거 수행 과정
제거할 선형 주소 공간의 처음 위치 주소 제거할 선형 주소 공간의 길이 수행 과정 1. 메모리 영역에 unmap 메소드가 있는지 검사 2. remove_shared_vm_struct() 호출하여 메모리 영역 디스크립터를 i_mmap 필드에서 제거
34
메모리 매핑 요구 페이징 효율성을 위해서 페이지 프레임을 생성 후에 바로 메모리 매핑을 하지 않음
do_no_page() 메소드 페이지 프레임 할당과 페이지 테이블 갱신을 수행 1. 요청한 페이지를 포함하는 페이지 프레임 주소 반환하는 nopage() 메소드 호출 2. 새로운 페이지 프레임 할당을 알리기 위해 프로세스 메모리 디스크립터의 rss 필드 증가 3. 페이지 테이블 엔트리를 페이지 프레임 주소와 페이지 접근 권한으로 설정한다 메모리 매핑을 수행하는 중에 다른 프로세스가 매핑할려는 주소에 접근하면 "Page Fault"가 발생 메모리 디스크립터의 rss 필드 증가 : 프로세스에 할당된 페이지 프레임의 수를 나타내는 플래그 297Page
35
메모리 매핑 findmap_nopage() 페이지가 페이지 캐시안에 없는 경우 디스크에서 읽어오는 함수 매개 변수
area - 요청한 페이지를 포함하는 메모리 영역의 디스크립터 주소 address-요청한 페이지의 선형 주소 no_share - 반환한 페이지 프레임을 다른 프로세스와 공유해서는 안됨을 지시하는 flag
36
메모리 매핑 findmap_nopage() 1. 파일 객체와 inode 객체 주소 얻기
2. 시작 페이지에 대응하는 데이터 파일내 오프셋 결정 3. 오프셋의 초과 여부 검사-초과시 버스에러(SIGBUS) 4. find_page() 호출하여 inode와 파일 오프셋에서 지정한 페이지를 페이지 캐시에서 찾는다. 5. wait_on_page() 호출하여 페이지 락이 풀릴때까지 대기 6. no_share=0 페이지 프레임의 공유를 위해 페이지 프레임 주소 반환 7. no_share=1 비공개 메모리 매핑 페이지에 쓰기 시도 __get_free_page() 호출 페이지 캐시에 포함된 페이지를 새로운 페이지 프레임에 복사 페이지 캐시내의 카운트 감소 새로운 페이지 프레임 주소 반환 Shared 인경우 -> 오프셋의 초과 여부 검사-초과시 버스에러(SIGBUS) Priave 인경우 ->새로운 페이지를 프로세스에게 할당
37
메모리 매핑 더티 메모리 매핑 페이지를 디스크에 Flush 하기
프로세스는 msync()함수를 이용하여 공유 메모리 매핑에 속하는 더티 페이지를 디스크에 flush 함 매개 변수 선형 주소 공간의 시작주소 선형 주소 공간의 길이 플래그 집합 MS_SYNC - 입출력연산 종료시까지 프로세스 연기 MS_ASYNC - 프로세스를 연기하지 않고, 즉시 반환 MS_INVALIDATE - 매핑된 모든 페이지를 프로세스 주소 공간에서 제거 매개변수 : Flush 할 선형 주소 공간의 시작주소와 공간길이 그리고 플래그를 전달
38
메모리 매핑 msync_interval() msync함수가 선형주소 공간의 각 메모리 영역에 대하여 호출
1. vm_file 필드가 NULL이면 0 반환(파일 매핑 불가) 2. sync() 호출 - filemap_sync가 실제 수행 3. MS_SYNC=1이면, file_fsync를 호출하여 관련 파일 정보(inode, 슈퍼블럭, 더티버퍼등)를 디스크에 flush함 vm_file 필드가 NULL -> 메모리 매핑과 관련된 파일이 없음 filemap_sync 다음장에 설명
39
메모리 매핑 filemap_sync() 함수 메모리 영역에 포함된 데이터를 디스크에 복사
1. flush_tlb_page()를 호출하여 TBL(Translation Lookaside Buffer)을 flush 2. MS_INVALIDATE=0이면, 페이지 디스크립터의 카운터 증가 3. MS_INVALIDATE=1이면, 대응하는 페이지 테이블 엔트리를 0으로 설정하여, 페이지가 더 이상 존재하지 않음을 알림 4. filemap_write_page() 호출-페이지의 내용을 기록 파일과 관련한 파일 객체의 카운터 증가 do_write_page() 호출하여 파일의 write() 실행-페이지의 내용을 기록 fput() 파일 객체의 사용 카운터 감소 5. free_page() 호출->페이지 디스크립터의 카운터 감소 TBL : 변환참조버퍼 , 선형주소 변환 속도를 높여주는 캐쉬 (106p.) 한번 변환한 선형주소를 저장하고 있다가, 똑같은 선형주소 변환시에 빠르게 변환하도록 함. MS_INVALIDATE=1 -> 페이지를 주소공간에서 삭제
40
Q & A
Similar presentations