Q: A reliable way of testing if O_DIRECT is supported

From: Terje Eggestad (terje.eggestad@scali.no)
Date: Tue Oct 16 2001 - 06:41:07 EST


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/



This archive was generated by hypermail 2b29 : Tue Oct 23 2001 - 21:00:14 EST