#include "fio.h"
#include "smalloc.h"
#include "filehash.h"
+#include "os/os.h"
+
+#ifdef FIO_HAVE_LINUX_FALLOCATE
+#include <linux/falloc.h>
+#endif
static int root_warn;
}
#ifdef FIO_HAVE_FALLOCATE
- if (td->o.fallocate && !td->o.fill_device) {
- dprint(FD_FILE, "fallocate file %s size %llu\n", f->file_name,
- f->real_file_size);
-
- r = posix_fallocate(f->fd, 0, f->real_file_size);
- if (r > 0) {
- log_err("fio: posix_fallocate fails: %s\n",
- strerror(r));
+ if (!td->o.fill_device) {
+ switch (td->o.fallocate_mode) {
+ case FIO_FALLOCATE_NONE:
+ break;
+ case FIO_FALLOCATE_POSIX:
+ dprint(FD_FILE, "posix_fallocate file %s size %llu\n",
+ f->file_name, f->real_file_size);
+
+ r = posix_fallocate(f->fd, 0, f->real_file_size);
+ if (r > 0) {
+ log_err("fio: posix_fallocate fails: %s\n",
+ strerror(r));
+ }
+ break;
+#ifdef FIO_HAVE_LINUX_FALLOCATE
+ case FIO_FALLOCATE_KEEP_SIZE:
+ dprint(FD_FILE,
+ "fallocate(FALLOC_FL_KEEP_SIZE) "
+ "file %s size %llu\n",
+ f->file_name, f->real_file_size);
+
+ r = fallocate(f->fd, FALLOC_FL_KEEP_SIZE, 0,
+ f->real_file_size);
+ if (r != 0) {
+ td_verror(td, errno, "fallocate");
+ }
+ break;
+#endif /* FIO_HAVE_LINUX_FALLOCATE */
+ default:
+ log_err("fio: unknown fallocate mode: %d\n",
+ td->o.fallocate_mode);
+ assert(0);
}
}
-#endif
-
+#endif /* FIO_HAVE_FALLOCATE */
+
if (!new_layout)
goto done;
static unsigned long long get_rand_file_size(struct thread_data *td)
{
unsigned long long ret, sized;
- long r;
+ unsigned long r;
+
+ if (td->o.use_os_rand) {
+ r = os_random_long(&td->file_size_state);
+ sized = td->o.file_size_high - td->o.file_size_low;
+ ret = (unsigned long long) ((double) sized * (r / (OS_RAND_MAX + 1.0)));
+ } else {
+ r = __rand(&td->__file_size_state);
+ sized = td->o.file_size_high - td->o.file_size_low;
+ ret = (unsigned long long) ((double) sized * (r / (FRAND_MAX + 1.0)));
+ }
- r = os_random_long(&td->file_size_state);
- sized = td->o.file_size_high - td->o.file_size_low;
- ret = (unsigned long long) ((double) sized * (r / (OS_RAND_MAX + 1.0)));
ret += td->o.file_size_low;
ret -= (ret % td->o.rw_min_bs);
return ret;
static int bdev_size(struct thread_data *td, struct fio_file *f)
{
- unsigned long long bytes;
+ unsigned long long bytes = 0;
int r;
if (td->io_ops->open_file(td, f)) {
return 1;
}
- r = blockdev_size(f->fd, &bytes);
+ r = blockdev_size(f, &bytes);
if (r) {
td_verror(td, r, "blockdev_size");
goto err;
static int char_size(struct thread_data *td, struct fio_file *f)
{
#ifdef FIO_HAVE_CHARDEV_SIZE
- unsigned long long bytes;
+ unsigned long long bytes = 0;
int r;
if (td->io_ops->open_file(td, f)) {
return 1;
}
- r = chardev_size(f->fd, &bytes);
+ r = chardev_size(f, &bytes);
if (r) {
td_verror(td, r, "chardev_size");
goto err;
return ret;
if (f->file_offset > f->real_file_size) {
- log_err("%s: offset extends end (%Lu > %Lu)\n", td->o.name,
+ log_err("%s: offset extends end (%llu > %llu)\n", td->o.name,
f->file_offset, f->real_file_size);
return 1;
}
* FIXME: add blockdev flushing too
*/
if (f->mmap_ptr) {
- ret = madvise(f->mmap_ptr, f->mmap_sz, MADV_DONTNEED);
+ ret = posix_madvise(f->mmap_ptr, f->mmap_sz, POSIX_MADV_DONTNEED);
#ifdef FIO_MADV_FREE
- (void) madvise(f->mmap_ptr, f->mmap_sz, FIO_MADV_FREE);
+ (void) posix_madvise(f->mmap_ptr, f->mmap_sz, FIO_MADV_FREE);
#endif
} else if (f->filetype == FIO_TYPE_FILE) {
- ret = fadvise(f->fd, off, len, POSIX_FADV_DONTNEED);
+ ret = posix_fadvise(f->fd, off, len, POSIX_FADV_DONTNEED);
} else if (f->filetype == FIO_TYPE_BD) {
- ret = blockdev_invalidate_cache(f->fd);
+ ret = blockdev_invalidate_cache(f);
if (ret < 0 && errno == EACCES && geteuid()) {
if (!root_warn) {
log_err("fio: only root may flush block "
if (!from_hash && f->fd != -1) {
if (add_file_hash(f)) {
- int ret;
+ int fio_unused ret;
/*
* OK to ignore, we haven't done anything with it
extend_size = total_size = 0;
need_extend = 0;
for_each_file(td, f, i) {
- f->file_offset = td->o.start_offset;
+ f->file_offset = td->o.start_offset +
+ (td->thread_number - 1) * td->o.offset_increment;
if (!td->o.file_size_low) {
/*
}
}
+ if (td->o.size_percent)
+ total_size = (total_size * td->o.size_percent) / 100;
+
if (!td->o.size || td->o.size > total_size)
td->o.size = total_size;
temp_stall_ts = 1;
if (!terse_output)
log_info("%s: Laying out IO file(s) (%u file(s) /"
- " %LuMB)\n", td->o.name, need_extend,
+ " %lluMB)\n", td->o.name, need_extend,
extend_size >> 20);
for_each_file(td, f, i) {
(unsigned long long) td->o.rw_min_bs;
num_maps = (blocks + BLOCKS_PER_MAP - 1) /
(unsigned long long) BLOCKS_PER_MAP;
- f->file_map = smalloc(num_maps * sizeof(int));
- if (f->file_map) {
- f->num_maps = num_maps;
- continue;
- }
+ if (num_maps == (unsigned long) num_maps) {
+ f->file_map = smalloc(num_maps * sizeof(unsigned long));
+ if (f->file_map) {
+ f->num_maps = num_maps;
+ continue;
+ }
+ } else
+ f->file_map = NULL;
+
if (!td->o.softrandommap) {
log_err("fio: failed allocating random map. If running"
" a large number of jobs, try the 'norandommap'"
else
f->filetype = FIO_TYPE_FILE;
+ /* \\.\ is the device namespace in Windows, where every file is
+ * a block device */
+ if (strncmp(f->file_name, "\\\\.\\", 4) == 0)
+ f->filetype = FIO_TYPE_BD;
+
if (!stat(f->file_name, &sb)) {
if (S_ISBLK(sb.st_mode))
f->filetype = FIO_TYPE_BD;
if (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, ".."))
continue;
- sprintf(full_path, "%s/%s", dirname, dir->d_name);
+ sprintf(full_path, "%s%s%s", dirname, FIO_OS_PATH_SEPARATOR, dir->d_name);
if (lstat(full_path, &sb) == -1) {
if (errno != ENOENT) {