Linux device driver 내부에서 block device request 생성하는 방법

wangmir의 이미지

안녕하세요.

지금 제가 scsi high level 디바이스 드라이버 (driver/scsi/scsi_lib.c)에서 별도의 block request를 생성해서 보내려고 하고 있는데요..

환경은 SATA 디바이스가 연결된 상황이고, SATA는 block interface를 scsi device driver와 공유해서 사용하기 때문에 scsi_lib.c에서 작업을 진행하고 있습니다.

궁금한건, 제가 파일시스템을 통해 내려오지 않은 임의의 request를 생성해서 보내고 싶고, 해당 request는 일반적인 write function과 유사하며, 2 page 이상의 write를 보내게 되는데, 이러한 request를 device driver 내부에서 VFS와 파일시스템을 거치지 않고 생성하는 방법이 뭔지 궁금해서요..

일단 제가 찾아본바로는 blk_make_request란 함수가 별도의 request를 생성하게 해주는 거 같아서 해당 request를 사용해서 코드를 좀 짜봤는데,

코드는 개략적으로 다음과 같습니다.

	bio = bio_kmalloc(GFP_KERNEL, 2);
 
	for(i=0; i < 2; i++)
		bio_add_pc_page(q, bio, virt_to_page((void *)buff), PAGE_SIZE, 0);
 
	bio->bi_end_io = bio_map_kern_endio;
	bio->bi_rw |= REQ_WRITE;
 
	req = blk_make_request(q, bio, GFP_KERNEL);
 
	block = addr; //sector address 입니다.
	this_count = 8 * 2; //8은 page 내 sector (512byte) 개수를 의미합니다.
 
	req->__sector = block;
	req->__data_len = this_count << 9;
 
 
	//cmd를 채우는 것은 sd.c (driver/scsi)를 참고해서 거기서 제가 실험하는 storage의 일반적인 write cmd를 만들 때 지나는 function을 그대로 따라했습니다.
 
	if (direction == WRITE) {
		req->cmd[0] = WRITE_6;
 
	} else if (direction == READ) {
		req->cmd[0] = READ_6;
	}
	req->cmd[0] += READ_10 - READ_6;
	req->cmd[1] = 0;
	req->cmd[2] = (unsigned char) (block >> 24) & 0xff;
	req->cmd[3] = (unsigned char) (block >> 16) & 0xff;
	req->cmd[4] = (unsigned char) (block >> 8) & 0xff;
	req->cmd[5] = (unsigned char) block & 0xff;
	req->cmd[6] = req->cmd[9] = 0;
	req->cmd[7] = (unsigned char) (this_count >> 8) & 0xff;
	req->cmd[8] = (unsigned char) this_count & 0xff;
 
	req->cmd_flags |= REQ_WRITE;
	req->retries = 5;
	req->timeout = 60;
 
	return req;

이런식으로 짜봤는데, 일단 기본적으로 제가 보기엔 일반적인 file system의 write request와 유사하다고 생각했는데, 구동을 해보니 SATA error를 뿜고 죽네요.. (일단 write request가 dispatch되서 send까지 된다음 interrupt 에러가 나는 것 같습니다.)

Error 메시지는 다음과 같습니다.

ata4.00: exception Emask 0x70 SAct 0x1e0 SErr 0x400900 action 0x6 frozen
ata4.00: irq_stat 0x28000000, host bus error, interface fatal error
ata4: SError: UnrecovData HostInt Handshk
ata4.00: failed command: WRITE FPDMA QUEUED
ata4.00: cmd61/10:28:00:00:c0/00:00:0d:00:00/40 tag 5 ncq 8192 out
              res 40/00:30:00:00:bf/00:00:0d:00:00/40 Emask 0x70 (host bus error)
ata4.00: status: {DRDY} ...

혹시 blk request를 device driver 내부에서 독립적으로 생성하는 방법이나, 또는 해당 ata error에 대해서 솔루션이 있으신 분 있으신가요.. 혼자서 해결하기가 힘드네요.

감사합니다.

furmuwon의 이미지

struct buffer_head
__getblk
set_buffer_uptodate

를 사용하면 안되나요?

wangmir의 이미지

답변 감사합니다.

buffer_head를 사용하고, buffer_uptodate를 사용하는 경우, 당장 write request를 진행하는 것이 아니라, 추후에 flush thread에서 write 진행할 때 write가 되는 구조 아닌가요?

현재 제가 하고자 하는 것은 request를 만들어서 바로 I/O scheduler의 front에 추가한 다음, write request가 제일 먼저 처리되어야 하는 상황이거든요.. ordering이 중요한 상황이라..

ejaho0103의 이미지

안녕하세요.
wangmir님께서 올려주신 부분을 저도 구현해서 공부해보려고 하는 중입니다.
돌아다녀보니 자료가 너무 없어서 부득이 이렇게 답글 남기게 되었습니다.
혹시 이 문제에 대하여 해결하셨다면 어떻게 해결하셨는지 알려주실 수 있으신가요?
정말 감사합니다..

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.