public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Yves Crespin <crespin.quartz@wanadoo.fr>
To: "Randy.Dunlap" <rddunlap@osdl.org>
Cc: linux-kernel@vger.kernel.org
Subject: Re: read failed EINVAL with O_DIRECT flag
Date: Wed, 13 Apr 2005 15:15:47 +0200	[thread overview]
Message-ID: <425D1B83.50809@wanadoo.fr> (raw)
In-Reply-To: <20050412094752.0f4d88a5.rddunlap@osdl.org>


 >| How can I obtains an buffer alignement from a "user program" ?
 >
 >I actually left that as an exercise (after I did it at home
 >last night).  Did you read the hint (below)?

Well ... either with malloc() and alignement or posix_memalign(),
read() still failed!
My read buffer is in user space, so it's copy to kernel space.
Inside the read() call, it's the kernel buffer which must be aligned?

 >
 >| >In fs/buffer.c, it wants the buffer & the length (size) to be aligned:
 >| >
 >| >function: brw_kiovec()
 >| >
 >| >    /*
 >| >     * First, do some alignment and validity checks
 >| >     */
 >| >    for (i = 0; i < nr; i++) {
 >| >        iobuf = iovec[i];
 >| >        if ((iobuf->offset & (size-1)) ||
 >| >            (iobuf->length & (size-1)))
 >| >            return -EINVAL;
 >| >        if (!iobuf->nr_pages)
 >| >            panic("brw_kiovec: iobuf not initialised");
 >| >    }
 >| >
 >| >so in your program, malloc() the buf [pointer] (larger than needed)
 >| >and then align it to a page boundary and pass that aligned pointer
 >| >to read().
 >| >
/* --- start code --- */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

#define O_BINARY    0

int main(int argc,char *argv[])
{
    struct stat    sbuf;
    char *        buf;
    int        openFlags;
    int        fd;
    int        nb;
    off_t        size;
    blksize_t    blksize;
    off_t        offset;

    if (argc!=2){
        printf("Missing file name\n");
        exit(2);
    }
    printf("[%s]\n",argv[1]);
    openFlags = O_RDWR|O_BINARY|O_NOCTTY;
    openFlags |= O_DIRECT;    /* Not POSIX */
    fd = open(argv[1],openFlags,0666);
    if (fd==-1){
        printf("open failed [%s] %#o %#o errno 
%d\n",argv[1],openFlags,0666,errno);
        exit(1);
    }
    if (fstat(fd,&sbuf)<0){
        printf("fstat failed\n");
        exit(1);
    }
    blksize = sbuf.st_blksize;
    size = sbuf.st_size;
    nb = posix_memalign((void **)&buf,blksize,size);
    if (nb!=0){
        printf("posix_memalign blksize %lu size %lu failed 
%d\n",blksize,size,nb);
        exit(3);
    }
#if 0
    free(buf);
    buf = malloc(2*blksize);
#endif
    printf("direct: buf %p buf & (blksize-1) %lu\n",buf,(unsigned 
long)buf & (unsigned long)(blksize-1));
    for (offset=0;offset<blksize;offset++){
        if (!((unsigned long)(buf+offset) & (unsigned long)(blksize-1))){
            printf("offset: buf %p buf & (blksize-1) %lu offset 
%lu\n",buf+offset,(unsigned long)(buf+offset) & (unsigned 
long)(blksize-1),offset);
            break;
        }
    }
    printf("align:  buf %p buf & (blksize-1) %lu\n",buf+offset,(unsigned 
long)(buf+offset) & (unsigned long)(blksize-1));
    nb = read(fd,buf+offset,blksize);
    if (nb != blksize){
        printf("read failed fd %d buf %p buf & (blksize-1) %lu blksize 
%lu size %lu nb %d errno %d\n",
                fd,buf+offset,(unsigned long)(buf+offset) & (unsigned 
long)(blksize-1),
                (unsigned long)blksize,size,nb,errno);
        exit(1);
    }
    if (close(fd)){
        printf("close failed\n");
        exit(1);
    }
    free(buf);
    return 0;
}
/* --- end code --- */



  reply	other threads:[~2005-04-13 13:16 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-04-11 19:14 read failed EINVAL with O_DIRECT flag Yves Crespin
2005-04-12  3:49 ` Randy.Dunlap
2005-04-12 16:16   ` Yves Crespin
2005-04-12 16:47     ` Randy.Dunlap
2005-04-13 13:15       ` Yves Crespin [this message]
2005-04-13 19:26         ` Randy.Dunlap

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=425D1B83.50809@wanadoo.fr \
    --to=crespin.quartz@wanadoo.fr \
    --cc=linux-kernel@vger.kernel.org \
    --cc=rddunlap@osdl.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox