Re: read failed EINVAL with O_DIRECT flag

2005-04-13 Thread Randy.Dunlap
On Wed, 13 Apr 2005 15:15:47 +0200 Yves Crespin wrote:

| 
|  >| 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?

No, it's the userspace buffer.  However...
the check below isn't even reached for ext3 filesystems in
Linux 2.4.  I.e., 2.4 does not support O_DIRECT for ext3fs.
mount a partition as -t ext2 and your (modified) program
works fine.  Or use 2.6.current...

Sorry to mislead you somewhat, although you do still need
the buffer alignment fixes.


|  >| >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().


---
~Randy
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: read failed EINVAL with O_DIRECT flag

2005-04-13 Thread Yves Crespin
>| 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 
#include 
#include 
#include 
#include 
#include 
#include 
#define O_BINARY0
int main(int argc,char *argv[])
{
   struct statsbuf;
   char *buf;
   intopenFlags;
   intfd;
   intnb;
   off_tsize;
   blksize_tblksize;
   off_toffset;
   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,)<0){
   printf("fstat failed\n");
   exit(1);
   }
   blksize = sbuf.st_blksize;
   size = sbuf.st_size;
   nb = posix_memalign((void **),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
   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 --- */

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: read failed EINVAL with O_DIRECT flag

2005-04-13 Thread Yves Crespin
| 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_BINARY0
int main(int argc,char *argv[])
{
   struct statsbuf;
   char *buf;
   intopenFlags;
   intfd;
   intnb;
   off_tsize;
   blksize_tblksize;
   off_toffset;
   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;offsetblksize;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 --- */

-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: read failed EINVAL with O_DIRECT flag

2005-04-13 Thread Randy.Dunlap
On Wed, 13 Apr 2005 15:15:47 +0200 Yves Crespin wrote:

| 
|  | 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?

No, it's the userspace buffer.  However...
the check below isn't even reached for ext3 filesystems in
Linux 2.4.  I.e., 2.4 does not support O_DIRECT for ext3fs.
mount a partition as -t ext2 and your (modified) program
works fine.  Or use 2.6.current...

Sorry to mislead you somewhat, although you do still need
the buffer alignment fixes.


|  | 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().


---
~Randy
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: read failed EINVAL with O_DIRECT flag

2005-04-12 Thread Randy.Dunlap
On Tue, 12 Apr 2005 18:16:40 +0200 Yves Crespin wrote:

| I've got compilation error when I call vmalloc() from a user program 
| (w/o defined __KENEL).

Where did vmalloc() come from?
I said malloc(), not vmalloc().

| 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)?

| >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().

'man malloc' refers to posix_memalign().  That's not what I
used to test it, but if it works, it should be a good choice.


| Randy.Dunlap wrote:
| 
| >On Mon, 11 Apr 2005 21:14:17 +0200 Yves Crespin wrote:
| >
| >| Hello,
| >| 
| >| Using O_DIRECT flag, read() failed and errno is EINVAL.
| >| kernel 2.4.22
| >| Filesystem Ext3 mount on /home
| >| What's wrong ?
| >| Thanks
| >
| >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 
| >| #include 
| >| #include 
| >| #include 
| >| #include 
| >| #include 
| >| #include 
| >| 
| >| #define O_BINARY0
| >| 
| >| int main(int argc,char *argv[])
| >| {
| >| struct statsbuf;
| >| charbuf[8192];
| >| intopenFlags;
| >| intfd;
| >| intnb;
| >| intsize;
| >| 
| >| if (argc!=2){
| >| printf("Missing file name\n");
| >| exit(2);
| >| }
| >| 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,)<0){
| >| printf("fstat failed\n");
| >| exit(1);
| >| }
| >| size = sbuf.st_blksize;
| >| if (size > sizeof(buf)){
| >| printf("Page size too big\n");
| >| exit(3);
| >| }
| >| if (size > sbuf.st_size){
| >| printf("File too small\n");
| >| exit(3);
| >| }
| >| nb = read(fd,buf,size);
| >| if (nb != size){
| >| printf("read failed fd %d size %d nb %d errno 
| >| %d\n",fd,size,nb,errno);
| >| exit(1);
| >| }
| >| if (close(fd)){
| >| printf("close failed\n");
| >| exit(1);
| >| }
| >| return 0;
| >| }

---
~Randy
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: read failed EINVAL with O_DIRECT flag

2005-04-12 Thread Yves Crespin
I've got compilation error when I call vmalloc() from a user program 
(w/o defined __KENEL).
How can I obtains an buffer alignement from a "user program" ?

Randy.Dunlap wrote:
On Mon, 11 Apr 2005 21:14:17 +0200 Yves Crespin wrote:
| Hello,
| 
| Using O_DIRECT flag, read() failed and errno is EINVAL.
| kernel 2.4.22
| Filesystem Ext3 mount on /home
| What's wrong ?
| Thanks

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 
| #include 
| #include 
| #include 
| #include 
| #include 
| #include 
| 
| #define O_BINARY0
| 
| int main(int argc,char *argv[])
| {
| struct statsbuf;
| charbuf[8192];
| intopenFlags;
| intfd;
| intnb;
| intsize;
| 
| if (argc!=2){
| printf("Missing file name\n");
| exit(2);
| }
| 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,)<0){
| printf("fstat failed\n");
| exit(1);
| }
| size = sbuf.st_blksize;
| if (size > sizeof(buf)){
| printf("Page size too big\n");
| exit(3);
| }
| if (size > sbuf.st_size){
| printf("File too small\n");
| exit(3);
| }
| nb = read(fd,buf,size);
| if (nb != size){
| printf("read failed fd %d size %d nb %d errno 
| %d\n",fd,size,nb,errno);
| exit(1);
| }
| if (close(fd)){
| printf("close failed\n");
| exit(1);
| }
| return 0;
| }

---
~Randy
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
 

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: read failed EINVAL with O_DIRECT flag

2005-04-12 Thread Yves Crespin
I've got compilation error when I call vmalloc() from a user program 
(w/o defined __KENEL).
How can I obtains an buffer alignement from a user program ?

Randy.Dunlap wrote:
On Mon, 11 Apr 2005 21:14:17 +0200 Yves Crespin wrote:
| Hello,
| 
| Using O_DIRECT flag, read() failed and errno is EINVAL.
| kernel 2.4.22
| Filesystem Ext3 mount on /home
| What's wrong ?
| Thanks

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_BINARY0
| 
| int main(int argc,char *argv[])
| {
| struct statsbuf;
| charbuf[8192];
| intopenFlags;
| intfd;
| intnb;
| intsize;
| 
| if (argc!=2){
| printf(Missing file name\n);
| exit(2);
| }
| 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);
| }
| size = sbuf.st_blksize;
| if (size  sizeof(buf)){
| printf(Page size too big\n);
| exit(3);
| }
| if (size  sbuf.st_size){
| printf(File too small\n);
| exit(3);
| }
| nb = read(fd,buf,size);
| if (nb != size){
| printf(read failed fd %d size %d nb %d errno 
| %d\n,fd,size,nb,errno);
| exit(1);
| }
| if (close(fd)){
| printf(close failed\n);
| exit(1);
| }
| return 0;
| }

---
~Randy
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/
 

-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: read failed EINVAL with O_DIRECT flag

2005-04-12 Thread Randy.Dunlap
On Tue, 12 Apr 2005 18:16:40 +0200 Yves Crespin wrote:

| I've got compilation error when I call vmalloc() from a user program 
| (w/o defined __KENEL).

Where did vmalloc() come from?
I said malloc(), not vmalloc().

| 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)?

| 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().

'man malloc' refers to posix_memalign().  That's not what I
used to test it, but if it works, it should be a good choice.


