ext4, fsync(2), and perl

Christopher Chan christopher.chan at bradbury.edu.hk
Fri Mar 5 02:37:04 UTC 2010


On Friday, March 05, 2010 03:19 AM, Josef Wolf wrote:
> 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?

   my $hd;
   open($hd, $histdir);
   link ($history, "$history-$ymd_hms") unless -e "$history-$ymd_hms";
   rename "$history.$$", $history or die "Cant rename: $!";
   unless (fsync($hd)) {
     print STDERR "error: problem fsync-ing directory '$histdir': $!\n";
     close($dh);
     return 0;
   }

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

UFS and soft-updates anyone?




More information about the ubuntu-users mailing list