OSDN Git Service

fec: remove unused mmap code
[android-x86/system-extras.git] / verity / fec / image.cpp
index 95bc88e..4a70a02 100644 (file)
@@ -51,24 +51,7 @@ void image_init(image *ctx)
     memset(ctx, 0, sizeof(*ctx));
 }
 
-static void mmap_image_free(image *ctx)
-{
-    if (ctx->input) {
-        munmap(ctx->input, (size_t)ctx->inp_size);
-        TEMP_FAILURE_RETRY(close(ctx->inp_fd));
-    }
-
-    if (ctx->fec_mmap_addr) {
-        munmap(ctx->fec_mmap_addr, FEC_BLOCKSIZE + ctx->fec_size);
-        TEMP_FAILURE_RETRY(close(ctx->fec_fd));
-    }
-
-    if (!ctx->inplace && ctx->output) {
-        delete[] ctx->output;
-    }
-}
-
-static void file_image_free(image *ctx)
+void image_free(image *ctx)
 {
     assert(ctx->input == ctx->output);
 
@@ -79,19 +62,11 @@ static void file_image_free(image *ctx)
     if (ctx->fec) {
         delete[] ctx->fec;
     }
-}
-
-void image_free(image *ctx)
-{
-    if (ctx->mmap) {
-        mmap_image_free(ctx);
-    } else {
-        file_image_free(ctx);
-    }
 
     image_init(ctx);
 }
 
+#ifdef IMAGE_NO_SPARSE
 static uint64_t get_size(int fd)
 {
     struct stat st;
@@ -114,6 +89,7 @@ static uint64_t get_size(int fd)
 
     return size;
 }
+#endif
 
 static void calculate_rounds(uint64_t size, image *ctx)
 {
@@ -129,56 +105,6 @@ static void calculate_rounds(uint64_t size, image *ctx)
     ctx->rounds = fec_div_round_up(ctx->blocks, ctx->rs_n);
 }
 
-static void mmap_image_load(int fd, image *ctx, bool output_needed)
-{
-    calculate_rounds(get_size(fd), ctx);
-
-    /* check that we can memory map the file; on 32-bit platforms we are
-       limited to encoding at most 4 GiB files */
-    if (ctx->inp_size > SIZE_MAX) {
-        FATAL("cannot mmap %" PRIu64 " bytes\n", ctx->inp_size);
-    }
-
-    if (ctx->verbose) {
-        INFO("memory mapping '%s' (size %" PRIu64 ")\n", ctx->fec_filename,
-            ctx->inp_size);
-    }
-
-    int flags = PROT_READ;
-
-    if (ctx->inplace) {
-        flags |= PROT_WRITE;
-    }
-
-    void *p = mmap(NULL, (size_t)ctx->inp_size, flags, MAP_SHARED, fd, 0);
-
-    if (p == MAP_FAILED) {
-        FATAL("failed to mmap '%s' (size %" PRIu64 "): %s\n",
-            ctx->fec_filename, ctx->inp_size, strerror(errno));
-    }
-
-    ctx->inp_fd = fd;
-    ctx->input = (uint8_t *)p;
-
-    if (ctx->inplace) {
-        ctx->output = ctx->input;
-    } else if (output_needed) {
-        if (ctx->verbose) {
-            INFO("allocating %" PRIu64 " bytes of memory\n", ctx->inp_size);
-        }
-
-        ctx->output = new uint8_t[ctx->inp_size];
-
-        if (!ctx->output) {
-                FATAL("failed to allocate memory\n");
-        }
-
-        memcpy(ctx->output, ctx->input, ctx->inp_size);
-    }
-
-    /* fd is closed in mmap_image_free */
-}
-
 #ifndef IMAGE_NO_SPARSE
 static int process_chunk(void *priv, const void *data, int len)
 {
@@ -194,33 +120,43 @@ static int process_chunk(void *priv, const void *data, int len)
 }
 #endif
 