| Randy.Dunlap wrote:
| 
| On Mon, 11 Apr 2005 21:14:17 +0200 Yves Crespin wrote:
| 
| | Hello,
| | 
| | Using O_DIRECT flag, read() failed and errno is EINVAL.
| | kernel 2.4.22
| | Filesystem Ext3 mount on /home
| | What's wrong ?
| | Thanks
| 
| 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_BINARY0
| | 
| | int main(int argc,char *argv[])
| | {
| | struct statsbuf;
| | charbuf[8192];
| | intopenFlags;
| | intfd;
| | intnb;
| | intsize;
| | 
| | if (argc!=2){
| | printf(Missing file name\n);
| | exit(2);
| | }
| | 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);
| | }
| | size = sbuf.st_blksize;
| | if (size  sizeof(buf)){
| | printf(Page size too big\n);
| | exit(3);
| | }
| | if (size  sbuf.st_size){
| | printf(File too small\n);
| | exit(3);
| | }
| | nb = read(fd,buf,size);
| | if (nb != size){
| | printf(read failed fd %d size %d nb %d errno 
| | %d\n,fd,size,nb,errno);
| | exit(1);
| | }
| | if (close(fd)){
| | printf(close failed\n);
| | exit(1);
| | }
| | return 0;
| | }

---
~Randy
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: read failed EINVAL with O_DIRECT flag

2005-04-11 Thread Randy.Dunlap
On Mon, 11 Apr 2005 21:14:17 +0200 Yves Crespin wrote:

| Hello,
| 
| Using O_DIRECT flag, read() failed and errno is EINVAL.
| kernel 2.4.22
| Filesystem Ext3 mount on /home
| What's wrong ?
| Thanks

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 
| #include 
| #include 
| #include 
| #include 
| #include 
| #include 
| 
| #define O_BINARY0
| 
| int main(int argc,char *argv[])
| {
| struct statsbuf;
| charbuf[8192];
| intopenFlags;
| intfd;
| intnb;
| intsize;
| 
| if (argc!=2){
| printf("Missing file name\n");
| exit(2);
| }
| 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,)<0){
| printf("fstat failed\n");
| exit(1);
| }
| size = sbuf.st_blksize;
| if (size > sizeof(buf)){
| printf("Page size too big\n");
| exit(3);
| }
| if (size > sbuf.st_size){
| printf("File too small\n");
| exit(3);
| }
| nb = read(fd,buf,size);
| if (nb != size){
| printf("read failed fd %d size %d nb %d errno 
| %d\n",fd,size,nb,errno);
| exit(1);
| }
| if (close(fd)){
| printf("close failed\n");
| exit(1);
| }
| return 0;
| }

---
~Randy
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: read failed EINVAL with O_DIRECT flag

2005-04-11 Thread Randy.Dunlap
On Mon, 11 Apr 2005 21:14:17 +0200 Yves Crespin wrote:

| Hello,
| 
| Using O_DIRECT flag, read() failed and errno is EINVAL.
| kernel 2.4.22
| Filesystem Ext3 mount on /home
| What's wrong ?
| Thanks

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_BINARY0
| 
| int main(int argc,char *argv[])
| {
| struct statsbuf;
| charbuf[8192];
| intopenFlags;
| intfd;
| intnb;
| intsize;
| 
| if (argc!=2){
| printf(Missing file name\n);
| exit(2);
| }
| 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);
| }
| size = sbuf.st_blksize;
| if (size  sizeof(buf)){
| printf(Page size too big\n);
| exit(3);
| }
| if (size  sbuf.st_size){
| printf(File too small\n);
| exit(3);
| }
| nb = read(fd,buf,size);
| if (nb != size){
| printf(read failed fd %d size %d nb %d errno 
| %d\n,fd,size,nb,errno);
| exit(1);
| }
| if (close(fd)){
| printf(close failed\n);
| exit(1);
| }
| return 0;
| }

---
~Randy
-
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/