git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 18/22] lockfile: also keep track of the filename of the file being locked

From
Michael Haggerty <mhagger@alum.mit.edu>
Date
Apr 1, 2014, 15:58 UTC
Message-ID
<1396367910-7299-19-git-send-email-mhagger@alum.mit.edu>
In-Reply-To
<1396367910-7299-1-git-send-email-mhagger@alum.mit.edu>

This reduces the amount of string editing gyrations and makes it unnecessary for callers to know how to derive the filename from the lock_filename.

Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu>
---
 cache.h    |  1 +
 lockfile.c | 57 ++++++++++++++++++++++++++++++++-------------------------
 refs.c     | 10 ++--------
 3 files changed, 35 insertions(+), 33 deletions(-)
diff --git a/cache.h b/cache.h
index 3d0a835..0fefc66 100644
--- a/cache.h
+++ b/cache.h
@@ -538,6 +538,7 @@ struct lock_file {
 	int fd;
 	pid_t owner;
 	unsigned char flags;
+	struct strbuf filename;
 	struct strbuf lock_filename;
 };
 #define LOCK_DIE_ON_ERROR 1
diff --git a/lockfile.c b/lockfile.c
index 87b40c4..07b5c21 100644
--- a/lockfile.c
+++ b/lockfile.c
@@ -35,24 +35,26 @@
  *
  * - Uninitialized.  In this state the object's flags field must be
  *   zero but the rest of the contents need not be initialized.  In
- *   particular, the lock_filename strbuf should *not* be initialized
- *   externally.  The first time the object is used in any way, it is
- *   initialized, permanently registered in the lock_file_list, and
- *   flags & LOCK_FLAGS_ON_LIST is set.
+ *   particular, the filename and lock_filename strbufs should *not*
+ *   be initialized externally.  The first time the object is used in
+ *   any way, it is initialized, permanently registered in the
+ *   lock_file_list, and flags & LOCK_FLAGS_ON_LIST is set.
  *
  * - Locked, lockfile open (after hold_lock_file_for_update() or
  *   hold_lock_file_for_append()).  In this state, the lockfile
- *   exists, lock_filename holds the filename of the lockfile, fd
- *   holds a file descriptor open for writing to the lockfile, and
- *   owner holds the PID of the process that locked the file.
+ *   exists, filename holds the filename of the locked file,
+ *   lock_filename holds the filename of the lockfile, fd holds a file
+ *   descriptor open for writing to the 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.
  *
  * - Unlocked (after commit_lock_file(), rollback_lock_file(), or a
- *   failed attempt to lock).  In this state, lock_filename is the
- *   empty string and fd is -1.  The object is left registered in the
- *   lock_file_list, and flags & LOCK_FLAGS_ON_LIST is set.
+ *   failed attempt to lock).  In this state, filename and
+ *   lock_filename are the empty string and fd is -1.  The object is
+ *   left registered in the lock_file_list, and flags &
+ *   LOCK_FLAGS_ON_LIST is set.
  *
  * See Documentation/api-lockfile.txt for more information.
  */
@@ -164,25 +166,30 @@ static int lock_file(struct lock_file *lk, const char *path, int flags)
 
 	lk->owner = getpid();
 	if (lk->flags & LOCK_FLAGS_ON_LIST) {
-		assert(!lk->lock_filename.len); /* object not already in use */
-		if (strbuf_avail(&lk->lock_filename) < path_len + LOCK_SUFFIX_LEN)
-			strbuf_grow(&lk->lock_filename, path_len + LOCK_SUFFIX_LEN);
+		/* Sanity check that object is not already in use: */
+		assert(!lk->filename.len);
+		assert(!lk->lock_filename.len);
 	} else {
 		/* Initialize *lk and add it to lock_file_list: */
 		lk->fd = -1;
 		lk->flags |= LOCK_FLAGS_ON_LIST;
-		strbuf_init(&lk->lock_filename, path_len + LOCK_SUFFIX_LEN);
+		strbuf_init(&lk->filename, path_len);
+		strbuf_init(&lk->lock_filename, 0);
 		lk->next = lock_file_list;
 		lock_file_list = lk;
 	}
 
-	strbuf_add(&lk->lock_filename, path, path_len);
+	strbuf_add(&lk->filename, path, path_len);
 	if (!(flags & LOCK_NODEREF))
-		resolve_symlink(&lk->lock_filename);
+		resolve_symlink(&lk->filename);
+
+	strbuf_grow(&lk->lock_filename, lk->filename.len + LOCK_SUFFIX_LEN);
+	strbuf_addbuf(&lk->lock_filename, &lk->filename);
 	strbuf_addstr(&lk->lock_filename, ".lock");
 
 	lk->fd = open(lk->lock_filename.buf, O_RDWR | O_CREAT | O_EXCL, 0666);
 	if (lk->fd < 0) {
+		strbuf_setlen(&lk->filename, 0);
 		strbuf_setlen(&lk->lock_filename, 0);
 		return -1;
 	}
@@ -269,18 +276,16 @@ int close_lock_file(struct lock_file *lk)
 
 int commit_lock_file(struct lock_file *lk)
 {
-	char *result_file;
-	size_t path_len = lk->lock_filename.len - LOCK_SUFFIX_LEN;
 	int err = 0;
 
 	if (lk->fd >= 0 && close_lock_file(lk))
 		return -1;
-	result_file = xmemdupz(lk->lock_filename.buf, path_len);
-	if (rename(lk->lock_filename.buf, result_file))
+	if (rename(lk->lock_filename.buf, lk->filename.buf)) {
 		err = -1;
-	else
+	} else {
+		strbuf_setlen(&lk->filename, 0);
 		strbuf_setlen(&lk->lock_filename, 0);
-	free(result_file);
+	}
 	return err;
 }
 
@@ -304,19 +309,21 @@ int commit_locked_index(struct lock_file *lk)
 			return -1;
 		if (rename(lk->lock_filename.buf, alternate_index_output))
 			return -1;
+		strbuf_setlen(&lk->filename, 0);
 		strbuf_setlen(&lk->lock_filename, 0);
 		return 0;
-	}
-	else
+	} else {
 		return commit_lock_file(lk);
+	}
 }
 
 void rollback_lock_file(struct lock_file *lk)
 {
-	if (lk->lock_filename.len) {
+	if (lk->filename.len) {
 		if (lk->fd >= 0)
 			close_lock_file(lk);
 		unlink_or_warn(lk->lock_filename.buf);
+		strbuf_setlen(&lk->filename, 0);
 		strbuf_setlen(&lk->lock_filename, 0);
 	}
 }
diff --git a/refs.c b/refs.c
index 93abc94..85967e7 100644
--- a/refs.c
+++ b/refs.c
@@ -2485,14 +2485,8 @@ static int repack_without_ref(const char *refname)
 static int delete_ref_loose(struct ref_lock *lock, int flag)
 {
 	if (!(flag & REF_ISPACKED) || flag & REF_ISSYMREF) {
-		/*
-		 * loose.  The loose file name is the same as the
-		 * lockfile name, minus ".lock":
-		 */
-		char *loose_filename = xmemdupz(lock->lk->lock_filename.buf,
-						lock->lk->lock_filename.len - 5);
-		int err = unlink_or_warn(loose_filename);
-		free(loose_filename);
+		/* loose */
+		int err = unlink_or_warn(lock->lk->filename.buf);
 		if (err && errno != ENOENT)
 			return 1;
 	}
-- 
1.9.0
Previous: Michael HaggertyNext: Junio C Hamano
Message 49 of 62 in “Lockfile refactoring and pre-activation”
  1. 00/22 Lockfile refactoring and pre-activationMichael Haggerty, Apr 1, 2014
  2. 01/22 t3204: test deleting references when lock files already existMichael Haggerty, Apr 1, 2014
  3. Jeff KingApr 1, 2014
  4. Michael HaggertyApr 2, 2014
  5. 02/22 try_merge_strategy(): remove redundant lock_file allocationMichael Haggerty, Apr 1, 2014
  6. Jeff KingApr 1, 2014
  7. Michael HaggertyApr 2, 2014
  8. Junio C HamanoApr 2, 2014
  9. Michael HaggertyApr 3, 2014
  10. 03/22 rollback_lock_file(): do not clear filename redundantlyMichael Haggerty, Apr 1, 2014
  11. 04/22 rollback_lock_file(): set fd to -1Michael Haggerty, Apr 1, 2014
  12. Jeff KingApr 1, 2014
  13. Junio C HamanoApr 2, 2014
  14. Michael HaggertyApr 6, 2014
  15. Junio C HamanoApr 7, 2014
  16. 05/22 lockfile: unlock file if lockfile permissions cannot be adjustedMichael Haggerty, Apr 1, 2014
  17. Jeff KingApr 1, 2014
  18. Jeff KingApr 1, 2014
  19. Torsten BögershausenApr 2, 2014
  20. Michael HaggertyApr 6, 2014
  21. 06/22 hold_lock_file_for_append(): release lock on errorsMichael Haggerty, Apr 1, 2014
  22. 07/22 lock_file(): always add lock_file object to lock_file_listMichael Haggerty, Apr 1, 2014
  23. Jeff KingApr 1, 2014
  24. Junio C HamanoApr 2, 2014
  25. Michael HaggertyApr 6, 2014
  26. Jeff KingApr 7, 2014
  27. 08/22 struct lock_file: replace on_list field with flags fieldMichael Haggerty, Apr 1, 2014
  28. 09/22 api-lockfile: expand the documentationMichael Haggerty, Apr 1, 2014
  29. Jeff KingApr 1, 2014
  30. Michael HaggertyApr 2, 2014
  31. 10/22 lockfile.c: document the various states of lock_file objectsMichael Haggerty, Apr 1, 2014
  32. 11/22 lockfile: define a constant LOCK_SUFFIX_LENMichael Haggerty, Apr 1, 2014
  33. Junio C HamanoApr 2, 2014
  34. 12/22 delete_ref_loose(): don't muck around in the lock_file's filenameMichael Haggerty, Apr 1, 2014
  35. Jeff KingApr 1, 2014
  36. Michael HaggertyApr 2, 2014
  37. Torsten BögershausenApr 2, 2014
  38. Jeff KingApr 2, 2014
  39. 13/22 config: change write_error() to take a (struct lock_file *) argumentMichael Haggerty, Apr 1, 2014
  40. Torsten BögershausenApr 2, 2014
  41. Michael HaggertyApr 6, 2014
  42. Junio C HamanoApr 2, 2014
  43. 14/22 lockfile: use strbufs when handling (most) pathsMichael Haggerty, Apr 1, 2014
  44. Jeff KingApr 1, 2014
  45. Junio C HamanoApr 2, 2014
  46. 15/22 resolve_symlink(): use a strbuf internallyMichael Haggerty, Apr 1, 2014
  47. 16/22 commit_lock_file(): don't work with a fixed-length bufferMichael Haggerty, Apr 1, 2014
  48. 17/22 lock_file(): exit early if lockfile cannot be openedMichael Haggerty, Apr 1, 2014
  49. 18/22 lockfile: also keep track of the filename of the file being lockedMichael Haggerty, Apr 1, 2014
  50. Junio C HamanoApr 2, 2014
  51. Michael HaggertyApr 6, 2014
  52. 19/22 struct lock_file: rename lock_filename field to staging_filenameMichael Haggerty, Apr 1, 2014
  53. 20/22 remove_lock_file(): call rollback_lock_file()Michael Haggerty, Apr 1, 2014
  54. 21/22 lockfile: extract a function reset_lock_file()Michael Haggerty, Apr 1, 2014
  55. Eric SunshineApr 2, 2014
  56. Michael HaggertyApr 2, 2014
  57. 22/22 lockfile: allow new file contents to be written while retaining lockMichael Haggerty, Apr 1, 2014
  58. Jeff KingApr 1, 2014
  59. Eric SunshineApr 2, 2014
  60. Junio C HamanoApr 2, 2014
  61. Jeff KingApr 1, 2014
  62. Michael HaggertyApr 3, 2014

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.