Bug 72242 - O_DIRECT flag in open() syscall seems to be not working
O_DIRECT flag in open() syscall seems to be not working
Status: CLOSED WORKSFORME
Product: Red Hat Linux
Classification: Retired
Component: kernel (Show other bugs)
7.3
i686 Linux
medium Severity medium
: ---
: ---
Assigned To: Arjan van de Ven
Brian Brock
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2002-08-22 06:47 EDT by Mindaugas Riauba
Modified: 2007-04-18 12:45 EDT (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2002-08-22 08:02:16 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Mindaugas Riauba 2002-08-22 06:47:41 EDT
From Bugzilla Helper:
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)

Description of problem:
I'm trying to use Direct I/O in my program by I'm not able to use O_DIRECT flag 
in open() syscall.

Version-Release number of selected component (if applicable):


How reproducible:
Always

Steps to Reproduce:
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define O_DIRECT 040000

#define BUFSIZE 8192

int main (int argc, char **argv) {

  int fd, err;
  char *buf;

  if ( argc < 2 ) {
    printf ("Usage: readttst <filename>\n");
    exit (1);
  }

  if ( (buf=valloc(BUFSIZE)) == NULL ) {
    printf ("Cannot allocate enough memory\n");
    exit (4);
  }

  fd = open (argv[1], O_RDONLY | O_DIRECT);
  
  if ( fd == -1 ) {
    printf ("Cannot open file: %s. Error: %s\n", argv[1], strerror(errno));
    exit (2);
  }
  
  if ( (err = read(fd, buf, BUFSIZE)) != 0 ) {
    if ( err == -1 ) {
      printf ("Error reading file: %s\n", strerror(errno));
      exit (3);
    }
    printf ("OK");
  }
  close (fd);
  return 0;
}

Actual Results:  Program writes:
  Error reading file: Invalid argument

Expected Results:  I should get many "OK" messages.

Additional info:
Comment 1 Arjan van de Ven 2002-08-22 06:50:42 EDT
what filesystem is this on?
Comment 2 Mindaugas Riauba 2002-08-22 08:02:08 EDT
Filesystems are ext2 and ext3. Program succeeds on /proc though.
Comment 3 Stephen Tweedie 2002-08-23 07:35:27 EDT
I just tried this on a 7.3 system, and it works fine for ext2 and fails on ext3,
as expected --- ext3 does not yet support O_DIRECT.
Comment 4 Mindaugas Riauba 2002-08-23 07:55:57 EDT
# mount
/dev/cciss/c0d0p5 on / type ext3 (rw)
none on /proc type proc (rw)
usbdevfs on /proc/bus/usb type usbdevfs (rw)
none on /dev/pts type devpts (rw,gid=5,mode=620)
none on /dev/shm type tmpfs (rw)
/dev/cciss/c0d0p6 on /var type ext3 (rw)
/dev/cciss/c0d0p1 on /boot type ext2 (rw)
# ./readtst /boot/vmlinuz-2.4.18-5smp 
Error reading file: Invalid argument
Comment 5 Stephen Tweedie 2002-08-23 09:16:11 EDT
Which kernel (uname -a), and what does "cat /proc/mounts" show?
Comment 6 Mindaugas Riauba 2002-08-23 09:30:01 EDT
# uname -a
Linux antares 2.4.18-5smp #1 SMP Mon Jun 10 15:19:40 EDT 2002 i686 unknown
# cat /proc/mounts 
rootfs / rootfs rw 0 0
/dev/root / ext3 rw 0 0
/proc /proc proc rw 0 0
usbdevfs /proc/bus/usb usbdevfs rw 0 0
none /dev/pts devpts rw 0 0
none /dev/shm tmpfs rw 0 0
/dev/cciss/c0d0p6 /var ext3 rw 0 0
/dev/cciss/c0d0p1 /boot ext2 rw 0 0
Comment 7 Mindaugas Riauba 2002-09-09 07:04:30 EDT
  My mistake. O_DIRECT produces errors only when trying to read not full block 
files' endings.
  And where to read more about programming with O_DIRECT? Which filesystems
supports it, what are the possible block sizes and so on.

[root@antares root]# mke2fs /dev/cciss/c0d0p2 
mke2fs 1.27 (8-Mar-2002)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
256000 inodes, 511020 blocks
25551 blocks (5.00%) reserved for the super user
First data block=0
16 block groups
32768 blocks per group, 32768 fragments per group
16000 inodes per group
Superblock backups stored on blocks: 
        32768, 98304, 163840, 229376, 294912

Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 32 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.
[root@antares root]# mount -t ext2 /dev/cciss/c0d0p2 /mnt/cdrom/
[root@antares root]# cd /mnt/cdrom/
[root@antares cdrom]# dd if=/dev/zero of=testing bs=8192 count=1024
1024+0 records in
1024+0 records out
[root@antares cdrom]# ~/readtst testing 
OKOKOKOKOKOKOKOKOKOKOKOKOK<and so on>
[root@antares cdrom]# cp /boot/vmlinux-2.4.18-5smp .
[root@antares cdrom]# ~/readtst vmlinux-2.4.18-5smp 
OKOKOKOKOKOKOKOKOK<.....>OKOKOKOKOKOKOKOKOKError reading file: Invalid argument
Comment 8 Arjan van de Ven 2002-09-09 07:06:52 EDT
O_DIRECT _requires_ page size sized and aligned IO. Anything else is invalid by
definition.

Note You need to log in before you can comment on or make changes to this bug.