2003-11-21 15:54:58

by Dhruv Anand

[permalink] [raw]
Subject: DIRECT IO for ext3/ext2.

Hi,
I am working on an application on linux-2.6 that needs to
bypass the buffer cache. In order to do so i use the direct
IO functionality. Although open to the device succeeds with
the DIRECT_IO flag, read from the device fails.

Following is the exceprt fromt he code to open and read;
--------------------------------------------------------

if ((devf = open(dumpdev, O_RDONLY | O_DIRECT, 0)) < 0) {
fprintf(KL_ERRORFP, "Error: open failed!\n");
...
}

if(err = read(devf, &magic_nr, sizeof(magic_nr)) != sizeof(magic_nr)) {
fprintf(KL_ERRORFP, "Error: read() failed!\n");
...
}

---------------------------------------------------------
I am returned an errno=22, indicating 'Invalid argument'

I would appreciate it, if you could knowledge me importantly about
the completeness of the 'direct IO' functionality in ext3 file-system.
Or if i am doing something wrong in usage?


Regards
Dhruv.


2003-11-21 17:34:50

by Andrew Morton

[permalink] [raw]
Subject: Re: DIRECT IO for ext3/ext2.

<[email protected]> wrote:
>
>
> Hi,
> I am working on an application on linux-2.6 that needs to
> bypass the buffer cache. In order to do so i use the direct
> IO functionality. Although open to the device succeeds with
> the DIRECT_IO flag, read from the device fails.
>
> Following is the exceprt fromt he code to open and read;
> --------------------------------------------------------
>
> if ((devf = open(dumpdev, O_RDONLY | O_DIRECT, 0)) < 0) {
> fprintf(KL_ERRORFP, "Error: open failed!\n");
> ...
> }
>
> if(err = read(devf, &magic_nr, sizeof(magic_nr)) != sizeof(magic_nr)) {
> fprintf(KL_ERRORFP, "Error: read() failed!\n");
> ...
> }
>
> ---------------------------------------------------------
> I am returned an errno=22, indicating 'Invalid argument'
>

O_DIRECT reads must be aligned to the filesystem blocksize. Both the
memory address and the file offset must be thus aligned.

2003-11-21 19:31:52

by Dhruv Anand

[permalink] [raw]
Subject: RE: DIRECT IO for ext3/ext2.

Hi Andrew,

Thanks for your reply. I looked into the boundary alignment issue.
Observed something strange happening;

I wrote my own kernel module and then;
1. retrieved the block size = 4096 using block_size(struct block_device
*bdev)
2. in the user application i did a lseek by 4906 (block size seek)
3. then found the address of the variable i wanted to read into, to be
block
size aligned.

However, the read still seems to fail with the O_DIRECT flag specified.
The same check _passes if i do not specify the flag in open of the
device.

Boundary issues seem to be not the cause of failure here.
Would have any more kind suggestions on something that i should do or
could be missing on?

Regards
Dhruv

>>-----Original Message-----
>>From: Andrew Morton [mailto:[email protected]]
>>Sent: Friday, November 21, 2003 11:11 PM
>>To: Dhruv Prem Anand (WT01 - EMBEDDED & PRODUCT ENGINEERING SOLUTIONS)
>>Cc: [email protected]; [email protected];
>>[email protected]; [email protected]; [email protected]
>>Subject: Re: DIRECT IO for ext3/ext2.
>>
>>
>><[email protected]> wrote:
>>>
>>>
>>> Hi,
>>> I am working on an application on linux-2.6 that needs to
>>bypass the
>>> buffer cache. In order to do so i use the direct IO functionality.
>>> Although open to the device succeeds with the DIRECT_IO flag, read
>>> from the device fails.
>>>
>>> Following is the exceprt fromt he code to open and read;
>>> --------------------------------------------------------
>>>
>>> if ((devf = open(dumpdev, O_RDONLY | O_DIRECT, 0)) < 0) {
>>> fprintf(KL_ERRORFP, "Error: open failed!\n");
>>> ...
>>> }
>>>
>>> if(err = read(devf, &magic_nr, sizeof(magic_nr)) !=
>>sizeof(magic_nr)) {
>>> fprintf(KL_ERRORFP, "Error: read() failed!\n");
>>> ...
>>> }
>>>
>>> ---------------------------------------------------------
>>> I am returned an errno=22, indicating 'Invalid argument'
>>>
>>
>>O_DIRECT reads must be aligned to the filesystem blocksize.
>>Both the memory address and the file offset must be thus aligned.
>>
>>

2003-11-21 19:39:26

by Andrew Morton

[permalink] [raw]
Subject: Re: DIRECT IO for ext3/ext2.

<[email protected]> wrote:
>
> Thanks for your reply. I looked into the boundary alignment issue.
> Observed something strange happening;
>
> I wrote my own kernel module and then;
> 1. retrieved the block size = 4096 using block_size(struct block_device
> *bdev)
> 2. in the user application i did a lseek by 4906 (block size seek)
> 3. then found the address of the variable i wanted to read into, to be
> block
> size aligned.

O_DIRECT works - trust me ;)

Please grab

http://www.zip.com.au/~akpm/linux/patches/stuff/ext3-tools.tar.gz

There are a number of examples in there (odread.c is one).


2003-11-25 08:17:04

by Michael Kerrisk

[permalink] [raw]
Subject: Re: DIRECT IO for ext3/ext2.

> Thanks for your reply. I looked into the boundary alignment issue.
> Observed something strange happening;
>
> I wrote my own kernel module and then;
> 1. retrieved the block size = 4096 using block_size(struct block_device
> *bdev)
> 2. in the user application i did a lseek by 4906 (block size seek)
> 3. then found the address of the variable i wanted to read into, to be
> block
> size aligned.
>
> However, the read still seems to fail with the O_DIRECT flag specified.
> The same check _passes if i do not specify the flag in open of the
> device.
>
> Boundary issues seem to be not the cause of failure here.
> Would have any more kind suggestions on something that i should do or
> could be missing on?

Is the size of the data you are reading also a multiple the block size? (It
should be.)

Cheers,

Michael