xfs
[Top] [All Lists]

Re: direct-IO writes strange behavior

To: Alberto Nava <beto@xxxxxxxxxxx>, Steve Lord <lord@xxxxxxx>
Subject: Re: direct-IO writes strange behavior
From: Nathan Scott <nathans@xxxxxxx>
Date: Thu, 27 Nov 2003 11:30:56 +1100
Cc: linux-xfs@xxxxxxxxxxx
In-reply-to: <3FC0EFEA.5070108@xfs.org>
References: <3FBECF7E.6010509@kasenna.com> <3FBFEF6A.3000609@kasenna.com> <3FC0EFEA.5070108@xfs.org>
Sender: linux-xfs-bounce@xxxxxxxxxxx
User-agent: Mutt/1.5.3i
On Sun, Nov 23, 2003 at 11:35:38AM -0600, Steve Lord wrote:
> Alberto Nava wrote:
> >Hi,
> >
> >I've done some more digging on this issue. The reason the
> >request is going in 4k pages is that the direct-io code is
> >giving up in do_direct_IO() and the request is issued as buffer IO :-(.
> >
> >The reason do_direct_IO gives up is because the first call to 
> >get_more_blocks() is returning an unmapped buffer header.
> >This is a snip of the code that's failing (look for XXXXX)
> >
> >static int do_direct_IO(struct dio *dio)
> >{
> >    const unsigned blkbits = dio->blkbits;
> >    const unsigned blocks_per_page = PAGE_SIZE >> blkbits;
> >    struct page *page;
> >    unsigned block_in_page;
> >    struct buffer_head *map_bh = &dio->map_bh;
> >    int ret = 0;
> >
> >    /* The I/O can start at any block offset within the first page*/
> >    block_in_page = dio->first_block_in_page;
> >
> >    while (dio->block_in_file < dio->final_block_in_request) {
> >        page = dio_get_page(dio);
> >        if (IS_ERR(page)) {
> >            ret = PTR_ERR(page);
> >            goto out;
> >        }
> >
> >        while (block_in_page < blocks_per_page) {
> >            unsigned offset_in_page = block_in_page << blkbits;
> >            unsigned this_chunk_bytes;    /* # of bytes mapped */
> >            unsigned this_chunk_blocks;    /* # of blocks */
> >            unsigned u;
> >
> >            if (dio->blocks_available == 0) {
> >                /*
> >                 * Need to go and map some more disk
> >                 */
> >                unsigned long blkmask;
> >                unsigned long dio_remainder;
> >
> >                ret = get_more_blocks(dio);
> >                if (ret) {
> >                    page_cache_release(page);
> >                    goto out;
> >                }
> >                if (!buffer_mapped(map_bh))
> >                    goto do_holes;    XXXXXX
> >                   
> >        .....
> >do_holes:
> >            /* Handle holes */
> >            if (!buffer_mapped(map_bh)) {
> >                char *kaddr;
> >
> >                /* AKPM: eargh, -ENOTBLK is a hack */
> >                if (dio->rw == WRITE)
> >                    return -ENOTBLK; XXXXXX
> >
> >
> >Even if I reserve space for the file, the directio IO fails.
> >
> >I tried the same with ext3 and it does perform the directIO on the new 
> >file.  However, I really disklike the sizes that it's using, it's all 
> >over the place 8k, 160, 200k, etc. I really like the 512K requests I'm 
> >getting with XFS specially with the 320 SCSI controller I'm using.
> >
> >I'll try looking at the XFS code to see why is returning an unmapped bh, 
> >but some help here would be greatly appreciate as I'm not familiar with 
> >XFS code.

Hi Alberto,

I spent some time this morning looking into this.  Firstly, the
fs/direct-io.c code has moved on from what you were looking at
in test9 -- I've been testing using test11 this morning and the
code snippet you've pasted above is no longer the same (Andrews
comment above has modified - ENOTBLK is never returned now).

Secondly, I cannot reproduce the behaviour you've described --
direct IO into both unwritten and newly allocated extents works
correctly, and using your test case I got nice big 512k chunks
every time.  There have been no changes in XFS in this area that
could have affected this, so I wonder what led you to suspect
the buffer was unmapped (your first "XXXXXX" above) originally?

Did you put a printk in there that was being triggered?  (I did,
and it didn't, using -test11).  I also put the printks into XFS
as I described in my previous mail, and we are definately giving
large IOs back to the generic direct IO code, for both cases -
pre-allocated and and not-pre-allocated cases.

Any chance you could retry your tests on the current kernel just
to verify that there is no problem here for me?

thanks!

-- 
Nathan


<Prev in Thread] Current Thread [Next in Thread>