저는 리눅스 커널 작업을 하고 있습니다. 현재 v3.10.61에서만 작동하며 이는 단지 개념 증명일 뿐입니다.
특정 WRITE\READ 작업의 데이터 유형에 대한 몇 가지 힌트를 하드웨어에 전달해야 합니다. 예를 들어 inode 비트맵 읽기, 로그 블록 쓰기, 사용자 데이터 쓰기 등...
나는 드라이버 수준 bio struct
에서 request_queue struct
.
- 다음 명령으로 FS를 만들었습니다.
mkfs.ext4 -b 4096 -E lazy_itable_init=0,lazy_journal_init=0 -m 0 /dev/vda
- 다음 명령을 사용하여 설치했습니다.
mount -o rw,nosuid,nodev,discard,noauto_da_alloc,data=ordered /dev/vda /mnt
- 중단점 추가
virtio_blk.c:377
및 로그 관련 쓰기 건너뛰기 - 이 dd 명령을 실행하십시오:
dd if=/dev/urandom of=/mnt/foo2 bs=764 count=34
- 중단점이 적중될 때까지 기다리고 쓰기 저장 하위 시스템에서 추적을 분석합니다.
추적 내용은 다음과 같습니다.
#0 virtblk_request (q=0x87ab8000) at drivers/block/virtio_blk.c:377
#1 0x801c0b4c in __blk_run_queue_uncond (q=<optimized out>) at block/blk-core.c:312
#2 __blk_run_queue (q=0x87ab8000) at block/blk-core.c:329
#3 0x801c0c94 in queue_unplugged (q=0x87ab8000, depth=<optimized out>, from_schedule=<optimized out>) at block/blk-core.c:2920
#4 0x801c3a98 in blk_flush_plug_list (plug=<optimized out>, from_schedule=false) at block/blk-core.c:3030
#5 0x801c3d9c in blk_finish_plug (plug=0x8785fd8c) at block/blk-core.c:3037
#6 0x80091644 in generic_writepages (mapping=<optimized out>, wbc=0x8785fde0) at mm/page-writeback.c:1910
#7 0x80092a88 in do_writepages (mapping=<optimized out>, wbc=<optimized out>) at mm/page-writeback.c:1923
#8 0x800e7084 in __writeback_single_inode (inode=0x8740c290, wbc=0x8785fde0) at fs/fs-writeback.c:454
#9 0x800e7360 in writeback_sb_inodes (sb=0x87811000, wb=0x87ab81b0, work=0x8785fea4) at fs/fs-writeback.c:678
#10 0x800e757c in __writeback_inodes_wb (wb=0x1 <__vectors_start>, work=0x3ff) at fs/fs-writeback.c:723
#11 0x800e7760 in wb_writeback (wb=0x87ab81b0, work=0x8785fea4) at fs/fs-writeback.c:854
#12 0x800e838c in wb_check_old_data_flush (wb=<optimized out>) at fs/fs-writeback.c:969
#13 wb_do_writeback (wb=0x87ab81b0, force_wait=0) at fs/fs-writeback.c:1010
#14 0x800e848c in bdi_writeback_workfn (work=0x87ab81bc) at fs/fs-writeback.c:1040
#15 0x80039d34 in process_one_work (worker=0x87816180, work=0x87ab81bc) at kernel/workqueue.c:2189
#16 0x8003a40c in worker_thread (__worker=0x1 <__vectors_start>) at kernel/workqueue.c:2313
#17 0x8003f714 in kthread (_create=0x87845e20) at kernel/kthread.c:200
#18 0x8000dfb8 in ret_from_fork () at arch/arm/kernel/entry-common.S:91
좋아, 간다... 프레임 8에서는 아직 확인할 inode 변수를 최적화하지 않았다.
p (*inode)->i_ino
$7 = 0
이 inode가 무엇을 의미하는지 누가 설명할 수 있나요? 그러한 inode에 대한 정보는 어디서 찾을 수 있나요? 쓰기 저장 작업의 inode 번호를 추적하는 방법은 무엇입니까?
답변1
면책조항: 저는 아직 이러한 기능을 사용해 본 적이 없으며 문서와 의견을 작성하는 중입니다. 내 관찰이 틀렸을 수도 있습니다!
i_ino
해당 값을 사용하는 것으로 볼 수 있는 유일한 함수는 인덱스 노드가 해시된 경우(아직 표시되지 않은 경우) 더티로 표시하고 타임스탬프(향후 쓰기 저장 작업을 위해)를 설정하는 fs/writeback.c
내부 함수입니다 . block_dump___mark_inode_dirty
다시 기록될 현재 inode 목록은 struct bdi_writeback *wb
주어진 list() 로 사용 가능한 것으로 보입니다 wb_writeback()
.
마운트 옵션을 사용 하면 data=ordered
데이터 쓰기 저장이 발생하지 않을 것이라고 생각하므로 inode를 "더러운" 것으로 간주해서는 안 됩니다. ~에 따르면ext4 문서:
data=ordered
(*)모든 데이터는 메타데이터가 저널에 커밋되기 전에 기본 파일 시스템에 직접 강제 적용됩니다.
ext4에서 쓰기 저장이 작동하는 방식은 나중에 설명됩니다.
데이터 스키마
- 쓰기 저장 모드
mode
data=writeback
, ext4는 데이터를 전혀 기록하지 않습니다. 이 모드는 XFS, JFS 및 ReiserFS의 기본 모드인 메타데이터 로깅과 유사한 로깅 수준을 제공합니다. 충돌 + 복구로 인해 충돌 직전에 작성된 파일의 데이터가 잘못될 수 있습니다. 이 모드는 일반적으로 최고의 ext4 성능을 제공합니다.
- 주문 모드
모드 에서
data=ordered
ext4는 메타데이터만 공식적으로 기록하지만, 데이터 블록을 통해 데이터 변경과 관련된 메타데이터 정보를 트랜잭션이라는 단일 단위로 논리적으로 그룹화합니다. 새로운 메타데이터를 디스크에 기록해야 하는 경우 관련 데이터 블록이 먼저 기록됩니다. 일반적으로 이 모드는 쓰기 저장보다 약간 느리게 수행되지만 로그 모드보다 훨씬 빠릅니다.
ext4 파티션에서 이벤트를 추적하려면 ext4-JBD2 인터페이스의 작동 방식 fs/ext4/ext4_jbd2.c
과 include/trace/events/ext4.h
.