2

I'm searching for a solution to solve the above described problem.

Here's my "doesn't working code". charsInCurrentBuffer returns always -1!

#define BUFSIZE 512

char *bufferA = new char[BUFSIZE];
char *bufferB = new char[BUFSIZE];

const char *inputFile = "in.txt";

if ( (fdInputFile = open(inputFile, O_DIRECT) ) != -1) {
    cout << "input opened!" << endl;
} else {
    cout << "can't open input file!";
}

int charsInCurrentBuffer = read(fdInputFile, currBuffer, BUFSIZE);
cout << charsInCurrentBuffer << endl;
Community
  • 1
  • 1
silentCoder
  • 23
  • 1
  • 5

1 Answers1

8

When you read from an O_DIRECT fd, the "alignment of the user buffer and the file offset must all be multiples of the logical block size of the file system" (quoted from the open man page) on Linux. Other environments might have different constraints on this, and it's in fact filesystem dependent.

That's not going to be the case with new generally (unless you get lucky).

You should consider using a posix_memalign function if your platform has that, or simply allocate a larger buffer (BLOCK_SIZE + BUFSIZE) and use the block-size aligned part of it.

If you want to stick with new, you're going to need to use some form of placement new combined with the above, but I'm not familiar enough with that to show how that would work.

For reference, see for example this thread on LKML, or the Notes section of the above-quoted man page.

Mat
  • 202,337
  • 40
  • 393
  • 406
  • in fact, `man 2 open` says in the `NOTES` section on `O_DIRECT`: `The O_DIRECT flag may impose alignment restrictions on the length and address of userspace buffers and the file offset of I/Os. In Linux alignment restrictions vary by file system and kernel version and might be absent entirely. However there is currently no file system-independent interface for an application to discover these restrictions for a given file or file system.`. – Andre Holzner May 14 '11 at 10:51
  • It should be noted that things have gotten a little easier since Linux 2.6: "Under Linux 2.4, transfer sizes, and the alignment of the user buffer and the file offset must all be multiples of the logical block size of the filesystem. **Under Linux 2.6, alignment to 512-byte boundaries suffices.**" (http://man7.org/linux/man-pages/man2/open.2.html) – void-pointer Jan 02 '14 at 13:28