Almighty Bus Error

Loading search...

Using Direct I/O in FUSE Filesystem

While creating a filesystem using FUSE (version 2.8.3) for operating systems class, I was confronted with a problem, which manifested by ignoring read data even though the correct read size is returned (less than requested when EOF or the requested size) and the data buffer is set with the read data.

After investigating the issue for some time, the only solution mentioned was the usage of Direct I/O. However whenever I tried to open the file in fuse with direct_io enabled and tried to read, a segmentation fault would occur.

Direct Memory Access:

Direct memory access (DMA) is a feature of modern computers that allows certain hardware subsystems within the computer to access system memory independently of the central processing unit (CPU).

Using direct_io requires that every system call which deals with Direct Memory Access (e.g. file read functions) must use aligned memory. Aligned buffer can be obtained by using memalign function (or posix_memalign).

The following example is a simplified version of the solution, the file to be read must have the direct_io set to 1 in the fuse_file_info structure. Setting direct_io must be done in fuse open function.

#include <stdlib.h>
...
int example_read(const char * _name, char * _buf, size_t _count,
						off_t _offset, struct fuse_file_info * _fi) {
	char * data;
	int * fd;
	int read;

	fd = open(_name, O_RDONLY);
	// Obtains a pointer aligned with 512 with a power of 512 size. 
	data = memalign(512, 512 * (_count/512 + (_count % 512 == 0 ? 0 : 1)) );
	read = pread(fd, data, _count);

	_buf = data;
	close(fd);
	return read;
}

Thank you for reading, comments are welcome!