diff options
| -rw-r--r-- | util/nvmutil/nvmutil.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c index 2d602038..c05487cf 100644 --- a/util/nvmutil/nvmutil.c +++ b/util/nvmutil/nvmutil.c @@ -390,6 +390,7 @@ static ssize_t rw_file_once(int fd, u8 *mem, size_t len, int loop_eintr, size_t max_retries); static ssize_t prw(int fd, void *mem, size_t nrw, off_t off, int rw_type, int loop_eagain, int loop_eintr); +static int check_file(int fd, struct stat *st); static int rw_over_nrw(ssize_t r, size_t nrw); static off_t lseek_loop(int fd, off_t off, int whence, int loop_eagain, int loop_eintr); @@ -1831,21 +1832,9 @@ rw_file_exact(int fd, u8 *mem, size_t nrw, off_t off, int rw_type, int loop_eagain, int loop_eintr, size_t max_retries) { - struct stat st; ssize_t rv; size_t rc; - /* Programs like cat can use this, - so we only check if it's a normal - file if not looping EAGAIN */ - if (!loop_eagain) { - if (fstat(fd, &st) == -1) - goto err_rw_file_exact; - - if (S_ISREG(st.st_mode)) - goto err_rw_file_exact; - } - for (rc = 0, rv = 0; rc < nrw; ) { if ((rv = rw_file_once(fd, mem, nrw, off, rw_type, rc, loop_eagain, loop_eintr, max_retries)) < 0) @@ -1960,6 +1949,7 @@ prw(int fd, void *mem, size_t nrw, ssize_t r; int saved_errno; int positional_rw; + struct stat st; if (mem == NULL) goto err_prw; @@ -1973,6 +1963,20 @@ prw(int fd, void *mem, size_t nrw, r = -1; + /* Programs like cat can use this, + so we only check if it's a normal + file if not looping EAGAIN */ + if (!loop_eagain) { + /* + * Checking on every run of prw() + * is expensive if called many + * times, but is defensive in + * case the status changes. + */ + if (check_file(fd, &st) == -1) + return -1; + } + if (rw_type >= IO_PREAD) positional_rw = 1; /* pread/pwrite */ else @@ -2045,6 +2049,22 @@ err_prw: return -1; } +static int +check_file(int fd, struct stat *st) +{ + if (fstat(fd, st) == -1) + goto err_is_file; + + if (S_ISREG(st->st_mode)) + goto err_is_file; + + return 0; + +err_is_file: + errno = EIO; + return -1; +} + /* * Check overflows caused by buggy libc. * |
