diff options
Diffstat (limited to 'updater/blockimg.c')
-rw-r--r-- | updater/blockimg.c | 79 |
1 files changed, 45 insertions, 34 deletions
diff --git a/updater/blockimg.c b/updater/blockimg.c index d5344f991..b006d10c5 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; |