[f2fs] Support append write

Add append write handler to File class

Test: fx test append-tests

Change-Id: I5a4fb447f44a21f78a9cd7538f2b4bf376b2f98e
Reviewed-on: https://fuchsia-review.googlesource.com/c/third_party/f2fs/+/536509
Reviewed-by: Brett Wilson <brettw@google.com>
diff --git a/file.cc b/file.cc
index 8b1b4d5..1dd7ea9 100644
--- a/file.cc
+++ b/file.cc
@@ -482,7 +482,7 @@
   return ZX_OK;
 }
 
-zx_status_t File::Write(const void *data, size_t len, size_t offset, size_t *out_actual) {
+zx_status_t File::DoWrite(const void *data, size_t len, size_t offset, size_t *out_actual) {
   uint64_t blk_start = offset / kBlockSize;
   uint64_t blk_end = (offset + len) / kBlockSize;
   size_t off_in_block = offset % kBlockSize;
@@ -492,8 +492,6 @@
   uint64_t n;
   size_t left = len;
 
-  fbl::AutoLock lock(&i_mutex_);
-
   for (n = blk_start; n <= blk_end; n++) {
     size_t cur_len = std::min(static_cast<size_t>(kBlockSize - off_in_block), left);
     if (zx_status_t ret = WriteBegin(n * kBlockSize + off_in_block, cur_len, &data_page);
@@ -547,6 +545,21 @@
   return ZX_OK;
 }
 
+zx_status_t File::Write(const void *data, size_t len, size_t offset, size_t *out_actual) {
+  fbl::AutoLock lock(&i_mutex_);
+  return DoWrite(data, len, offset, out_actual);
+}
+
+zx_status_t File::Append(const void *data, size_t len, size_t *out_end, size_t *out_actual) {
+  fbl::AutoLock lock(&i_mutex_);
+  size_t off = i_size_;
+  zx_status_t ret = DoWrite(data, len, off, out_actual);
+
+  *out_end = off + *out_actual;
+
+  return ret;
+}
+
 zx_status_t File::Truncate(size_t len) {
   if (len == i_size_)
     return ZX_OK;
diff --git a/file.h b/file.h
index b99e9c3..b1972eb 100644
--- a/file.h
+++ b/file.h
@@ -28,7 +28,9 @@
 #endif
 
   zx_status_t Read(void* data, size_t len, size_t off, size_t* out_actual);
+  zx_status_t DoWrite(const void* data, size_t len, size_t offset, size_t* out_actual);
   zx_status_t Write(const void* data, size_t len, size_t offset, size_t* out_actual);
+  zx_status_t Append(const void* data, size_t len, size_t* out_end, size_t* out_actual);
   zx_status_t Truncate(size_t len);
 };