리눅스 커널의 이해 중에서 17장. Ext2 파일시스템 회로 및 시스템 박사과정 1학기 이창희○ 국중옥
목차 ■ 일반적인 특성 ■ 디스크 자료 구조 ■ 메모리 자료 구조 ■ 파일시스템 생성 ■ Ext2 메소드 ■ 디스크 공간 관리
일반적인 특성 파일시스템의 종류 minix : 최초 버전, 파일명 14자, 파일크기 64MB EXT : 1992년 4월 소개, 초기 Linux 파일 시스템 EXT2 : 1994년 도입, 가장 널리 쓰이는 Linux 파일시스템 xiafs : minix 수정, 파일명 확장 umsdos : DOS에 Linux 지원, DOS파티션에 Linux사용시 설치 hpfs : OS/2의 HPFS파일 시스템 isofs : CD-ROM에서 사용하는 ISO9660포맷 지원 msdos : DOS의 FAT 파일 시스템 nfs : 네트워크 파일 시스템. sysv : UNIX System V의 파일 시스템
일반적인 특성 특성 최적의 블록 크기(1024~4096Byte) 선택 가능 예상한 파일수의 inode 수 선택 가능, 디스크 공간 효율적으로 사용 디스크 블록을 그룹으로 분할, 디스크 탐색 시간 감소 사용 전에 디스크 데이터 블록 예약, 파일 단편화 감소 빠른 심볼릭 링크 지원 시스템 중단(crash)으로 인한 영향 최소화 부트과정에서 파일시스템 상태에 대한 일관성 검사 자동 지원 변경 불가 파일과 추가만 가능한 파일 지원, 파일 보호 메커니즘 유닉스 시스템 V 릴리즈 4 (SVR4), BSD 구현 모두 지원
일반적인 특성 차기 버전 고려 사항 블록 단편화 접근 제어 리스트(ACL, Access Control List) 일반적으로 큰 블록 크기를 선택 → 작은 파일은 디스크 공간 낭비 해결방법 : 여러 파일을 같은 블록의 다른 단편에 저장 접근 제어 리스트(ACL, Access Control List) 특정 사용자나 사용자 조합을 위한 접근 권한 지정 압축된 파일과 암호화된 파일의 처리 파일 생성시 파일을 압축, 암호화하여 저장 논리적 삭제 삭제 파일의 복구 가능
디스크 자료 구조 EXT2 파티션 블록 종류 EXT2 파티션과 각 블록 그룹의 내부 배치 부트 블록 : 부트 섹터용 블록 그룹 : 동일 크기의 특정 자료 구조를 갖음. EXT2 파티션과 각 블록 그룹의 내부 배치 ∙ ∙ ∙ ∙ ∙ 블록그룹 0 부트 블록 블록그룹 n 아이노드 비트맵 데이터 블록 그룹 디스크립터 수퍼 블록 테이블 1블록 N블록
디스크 자료 구조 수퍼 블록 파일 시스템의 크기나 모양을 설명. 마운트 될 때 블록 그룹 0의 수퍼블록을 읽음. 모든 블록에는 똑같은 복사본이 있음. 파일 시스템이 깨지는 경우를 대비함. ext2_super_block 구조체에 저장됨.(표17-1 참조)
디스크 자료 구조 수퍼 블록 필드 설명 s_inodes_count : 아니노드 개수를 저장 s_block_count : 블록 수 저장 s_log_block_size : 블록 크기를 2의 지수로 표현 (2nⅹ1024) s_log_frag_size : s_log_block_size와 같음, 블록 단편화 용(구현안됨) s_blocks_per_group, s_flags_per_group, s_inodes_per_group : 각각블록 그룹의 수, 단편 수, 아이노드 수 의미 s_def_resuid, s_def_resgid : 슈퍼 유저(시스템 관리자)를 위한 사용자 또는 사용자그룹 s_mnt_count, s_max_count, s_lastcheck, s_checkinterval : 부트과정에서 자동으로 검사해야 하는 EXT2파일시스템을 설정.
디스크 자료 구조 그룹 디스크립터와 비트맵 [표17-2] EXT2 그룹디스크립터 필드(ext2_group_desc구조체) 유형 설명 비트맵 __u32 bg_block_bitmap 블록 비트맵의 블록 번호 bg_inode_bitmap 아이노드 비트맵의 블록 번호 bg_inode_table 첫째 아이노드 테이블 블록의 블록 번호 __u16 bg_free_blocks_count 그룹 안에 있는 빈 블록 수 bg_free_inodes_count 그룹 안에 있는 아이노드 수 bg_free_dirs_count 그룹 안에 있는 빈 디렉토리 수 bg_pad 워드 정렬을 위한 빈 공간 __u32[3] bg_reserved 12바이트를 채우기 위한 빈 공간
디스크 자료 구조 그룹 디스크립터와 비트맵 bg_free_blocks_count, bg_free_inodes_count, bg_used_dirs_count 새로운 inode와 data블록 할당 시 사용 각 자료구조를 할당 하기에 가장 적절한 블록을 선택할 때 사용 비트맵 비트의 연속으로 되어있으며 블록 할당 상태를 나타냄. 비트 값 = 0 : 대응하는 아이노드 또는 데이터 블록이 비었음을 의미 비트 값 = 1 : 사용 중 의미 각 비트맵은 한 블록안에 저장 블록크기=1024,2048,4096 ⇒ 한 비트맵은 1024ⅹ8,2048ⅹ8,4096ⅹ8개의 블록 상태를 나타낼 수 있음. block Bitmap : 블록 할당 상태를 나타냄 inode Bitmap : Inode 할당 상태를 나타냄
디스크 자료 구조 아이노드 테이블 인접하는 연속된 블록으로 구성됨 각 블록은 미리 정의된 아이노드 개수가 있음 아이노드 테이블 내 첫 블록의 블록번호를 그룹 디스크립터의 bg_inode_table필드에 저장 아이노드 크기 : 128byte ( 예)1024블록 8개 inode를 갖음 )
디스크 자료 구조 아이노드 테이블 ext2_inode 구조체 필드 유형 필드 설명 __u16 i_mode 파일 유형과 접근 권한 i_uid 소유자 식별자 __u32 i_size 파일 길이(바이트 단위) i_atime 마지막 파일 접근 시간 i_ctime 아이노드를 마지막으로 변경한 시간 i_mtime 파일 내용을 마지막으로 변경한 시간 i_dtime 파일 삭제 시간 i_gid 그룹 식별자 i_links_count 하드 링크 수 i_blocks 파일의 데이터 블록 수 i_flags 파일 플래그 union osd1 특정 운영체제 정보 __u32 [EXT2_N_BLOCKS] i_block 데이터 블록에 대한 포인터 i_version 파일 버전(NFS용) i_file_acl 파일 접근 제어 리스트 i_dir_acl 디렉토리 접근 제어 리스트 i_faddr 단편 주소 osd2
디스크 자료 구조 아이노드 테이블(ext2_inode 구조체 필드) i_size i_blocks i_block 파일의 실제 길이를 바이트 단위로 표시 32비트, 파일크기 4GB로 제한함 (실제는 최상위비트를 뺀 2GB) i_blocks 파일에 할당된 데이터 블록 수를 표시 i_block 파일의 데이터 블록을 식별하기 위한 블록을 가리키는 배열임 EXT2_N_BLOCKS개(보통15)로 이루어짐 파일의 아이노드 번호는 디스크에 저장할 필요가 없음 이유:블록그룹번호와 아이노드 테이블의 상대적 위치에서 아이노드 번호를 구할 수 있다. 예) 디스크의 inode 13021의 주소 = 4096(블록의 inode수)ⅹ3(블록그룹 수) = 12288(inode table) + 733 = 13021
디스크 자료 구조 여러 파일 유형이 디스크 블록을 사용하는 방법 정규 파일 디렉토리 처음 정규파일 생성 시 데이터 블록이 없음 데이터를 저장하기 시작하면 데이터 블록이 생김 디렉토리 데이터 블록의 아이노드번호와 파일명을 저장 데이터 블록은 ext2_dir_entry_2 구조체를 갖고 있다. 유형 필드 설명 __u32 inode 아이노드 번호 __u16 rec_len 디렉토리 엔트리의 길이 __u8 name_len 파일명 길이 file_type 파일 유형 Char [EXT2_NAME_LEN] name 파일명
디스크 자료 구조 여러 파일 유형이 디스크 블록을 사용하는 방법 디렉토리(ext2_dir_entry_2 구조체 필드 설명) inode 필드 : 이 디렉토리 엔트리에 해당하는 inode. 블록그룹의 inode테이블에 저장된 inode배열에 대한 인덱스임. name 필드 : 문자 EXT2_NAME_LEN개(255)로 이뤄진 가변길이의 배열 → 구조체 길이는 가변적임 rec_len 필드 : 디렉토리 엔트리 길이는 4의 배수 name_len 필드 : 실제 파일명의 길이를 저장 file_type 필드 : 파일 유형 나타냄 File_type 설명 알려지지 않음 1 정규파일 2 디렉토리 3 문자장치 4 블록장치 5 명명된 파이프 6 소켓 7 심볼릭 링크
디스크 자료 구조 여러 파일 유형이 디스크 블록을 사용하는 방법 심볼릭 링크 장치파일, 파이프, 소켓 경로명이 60자 이하이면, 아이노드의 i_block필드에 심볼릭 링크 저장, 데이터 블록 미사용 경로명이 60자를 넘으면, 데이터 블록 하나 사용함. 장치파일, 파이프, 소켓 데이터 블록 불필요 모든 정보를 아이노드에 저장함
메모리 자료구조 개념 마운트시 디스크 자료구조 정보를 RAM에 복사 반복적인 디스크 읽기 연산 단축 자료구조 변경 시 연산 예 파일 생성 시 s_free_inodes_count, bg_free_inodes_count 감소 데이터 추가 시 s_free_blocks_count, bg_free_blocks_count 변경 파일 일부분 재기록 시 s_wtime 변경 버퍼 캐시 디스크 Access시 프로세스를 자유롭게 놓아줌 데이터를 디스크에 일정 간격으로 기록 느린 입출력 연산으로 인한 프로세스의 성능과 응답시간의 영향을 줄여줌
메모리 자료구조 EXT2 자료구조의 VFS 이미지 유형 디스크 자료 구조 메모리 자료 구조 캐싱 모드 수퍼블록 ext2_super_block Ext2_sb_info 항상 캐시 됨 그룹 디스크립터 ext2_group_desc Ext2_group_desc 블록 비트맵 블록에 저장된 비트 배열 버퍼에 저장된 비트 배열 고정된 크기 아이노드 비트맵 아이노드 ext2_inode Ext2_inode_info 동적 데이터 블록 지정되지 않음 버퍼 빈 아이노드 없음 캐시 되지 않음 빈 블록
메모리 자료구조 캐싱 모드 고정된 제한 모드 (Fixed limit mode) 동적 모드 (Dynamic mode) 지정된 수의 자료구조만 버퍼캐시에 저장 지정된 수를 넘으면 오래된 자료구조를 디스크에 몰아 씀 동적 모드 (Dynamic mode) 아이노드 또는 블록을 사용하는 동안 만 데이터를 버퍼캐시에 저장 파일 닫기나 블록 삭제 명령으로 데이터를 캐시에서 제거 이를 디스크에 다시 씀
메모리 자료구조 ext2_sb_info 구조체 정보 디스크 수퍼 블록 필드 대부분 블록 비트맵 캐시 아이노드 비트맵 캐시 버퍼 헤드를 가리키는 포인터 버퍼를 가리키는 포인터 한 블록의 그룹 디스크립터 수 버퍼 헤드 배열을 가리키는 포인터 마운트 상태, 옵션등과 관련한 기타 데이터
메모리 자료구조 ext2_inode_info 구조체 디스크 아이노드 중 일반 VFS 아이노드에 저장하지 않는 필드 단편 크기와 단편 번호 i_block_group i_alloc_block, i_alloc_count i_osync : 디스크 아이노드의 동시 갱신 유무 표현
메모리 자료구조 비트맵 캐시 비트맵이 캐시에 있는 경우 비트맵 추가 비트맵이 캐시에 없지만 빈공간이 있는 경우 비트맵 추가 비트맵이 캐시에도 없고 빈공간도 없는 경우 비트맵 추가 3 1 17 4 8 5 6 20 5 3 1 17 4 8 6 20 3 1 17 4 8 5 3 1 17 4 8 3 1 17 4 8 6 20 7 5 3 1 17 7 8 6 20
메모리 자료구조 마운트 시킨 EXT2 메모리 자료 구조
파일시스템 생성 포맷 작업 파일시스템 생성 작업 디스크 드라이버가 디스크에 블록을 읽고 쓸 수 있게 함. 유틸리티 프로그램 : /usr/bin/superformat 파일시스템 생성 작업 전에 설명한 구조체를 설정함 유틸리티 프로그램 : /sbin/mke2fs
파일시스템 생성 /sbin/mke2fs 기본 옵션 블록크기 : 1024byte 단편크기 : 블록크기 예약된 블록 비율 : 5%
파일시스템 생성 /sbin/mke2fs 실행 작업 과정 수퍼블록과 그룹 디스크립터 초기화 파티션에 손상된 블록 검사 및 목록 제작 각 블록그룹에 대해 블록을 저장하기 위한 모든 디스크 블록 예약 수퍼블록, 그룹 디스크립터, 아이노드 테이블, 비트맵 각 블록 그룹의 아이노드와 데이터 블록 비티맵을 0으로 초기화 각 블록 그룹의 아이노드 테이블 초기화 / 루트 디렉토리 생성 Lost+found 디렉토리 생성 – 손상된 블록 연결 시 사용됨 아이노드 비트맵과 데이터 블록 비트맵 갱신 손상된 블록을 lost+found 디렉토리에 넣는다.
파일시스템 생성 예) EXT2 1.4MB 플로피 디스크 초기화 마운트 시, VFS에 1024byte길이 1390개 블록으로 한 볼륨이 됨 1 볼륨 = 1024 ⅹ1390 = 1423360 [byte] 디스크 내용 검사 $ dd if=/dev/fd0 bs=1k count=1440 | od –tx1 –Ax > /tmp/dump_hex 플로피 디스크 내용인 파일 dump_hex가 /tmp디렉토리에 생성됨 Dump파일 내용 : 그룹 디스크립터 하나로 충분함, 예약 블록 수 72(1440의 5%), 아이노드 테이블 4096byte마다 아이노드 하나씩 포함됨, 45개 블록안에 360개 아이노드가 저장됨. 블록 내용 부트 블록 1 수퍼 블록 2 단일 블록 그룹 디스크립터를 포함한 블록 3 데이터 블록 비트맵 4 아이노드 비트맵 5~49 아이노드 테이블: 10번까지 예약됨, 11번은 lost+found, 12~360은 비어 있음 50 루트 디렉토리(., .., lost+found포함)
EXT2 메소드 EXT2 수퍼블록 연산 EXT2 아이노드 연산 모든 VFS 수퍼블록 연산은 EXT2내에서 독자적으로 구현 그 이외에 clear_inode와 umount_begin VFS 메소드가 있음 수퍼블록 메소드 주소를 포인터 배열인 ext2_sops에 저장 EXT2 아이노드 연산 VFS inode 연산은 EXT2에서 독자적으로 파일 유형에 따라 구현 대응하는 EXT2메소드를 정의하지 않은 경우(NULL포인터), VFS는 자신의 정규 함수를 사용한다. 아이노드가 심볼릭 링크를 나타내는 경우, 모든 아이노드 메소드는 NULL이고, ext2_readlink(), ext2_follow_link()가 readlink와 follow_link메소드를 구현, 이들 메소드 주소를 ext2_symlink_inode_operations 테이블에 저장. 아이노드가 문자장치파일, 블록장치파일, 파이프를 나타내는 경우, 아이노드 연산은 파일시스템에 의존하지 않는다. 이들을 가각 chrdev_inode_operations, blkdev_inode_operations, fifo_inode_operations 테이블에 저장함.
EXT2 메소드 EXT2 아이노드 연산(계속) 정규 파일과 디렉토리 파일에 대한 EXT2 아이노드 연산 VFS 아이노드 연산 lookup NULL ext2_lookup link ext2_link unlink ext2_unlink symlink ext2_symlink mkdir ext2_mkdir rmdir ext2_rmdir create ext2_create mknod ext2_mknod rename ext2_rename readlink follow_link readpage generic_readpage() writepage bmap ext2_bmap() truncate ext2_truncate() permission ext2_permission() smap updatepage revalidate
EXT2 메소드 EXT2 파일 연산 파일시스템 특유의 파일 연산은 다음과 같다. VFS파일연산 EXT2 메소드 lseek ext2_file_lseek() read generic_file_read() write ext2_file_write() readdir NULL poll ioctl ext2_ioctl() mmap generic_file_mmap() open ext2_open_file() flush release ext2_release_file() fsync ext2_sync_file() fasync check_media_change revalidate lock
디스크 공간 관리 디스크 파일의 저장 공간 디스크 공간 관리의 문제 디스크에 흩어진 블록 파일 구멍 발생 – 실제 파일보다 크게 보임. 디스크 공간 관리의 문제 파일 단편화 파일의 물리적 저장 공간이 작은 조각으로 나뉘는 현상 순차적 파일 읽기 평균시간 증가 – 디스크 헤드의 위치 변경 원인 공간 관리의 고속화 커널의 디스크 접근 횟수 제한 평균 파일 접근 시간 증가
디스크 공간 관리 아이노드 생성 (ext2_new_inode()) get_empty_inode() 호출 새로운 아이노드 객체 할당, i_sb필드를 수퍼블록 주소로 설정. lock_super() 호출 수퍼블록 객체에 대한 배타적 접근을 얻음 새로운 아이노드가 디렉토리 이면 빈 아이노드가 많은 블록 그룹에 위치시킴. 새로운 아이노드가 디렉토리 아니면 빈 아이노드를 포함한 블록 그룹에 위치시킴. load_inode_bitmap() 호출 디스크 아이노드 할당
디스크 공간 관리 아이노드 생성 (ext2_new_inode()) (계속) 블록 그룹 디스크립터의 bg_free_inodes_count 감소, dirty표시 디스크 수퍼블록의 s_free_inodes_count 감소, dirty 표시 아이노드 객체 필드 초기화 새로운 아이노드 객체를 inode_hashtable에 삽입 mark_inode_dirty() 호출 unlock_super() 호출 새로운 아이노드 객체 주소 반환
디스크 공간 관리 아이노드 제거 - ext2_free_inode() lock_super() 호출 ⇒수퍼블록 객체에 대한 배타적 접근을 얻음 디스크 아이노드를 포함 한 블록그룹의 인덱스 계산 load_inode_bitmap() 호출 ⇒ 아이노드 비트맵을 얻음 clear_inode() 호출 ⇒ 다음 작업 실행 페이지 캐시에 있는 모든 페이지 해제함 수퍼블록 객체에 clear_inode메소드를 정의했다면, 이를 호출함 그룹 디스크립터의 bg_free_inodes_count 증가, bg_used_dirs_count 감소 디스크 수퍼블록의 s_free_inodes_count 증가 아이노드 비트맵 지움, 버퍼 dirty unlock_super 호출 ⇒ 수퍼블록 객체에 걸린 락 해제
디스크 공간 관리 데이터 블록 주소 지정 상대적 위치(Offset f)로부터 논리 블록 번호 얻기 2 단계 : 파일 블록 번호를 대응하는 논리 블록 번호로 변환. 데이터 블록의 불연속으로 파일블록번호의 논리블록번호를 얻기 어려움. 해결방법 – 파일블록번호와 논리블록번호의 관계를 디스크에 저장 즉, 아이노드 확장 디스크 파티션 내의 위치 참조
디스크 공간 관리 데이터 블록 주소 지정 (계속) 파일의 데이터 블록 주소를 얻기 위해 사용하는 자료 구조 Data blocks 2(b/4)+11 (b/4)2+ 2(b/4)+12 (b/4)2+ b/4+12 … 1 1 6 12 … … … … … 1 2 3 4 5 6 7 8 9 10 11 12 13 14 i_block 직접참조
디스크 공간 관리 데이터 블록 주소 지정 파일시스템의 블록 크기가 큰 경우 논리 블록 번호를 한 블록 안에 더 많이 저장 가능 데이터 블록 주소 지정에 대한 파일 크기 제한 블록크기 직접 1-간접 2-간접 3-간접 1024 1KB 268KB 63.55MB 2GB 2048 24KB 1.02MB 513.02MB 4096 48KB 4.04MB -
디스크 공간 관리 파일 구멍 앞부분에 구멍이 있는 파일
디스크 공간 관리 데이터 블록 할당 ext2_getblk() 함수 ext2_alloc_block() 함수 블록 파일 번호가 연속이면 이전 블록의 논리블록번호 +1 (파일 단편화) 블록 파일 번호가 불연속이면 이미 할당한 블록의 논리블록번호 이다. 위 규칙에 적용이 안되면 블록 그룹 내 첫째 블록의 논리블록번호 이다. ext2_alloc_block() 함수 새로운 블록의 위치가 미리 할당된 블록중 하나인지 검사 그렇다면 블록의 논리블록번호를 반환 그렇지 않으면 미리 할당된 모든 블록 해제 ext2_new_block() 함수 Ext2_alloc_block()의 할당 블록이 비어 있으면, 이 값을 할당 할당 블록이 사용 중이면, 할당 블록 다음 64개 블록 중 빈 블록 검사 빈 블록을 못 찾으면, 모든 블록 그룹 검사 – 최소한 빈 블록이 8개 인접 그룹 찾기, 없으면, 비어 있는 블록 하나를 찾는다.
디스크 공간 관리 데이터 블록 해제 ext2_truncate() ext2_free_blocks() lock_super() 파일 삭제, 파일 길이 0 이면 파일의 모든 데이터 블록 반환 ext2_free_blocks() 하나 이상 인접한 데이터 블록의 그룹 해제 inode, block, count lock_super() 블록 그룹의 블록 비트맵 얻음 블록 비트맵 비트 지우고, 버퍼 dirty표시 bg_free_blocks_count 증가, 버퍼 dirty표시 S_free_blocks_count 증가, 버퍼 dirty표시, 수퍼블록 객체의 s_dirt 설정 ll_rw_block() 호출, 비트맵의 버퍼에 대한 쓰기 연산 종료할 때까지 기다림 unlock_super() 수퍼블록 해제
EXT2 정규 파일 읽기와 쓰기 정규 파일 읽기 정규 파일 쓰기 EXT2의 read메소드는 generic_file_read()함수로 구현 ’15장. 정규파일접근’의 정규 파일에서 읽기’에서 설명. 정규 파일 쓰기 ext2_file_write() 모든 슈퍼유저 권한 제거 O_APPEND플래그 설정 시, 오프셋을 파일 끝으로 설정 O_SYNC 플래그 설정 시, ext2_inode_info의 i_osync를 1로 설정 파일 블록 번호와 블록 내 상대적인 오프셋을 계산 ext2_getblk()호출, ll_rw_block(), 블록에 기록할 바이트를 프로세스의 주소공간에서 버퍼로 복사, update_vm_cashe()를 호출하여 캐시내용을 버퍼캐시와 동기화, 지역배열에 버퍼 삽입, 배열이 다차면(32개 항목) ll_rw_block()호출 파일을 동기모드로 열었으면, 디스크 아이노드의 I_osync플래그를 지운다. 아이노드 객체의 i_size 필드 갱신 아이노드 객체의 i_ctime, i_mtime필드를 xtime.tv_sec로 설정, 아이노드 dirty 표시 데이터가 기록될 파일 오프셋을 저장한 변수 *ppos를 갱신 파일에 기록된 바이트수를 반환
리눅스 2.4 예상 generic_file_write()의 이점 파일 크기 제한(2GB)이 사라짐 32비트 구조에서 큰 파일에 접근이 가능 블록 단편화, 접근 제어 리스트, 압축된 파일과 암호화된 파일의 처리, 논리적 삭제의 특징은 리눅스 2.4에서 반영되지 않았음
Part VI : Q & A
디스크 구조 및 초기화 하드디스크 내부구조 하드디스크 CD-ROM
디스크 구조 및 초기화 디스크 초기화 (fdisk) 파일 시스템 물리적인 디스크를 논리적인 파티션으로 분리 각 파티션은 하나의 파일 시스템을 갖음 파일 시스템 물리적인 장치의 블록에 파일을 논리적인 계층구조로 구성 파일시스템을 담을 수 있는 장치는 블록 장치임 블록장치는 단순히 일렬로 늘어놓은 블록의 모음으로 간주 블록장치 밑에 있는 물리적 디스크를 직접 제어 안함. 원하는 장치의 특정 블록에 대한 하드 디스크의 위치는 디바이스 드라이버가 매핑 함.