sb_getblk.. 몇일째 헤매고 있네요.
안녕하세요. 너무 길을 몰라서.. 여기에 남깁니다.
제가 하드디스크의 특정 블록을 얻어오려고..
struct buffer_head *bh = sb_getblk( struct super_block *sb, unsigned long block );
이런식으로 bh을 얻어 옵니다. 이 것을 가지고 bh->b_data에 접근해서
실제 블록에 접근을 하게 됩니다.
헌데 문제는요. 이게 가끔 크래쉬를 발생시킨다는 것입니다.
매번 그런 것은 아니고요. 몇 번 호출하다 보면 그대로 뻗어버립니다.
아무래도 이유인즉, 동기화 문제인 거 같아서
여러가지 해결책을 생각해봤는데요.
sb_getblk() 호출 후 brelse() 를 통해서 bh를 해제시켜도 마찬가지였습니다.
또한 lock_buffer()/unlock_buffer()를 써도 의미가 없었구요.
이게 실제로 sb_getblk()에서 얻어온 데이터를 수정한다면 lock/unlock을
사용하면 유용할 거 같은데 현재는 sb_getblk()해서 참조만 할 거라서 무의미한 거 같습니다.
get_bh/put_bh 같은 경우에도 bh를 수정할 때 쓰이는 거 같더라구요.
결과적으로는 아직까지 어떠한 해결책도 못 찾아서 헤매는 중입니다. ㅠㅠ
현재, 제 시스템은 Ubuntu 8.10, linux-2.6.27-14-gen 버전입니다.
파일 시스템은 ext3 이고요.
혹시나 도움이 될까 해당 소스를 올려보았습니다.
물론 이 함수 호출 전에 open_bdev_excl()로 블록 디바이스 장치를 오픈해서
get_super() 함수로 sb를 얻었는 상태에서 호출한 것입니다.
169 struct ext3_super_block *ext3_get_superblock( struct super_block *sb, struct fs_info *fs_i ) 170 { 171 unsigned long offset = 0; 172 ext3_fsblk_t logic_sb_block; 173 struct buffer_head *bh = NULL; 176 177 // 슈퍼블록 블록 번호를 구함 178 logic_sb_block = get_logic_sb_block( sb, LOGIC_SB_BLOCK ); 179 offset = get_logic_sb_block( sb, OFFSET ); 182 183 brelse( bh ); 184 // 슈퍼 블록을 읽어 버퍼헤드 형태로 저장 185 if( !(bh = sb_getblk( sb, logic_sb_block )) ) 186 { 189 goto OUT_FAIL; 190 } 192 brelse( bh ); 196 return NULL;
혹시, 작은 조언이라도 좋으니 부탁드리겠습니다...
블록 디바이스 장치는 usb입니다.
블록 디바이스 장치는 usb입니다. 2GB 이며, 현재 ext3로 파티션이 생성 돼 있는 상태입니다..
Always as first
Always as first
글을 읽어보니 32bit
글을 읽어보니 32bit 커널이군요.
해당 페이지(즉, bh->b_page)가 high memory에 있는 경우와 low memory에 있는 경우에 따라 bh->b_data가 다르게 해석됩니다.
Understanding the Linux Kernel 책을 뒤져보니 아래처럼 나오는 군요.
아래 예제 코드를 수정해서 쓰시면 됩니다.
댓글 달기