From: Jens Axboe Date: Tue, 8 Nov 2005 08:20:58 +0000 (+0100) Subject: [PATCH] fio: add size detection for block devices X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=c94deb1c1dfd93220efa54e03a73116669a6b96a;p=disktools.git [PATCH] fio: add size detection for block devices --- diff --git a/fio.c b/fio.c index f546151..6366f22 100644 --- a/fio.c +++ b/fio.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -46,6 +47,10 @@ #include "list.h" #include "md5.h" +#ifndef BLKGETSIZE64 +#define BLKGETSIZE64 _IOR(0x12,114,size_t) +#endif + #define MAX_JOBS (1024) /* @@ -1417,6 +1422,11 @@ static int create_file(struct thread_data *td) return 1; } + if (ftruncate(td->fd, td->file_size) == -1) { + td->error = errno; + return 1; + } + td->io_size = td->file_size; b = malloc(td->max_bs); memset(b, 0, td->max_bs); @@ -1461,9 +1471,58 @@ static int file_exists(struct thread_data *td) return errno != ENOENT; } -static int setup_file(struct thread_data *td) +static int get_file_size(struct thread_data *td) { + size_t bytes = 0; struct stat st; + + if (fstat(td->fd, &st) == -1) { + td->error = errno; + return 1; + } + + /* + * if block device, get size via BLKGETSIZE64 ioctl. try that as well + * if this is a link, fall back to st.st_size if it fails + */ + if (S_ISBLK(st.st_mode) || S_ISLNK(st.st_mode)) { + if (ioctl(td->fd, BLKGETSIZE64, &bytes)) { + if (S_ISBLK(st.st_mode)) { + td->error = errno; + return 1; + } else + bytes = st.st_size; + } + } else + bytes = st.st_size; + + if (td_read(td)) { + if (td->file_size > bytes) + bytes = td->file_size; + } else { + if (!td->file_size) + td->file_size = 1024 * 1024 * 1024; + + bytes = td->file_size; + } + + if (td->file_offset > bytes) { + fprintf(stderr, "Client%d: offset larger than length\n", td->thread_number); + return 1; + } + + td->io_size = bytes - td->file_offset; + if (td->io_size == 0) { + fprintf(stderr, "Client%d: no io blocks\n", td->thread_number); + td->error = EINVAL; + return 1; + } + + return 0; +} + +static int setup_file(struct thread_data *td) +{ int flags = 0; if (!file_exists(td)) { @@ -1498,35 +1557,16 @@ static int setup_file(struct thread_data *td) return 1; } - if (td_read(td)) { - if (fstat(td->fd, &st) == -1) { - td->error = errno; - return 1; - } - - if (td->file_size > st.st_size) - st.st_size = td->file_size; - } else { - if (!td->file_size) - td->file_size = 1024 * 1024 * 1024; - - st.st_size = td->file_size; - } - - if (td->file_offset > st.st_size) { - fprintf(stderr, "Client%d: offset larger than length\n", td->thread_number); + if (get_file_size(td)) return 1; - } - td->io_size = st.st_size - td->file_offset; - if (td->io_size == 0) { - fprintf(stderr, "Client%d: no io blocks\n", td->thread_number); - td->error = EINVAL; + if (!td_read(td) && ftruncate(td->fd, td->file_size) == -1) { + td->error = errno; return 1; } if (td->invalidate_cache) { - if (fadvise(td->fd, 0, st.st_size, POSIX_FADV_DONTNEED) < 0) { + if (fadvise(td->fd, td->file_offset, td->file_size, POSIX_FADV_DONTNEED) < 0) { td->error = errno; return 1; }