Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(874)

Unified Diff: src/platform/update_engine/extent_writer.h

Issue 551132: AU: Extent writer utility classes (Closed)
Patch Set: fixes for review Created 10 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/platform/update_engine/extent_writer.h
diff --git a/src/platform/update_engine/extent_writer.h b/src/platform/update_engine/extent_writer.h
new file mode 100644
index 0000000000000000000000000000000000000000..cbb62fefeaff3fd50c81fb3bd756322cca18be61
--- /dev/null
+++ b/src/platform/update_engine/extent_writer.h
@@ -0,0 +1,125 @@
+// Copyright (c) 2009 The Chromium OS Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROMEOS_PLATFORM_UPDATE_ENGINE_EXTENT_WRITER_H__
+#define CHROMEOS_PLATFORM_UPDATE_ENGINE_EXTENT_WRITER_H__
+
+#include <vector>
+#include "chromeos/obsolete_logging.h"
+#include "update_engine/update_metadata.pb.h"
+#include "update_engine/utils.h"
+
+// ExtentWriter is an abstract class which synchronously writes to a given
+// file descriptor at the extents given.
+
+namespace chromeos_update_engine {
+
+// When an extent's start block is kSparseHole, that data written for that
+// extent will be dropped rather than written to the unerlying fd.
+const uint64 kSparseHole = kuint64max;
+
+class ExtentWriter {
+ public:
+ ExtentWriter() : end_called_(false) {}
+ virtual ~ExtentWriter() {
+ LOG_IF(ERROR, !end_called_) << "End() not called on ExtentWriter.";
+ }
+
+ // Returns true on success.
+ virtual bool Init(int fd,
+ const std::vector<Extent>& extents,
+ size_t block_size) = 0;
+
+ // Returns true on success.
+ virtual bool Write(const void* bytes, size_t count) = 0;
+
+ // Should be called when all writing is complete. Returns true on success.
+ // The fd is not closed. Caller is responsible for closing it.
+ bool End() {
+ end_called_ = true;
+ return EndImpl();
+ }
+ virtual bool EndImpl() = 0;
+ private:
+ bool end_called_;
+};
+
+// DirectExtentWriter is probably the simplest ExtentWriter implementation.
+// It writes the data directly into the extents.
+
+class DirectExtentWriter : public ExtentWriter {
+ public:
+ DirectExtentWriter()
+ : fd_(-1),
+ block_size_(0),
+ extent_bytes_written_(0),
+ next_extent_index_(0) {}
+ ~DirectExtentWriter() {}
+
+ bool Init(int fd, const std::vector<Extent>& extents, size_t block_size) {
+ fd_ = fd;
+ block_size_ = block_size;
+ extents_ = extents;
+ return true;
+ }
+ bool Write(const void* bytes, size_t count);
+ bool EndImpl() {
+ return true;
+ }
+
+ private:
+ int fd_;
+
+ size_t block_size_;
+ // Bytes written into next_extent_index_ thus far
+ uint64 extent_bytes_written_;
+ std::vector<Extent> extents_;
+ // The next call to write should correspond to extents_[next_extent_index_]
+ std::vector<Extent>::size_type next_extent_index_;
+};
+
+// Takes an underlying ExtentWriter to which all operations are delegated.
+// When End() is called, ZeroPadExtentWriter ensures that the total number
+// of bytes written is a multiple of block_size_. If not, it writes zeros
+// to pad as needed.
+
+class ZeroPadExtentWriter : public ExtentWriter {
+ public:
+ ZeroPadExtentWriter(ExtentWriter* underlying_extent_writer)
+ : underlying_extent_writer_(underlying_extent_writer),
+ block_size_(0),
+ bytes_written_mod_block_size_(0) {}
+ ~ZeroPadExtentWriter() {}
+
+ bool Init(int fd, const std::vector<Extent>& extents, size_t block_size) {
+ block_size_ = block_size;
+ return underlying_extent_writer_->Init(fd, extents, block_size);
+ }
+ bool Write(const void* bytes, size_t count) {
+ if (underlying_extent_writer_->Write(bytes, count)) {
+ bytes_written_mod_block_size_ += count;
+ bytes_written_mod_block_size_ %= block_size_;
+ return true;
+ }
+ return false;
+ }
+ bool EndImpl() {
+ if (bytes_written_mod_block_size_) {
+ const size_t write_size = block_size_ - bytes_written_mod_block_size_;
+ std::vector<char> zeros(write_size, 0);
+ TEST_AND_RETURN_FALSE(underlying_extent_writer_->Write(&zeros[0],
+ write_size));
+ }
+ return underlying_extent_writer_->End();
+ }
+
+ private:
+ ExtentWriter* underlying_extent_writer_; // The underlying ExtentWriter.
+ size_t block_size_;
+ size_t bytes_written_mod_block_size_;
+};
+
+} // namespace chromeos_update_engine
+
+#endif // CHROMEOS_PLATFORM_UPDATE_ENGINE_EXTENT_WRITER_H__

Powered by Google App Engine
This is Rietveld 408576698