Commit ab750274 authored by Xing Liu's avatar Xing Liu Committed by Commit Bot

Download location: Fix an issue in file writing.

When we write to a file, currently we assume the whole chunk is written.
However when users pull out the SD card or disk, base::File::Write will
return a size less than the chunk size, and the next call to
base::File::Write will return an error.

This CL fixed this issue so FILE_FAILED error can be correctly reported
when the SD card is unmounted.

This CL basically makes the core write function back to this revision:
https://chromium.googlesource.com/chromium/src/+/29db19d0c973a8990283ec4b81111db5bdb8d2de/content/browser/download/base_file.cc#101

Bug: 841559,792775
Change-Id: Icfba65833bf3aec07d30d8d3bed57a9abba7f8d1
Reviewed-on: https://chromium-review.googlesource.com/1053233
Commit-Queue: Xing Liu <xingliu@chromium.org>
Reviewed-by: default avatarDavid Trainor <dtrainor@chromium.org>
Cr-Commit-Position: refs/heads/master@{#557903}
parent 2a741a1f
......@@ -13,6 +13,7 @@
#include "base/format_macros.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/numerics/safe_conversions.h"
#include "base/pickle.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_restrictions.h"
......@@ -137,22 +138,35 @@ DownloadInterruptReason BaseFile::WriteDataToFile(int64_t offset,
// belong to the same download will be grouped together.
CONDITIONAL_TRACE(
NESTABLE_ASYNC_BEGIN0("download", "DownloadFileWrite", download_id_));
int write_result = file_.Write(offset, data, data_len);
if (bytes_so_far_ != offset) {
// A hole is created in the file.
is_sparse_file_ = true;
secure_hash_.reset();
}
// Writes to the file.
int64_t len = base::saturated_cast<int64_t>(data_len);
const char* current_data = data;
int64_t current_offset = offset;
while (len > 0) {
// |write_result| may be less than |len|, and return an error on the next
// write call when the disk is unavaliable.
int write_result = file_.Write(current_offset, current_data, len);
DCHECK_NE(0, write_result);
// Report errors on file writes.
if (write_result < 0)
return LogSystemError("Write", logging::GetLastSystemErrorCode());
DCHECK_EQ(static_cast<size_t>(write_result), data_len);
if (bytes_so_far_ != offset) {
// A hole is created in the file.
is_sparse_file_ = true;
secure_hash_.reset();
// Update status.
DCHECK_LE(write_result, len);
len -= write_result;
current_data += write_result;
current_offset += write_result;
bytes_so_far_ += write_result;
}
bytes_so_far_ += data_len;
CONDITIONAL_TRACE(NESTABLE_ASYNC_END1("download", "DownloadFileWrite",
download_id_, "bytes", data_len));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment