git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Michael Haggerty <mhagger@alum.mit.edu>
To: Junio C Hamano <gitster@pobox.com>
Cc: "Johannes Sixt" <j6t@kdbg.org>,
	"Torsten Bögershausen" <tboegi@web.de>,
	"Jeff King" <peff@peff.net>,
	"Ronnie Sahlberg" <sahlberg@google.com>,
	"Jonathan Nieder" <jrnieder@gmail.com>,
	git@vger.kernel.org, "Michael Haggerty" <mhagger@alum.mit.edu>
Subject: [PATCH v7 18/38] close_lock_file(): if close fails, roll back
Date: Wed,  1 Oct 2014 12:28:22 +0200	[thread overview]
Message-ID: <1412159322-2622-19-git-send-email-mhagger@alum.mit.edu> (raw)
In-Reply-To: <1412159322-2622-1-git-send-email-mhagger@alum.mit.edu>

If closing an open lockfile fails, then we cannot be sure of the
contents of the lockfile, so there is nothing sensible to do but
delete it. This change also insures that the lock_file object is left
in a defined state in this error path (namely, unlocked).

The only caller that is ultimately affected by this change is
try_merge_strategy() -> write_locked_index(), which can call
close_lock_file() via various execution paths. This caller uses a
static lock_file object which previously could have been reused after
a failed close_lock_file() even though it was still in locked state.
This change causes the lock_file object to be unlocked on failure,
thus fixing this error-handling path.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 Documentation/technical/api-lockfile.txt |  7 ++++---
 lockfile.c                               | 28 ++++++++++++++++++----------
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/Documentation/technical/api-lockfile.txt b/Documentation/technical/api-lockfile.txt
index 6538610..d3bf940 100644
--- a/Documentation/technical/api-lockfile.txt
+++ b/Documentation/technical/api-lockfile.txt
@@ -162,9 +162,10 @@ close_lock_file::
 	Take a pointer to the `struct lock_file` initialized with an
 	earlier call to `hold_lock_file_for_update` or
 	`hold_lock_file_for_append`, and close the file descriptor.
-	Return 0 upon success or a negative value on failure to
-	close(2). Usually `commit_lock_file` or `rollback_lock_file`
-	should be called after `close_lock_file`.
+	Return 0 upon success. On failure to `close(2)`, return a
+	negative value and rollback the lock file. Usually
+	`commit_lock_file` or `rollback_lock_file` should eventually
+	be called if `close_lock_file` succeeds.
 
 reopen_lock_file::
 
diff --git a/lockfile.c b/lockfile.c
index c897dd8..1d18c67 100644
--- a/lockfile.c
+++ b/lockfile.c
@@ -37,13 +37,14 @@
  *   lockfile, and owner holds the PID of the process that locked the
  *   file.
  *
- * - Locked, lockfile closed (after close_lock_file()).  Same as the
- *   previous state, except that the lockfile is closed and fd is -1.
+ * - Locked, lockfile closed (after successful close_lock_file()).
+ *   Same as the previous state, except that the lockfile is closed
+ *   and fd is -1.
  *
- * - Unlocked (after commit_lock_file(), rollback_lock_file(), or a
- *   failed attempt to lock).  In this state, filename[0] == '\0' and
- *   fd is -1.  The object is left registered in the lock_file_list,
- *   and on_list is set.
+ * - Unlocked (after commit_lock_file(), rollback_lock_file(), a
+ *   failed attempt to lock, or a failed close_lock_file()). In this
+ *   state, filename[0] == '\0' and fd is -1. The object is left
+ *   registered in the lock_file_list, and on_list is set.
  */
 
 static struct lock_file *lock_file_list;
@@ -284,7 +285,13 @@ int close_lock_file(struct lock_file *lk)
 		return 0;
 
 	lk->fd = -1;
-	return close(fd);
+	if (close(fd)) {
+		int save_errno = errno;
+		rollback_lock_file(lk);
+		errno = save_errno;
+		return -1;
+	}
+	return 0;
 }
 
 int reopen_lock_file(struct lock_file *lk)
@@ -330,7 +337,8 @@ void rollback_lock_file(struct lock_file *lk)
 	if (!lk->filename[0])
 		return;
 
-	close_lock_file(lk);
-	unlink_or_warn(lk->filename);
-	lk->filename[0] = 0;
+	if (!close_lock_file(lk)) {
+		unlink_or_warn(lk->filename);
+		lk->filename[0] = 0;
+	}
 }
-- 
2.1.0

  parent reply	other threads:[~2014-10-01 10:30 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-01 10:28 [PATCH v7 00/38] Lockfile correctness and refactoring Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 01/38] unable_to_lock_die(): rename function from unable_to_lock_index_die() Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 02/38] api-lockfile: revise and expand the documentation Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 03/38] close_lock_file(): exit (successfully) if file is already closed Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 04/38] rollback_lock_file(): do not clear filename redundantly Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 05/38] rollback_lock_file(): exit early if lock is not active Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 06/38] rollback_lock_file(): set fd to -1 Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 07/38] lockfile: unlock file if lockfile permissions cannot be adjusted Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 08/38] hold_lock_file_for_append(): release lock on errors Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 09/38] lock_file(): always initialize and register lock_file object Michael Haggerty
2014-10-01 11:27   ` René Scharfe
2014-10-01 11:38     ` Michael Haggerty
2014-10-01 20:36       ` Junio C Hamano
2014-10-01 10:28 ` [PATCH v7 10/38] lockfile.c: document the various states of lock_file objects Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 11/38] cache.h: define constants LOCK_SUFFIX and LOCK_SUFFIX_LEN Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 12/38] delete_ref_loose(): don't muck around in the lock_file's filename Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 13/38] prepare_index(): declare return value to be (const char *) Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 14/38] lock_file(): exit early if lockfile cannot be opened Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 15/38] remove_lock_file(): call rollback_lock_file() Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 16/38] commit_lock_file(): inline temporary variable Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 17/38] commit_lock_file(): die() if called for unlocked lockfile object Michael Haggerty
2014-10-01 10:28 ` Michael Haggerty [this message]
2014-10-01 10:28 ` [PATCH v7 19/38] commit_lock_file(): rollback lock file on failure to rename Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 20/38] api-lockfile: document edge cases Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 21/38] dump_marks(): remove a redundant call to rollback_lock_file() Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 22/38] git_config_set_multivar_in_file(): avoid " Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 23/38] lockfile: avoid transitory invalid states Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 24/38] struct lock_file: declare some fields volatile Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 25/38] try_merge_strategy(): remove redundant lock_file allocation Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 26/38] try_merge_strategy(): use a statically-allocated lock_file object Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 27/38] commit_lock_file(): use a strbuf to manage temporary space Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 28/38] Change lock_file::filename into a strbuf Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 29/38] resolve_symlink(): use a strbuf for internal scratch space Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 30/38] resolve_symlink(): take a strbuf parameter Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 31/38] trim_last_path_component(): replace last_path_elm() Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 32/38] Extract a function commit_lock_file_to() Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 33/38] Rename LOCK_NODEREF to LOCK_NO_DEREF Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 34/38] lockfile.c: rename static functions Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 35/38] get_locked_file_path(): new function Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 36/38] hold_lock_file_for_append(): restore errno before returning Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 37/38] Move read_index() definition to read-cache.c Michael Haggerty
2014-10-01 10:28 ` [PATCH v7 38/38] lockfile.h: extract new header file for the functions in lockfile.c Michael Haggerty
2014-10-01 21:05 ` [PATCH v7 00/38] Lockfile correctness and refactoring Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1412159322-2622-19-git-send-email-mhagger@alum.mit.edu \
    --to=mhagger@alum.mit.edu \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=j6t@kdbg.org \
    --cc=jrnieder@gmail.com \
    --cc=peff@peff.net \
    --cc=sahlberg@google.com \
    --cc=tboegi@web.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).