U_I fichier_local::fichier_global_inherited_write(const char *a, U_I size) { ssize_t ret; U_I total = 0; // due to posix inconsistence in write(2) // we cannot write more than SSIZE_MAX/2 byte // to be able to have a positive returned value // in case of success, a negative else. As the // returned type of write() is signed size_t, // which max positive value is SSIZE_MAX/2 (rounded // to the lower interger) #ifdef SSIZE_MAX static const U_I step = SSIZE_MAX/2; #else const U_I step = size; // which is no limit... #endif #ifdef MUTEX_WORKS check_self_cancellation(); #endif while(total < size) { if(size - total > step) ret = ::write(filedesc, a+total, step); else ret = ::write(filedesc, a+total, size - total); if(ret < 0) { switch(errno) { case EINTR: break; case EIO: throw Ehardware("fichier_local::inherited_write", string(gettext("Error while writing to file: ")) + tools_strerror_r(errno)); case ENOSPC: return total; // partial writing, we stop here returning the amount of data wrote so far // because there is no space left on device. The parent class manages the user interaction // to allow abortion or action that frees up some storage space. default : throw Erange("fichier_local::inherited_write", string(gettext("Error while writing to file: ")) + tools_strerror_r(errno)); } } else total += ret; } if(adv == advise_dontneed) // we should call fsync() here but we do not to to avoid blocking the process: // we assume the system has flushed some blocks of possibly previous writes // so we just inform the system to remove from cache blocks associated to this // file that have already been flushed. fadvise(adv); return total; }
int main (void) { /* Valid. */ fadvise (stdin, FADVISE_SEQUENTIAL); fdadvise (fileno (stdin), 0, 0, FADVISE_RANDOM); /* Ignored. */ fadvise (NULL, FADVISE_RANDOM); /* Invalid. */ fdadvise (42, 0, 0, FADVISE_RANDOM); /* Unfortunately C enums are not types. One could hack type safety by wrapping in a struct, but it's probably not worth the complexity in this case. */ fadvise (stdin, FADVISE_SEQUENTIAL + FADVISE_RANDOM); fadvise (stdin, 4242); return 0; }
static _Bool cut_file(char const *file ) { FILE *stream ; int *tmp ; int tmp___0 ; int *tmp___1 ; int tmp___2 ; int *tmp___3 ; int tmp___4 ; int tmp___5 ; { tmp___0 = strcmp(file, "-"); if (tmp___0 == 0) { have_read_stdin = (_Bool)1; stream = stdin; } else { stream = fopen((char const */* __restrict */)file, (char const */* __restrict */)"r"); if ((unsigned long )stream == (unsigned long )((void *)0)) { tmp = __errno_location(); error(0, *tmp, "%s", file); return ((_Bool)0); } else { } } fadvise(stream, (enum __anonenum_fadvice_t_62 )2); cut_stream(stream); tmp___2 = ferror_unlocked(stream); if (tmp___2) { tmp___1 = __errno_location(); error(0, *tmp___1, "%s", file); return ((_Bool)0); } else { } tmp___5 = strcmp(file, "-"); if (tmp___5 == 0) { clearerr_unlocked(stream); } else { tmp___4 = fclose(stream); if (tmp___4 == -1) { tmp___3 = __errno_location(); error(0, *tmp___3, "%s", file); return ((_Bool)0); } else { } } return ((_Bool)1); } }
static int __file_invalidate_cache(struct thread_data *td, struct fio_file *f, unsigned long long off, unsigned long long len) { int ret = 0; if (len == -1ULL) len = f->io_size; if (off == -1ULL) off = f->file_offset; if (len == -1ULL || off == -1ULL) return 0; dprint(FD_IO, "invalidate cache %s: %llu/%llu\n", f->file_name, off, len); /* * FIXME: add blockdev flushing too */ if (f->mmap_ptr) { ret = madvise(f->mmap_ptr, f->mmap_sz, MADV_DONTNEED); #ifdef FIO_MADV_FREE (void) 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); } else if (f->filetype == FIO_TYPE_BD) { ret = blockdev_invalidate_cache(f->fd); if (ret < 0 && errno == EACCES && geteuid()) { if (!root_warn) { log_err("fio: only root may flush block " "devices. Cache flush bypassed!\n"); root_warn = 1; } ret = 0; } } else if (f->filetype == FIO_TYPE_CHAR || f->filetype == FIO_TYPE_PIPE) ret = 0; if (ret < 0) { td_verror(td, errno, "invalidate_cache"); return 1; } else if (ret > 0) { td_verror(td, ret, "invalidate_cache"); return 1; } return ret; }
bool fichier_local::fichier_global_inherited_read(char *a, U_I size, U_I & read, string & message) { ssize_t ret = -1; read = 0; #ifdef MUTEX_WORKS check_self_cancellation(); #endif do { #ifdef SSIZE_MAX U_I to_read = size - read > SSIZE_MAX ? SSIZE_MAX : size - read; #else U_I to_read = size - read; #endif ret = ::read(filedesc, a+read, to_read); if(ret < 0) { switch(errno) { case EINTR: break; case EAGAIN: throw SRC_BUG; // "non blocking" read is not expected in this implementation case EIO: throw Ehardware("fichier_local::inherited_read", string(gettext("Error while reading from file: ")) + tools_strerror_r(errno)); default : throw Erange("fichier_local::inherited_read", string(gettext("Error while reading from file: ")) + tools_strerror_r(errno)); } } else read += ret; } while(read < size && ret != 0); if(adv == advise_dontneed) fadvise(adv); return true; // we never make partial reading, here }