summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorColin Cross2014-04-25 16:28:54 -0500
committerColin Cross2014-04-25 17:19:18 -0500
commit0e3f47e4827a067b9b9795a3ae7297b51c9f0776 (patch)
tree83a1c9a76d708c900155729d92687ac78b59984f /libsparse
parent9fdc8156ca8fb3449859bebf080a477fa3bcff5c (diff)
downloadplatform-system-core-0e3f47e4827a067b9b9795a3ae7297b51c9f0776.tar.gz
platform-system-core-0e3f47e4827a067b9b9795a3ae7297b51c9f0776.tar.xz
platform-system-core-0e3f47e4827a067b9b9795a3ae7297b51c9f0776.zip
append2simg: write to temporary file
append2simg causes libsparse to write mmapped data from a file back to that same file. On btrfs, this sometimes causes a page of zeroes to be written instead of the file data. Work around the issue by writing the output to a temporary file and then renaming it over the original file. Change-Id: Ia194b6ba0ddb8548747b63292b523756f544706a
Diffstat (limited to 'libsparse')
-rw-r--r--libsparse/Android.mk3
-rw-r--r--libsparse/append2simg.c30
2 files changed, 32 insertions, 1 deletions
diff --git a/libsparse/Android.mk b/libsparse/Android.mk
index a21e090c4..4aba16873 100644
--- a/libsparse/Android.mk
+++ b/libsparse/Android.mk
@@ -81,6 +81,8 @@ LOCAL_STATIC_LIBRARIES := \
81include $(BUILD_EXECUTABLE) 81include $(BUILD_EXECUTABLE)
82 82
83 83
84ifneq ($(HOST_OS),windows)
85
84include $(CLEAR_VARS) 86include $(CLEAR_VARS)
85LOCAL_SRC_FILES := append2simg.c 87LOCAL_SRC_FILES := append2simg.c
86LOCAL_MODULE := append2simg 88LOCAL_MODULE := append2simg
@@ -89,6 +91,7 @@ LOCAL_STATIC_LIBRARIES := \
89 libz 91 libz
90include $(BUILD_HOST_EXECUTABLE) 92include $(BUILD_HOST_EXECUTABLE)
91 93
94endif
92 95
93include $(CLEAR_VARS) 96include $(CLEAR_VARS)
94LOCAL_MODULE := simg_dump.py 97LOCAL_MODULE := simg_dump.py
diff --git a/libsparse/append2simg.c b/libsparse/append2simg.c
index 180584f48..65e6cc29b 100644
--- a/libsparse/append2simg.c
+++ b/libsparse/append2simg.c
@@ -16,6 +16,7 @@
16 16
17#define _FILE_OFFSET_BITS 64 17#define _FILE_OFFSET_BITS 64
18#define _LARGEFILE64_SOURCE 1 18#define _LARGEFILE64_SOURCE 1
19#define _GNU_SOURCE
19 20
20#include <errno.h> 21#include <errno.h>
21#include <fcntl.h> 22#include <fcntl.h>
@@ -56,6 +57,11 @@ int main(int argc, char *argv[])
56 char *input_path; 57 char *input_path;
57 off64_t input_len; 58 off64_t input_len;
58 59
60 int tmp_fd;
61 char *tmp_path;
62
63 int ret;
64
59 if (argc == 3) { 65 if (argc == 3) {
60 output_path = argv[1]; 66 output_path = argv[1];
61 input_path = argv[2]; 67 input_path = argv[2];
@@ -64,6 +70,12 @@ int main(int argc, char *argv[])
64 exit(-1); 70 exit(-1);
65 } 71 }
66 72
73 ret = asprintf(&tmp_path, "%s.append2simg", output_path);
74 if (ret < 0) {
75 fprintf(stderr, "Couldn't allocate filename\n");
76 exit(-1);
77 }
78
67 output = open(output_path, O_RDWR | O_BINARY); 79 output = open(output_path, O_RDWR | O_BINARY);
68 if (output < 0) { 80 if (output < 0) {
69 fprintf(stderr, "Couldn't open output file (%s)\n", strerror(errno)); 81 fprintf(stderr, "Couldn't open output file (%s)\n", strerror(errno));
@@ -99,14 +111,30 @@ int main(int argc, char *argv[])
99 } 111 }
100 sparse_output->len += input_len; 112 sparse_output->len += input_len;
101 113
114 tmp_fd = open(tmp_path, O_WRONLY | O_CREAT | O_BINARY, 0664);
115 if (tmp_fd < 0) {
116 fprintf(stderr, "Couldn't open temporary file (%s)\n", strerror(errno));
117 exit(-1);
118 }
119
102 lseek64(output, 0, SEEK_SET); 120 lseek64(output, 0, SEEK_SET);
103 if (sparse_file_write(sparse_output, output, false, true, false) < 0) { 121 if (sparse_file_write(sparse_output, tmp_fd, false, true, false) < 0) {
104 fprintf(stderr, "Failed to write sparse file\n"); 122 fprintf(stderr, "Failed to write sparse file\n");
105 exit(-1); 123 exit(-1);
106 } 124 }
107 125
108 sparse_file_destroy(sparse_output); 126 sparse_file_destroy(sparse_output);
127 close(tmp_fd);
109 close(output); 128 close(output);
110 close(input); 129 close(input);
130
131 ret = rename(tmp_path, output_path);
132 if (ret < 0) {
133 fprintf(stderr, "Failed to rename temporary file (%s)\n", strerror(errno));
134 exit(-1);
135 }
136
137 free(tmp_path);
138
111 exit(0); 139 exit(0);
112} 140}