summaryrefslogtreecommitdiffstats
path: root/updater/blockimg.c
diff options
context:
space:
mode:
Diffstat (limited to 'updater/blockimg.c')
-rw-r--r--updater/blockimg.c79
1 files changed, 45 insertions, 34 deletions
diff --git a/updater/blockimg.c b/updater/blockimg.c
index d5344f9..b006d10 100644
--- a/updater/blockimg.c
+++ b/updater/blockimg.c
@@ -19,6 +19,7 @@
#include <dirent.h>
#include <fcntl.h>
#include <inttypes.h>
+#include <libgen.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
@@ -101,7 +102,7 @@ static int range_overlaps(RangeSet* r1, RangeSet* r2) {
r2_0 = r2->pos[j * 2];
r2_1 = r2->pos[j * 2 + 1];
- if (!(r2_0 > r1_1 || r1_0 > r2_1)) {
+ if (!(r2_0 >= r1_1 || r1_0 >= r2_1)) {
return 1;
}
}
@@ -113,13 +114,12 @@ static int range_overlaps(RangeSet* r1, RangeSet* r2) {
static int read_all(int fd, uint8_t* data, size_t size) {
size_t so_far = 0;
while (so_far < size) {
- ssize_t r = read(fd, data+so_far, size-so_far);
- if (r < 0 && errno != EINTR) {
+ ssize_t r = TEMP_FAILURE_RETRY(read(fd, data+so_far, size-so_far));
+ if (r == -1) {
fprintf(stderr, "read failed: %s\n", strerror(errno));
return -1;
- } else {
- so_far += r;
}
+ so_far += r;
}
return 0;
}
@@ -127,13 +127,12 @@ static int read_all(int fd, uint8_t* data, size_t size) {
static int write_all(int fd, const uint8_t* data, size_t size) {
size_t written = 0;
while (written < size) {
- ssize_t w = write(fd, data+written, size-written);
- if (w < 0 && errno != EINTR) {
+ ssize_t w = TEMP_FAILURE_RETRY(write(fd, data+written, size-written));
+ if (w == -1) {
fprintf(stderr, "write failed: %s\n", strerror(errno));
return -1;
- } else {
- written += w;
}
+ written += w;
}
if (fsync(fd) == -1) {
@@ -144,19 +143,13 @@ static int write_all(int fd, const uint8_t* data, size_t size) {
return 0;
}
-static int check_lseek(int fd, off64_t offset, int whence) {
- while (true) {
- off64_t ret = lseek64(fd, offset, whence);
- if (ret < 0) {
- if (errno != EINTR) {
- fprintf(stderr, "lseek64 failed: %s\n", strerror(errno));
- return -1;
- }
- } else {
- break;
- }
+static bool check_lseek(int fd, off64_t offset, int whence) {
+ off64_t rc = TEMP_FAILURE_RETRY(lseek64(fd, offset, whence));
+ if (rc == -1) {
+ fprintf(stderr, "lseek64 failed: %s\n", strerror(errno));
+ return false;
}
- return 0;
+ return true;
}
static void allocate(size_t size, uint8_t** buffer, size_t* buffer_alloc) {
@@ -213,8 +206,8 @@ static ssize_t RangeSinkWrite(const uint8_t* data, ssize_t size, void* token) {
rss->p_remain = (rss->tgt->pos[rss->p_block * 2 + 1] -
rss->tgt->pos[rss->p_block * 2]) * BLOCKSIZE;
- if (check_lseek(rss->fd, (off64_t)rss->tgt->pos[rss->p_block*2] * BLOCKSIZE,
- SEEK_SET) == -1) {
+ if (!check_lseek(rss->fd, (off64_t)rss->tgt->pos[rss->p_block*2] * BLOCKSIZE,
+ SEEK_SET)) {
break;
}
} else {
@@ -306,7 +299,7 @@ static int ReadBlocks(RangeSet* src, uint8_t* buffer, int fd) {
}
for (i = 0; i < src->count; ++i) {
- if (check_lseek(fd, (off64_t) src->pos[i * 2] * BLOCKSIZE, SEEK_SET) == -1) {
+ if (!check_lseek(fd, (off64_t) src->pos[i * 2] * BLOCKSIZE, SEEK_SET)) {
return -1;
}
@@ -332,7 +325,7 @@ static int WriteBlocks(RangeSet* tgt, uint8_t* buffer, int fd) {
}
for (i = 0; i < tgt->count; ++i) {
- if (check_lseek(fd, (off64_t) tgt->pos[i * 2] * BLOCKSIZE, SEEK_SET) == -1) {
+ if (!check_lseek(fd, (off64_t) tgt->pos[i * 2] * BLOCKSIZE, SEEK_SET)) {
return -1;
}
@@ -624,7 +617,7 @@ static int LoadStash(const char* base, const char* id, int verify, int* blocks,
lsout:
if (fd != -1) {
- TEMP_FAILURE_RETRY(close(fd));
+ close(fd);
}
if (fn) {
@@ -640,6 +633,7 @@ static int WriteStash(const char* base, const char* id, int blocks, uint8_t* buf
char *cn = NULL;
int fd = -1;
int rc = -1;
+ int dfd = -1;
int res;
struct stat st;
@@ -698,11 +692,29 @@ static int WriteStash(const char* base, const char* id, int blocks, uint8_t* buf
goto wsout;
}
+ const char* dname;
+ dname = dirname(cn);
+ dfd = TEMP_FAILURE_RETRY(open(dname, O_RDONLY | O_DIRECTORY));
+
+ if (dfd == -1) {
+ fprintf(stderr, "failed to open \"%s\" failed: %s\n", dname, strerror(errno));
+ goto wsout;
+ }
+
+ if (fsync(dfd) == -1) {
+ fprintf(stderr, "fsync \"%s\" failed: %s\n", dname, strerror(errno));
+ goto wsout;
+ }
+
rc = 0;
wsout:
if (fd != -1) {
- TEMP_FAILURE_RETRY(close(fd));
+ close(fd);
+ }
+
+ if (dfd != -1) {
+ close(dfd);
}
if (fn) {
@@ -1217,7 +1229,7 @@ static int PerformCommandZero(CommandParameters* params) {
if (params->canwrite) {
for (i = 0; i < tgt->count; ++i) {
- if (check_lseek(params->fd, (off64_t) tgt->pos[i * 2] * BLOCKSIZE, SEEK_SET) == -1) {
+ if (!check_lseek(params->fd, (off64_t) tgt->pos[i * 2] * BLOCKSIZE, SEEK_SET)) {
goto pczout;
}
@@ -1271,7 +1283,7 @@ static int PerformCommandNew(CommandParameters* params) {
rss.p_block = 0;
rss.p_remain = (tgt->pos[1] - tgt->pos[0]) * BLOCKSIZE;
- if (check_lseek(params->fd, (off64_t) tgt->pos[0] * BLOCKSIZE, SEEK_SET) == -1) {
+ if (!check_lseek(params->fd, (off64_t) tgt->pos[0] * BLOCKSIZE, SEEK_SET)) {
goto pcnout;
}
@@ -1367,7 +1379,7 @@ static int PerformCommandDiff(CommandParameters* params) {
rss.p_block = 0;
rss.p_remain = (tgt->pos[1] - tgt->pos[0]) * BLOCKSIZE;
- if (check_lseek(params->fd, (off64_t) tgt->pos[0] * BLOCKSIZE, SEEK_SET) == -1) {
+ if (!check_lseek(params->fd, (off64_t) tgt->pos[0] * BLOCKSIZE, SEEK_SET)) {
goto pcdout;
}
@@ -1432,7 +1444,6 @@ static int PerformCommandErase(CommandParameters* params) {
if (!S_ISBLK(st.st_mode)) {
fprintf(stderr, "not a block device; skipping erase\n");
- rc = 0;
goto pceout;
}
@@ -1456,7 +1467,7 @@ static int PerformCommandErase(CommandParameters* params) {
if (ioctl(params->fd, BLKDISCARD, &blocks) == -1) {
fprintf(stderr, "BLKDISCARD ioctl failed: %s\n", strerror(errno));
- // Continue anyway, nothing we can do
+ goto pceout;
}
}
}
@@ -1740,7 +1751,7 @@ pbiudone:
if (fsync(params.fd) == -1) {
fprintf(stderr, "fsync failed: %s\n", strerror(errno));
}
- TEMP_FAILURE_RETRY(close(params.fd));
+ close(params.fd);
}
if (logcmd) {
@@ -1906,7 +1917,7 @@ Value* RangeSha1Fn(const char* name, State* state, int argc, Expr* argv[]) {
int i, j;
for (i = 0; i < rs->count; ++i) {
- if (check_lseek(fd, (off64_t)rs->pos[i*2] * BLOCKSIZE, SEEK_SET) == -1) {
+ if (!check_lseek(fd, (off64_t)rs->pos[i*2] * BLOCKSIZE, SEEK_SET)) {
ErrorAbort(state, "failed to seek %s: %s", blockdev_filename->data,
strerror(errno));
goto done;