sb_getblk.. 몇일째 헤매고 있네요.

shad0wse의 이미지

안녕하세요. 너무 길을 몰라서.. 여기에 남깁니다.
제가 하드디스크의 특정 블록을 얻어오려고..

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;

혹시, 작은 조언이라도 좋으니 부탁드리겠습니다...

shad0wse의 이미지

블록 디바이스 장치는 usb입니다. 2GB 이며, 현재 ext3로 파티션이 생성 돼 있는 상태입니다..

Always as first

Always as first

headbang의 이미지

글을 읽어보니 32bit 커널이군요.
해당 페이지(즉, bh->b_page)가 high memory에 있는 경우와 low memory에 있는 경우에 따라 bh->b_data가 다르게 해석됩니다.

Understanding the Linux Kernel 책을 뒤져보니 아래처럼 나오는 군요.

Quote:

The b_data field specifies the position of the block buffer inside the buffer page. Actually, the encoding of this position depends on whether the page is in high memory or not. If the page is in high memory, the b_data field contains the offset of the block buffer with respect to the beginning of the page; otherwise, b_data contains the linear address of the block buffer.

아래 예제 코드를 수정해서 쓰시면 됩니다.

         char *buff = my_buff;
         char *addr;
         addr = kmap(bh->p_page) + offset_in_page(bh->b_data);
         memcpy(addr, buff, bh->b_size);                  
         kunmap(bh->p_page);

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.