<<< Date Index >>>     <<< Thread Index >>>

tempfile creation on NFS, VFAT, sshfs



Here are two patches that attempt to fix tempfile creation on NFS,
VFAT and SSHFS.

The NFS problem is bug #2707, where .muttxxx temp directories are left
lying around. I've worked around this by closing the file after
creating it O_EXCL. I believe this is safe, but I'd like the local
paranoiacs to weigh in.

The SSHFS and VFAT problems are unexpected return codes from
cross-directory link attempts (AFS should have the same problem). I've
simply fallen back to rename for these errors. Again, I believe this
is kosher but would like a second opinion.

Thanks.
# HG changeset patch
# User Brendan Cully <brendan@xxxxxxxxxx>
# Date 1175496059 25200
# Node ID 2661c11c375c8032215b12013108ab4a89838df1
# Parent  4f598543d7a5fbae15efe41032c6e1c1149cec71
Make safe_open with O_EXCL friendlier for NFS.
Per #2707, when an open file is moved into a different directory over
NFS, it may leave a .nfsXXX hardlink behind. This causes the rmdir in
safe_open to fail, leaving tempdir droppings around. This patch works
around the problem by closing the file after creating it and reopening
it after rename.

diff -r 4f598543d7a5 -r 2661c11c375c lib.c
--- a/lib.c     Sun Apr 01 23:12:45 2007 -0700
+++ b/lib.c     Sun Apr 01 23:40:59 2007 -0700
@@ -575,18 +575,15 @@ int safe_open (const char *path, int fla
       rmdir (safe_dir);
       return fd;
     }
-    
+
+    /* NFS and I believe cygwin do not handle movement of open files well */
+    close (fd);
     if (mutt_put_file_in_place (path, safe_file, safe_dir) == -1)
-    {
-      close (fd);
       return -1;
-    }
-  }
-  else
-  {
-    if ((fd = open (path, flags, 0600)) < 0)
-      return fd;
-  }
+  }
+
+  if ((fd = open (path, flags & ~O_EXCL, 0600)) < 0)
+    return fd;
     
   /* make sure the file is not symlink */
   if (lstat (path, &osb) < 0 || fstat (fd, &nsb) < 0 ||
# HG changeset patch
# User Brendan Cully <brendan@xxxxxxxxxx>
# Date 1175497762 25200
# Node ID fe43f5e6b7f246e0957173a979359eb6b02aedf7
# Parent  2661c11c375c8032215b12013108ab4a89838df1
safe_rename: fall back to rename on ENOSYS and EPERM as well as EXDEV.
sshfs returns ENOSYS when attempting cross-directory links.
vfat returns EPERM.

diff -r 2661c11c375c -r fe43f5e6b7f2 lib.c
--- a/lib.c     Sun Apr 01 23:40:59 2007 -0700
+++ b/lib.c     Mon Apr 02 00:09:22 2007 -0700
@@ -447,9 +447,10 @@ int safe_rename (const char *src, const 
     
     dprint (1, (debugfile, "safe_rename: link (%s, %s) failed: %s (%d)\n", 
src, target, strerror (errno), errno));
 
-    if (errno == EXDEV)
-    {
-      dprint (1, (debugfile, "safe_rename: errno was EXDEV; trying 
rename...\n"));
+    /* FUSE may return ENOSYS. VFAT may return EPERM */
+    if (errno == EXDEV || errno == ENOSYS || errno == EPERM)
+    {
+      dprint (1, (debugfile, "safe_rename: trying rename...\n"));
       if (rename (src, target) == -1) 
       {
        dprint (1, (debugfile, "safe_rename: rename (%s, %s) failed: %s 
(%d)\n", src, target, strerror (errno), errno));

Attachment: pgpLcgUhAcJKH.pgp
Description: PGP signature