From: Junio C Hamano 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?hp=--cc 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