Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 603058 Details for
Bug 846751
Does not work on file systems w/o support for hardlinks
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
git patch against gnome-keyring 3.4.1.
Provide-fallback-for-file-systems-without-working-ha.patch (text/plain), 8.16 KB, created by
Werner Koch
on 2012-08-08 15:29:52 UTC
(
hide
)
Description:
git patch against gnome-keyring 3.4.1.
Filename:
MIME Type:
Creator:
Werner Koch
Created:
2012-08-08 15:29:52 UTC
Size:
8.16 KB
patch
obsolete
>From 6c06cab7d9df5b98211a947614152c3444a512a5 Mon Sep 17 00:00:00 2001 >From: Werner Koch <wk@gnupg.org> >Date: Wed, 1 Aug 2012 17:23:19 +0200 >Subject: [PATCH] Provide fallback for file systems without working hardlinks > >* pkcs11/gkm/gkm-transaction.c (O_BINARY): Add fallback for Windows. >(copy_to_temp_file): New. >(begin_link_temporary_if_exists): Detect failure link(2) and resort to >a copy file method. >-- > >See bug 657234 for a description of the problem. The culprit is the >CIFS implementation on EMC servers. At least VFAT file systems should >have the same problem, thus the patch is a general improvement. >--- > pkcs11/gkm/gkm-transaction.c | 156 ++++++++++++++++++++++++++++++++++++++---- > 1 files changed, 143 insertions(+), 13 deletions(-) > >diff --git a/pkcs11/gkm/gkm-transaction.c b/pkcs11/gkm/gkm-transaction.c >index a15f810..9c7f287 100644 >--- a/pkcs11/gkm/gkm-transaction.c >+++ b/pkcs11/gkm/gkm-transaction.c >@@ -31,6 +31,10 @@ > #include <string.h> > #include <unistd.h> > >+#ifndef O_BINARY >+# define O_BINARY 0 >+#endif >+ > enum { > PROP_0, > PROP_COMPLETED, >@@ -168,10 +172,96 @@ complete_link_temporary (GkmTransaction *self, GObject *unused, gpointer user_da > return ret; > } > >+ >+/* Copy the file SRCNAME to the file DSTNAME. If DSTNAME already >+ exists -1 is returned and ERRNO set to EEXIST. Returns 0 on >+ success. */ >+static int >+copy_to_temp_file (const char *dstname, const char *srcname) >+{ >+ int dstfd, srcfd; >+ int nread, nwritten; >+ int saveerr; >+ char *bufp; >+ char buffer[512]; /* If you change this size, please also adjust */ >+ /* test-transaction.c:test_write_large_file. */ >+ >+ do { >+ srcfd = g_open (srcname, (O_RDONLY | O_BINARY)); >+ } while (srcfd == -1 && errno == EINTR); >+ if (srcfd == -1) { >+ saveerr = errno; >+ g_warning ("couldn't open file to " >+ "take temporary copy from: %s: %s", >+ srcname, g_strerror (saveerr)); >+ errno = saveerr; >+ return -1; >+ } >+ >+ do { >+ dstfd = g_open (dstname, >+ (O_WRONLY | O_CREAT | O_EXCL | O_BINARY), >+ (S_IRUSR | S_IWUSR)); >+ } while (dstfd == -1 && errno == EINTR); >+ if (dstfd == -1) { >+ saveerr = errno; >+ close (srcfd); >+ errno = saveerr; >+ return -1; >+ } >+ >+ while ((nread = read (srcfd, buffer, sizeof buffer))) { >+ if (nread == -1 && errno == EINTR) >+ continue; >+ if (nread == -1) { >+ saveerr = errno; >+ g_warning ("error reading file to " >+ "take temporary copy from: %s: %s", >+ srcname, g_strerror (saveerr)); >+ goto failure; >+ } >+ >+ bufp = buffer; >+ do { >+ do { >+ nwritten = write (dstfd, bufp, nread); >+ } while (nwritten == -1 && errno == EINTR); >+ if (nwritten == -1) { >+ saveerr = errno; >+ g_warning ("error wrinting to " >+ "temporary file: %s: %s", >+ dstname, g_strerror (saveerr)); >+ goto failure; >+ } >+ g_assert (nwritten <= nread); >+ nread -= nwritten; >+ bufp += nwritten; >+ } while (nread > 0); >+ } >+ /* EOF reached. */ >+ if (close (dstfd)) { >+ saveerr = errno; >+ g_warning ("error closing temporary file: %s: %s", >+ dstname, g_strerror (saveerr)); >+ goto failure; >+ } >+ close (srcfd); >+ return 0; >+ >+failure: >+ close (dstfd); /* (Doesn't harm if we try a second time.) */ >+ if (g_unlink (dstname)) >+ g_warning ("couldn't remove temporary file: %s: %s", >+ dstname, g_strerror (saveerr)); >+ close (srcfd); >+ errno = saveerr; >+ return -1; >+} >+ >+ > static gboolean > begin_link_temporary_if_exists (GkmTransaction *self, const gchar *filename, gboolean *exists) > { >- gchar *result; > guint i = 0; > > g_assert (GKM_IS_TRANSACTION (self)); >@@ -180,27 +270,67 @@ begin_link_temporary_if_exists (GkmTransaction *self, const gchar *filename, gbo > g_assert (exists); > > for (i = 0; i < MAX_TRIES; ++i) { >+ struct stat sb; >+ unsigned int nlink; >+ int stat_failed = 0; > > *exists = TRUE; > >- /* Try to link to random temporary file names */ >- result = g_strdup_printf ("%s.temp-%d", filename, g_random_int_range (0, G_MAXINT)); >- if (link (filename, result) == 0) { >- gkm_transaction_add (self, NULL, complete_link_temporary, result); >- return TRUE; >- } >- >- g_free (result); >- >- /* The original file does not exist */ >- if (errno == ENOENT || errno == ENOTDIR) { >+ /* Try to link to random temporary file names. We try >+ * to use a hardlink to create a copy but if that >+ * fails (i.e. not supported by the FS), we copy the >+ * entire file. The result should be the same except >+ * that the file times will change if we need to >+ * rollback the transaction. */ >+ if (stat (filename, &sb)) { >+ stat_failed = 1; >+ } else { >+ gchar *result; >+ >+ result = g_strdup_printf >+ ("%s.temp-%d", filename, >+ g_random_int_range (0, G_MAXINT)); >+ nlink = (unsigned int)sb.st_nlink; >+ /* The result code of link(2) is not reliable. >+ * Unless it fails with EEXIST we stat the >+ * file to check for success. Note that there >+ * is a race here: If another process adds a >+ * link to the source file between link and >+ * stat, the check on the increased link count >+ * will fail. Fortunately the case for >+ * hardlinks are not working solves it. */ >+ if (link (filename, result) && errno == EEXIST) { >+ /* This is probably a valid error. >+ * Let us try another temporary file. */ >+ } else if (stat (filename, &sb)) { >+ stat_failed = 1; >+ } else { >+ if ((sb.st_nlink == nlink + 1) >+ || !copy_to_temp_file (result, >+ filename)) { >+ /* Either the link worked or >+ * the copy succeeded. */ >+ gkm_transaction_add >+ (self, NULL, >+ complete_link_temporary, >+ result); >+ return TRUE; >+ } >+ } >+ >+ g_free (result); >+ } >+ >+ if (stat_failed && (errno == ENOENT || errno == ENOTDIR)) { >+ /* The original file does not exist */ > *exists = FALSE; > return TRUE; > } > > /* If exists, try again, otherwise fail */ > if (errno != EEXIST) { >- g_warning ("couldn't create temporary file for: %s: %s", filename, g_strerror (errno)); >+ g_warning ("couldn't create temporary file " >+ "for: %s: %s", filename, g_strerror (errno)); > gkm_transaction_fail (self, CKR_DEVICE_ERROR); > return FALSE; > } >-- >1.7.7.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 846751
: 603058