From: Junio C Hamano <gitster@pobox.com>
Date: Mon, 25 Sep 2017 06:24:06 +0000 (+0900)
Subject: Merge branch 'jk/write-in-full-fix'
X-Git-Tag: v2.15.0-rc0~69
X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/c50424a6f0

Merge branch 'jk/write-in-full-fix'

Many codepaths did not diagnose write failures correctly when disks
go full, due to their misuse of write_in_full() helper function,
which have been corrected.

* jk/write-in-full-fix:
read_pack_header: handle signed/unsigned comparison in read result
config: flip return value of store_write_*()
notes-merge: use ssize_t for write_in_full() return value
pkt-line: check write_in_full() errors against "< 0"
convert less-trivial versions of "write_in_full() != len"
avoid "write_in_full(fd, buf, len) != len" pattern
get-tar-commit-id: check write_in_full() return against 0
config: avoid "write_in_full(fd, buf, len) < len" pattern
---

c50424a6f07f17ff9b06927606df650cd73a09a3
diff --cc diff.c
index ea7e5978bc,6f58bca2f9..3c6a3e0faa
--- a/diff.c
+++ b/diff.c
@@@ -3738,10 -2975,10 +3738,10 @@@ static void prep_temp_blob(const char *
  		blob = buf.buf;
  		size = buf.len;
  	}
- 	if (write_in_full(temp->tempfile->fd, blob, size) != size ||
 -	if (write_in_full(fd, blob, size) < 0)
++	if (write_in_full(temp->tempfile->fd, blob, size) < 0 ||
 +	    close_tempfile_gently(temp->tempfile))
  		die_errno("unable to write temp-file");
 -	close_tempfile(&temp->tempfile);
 -	temp->name = get_tempfile_path(&temp->tempfile);
 +	temp->name = get_tempfile_path(temp->tempfile);
  	oid_to_hex_r(temp->hex, oid);
  	xsnprintf(temp->mode, sizeof(temp->mode), "%06o", mode);
  	strbuf_release(&buf);
diff --cc pkt-line.c
index f364944b93,4823d3bb9d..647bbd3bce
--- a/pkt-line.c
+++ b/pkt-line.c
@@@ -136,20 -136,18 +136,19 @@@ static void format_packet(struct strbu
  static int packet_write_fmt_1(int fd, int gently,
  			      const char *fmt, va_list args)
  {
 -	struct strbuf buf = STRBUF_INIT;
 +	static struct strbuf buf = STRBUF_INIT;
- 	ssize_t count;
  
 +	strbuf_reset(&buf);
  	format_packet(&buf, fmt, args);
- 	count = write_in_full(fd, buf.buf, buf.len);
- 	if (count == buf.len)
- 		return 0;
- 
- 	if (!gently) {
- 		check_pipe(errno);
- 		die_errno("packet write with format failed");
+ 	if (write_in_full(fd, buf.buf, buf.len) < 0) {
+ 		if (!gently) {
+ 			check_pipe(errno);
+ 			die_errno("packet write with format failed");
+ 		}
+ 		return error("packet write with format failed");
  	}
- 	return error("packet write with format failed");
+ 
+ 	return 0;
  }
  
  void packet_write_fmt(int fd, const char *fmt, ...)
diff --cc refs/files-backend.c
index 32663a999e,f21a954ce7..dac33628b3
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@@ -1627,12 -2117,12 +1627,12 @@@ static int write_ref_to_lockfile(struc
  		unlock_ref(lock);
  		return -1;
  	}
 -	fd = get_lock_file_fd(lock->lk);
 +	fd = get_lock_file_fd(&lock->lk);
- 	if (write_in_full(fd, oid_to_hex(oid), GIT_SHA1_HEXSZ) != GIT_SHA1_HEXSZ ||
- 	    write_in_full(fd, &term, 1) != 1 ||
+ 	if (write_in_full(fd, oid_to_hex(oid), GIT_SHA1_HEXSZ) < 0 ||
+ 	    write_in_full(fd, &term, 1) < 0 ||
 -	    close_ref(lock) < 0) {
 +	    close_ref_gently(lock) < 0) {
  		strbuf_addf(err,
 -			    "couldn't write '%s'", get_lock_file_path(lock->lk));
 +			    "couldn't write '%s'", get_lock_file_path(&lock->lk));
  		unlock_ref(lock);
  		return -1;
  	}
@@@ -3000,17 -3333,16 +3000,17 @@@ static int files_reflog_expire(struct r
  			!(type & REF_ISSYMREF) &&
  			!is_null_oid(&cb.last_kept_oid);
  
 -		if (close_lock_file(&reflog_lock)) {
 +		if (close_lock_file_gently(&reflog_lock)) {
  			status |= error("couldn't write %s: %s", log_file,
  					strerror(errno));
 +			rollback_lock_file(&reflog_lock);
  		} else if (update &&
 -			   (write_in_full(get_lock_file_fd(lock->lk),
 +			   (write_in_full(get_lock_file_fd(&lock->lk),
- 				oid_to_hex(&cb.last_kept_oid), GIT_SHA1_HEXSZ) != GIT_SHA1_HEXSZ ||
- 			    write_str_in_full(get_lock_file_fd(&lock->lk), "\n") != 1 ||
+ 				oid_to_hex(&cb.last_kept_oid), GIT_SHA1_HEXSZ) < 0 ||
 -			    write_str_in_full(get_lock_file_fd(lock->lk), "\n") < 0 ||
 -			    close_ref(lock) < 0)) {
++			    write_str_in_full(get_lock_file_fd(&lock->lk), "\n") < 1 ||
 +			    close_ref_gently(lock) < 0)) {
  			status |= error("couldn't write %s",
 -					get_lock_file_path(lock->lk));
 +					get_lock_file_path(&lock->lk));
  			rollback_lock_file(&reflog_lock);
  		} else if (commit_lock_file(&reflog_lock)) {
  			status |= error("unable to write reflog '%s' (%s)",
diff --cc shallow.c
index 1cc1c76415,e8429a9a84..eabb65d3a7
--- a/shallow.c
+++ b/shallow.c
@@@ -286,20 -286,22 +286,20 @@@ int write_shallow_commits(struct strbu
  	return write_shallow_commits_1(out, use_pack_protocol, extra, 0);
  }
  
 -static struct tempfile temporary_shallow;
 -
  const char *setup_temporary_shallow(const struct oid_array *extra)
  {
 +	struct tempfile *temp;
  	struct strbuf sb = STRBUF_INIT;
 -	int fd;
  
  	if (write_shallow_commits(&sb, 0, extra)) {
 -		fd = xmks_tempfile(&temporary_shallow, git_path("shallow_XXXXXX"));
 +		temp = xmks_tempfile(git_path("shallow_XXXXXX"));
  
- 		if (write_in_full(temp->fd, sb.buf, sb.len) != sb.len ||
 -		if (write_in_full(fd, sb.buf, sb.len) < 0)
++		if (write_in_full(temp->fd, sb.buf, sb.len) < 0 ||
 +		    close_tempfile_gently(temp) < 0)
  			die_errno("failed to write to %s",
 -				  get_tempfile_path(&temporary_shallow));
 -		close_tempfile(&temporary_shallow);
 +				  get_tempfile_path(temp));
  		strbuf_release(&sb);
 -		return get_tempfile_path(&temporary_shallow);
 +		return get_tempfile_path(temp);
  	}
  	/*
  	 * is_repository_shallow() sees empty string as "no shallow