OSDN Git Service

Merge branch 'jk/write-in-full-fix'
authorJunio C Hamano <gitster@pobox.com>
Mon, 25 Sep 2017 06:24:06 +0000 (15:24 +0900)
committerJunio C Hamano <gitster@pobox.com>
Mon, 25 Sep 2017 06:24:06 +0000 (15:24 +0900)
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

17 files changed:
1  2 
builtin/receive-pack.c
builtin/unpack-file.c
config.c
diff.c
entry.c
fast-import.c
http-backend.c
notes-merge.c
pkt-line.c
read-cache.c
refs.c
refs/files-backend.c
rerere.c
sha1_file.c
shallow.c
streaming.c
transport-helper.c

Simple merge
Simple merge
diff --cc config.c
Simple merge
diff --cc diff.c
--- 1/diff.c
--- 2/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 entry.c
Simple merge
diff --cc fast-import.c
Simple merge
diff --cc http-backend.c
Simple merge
diff --cc notes-merge.c
Simple merge
diff --cc 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 read-cache.c
Simple merge
diff --cc refs.c
Simple merge
@@@ -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 rerere.c
Simple merge
diff --cc sha1_file.c
Simple merge
diff --cc 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
diff --cc streaming.c
Simple merge
Simple merge