fsync() fails when QNX6's snapshot is disabled

fsync() and fdatasync() fail with EAGAIN(11) when QNX6’s snapshot is disabled.

At first, I disabled QNX6’s snapshot by chattr utility like as follows.

$ chattr -snapshot /mnt/data # /mnt/data is QNX6 Power-Safe filesystem Hard disk drive

Next, I run the following simple program.

[code]#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

int main(int argc, char** argv)
{
int fd = open("./test.txt", O_CREAT|O_RDWR);
if (fd == -1) {
printf("%s\n", strerror(errno));
return -1;
}

const char* str = “Hello world\n”;
write(fd, str, strlen(str));

int rc = 0;
rc = fsync(fd);
printf(“fsync, rc=%d, %s(%d)\n”, rc, strerror(errno), errno);

rc = fdatasync(fd);
printf(“fdatasync, rc=%d, %s(%d)\n”, rc, strerror(errno), errno);

close(fd);
return 0;
}[/code]

Then, both fsync and fdatasync failed with errno=11(EAGAIN, Resource temporarily unavailable).

Do I need to avoid executing fsync and fdatasync explicitly when snapshot is disabled?

The reason why I tested this snapshot and fsync combination is I want to make my own high performance ‘cp’ command that can run on both snapshot-enabled/disabled filesystem.

According to the follwing QNX6’s Power-Safe filesystem performance manual section;

QNX6 Power-Safe filesystem:
http://www.qnx.com/developers/docs/6.4.0/neutrino/sys_arch/fsys.html#QNX6_filesystem

when you perform a higher-level write operation like ‘cp’, you may be able to gain write performance improvement by disabling Power-Safe filesystem’s snapshot function around the operation.

For a command like ‘cp’, intermediate snapshots are useless, because I’m interested in complete status of the file. Recovering to an intermediate snapshot during the cp doesn’t make sense.

If I need to test if snapshot is enabled or not before executing fsync, is there a way to know it?

I found that failing with EAGAIN when snapshot is diabled was correct behavior. It was clearly documented in the following page.

QNX6 Snapshots
http://www.qnx.com/developers/docs/660/index.jsp?topic=%2Fcom.qnx.doc.neutrino.user_guide%2Ftopic%2Ffsystems_QNX6_snapshots.html

Then, what is the best practice for fsync() on snapshot-disabled filesystem? Should I just ignore the EAGIN error or prevent to execute fsync by checking filesystem’s status?

This following is just a guess on my part because I’ve never used the Snapshot feature.

But from reading the doc’s you linked to, I would say the EAGAIN error indicates that the snapshot is ‘out of date’ because it’s been disabled (ie it has pending updates) and thus the write() hasn’t happened yet.

Presumably when you re-enable Snapshot after doing your performance improvement ‘cp’ it will do any pending updates and then fsync() will return with a success.

You might be able to test this by doing a while-loop on the EAGAIN error condition and letting your program sit there in a loop and then re-enabling snapshot and see if it clears.

eg
int rc=fsync(fd);
while (errno==EAGAIN)
{
delay (50) // 50 ms
rc=fsync(fd);
}

Then from a command terminal re-enable Snapshot and see if you exit your loop. If you don’t exit the loop after re-enable it may instead indicate that you need to issue the write() again.

Tim