mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-11 05:52:36 +02:00
libreboot-utils/file: never retry file rw on zero
even with a timer, it's possible that on a buggy system, we may keep writing even though the outcome is zero. if a system comes back with zero bytes written, that is a fatal bug and we should stop. Signed-off-by: Leah Rowe <leah@libreboot.org>
This commit is contained in:
@@ -83,10 +83,6 @@
|
|||||||
#error "Unexpected bit layout"
|
#error "Unexpected bit layout"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef MAX_ZERO_RW_RETRY
|
|
||||||
#define MAX_ZERO_RW_RETRY 5
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef _FILE_OFFSET_BITS
|
#ifndef _FILE_OFFSET_BITS
|
||||||
#define _FILE_OFFSET_BITS 64
|
#define _FILE_OFFSET_BITS 64
|
||||||
#endif
|
#endif
|
||||||
@@ -462,7 +458,7 @@ ssize_t rw_gbe_file_exact(int fd, unsigned char *mem, size_t nrw,
|
|||||||
|
|
||||||
int fsync_dir(const char *path);
|
int fsync_dir(const char *path);
|
||||||
ssize_t rw_file_exact(int fd, unsigned char *mem, size_t len,
|
ssize_t rw_file_exact(int fd, unsigned char *mem, size_t len,
|
||||||
off_t off, int rw_type, size_t max_retries);
|
off_t off, int rw_type);
|
||||||
ssize_t rw(int fd, void *mem, size_t nrw,
|
ssize_t rw(int fd, void *mem, size_t nrw,
|
||||||
off_t off, int rw_type);
|
off_t off, int rw_type);
|
||||||
int io_args(int fd, void *mem, size_t nrw,
|
int io_args(int fd, void *mem, size_t nrw,
|
||||||
|
|||||||
@@ -493,7 +493,7 @@ cat_buf(unsigned char *b)
|
|||||||
exitf("null pointer in cat command");
|
exitf("null pointer in cat command");
|
||||||
|
|
||||||
if (rw_file_exact(STDOUT_FILENO, b,
|
if (rw_file_exact(STDOUT_FILENO, b,
|
||||||
GBE_PART_SIZE, 0, IO_WRITE, MAX_ZERO_RW_RETRY) < 0)
|
GBE_PART_SIZE, 0, IO_WRITE) < 0)
|
||||||
exitf("stdout: cat");
|
exitf("stdout: cat");
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ err_fsync_dir:
|
|||||||
|
|
||||||
ssize_t
|
ssize_t
|
||||||
rw_file_exact(int fd, unsigned char *mem, size_t nrw,
|
rw_file_exact(int fd, unsigned char *mem, size_t nrw,
|
||||||
off_t off, int rw_type, size_t max_retries)
|
off_t off, int rw_type)
|
||||||
{
|
{
|
||||||
int saved_errno = errno;
|
int saved_errno = errno;
|
||||||
ssize_t rval = 0;
|
ssize_t rval = 0;
|
||||||
@@ -154,7 +154,6 @@ rw_file_exact(int fd, unsigned char *mem, size_t nrw,
|
|||||||
size_t nrw_cur;
|
size_t nrw_cur;
|
||||||
off_t off_cur;
|
off_t off_cur;
|
||||||
void *mem_cur;
|
void *mem_cur;
|
||||||
size_t retries_on_zero = 0;
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
|
|
||||||
if (io_args(fd, mem, nrw, off, rw_type) == -1)
|
if (io_args(fd, mem, nrw, off, rw_type) == -1)
|
||||||
@@ -178,17 +177,8 @@ rw_file_exact(int fd, unsigned char *mem, size_t nrw,
|
|||||||
|
|
||||||
off_cur = off + (off_t)rc;
|
off_cur = off + (off_t)rc;
|
||||||
|
|
||||||
if ((rval = rw(fd, mem_cur, nrw_cur, off_cur, rw_type)) < 0)
|
if ((rval = rw(fd, mem_cur, nrw_cur, off_cur, rw_type)) <= 0)
|
||||||
goto err_rw_file_exact;
|
goto err_rw_file_exact;
|
||||||
|
|
||||||
if (rval == 0) {
|
|
||||||
if (retries_on_zero++ < max_retries)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
goto err_rw_file_exact;
|
|
||||||
}
|
|
||||||
|
|
||||||
retries_on_zero = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (if_err((size_t)rc != nrw, EIO) ||
|
if (if_err((size_t)rc != nrw, EIO) ||
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ read_file(void)
|
|||||||
/* read main file
|
/* read main file
|
||||||
*/
|
*/
|
||||||
_r = rw_file_exact(f->gbe_fd, f->buf, f->gbe_file_size,
|
_r = rw_file_exact(f->gbe_fd, f->buf, f->gbe_file_size,
|
||||||
0, IO_PREAD, MAX_ZERO_RW_RETRY);
|
0, IO_PREAD);
|
||||||
|
|
||||||
if (_r < 0)
|
if (_r < 0)
|
||||||
exitf("%s: read failed", f->fname);
|
exitf("%s: read failed", f->fname);
|
||||||
@@ -117,7 +117,7 @@ read_file(void)
|
|||||||
/* copy to tmpfile
|
/* copy to tmpfile
|
||||||
*/
|
*/
|
||||||
_r = rw_file_exact(f->tmp_fd, f->buf, f->gbe_file_size,
|
_r = rw_file_exact(f->tmp_fd, f->buf, f->gbe_file_size,
|
||||||
0, IO_PWRITE, MAX_ZERO_RW_RETRY);
|
0, IO_PWRITE);
|
||||||
|
|
||||||
if (_r < 0)
|
if (_r < 0)
|
||||||
exitf("%s: %s: copy failed",
|
exitf("%s: %s: copy failed",
|
||||||
@@ -140,7 +140,7 @@ read_file(void)
|
|||||||
exitf("%s: fsync (tmpfile copy)", f->tname);
|
exitf("%s: fsync (tmpfile copy)", f->tname);
|
||||||
|
|
||||||
_r = rw_file_exact(f->tmp_fd, f->bufcmp, f->gbe_file_size,
|
_r = rw_file_exact(f->tmp_fd, f->bufcmp, f->gbe_file_size,
|
||||||
0, IO_PREAD, MAX_ZERO_RW_RETRY);
|
0, IO_PREAD);
|
||||||
|
|
||||||
if (_r < 0)
|
if (_r < 0)
|
||||||
exitf("%s: read failed (cmp)", f->tname);
|
exitf("%s: read failed (cmp)", f->tname);
|
||||||
@@ -556,8 +556,7 @@ rw_gbe_file_exact(int fd, unsigned char *mem, size_t nrw,
|
|||||||
if (nrw > (size_t)GBE_PART_SIZE)
|
if (nrw > (size_t)GBE_PART_SIZE)
|
||||||
goto err_rw_gbe_file_exact;
|
goto err_rw_gbe_file_exact;
|
||||||
|
|
||||||
r = rw_file_exact(fd, mem, nrw, off, rw_type,
|
r = rw_file_exact(fd, mem, nrw, off, rw_type);
|
||||||
MAX_ZERO_RW_RETRY);
|
|
||||||
|
|
||||||
return rw_over_nrw(r, nrw);
|
return rw_over_nrw(r, nrw);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user