Q: A reliable way of testing if O_DIRECT is supported

Terje Eggestad (terje.eggestad@scali.no)
16 Oct 2001 13:41:07 +0200


Is there a reliable way of testing if O_DIRECT is supported by the
kernel?

I've a test program as follows:

======================================================================
#include <errno.h>
#include <unistd.h>

#define __USE_GNU
#include <fcntl.h>

int main()
{
int fd, flags, rc;
char * buffer;

buffer = (char *) malloc(getpagesize()*2);
buffer = (char *) (((long)buffer) / getpagesize() * getpagesize()) +
getpagesize();
fd = open ("/tmp/checkdirect.dat", O_RDWR|O_CREAT|O_TRUNC|O_DIRECT,
0600);
if (fd == -1) {
printf("open failed with errno=%d\n", errno);
exit(errno);
};

printf("open OK\n", errno);
unlink ("/tmp/checkdirect.dat");

flags = fcntl(fd, F_GETFL);
printf("fcntl(fd, F_GETFL) retuned %#o \n", flags);

printf("setting O_DIRECT(=%#o) flag with fcntl()\n", O_DIRECT);
fcntl(fd, F_SETFL, O_DIRECT|flags);

flags = fcntl(fd, F_GETFL);
printf("fcntl(fd, F_GETFL) retuned %#o \n", flags, O_DIRECT);
if (!(flags & O_DIRECT)) {
printf("failed to set O_DIRECT flag errno=%d\n", errno);
exit(errno);
};

rc = write(fd, buffer, getpagesize());
if (rc != getpagesize()) {
printf("aligned write failed with errno=%d\n", errno);
exit(errno);
};
printf("aligned write OK\n", errno);
rc = write(fd, buffer+100, 100);
if (rc != 100) {
printf("unaligned write failed with errno=%d\n", errno);
exit(errno);
};
printf("unaligned write OK\n", errno);
};
======================================================================

Now on a 2.4.10 kernel it produces (correctly)

open OK
fcntl(fd, F_GETFL) retuned 040002
setting O_DIRECT(=040000) flag with fcntl()
fcntl(fd, F_GETFL) retuned 040002
aligned write OK
unaligned write failed with errno=22

But on both a RH6.2 with a 2.2.19 and a RH7.1 with 2.4.3 (both non
stock) it gives:

open OK
fcntl(fd, F_GETFL) retuned 040002
setting O_DIRECT(=040000) flag with fcntl()
fcntl(fd, F_GETFL) retuned 040002
aligned write OK
unaligned write OK

I guess the open(,,O_DIRECT) *should* have failed on earlier kernels,
but since they don't I need another way of testing if directio is
supported.

TJ

-- 
_________________________________________________________________________

Terje Eggestad terje.eggestad@scali.no Scali Scalable Linux Systems http://www.scali.com

Olaf Helsets Vei 6 tel: +47 22 62 89 61 (OFFICE) P.O.Box 70 Bogerud +47 975 31 574 (MOBILE) N-0621 Oslo fax: +47 22 62 89 51 NORWAY _________________________________________________________________________

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