1 /* 2 * TRIM/DISCARD support 3 */ 4 #include <unistd.h> 5 #include <fcntl.h> 6 #include <string.h> 7 #include <assert.h> 8 #include <pthread.h> 9 10 #include "fio.h" 11 #include "trim.h" 12 13 #ifdef FIO_HAVE_TRIM 14 int get_next_trim(struct thread_data *td, struct io_u *io_u) 15 { 16 struct io_piece *ipo; 17 18 /* 19 * this io_u is from a requeue, we already filled the offsets 20 */ 21 if (io_u->file) 22 return 0; 23 if (flist_empty(&td->trim_list)) 24 return 1; 25 26 assert(td->trim_entries); 27 ipo = flist_first_entry(&td->trim_list, struct io_piece, trim_list); 28 remove_trim_entry(td, ipo); 29 30 io_u->offset = ipo->offset; 31 io_u->buflen = ipo->len; 32 io_u->file = ipo->file; 33 34 /* 35 * If not verifying that trimmed ranges return zeroed data, 36 * remove this from the to-read verify lists 37 */ 38 if (!td->o.trim_zero) { 39 if (ipo->flags & IP_F_ONLIST) 40 flist_del(&ipo->list); 41 else { 42 assert(ipo->flags & IP_F_ONRB); 43 rb_erase(&ipo->rb_node, &td->io_hist_tree); 44 } 45 td->io_hist_len--; 46 free(ipo); 47 } else 48 ipo->flags |= IP_F_TRIMMED; 49 50 if (!fio_file_open(io_u->file)) { 51 int r = td_io_open_file(td, io_u->file); 52 53 if (r) { 54 dprint(FD_VERIFY, "failed file %s open\n", 55 io_u->file->file_name); 56 return 1; 57 } 58 } 59 60 get_file(io_u->file); 61 assert(fio_file_open(io_u->file)); 62 io_u->ddir = DDIR_TRIM; 63 io_u->xfer_buf = NULL; 64 io_u->xfer_buflen = io_u->buflen; 65 66 dprint(FD_VERIFY, "get_next_trim: ret io_u %p\n", io_u); 67 return 0; 68 } 69 70 int io_u_should_trim(struct thread_data *td, struct io_u *io_u) 71 { 72 unsigned long long val; 73 unsigned long r; 74 75 if (!td->o.trim_percentage) 76 return 0; 77 78 r = __rand(&td->trim_state); 79 val = (FRAND_MAX / 100ULL); 80 81 val *= (unsigned long long) td->o.trim_percentage; 82 return r <= val; 83 } 84 #endif 85