JFS day1
JFS 는 DFS(distribution file system) 지원을 위해 aggregate 와 fileset 이라는 개념을 도입해
diskspace allocation pool 과 mountable volume 을 분리하였다.
JFS 는 파티션 위에 1개의 aggregate 와 1개 이상의 fileset 으로 구성된다.
JFS 의 dynamic inode allocation 으로 인해, 별도의 mapping 정보가 필요하게 되어
등장한게 Inode allcation map 과 ag free inode list 이다.
JFS 는 file 이 사용하는 연속된 disk block 을 extents 라 부르며, AG 를 넘어가는 경우엔
B+ tree 에 별도의 인덱싱이 들어가게 된다.
JFS 는 IAG(inode allocation group) 를 사용해 inode allocation map 을 기술하며,
forward lookup 문제를 해결하기 위해 사용하고 있다. file lookup 이 대표적인 문제이며,
inode 번호로 on-disk inode 를 찾는 과정이다.
JFS 는 1개의 inode allocation map 에 4096 개의 disk inode extents 의 상태 관리(0, 1)를
하고, 최대 128개 AG 로 구분할수 있다.
__le32 wmap[EXTSPERIAG]; // 32 x 128 /* number of disk inode extent per iag */
JFS 는 file layout 를 작성할때 1개의 B+ tree node 가 8개의 xad_t 를 사용해
물리 영역과 논리 볼륨을 연결 해준다. 현재는 "18개의 xad_t" 까지 가능하다.
#define XTROOTMAXSLOT 18
JFS 는 on-disk inode (dinode) 와 inode (jfs_inode_info) 양쪽에 xad_t 를 두고 있고,
root 에 접근하는 별도의 매크로를 제공하고 있다.
#define di_xtroot u._file._u2._xtroot
#define i_xtroot u.file._xtroot
JFS 는 block allocation map 을 이용해 aggregate 내 fileset 들이 alloc / free 한
disk block 을 추적하며, 이때 block 단위는 1k(aggregate block) 이다.
JFS 의 block allocation map 은 aggregate inode 2번이며, 4K bytes 를 넘어가면
확장되거나 줄어들수 있다.
JFS 에서 block allocation map 은 dmap tree 로 구성되어 있으며,
1개의 dmap 은 8k 개 (BPERDMAP) 의 aggregate block 을 갖고, leaf 로부터 위로
L0/L1/L2 로 구성되어 총 2^3 x 2^40 개 block 를 보유하고 있다.
각 레벨당 2^10 개의 노드가 존재한다.
__le32 wmap[LPERDMAP]; // 256 /* num leaves per dmap tree */
256 x 32 = 8196 bit == 8196 개 aggregate block
JFS 에서 dmap 내 alloc / free 된 disk block 은 summary tree (dp->tree) 와
binary buddy system (budtab) 으로 관리되며, summary tree 는 budtab 의 인덱스 정보를
갖고 있다.
아래는 dbFindLeaf 슈도코드와 예시이다. ( ROOT -> L2 -> L1 - > L0 -> LEAF )
dbFindLeaf(dmtree_t *tp, int l2nb, int *leafidx)
1. dmtree_t 에서 l2nb (number of block in log2) 가능한 leafidx 를 찾는다.
2. l2nb > tp->dmt_stree[ROOT] 면 서비스 불가, -ENOSPC 리턴 ( ROOT:0 )
3. leftmost leaf 부터 내려가면서 sufficient free space 를 가진 leaf node idx 를 리턴한다.
JFS 는 file 내 특정 위치(pno) 에 xlen 만큼의 쓰기요청이 들어오면,
extend(xad) 가 쓸 disk block 할당 함수를 호출, block address(nxaddr) 와 실제 할당된
block 갯수(nxlen) 가 반환된다. 만약 반환된 block address 가 extend 와 continuous 하면
extend 를 확장하는 함수를 호출하게 된다.
JFS 는 inode 를 3종류의 정보(file, dir, link) 로 구분하고, file 은 xtree page (xtpage_t),
dir 은 directory root page (dtroot_t) 를 두어 관리하고 있다. 전자를 xtree, 후자를 dtree
라고 부르고 있다.
JFS jfs_readdir 함수는 jfs_dirent 구조체 배열에 정보를 채우고, 개별 jfs_dirent 에 대해
dir_emit 함수를 호출한다. 아래는 jfs_readdir 의 슈도코드이다.
1. start page (dtpage_t) 와 index 를 획득한다. 이때 dir_index 가 3이상이면,
directory table (dir_table_slot) 을 구해서 index 로 사용한다.
2. start page header 에서 nextindex 를 획득한다. index .... nextindex 사이를 순회하며
head/only segment(ldtentry) 의 이름을 복사한다. 이때 순회순서는 알파벳 정렬순이다.
( d = p->slot[stbl[i]] )
3. 2번 루프 안에서 dtslot next 가 없을때까지 순회하며, additional segment(dtslot) 의
이름을 복사한다.
3. jfs_dirent 배열을 역순회하면서 dir_emit 을 호출해준다.
JFS 는 suffix compression 을 지원하기 위해 direcotry B+ tree (sorted by name) 을 제공
하고, dir_table_slot 생성/삭제 시 메모리를 적게 shift 하기 위해 sorted entry index
table(stbl) 을 start page 에서 관리하고 있다.
JFS 의 진입점
super.c:996: rc = register_filesystem(&jfs_fs_type);
https://jfs.sourceforge.net/project/pub/jfslayout.pdf
추가 확인할 정보
dbSplit
XT_GETPAGE 와 XT_PUTPAGE ( metapage 라이프사이클 )
xtTruncate 내 xad 획득코드
1차 수정 : extent 정의 및 디테일(숫자) 추가, inode allocation map 과 block allocation map 의 차이점이 드러나게 내용수정
답글삭제2차 수정 : xad_t 설명 추가, 확인할 정보 추가
답글삭제3차 수정 : summary tree, binary buddy system 그림 추가, 동작예시 추가
답글삭제4차 수정 : binary buddy system 그림 오류 수정, extAlloc 시 hint 정보 추가 (extend 유무 결정)
답글삭제5차 수정 : readdir 및 dtree 설명 추가 ( xtree 와 dtree 의 차이점 )
답글삭제