ext4, fsync(2), and perl

Josef Wolf jw at raven.inka.de
Thu Mar 4 19:19:23 UTC 2010


Hello,

In the ext4/fsync/rename discussion, Ted Ts'o states that if an
application wants to guarantee that the new version of a file will
be present after a crash, it needs to

    fd = open(”foo.new”, O_WRONLY);
    write(fd, buf, bufsize);
    fsync(fd);
    close(fd);
    rename(”foo.new”, “foo”);

and do an additional fsync to the containing directory.

Now, I am trying to do that from perl. I've come up with this:

   my $histdir = "/some/dir";
   my $history = "$histdir/history";

   # writing/flushing the file works fine
   #
   my $h = new IO::Handle;
   open ($h, ">", "$history.$$") or die "$history.$$: $!";
   $h->print (Dump ($vers, $hist));
   $h->flush && $h->sync && $h->close or die "$history.$$: $!";

   # but for the directory, I have to comment the sync operations to
   # avoid an "illegal filehandle" error
   #
   my $hd = new IO::Handle;
   opendir ($hd, $histdir) or die "open $histdir: $!";
   link ($history, "$history-$ymd_hms") unless -e "$history-$ymd_hms";
#   $hd->sync or die "sync $histdir: $!";
   rename "$history.$$", $history or die "Cant rename: $!";
#   $hd->sync && $hd->closedir or die "closedir $histdir: $!";

Any ideas how to properly fsync the directory in perl?

PS: http://thunk.org/tytso/blog/2009/03/15/dont-fear-the-fsync/




More information about the ubuntu-users mailing list