-static void file_image_load(int fd, image *ctx)
+static void file_image_load(const std::vector<int>& fds, image *ctx)
 {
-    uint64_t len = 0;
+    uint64_t size = 0;
+#ifndef IMAGE_NO_SPARSE
+    std::vector<struct sparse_file *> files;
+#endif
+
+    for (auto fd : fds) {
+        uint64_t len = 0;
 
 #ifdef IMAGE_NO_SPARSE
-    if (ctx->sparse) {
-        FATAL("sparse files not supported\n");
-    }
+        if (ctx->sparse) {
+            FATAL("sparse files not supported\n");
+        }
 
-    len = get_size(fd);
+        len = get_size(fd);
 #else
-    struct sparse_file *file;
+        struct sparse_file *file;
 
-    if (ctx->sparse) {
-        file = sparse_file_import(fd, false, false);
-    } else {
-        file = sparse_file_import_auto(fd, false, ctx->verbose);
-    }
+        if (ctx->sparse) {
+            file = sparse_file_import(fd, false, false);
+        } else {
+            file = sparse_file_import_auto(fd, false, ctx->verbose);
+        }
 
-    if (!file) {
-        FATAL("failed to read file %s\n", ctx->fec_filename);
-    }
+        if (!file) {
+            FATAL("failed to read file %s\n", ctx->fec_filename);
+        }
 
-    len = sparse_file_len(file, false, false);
+        len = sparse_file_len(file, false, false);
+        files.push_back(file);
 #endif /* IMAGE_NO_SPARSE */
 
-    calculate_rounds(len, ctx);
+        size += len;
+    }
+
+    calculate_rounds(size, ctx);
 
     if (ctx->verbose) {
         INFO("allocating %" PRIu64 " bytes of memory\n", ctx->inp_size);
@@ -234,21 +170,32 @@ static void file_image_load(int fd, image *ctx)
 
     memset(ctx->input, 0, ctx->inp_size);
     ctx->output = ctx->input;
+    ctx->pos = 0;
 
 #ifdef IMAGE_NO_SPARSE
-    if (!android::base::ReadFully(fd, ctx->input, ctx->inp_size)) {
-        FATAL("failed to read: %s\n", strerror(errno));
+    for (auto fd : fds) {
+        uint64_t len = get_size(fd);
+
+        if (!android::base::ReadFully(fd, &ctx->input[ctx->pos], len)) {
+            FATAL("failed to read: %s\n", strerror(errno));
+        }
+
+        ctx->pos += len;
+        close(fd);
     }
 #else
-    ctx->pos = 0;
-    sparse_file_callback(file, false, false, process_chunk, ctx);
-    sparse_file_destroy(file);
-#endif
+    for (auto file : files) {
+        sparse_file_callback(file, false, false, process_chunk, ctx);
+        sparse_file_destroy(file);
+    }
 
-    TEMP_FAILURE_RETRY(close(fd));
+    for (auto fd : fds) {
+        close(fd);
+    }
+#endif
 }
 
-bool image_load(const char *filename, image *ctx, bool output_needed)
+bool image_load(const std::vector<std::string>& filenames, image *ctx)
 {
     assert(ctx->roots > 0 && ctx->roots < FEC_RSM);
     ctx->rs_n = FEC_RSM - ctx->roots;
@@ -259,83 +206,49 @@ bool image_load(const char *filename, image *ctx, bool output_needed)
         flags = O_RDWR;
     }
 
-    int fd = TEMP_FAILURE_RETRY(open(filename, flags | O_LARGEFILE));
+    std::vector<int> fds;
 
-    if (fd < 0) {
-        FATAL("failed to open file '%s': %s\n", filename, strerror(errno));
-    }
+    for (const auto& fn : filenames) {
+        int fd = TEMP_FAILURE_RETRY(open(fn.c_str(), flags | O_LARGEFILE));
 
-    if (ctx->mmap) {
-        mmap_image_load(fd, ctx, output_needed);
-    } else {
-        file_image_load(fd, ctx);
+        if (fd < 0) {
+            FATAL("failed to open file '%s': %s\n", fn.c_str(), strerror(errno));
+        }
+
+        fds.push_back(fd);
     }
 
+    file_image_load(fds, ctx);
+
     return true;
 }
 
-bool image_save(const char *filename, image *ctx)
+bool image_save(const std::string& filename, image *ctx)
 {
-    if (ctx->inplace && ctx->mmap) {
-        return true; /* nothing to do */
-    }
-
     /* TODO: support saving as a sparse file */
-    int fd = TEMP_FAILURE_RETRY(open(filename, O_WRONLY | O_CREAT | O_TRUNC,
-                0666));
+    int fd = TEMP_FAILURE_RETRY(open(filename.c_str(),
+                O_WRONLY | O_CREAT | O_TRUNC, 0666));
 
     if (fd < 0) {
-        FATAL("failed to open file '%s: %s'\n", filename, strerror(errno));
+        FATAL("failed to open file '%s: %s'\n", filename.c_str(),
+            strerror(errno));
     }
 
     if (!android::base::WriteFully(fd, ctx->output, ctx->inp_size)) {
         FATAL("failed to write to output: %s\n", strerror(errno));
     }
 
-    TEMP_FAILURE_RETRY(close(fd));
+    close(fd);
     return true;
 }
 
-static void mmap_image_ecc_new(image *ctx)
+bool image_ecc_new(const std::string& filename, image *ctx)
 {
-    if (ctx->verbose) {
-        INFO("mmaping '%s' (size %u)\n", ctx->fec_filename, ctx->fec_size);
-    }
-
-    int fd = TEMP_FAILURE_RETRY(open(ctx->fec_filename,
-                O_RDWR | O_CREAT, 0666));
-
-    if (fd < 0) {
-        FATAL("failed to open file '%s': %s\n", ctx->fec_filename,
-            strerror(errno));
-    }
-
-    assert(sizeof(fec_header) <= FEC_BLOCKSIZE);
-    size_t fec_size = FEC_BLOCKSIZE + ctx->fec_size;
-
-    if (ftruncate(fd, fec_size) == -1) {
-        FATAL("failed to ftruncate file '%s': %s\n", ctx->fec_filename,
-            strerror(errno));
-    }
-
-    if (ctx->verbose) {
-        INFO("memory mapping '%s' (size %zu)\n", ctx->fec_filename, fec_size);
-    }
-
-    void *p = mmap(NULL, fec_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-
-    if (p == MAP_FAILED) {
-        FATAL("failed to mmap '%s' (size %zu): %s\n", ctx->fec_filename,
-            fec_size, strerror(errno));
-    }
+    assert(ctx->rounds > 0); /* image_load should be called first */
 
-    ctx->fec_fd = fd;
-    ctx->fec_mmap_addr = (uint8_t *)p;
-    ctx->fec = ctx->fec_mmap_addr;
-}
+    ctx->fec_filename = filename.c_str();
+    ctx->fec_size = ctx->rounds * ctx->roots * FEC_BLOCKSIZE;
 
-static void file_image_ecc_new(image *ctx)
-{
     if (ctx->verbose) {
         INFO("allocating %u bytes of memory\n", ctx->fec_size);
     }
@@ -345,34 +258,21 @@ static void file_image_ecc_new(image *ctx)
     if (!ctx->fec) {
         FATAL("failed to allocate %u bytes\n", ctx->fec_size);
     }
-}
-
-bool image_ecc_new(const char *filename, image *ctx)
-{
-    assert(ctx->rounds > 0); /* image_load should be called first */
-
-    ctx->fec_filename = filename;
-    ctx->fec_size = ctx->rounds * ctx->roots * FEC_BLOCKSIZE;
-
-    if (ctx->mmap) {
-        mmap_image_ecc_new(ctx);
-    } else {
-        file_image_ecc_new(ctx);
-    }
 
     return true;
 }
 
-bool image_ecc_load(const char *filename, image *ctx)
+bool image_ecc_load(const std::string& filename, image *ctx)
 {
-    int fd = TEMP_FAILURE_RETRY(open(filename, O_RDONLY));
+    int fd = TEMP_FAILURE_RETRY(open(filename.c_str(), O_RDONLY));
 
     if (fd < 0) {
-        FATAL("failed to open file '%s': %s\n", filename, strerror(errno));
+        FATAL("failed to open file '%s': %s\n", filename.c_str(),
+            strerror(errno));
     }
 
     if (lseek64(fd, -FEC_BLOCKSIZE, SEEK_END) < 0) {
-        FATAL("failed to seek to header in '%s': %s\n", filename,
+        FATAL("failed to seek to header in '%s': %s\n", filename.c_str(),
             strerror(errno));
     }
 
@@ -383,27 +283,29 @@ bool image_ecc_load(const char *filename, image *ctx)
 
     if (!android::base::ReadFully(fd, header, sizeof(header))) {
         FATAL("failed to read %zd bytes from '%s': %s\n", sizeof(header),
-            filename, strerror(errno));
+            filename.c_str(), strerror(errno));
     }
 
     if (p->magic != FEC_MAGIC) {
-        FATAL("invalid magic in '%s': %08x\n", filename, p->magic);
+        FATAL("invalid magic in '%s': %08x\n", filename.c_str(), p->magic);
     }
 
     if (p->version != FEC_VERSION) {
-        FATAL("unsupported version in '%s': %u\n", filename, p->version);
+        FATAL("unsupported version in '%s': %u\n", filename.c_str(),
+            p->version);
     }
 
     if (p->size != sizeof(fec_header)) {
-        FATAL("unexpected header size in '%s': %u\n", filename, p->size);
+        FATAL("unexpected header size in '%s': %u\n", filename.c_str(),
+            p->size);
     }
 
     if (p->roots == 0 || p->roots >= FEC_RSM) {
-        FATAL("invalid roots in '%s': %u\n", filename, p->roots);
+        FATAL("invalid roots in '%s': %u\n", filename.c_str(), p->roots);
     }
 
     if (p->fec_size % p->roots || p->fec_size % FEC_BLOCKSIZE) {
-        FATAL("invalid length in '%s': %u\n", filename, p->fec_size);
+        FATAL("invalid length in '%s': %u\n", filename.c_str(), p->fec_size);
     }
 
     ctx->roots = (int)p->roots;
@@ -416,19 +318,19 @@ bool image_ecc_load(const char *filename, image *ctx)
     }
 
     if (p->fec_size != ctx->fec_size) {
-        FATAL("inconsistent header in '%s'\n", filename);
+        FATAL("inconsistent header in '%s'\n", filename.c_str());
     }
 
     if (lseek64(fd, 0, SEEK_SET) < 0) {
-        FATAL("failed to rewind '%s': %s", filename, strerror(errno));
+        FATAL("failed to rewind '%s': %s", filename.c_str(), strerror(errno));
     }
 
-    if (!ctx->mmap && !android::base::ReadFully(fd, ctx->fec, ctx->fec_size)) {
+    if (!android::base::ReadFully(fd, ctx->fec, ctx->fec_size)) {
         FATAL("failed to read %u bytes from '%s': %s\n", ctx->fec_size,
-            filename, strerror(errno));
+            filename.c_str(), strerror(errno));
     }
 
-    TEMP_FAILURE_RETRY(close(fd));
+    close(fd);
 
     uint8_t hash[SHA256_DIGEST_LENGTH];
     SHA256(ctx->fec, ctx->fec_size, hash);
@@ -447,10 +349,6 @@ bool image_ecc_save(image *ctx)
     uint8_t header[FEC_BLOCKSIZE];
     uint8_t *p = header;
 
-    if (ctx->mmap) {
-        p = (uint8_t *)&ctx->fec_mmap_addr[ctx->fec_size];
-    }
-
     memset(p, 0, FEC_BLOCKSIZE);
 
     fec_header *f = (fec_header *)p;
@@ -467,25 +365,23 @@ bool image_ecc_save(image *ctx)
     /* store a copy of the fec_header at the end of the header block */
     memcpy(&p[sizeof(header) - sizeof(fec_header)], p, sizeof(fec_header));
 
-    if (!ctx->mmap) {
-        assert(ctx->fec_filename);
+    assert(ctx->fec_filename);
 
-        int fd = TEMP_FAILURE_RETRY(open(ctx->fec_filename,
-                    O_WRONLY | O_CREAT | O_TRUNC, 0666));
-
-        if (fd < 0) {
-            FATAL("failed to open file '%s': %s\n", ctx->fec_filename,
-                strerror(errno));
-        }
+    int fd = TEMP_FAILURE_RETRY(open(ctx->fec_filename,
+                O_WRONLY | O_CREAT | O_TRUNC, 0666));
 
-        if (!android::base::WriteFully(fd, ctx->fec, ctx->fec_size) ||
-            !android::base::WriteFully(fd, header, sizeof(header))) {
-            FATAL("failed to write to output: %s\n", strerror(errno));
-        }
+    if (fd < 0) {
+        FATAL("failed to open file '%s': %s\n", ctx->fec_filename,
+            strerror(errno));
+    }
 
-        TEMP_FAILURE_RETRY(close(fd));
+    if (!android::base::WriteFully(fd, ctx->fec, ctx->fec_size) ||
+        !android::base::WriteFully(fd, header, sizeof(header))) {
+        FATAL("failed to write to output: %s\n", strerror(errno));
     }
 
+    close(fd);
+
     return true;
 }