Re: [PATCH v2] Add an option not to use link(src, dest) && unlink(src) when that is unreliable

Subsystems: the rest

6 messages, 5 authors, 2016-06-15 · open the first message on its own page

Re: [PATCH v2] Add an option not to use link(src, dest) && unlink(src) when that is unreliable

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:46:39

Johannes Schindelin [off-list ref] writes:
It seems that accessing NTFS partitions with ufsd (at least on my EeePC)
has an unnerving bug: if you link() a file and unlink() it right away,
the target of the link() will have the correct size, but consist of NULs.

It seems as if the calls are simply not serialized correctly, as single-stepping
through the function move_temp_to_file() works flawlessly.

As ufsd is "Commertial software" (sic!), I cannot fix it, and have to work
around it in Git.

At the same time, it seems that this fixes msysGit issues 222 and 229 to
assume that Windows cannot handle link() && unlink().

Signed-off-by: Johannes Schindelin <redacted>
Acked-by: Johannes Sixt <redacted>
Hannes, are you ok with this?
quoted hunk
diff --git a/environment.c b/environment.c
index 4696885..10578d2 100644
--- a/environment.c
+++ b/environment.c
@@ -43,6 +43,10 @@ unsigned whitespace_rule_cfg = WS_DEFAULT_RULE;
 enum branch_track git_branch_track = BRANCH_TRACK_REMOTE;
 enum rebase_setup_type autorebase = AUTOREBASE_NEVER;
 enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED;
+#ifndef UNRELIABLE_HARDLINKS
+#define UNRELIABLE_HARDLINKS 0
+#endif
+int unreliable_hardlinks = UNRELIABLE_HARDLINKS;
Hmm, this ifndef/define/endif is somewhat yucky to see especially in a .c
source file.  Sorry, I do not think of a better alternative, though.

	int unreliable_hardlinks = defined(UNRELIABLE_HARDLINKS)

would not work either X-<.
quoted hunk
diff --git a/sha1_file.c b/sha1_file.c
index 8fe135d..bb6eecf 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2225,7 +2225,9 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
 {
 	int ret = 0;
 
-	if (link(tmpfile, filename))
+	if (unreliable_hardlinks)
+		ret = ~EEXIST; /* anything but EEXIST */
It is a bit too far away from the:

	if (ret && ret != EEXIST)

you are trying to trigger with this hack, and without seeing that "if" in
the context anybody would go "Huh?".  It is a good sign that this is
fragile (the later "if" may be rewritten by somebody else without
realizing this hack exists).  Besides, it is (rather, "happens to be at
this moment") "anything non-zero but EEXIST".

I have a feeling that it would be much less fragile to write it like this,
as a label warns anybody touching the code to check where else the control
flow may come from.
diff --git a/sha1_file.c b/sha1_file.c
index 8fe135d..11969fc 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -2225,7 +2225,9 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
 {
 	int ret = 0;
 
-	if (link(tmpfile, filename))
+	if (unreliable_hardlinks)
+		goto try_rename;
+	else if (link(tmpfile, filename))
 		ret = errno;
 
 	/*
@@ -2240,6 +2242,7 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
 	 * left to unlink.
 	 */
 	if (ret && ret != EEXIST) {
+	try_rename:
 		if (!rename(tmpfile, filename))
 			goto out;
 		ret = errno;

Re: [PATCH v2] Add an option not to use link(src, dest) && unlink(src) when that is unreliable

From: Linus Torvalds <torvalds@linux-foundation.org>
Date: 2016-06-15 22:46:39


On Sat, 25 Apr 2009, Junio C Hamano wrote:
quoted hunk
@@ -2225,7 +2225,9 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
 {
 	int ret = 0;
 
-	if (link(tmpfile, filename))
+	if (unreliable_hardlinks)
+		goto try_rename;
Much better.

		Linus

Re: [PATCH v2] Add an option not to use link(src, dest) && unlink(src) when that is unreliable

From: Michael Gaber <hidden>
Date: 2016-06-15 22:46:39

Linus Torvalds schrieb:
On Sat, 25 Apr 2009, Junio C Hamano wrote:
quoted
@@ -2225,7 +2225,9 @@ int move_temp_to_file(const char *tmpfile, const char *filename)
 {
 	int ret = 0;
 
-	if (link(tmpfile, filename))
+	if (unreliable_hardlinks)
+		goto try_rename;
Much better.

		Linus
http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Re: [PATCH v2] Add an option not to use link(src, dest) && unlink(src) when that is unreliable

From: Linus Torvalds <torvalds@linux-foundation.org>
Date: 2016-06-15 22:46:39


On Sat, 25 Apr 2009, Michael Gaber wrote:
http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF
Yeah, and people thought "pascal" was a good language because it didn't 
contain "break" statements to break out of loops, or "return" statements 
to break out of functions early.

Too bad. They were wrong.

			Linus

Re: [PATCH v2] Add an option not to use link(src, dest) && unlink(src) when that is unreliable

From: Johannes Sixt <hidden>
Date: 2016-06-15 22:46:39

On Samstag, 25. April 2009, Junio C Hamano wrote:
Johannes Schindelin [off-list ref] writes:
quoted
It seems that accessing NTFS partitions with ufsd (at least on my EeePC)
has an unnerving bug: if you link() a file and unlink() it right away,
the target of the link() will have the correct size, but consist of NULs.

It seems as if the calls are simply not serialized correctly, as
single-stepping through the function move_temp_to_file() works
flawlessly.

As ufsd is "Commertial software" (sic!), I cannot fix it, and have to
work around it in Git.

At the same time, it seems that this fixes msysGit issues 222 and 229 to
assume that Windows cannot handle link() && unlink().

Signed-off-by: Johannes Schindelin <redacted>
Acked-by: Johannes Sixt <redacted>
Hannes, are you ok with this?
Yes. We have been using rename() instead of link() on Windows until recently 
anyway (until link() was implemented, 7be401e06, 2009-01-24). There is no 
regression to be expected from this side.

-- Hannes

Re: [PATCH v2] Add an option not to use link(src, dest) && unlink(src) when that is unreliable

From: Jay Soffian <hidden>
Date: 2016-06-15 22:46:39

On Sat, Apr 25, 2009 at 2:38 PM, Michael Gaber [off-list ref] wrote:
http://www.cs.utexas.edu/users/EWD/ewd02xx/EWD215.PDF
http://www.bartleby.com/59/3/foolishconsi.html

j.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help