Lines Matching refs:c

49 static inline void *qcow2_cache_get_table_addr(Qcow2Cache *c, int table)  in qcow2_cache_get_table_addr()  argument
51 return (uint8_t *) c->table_array + (size_t) table * c->table_size; in qcow2_cache_get_table_addr()
54 static inline int qcow2_cache_get_table_idx(Qcow2Cache *c, void *table) in qcow2_cache_get_table_idx() argument
56 ptrdiff_t table_offset = (uint8_t *) table - (uint8_t *) c->table_array; in qcow2_cache_get_table_idx()
57 int idx = table_offset / c->table_size; in qcow2_cache_get_table_idx()
58 assert(idx >= 0 && idx < c->size && table_offset % c->table_size == 0); in qcow2_cache_get_table_idx()
62 static inline const char *qcow2_cache_get_name(BDRVQcow2State *s, Qcow2Cache *c) in qcow2_cache_get_name() argument
64 if (c == s->refcount_block_cache) { in qcow2_cache_get_name()
66 } else if (c == s->l2_table_cache) { in qcow2_cache_get_name()
74 static void qcow2_cache_table_release(Qcow2Cache *c, int i, int num_tables) in qcow2_cache_table_release() argument
78 void *t = qcow2_cache_get_table_addr(c, i); in qcow2_cache_table_release()
80 size_t mem_size = (size_t) c->table_size * num_tables; in qcow2_cache_table_release()
89 static inline bool can_clean_entry(Qcow2Cache *c, int i) in can_clean_entry() argument
91 Qcow2CachedTable *t = &c->entries[i]; in can_clean_entry()
93 t->lru_counter <= c->cache_clean_lru_counter; in can_clean_entry()
96 void qcow2_cache_clean_unused(Qcow2Cache *c) in qcow2_cache_clean_unused() argument
99 while (i < c->size) { in qcow2_cache_clean_unused()
103 while (i < c->size && !can_clean_entry(c, i)) { in qcow2_cache_clean_unused()
108 while (i < c->size && can_clean_entry(c, i)) { in qcow2_cache_clean_unused()
109 c->entries[i].offset = 0; in qcow2_cache_clean_unused()
110 c->entries[i].lru_counter = 0; in qcow2_cache_clean_unused()
116 qcow2_cache_table_release(c, i - to_clean, to_clean); in qcow2_cache_clean_unused()
120 c->cache_clean_lru_counter = c->lru_counter; in qcow2_cache_clean_unused()
127 Qcow2Cache *c; in qcow2_cache_create() local
134 c = g_new0(Qcow2Cache, 1); in qcow2_cache_create()
135 c->size = num_tables; in qcow2_cache_create()
136 c->table_size = table_size; in qcow2_cache_create()
137 c->entries = g_try_new0(Qcow2CachedTable, num_tables); in qcow2_cache_create()
138 c->table_array = qemu_try_blockalign(bs->file->bs, in qcow2_cache_create()
139 (size_t) num_tables * c->table_size); in qcow2_cache_create()
141 if (!c->entries || !c->table_array) { in qcow2_cache_create()
142 qemu_vfree(c->table_array); in qcow2_cache_create()
143 g_free(c->entries); in qcow2_cache_create()
144 g_free(c); in qcow2_cache_create()
145 c = NULL; in qcow2_cache_create()
148 return c; in qcow2_cache_create()
151 int qcow2_cache_destroy(Qcow2Cache *c) in qcow2_cache_destroy() argument
155 for (i = 0; i < c->size; i++) { in qcow2_cache_destroy()
156 assert(c->entries[i].ref == 0); in qcow2_cache_destroy()
159 qemu_vfree(c->table_array); in qcow2_cache_destroy()
160 g_free(c->entries); in qcow2_cache_destroy()
161 g_free(c); in qcow2_cache_destroy()
167 qcow2_cache_flush_dependency(BlockDriverState *bs, Qcow2Cache *c) in qcow2_cache_flush_dependency() argument
171 ret = qcow2_cache_flush(bs, c->depends); in qcow2_cache_flush_dependency()
176 c->depends = NULL; in qcow2_cache_flush_dependency()
177 c->depends_on_flush = false; in qcow2_cache_flush_dependency()
183 qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i) in qcow2_cache_entry_flush() argument
188 if (!c->entries[i].dirty || !c->entries[i].offset) { in qcow2_cache_entry_flush()
193 c == s->l2_table_cache, i); in qcow2_cache_entry_flush()
195 if (c->depends) { in qcow2_cache_entry_flush()
196 ret = qcow2_cache_flush_dependency(bs, c); in qcow2_cache_entry_flush()
197 } else if (c->depends_on_flush) { in qcow2_cache_entry_flush()
200 c->depends_on_flush = false; in qcow2_cache_entry_flush()
208 if (c == s->refcount_block_cache) { in qcow2_cache_entry_flush()
210 c->entries[i].offset, c->table_size, false); in qcow2_cache_entry_flush()
211 } else if (c == s->l2_table_cache) { in qcow2_cache_entry_flush()
213 c->entries[i].offset, c->table_size, false); in qcow2_cache_entry_flush()
216 c->entries[i].offset, c->table_size, false); in qcow2_cache_entry_flush()
223 if (c == s->refcount_block_cache) { in qcow2_cache_entry_flush()
225 } else if (c == s->l2_table_cache) { in qcow2_cache_entry_flush()
229 ret = bdrv_pwrite(bs->file, c->entries[i].offset, c->table_size, in qcow2_cache_entry_flush()
230 qcow2_cache_get_table_addr(c, i), 0); in qcow2_cache_entry_flush()
235 c->entries[i].dirty = false; in qcow2_cache_entry_flush()
240 int qcow2_cache_write(BlockDriverState *bs, Qcow2Cache *c) in qcow2_cache_write() argument
247 trace_qcow2_cache_flush(qemu_coroutine_self(), c == s->l2_table_cache); in qcow2_cache_write()
249 for (i = 0; i < c->size; i++) { in qcow2_cache_write()
250 ret = qcow2_cache_entry_flush(bs, c, i); in qcow2_cache_write()
259 int qcow2_cache_flush(BlockDriverState *bs, Qcow2Cache *c) in qcow2_cache_flush() argument
261 int result = qcow2_cache_write(bs, c); in qcow2_cache_flush()
273 int qcow2_cache_set_dependency(BlockDriverState *bs, Qcow2Cache *c, in qcow2_cache_set_dependency() argument
285 if (c->depends && (c->depends != dependency)) { in qcow2_cache_set_dependency()
286 ret = qcow2_cache_flush_dependency(bs, c); in qcow2_cache_set_dependency()
292 c->depends = dependency; in qcow2_cache_set_dependency()
296 void qcow2_cache_depends_on_flush(Qcow2Cache *c) in qcow2_cache_depends_on_flush() argument
298 c->depends_on_flush = true; in qcow2_cache_depends_on_flush()
301 int qcow2_cache_empty(BlockDriverState *bs, Qcow2Cache *c) in qcow2_cache_empty() argument
305 ret = qcow2_cache_flush(bs, c); in qcow2_cache_empty()
310 for (i = 0; i < c->size; i++) { in qcow2_cache_empty()
311 assert(c->entries[i].ref == 0); in qcow2_cache_empty()
312 c->entries[i].offset = 0; in qcow2_cache_empty()
313 c->entries[i].lru_counter = 0; in qcow2_cache_empty()
316 qcow2_cache_table_release(c, 0, c->size); in qcow2_cache_empty()
318 c->lru_counter = 0; in qcow2_cache_empty()
324 qcow2_cache_do_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset, in qcow2_cache_do_get() argument
336 trace_qcow2_cache_get(qemu_coroutine_self(), c == s->l2_table_cache, in qcow2_cache_do_get()
339 if (!QEMU_IS_ALIGNED(offset, c->table_size)) { in qcow2_cache_do_get()
342 qcow2_cache_get_name(s, c), offset); in qcow2_cache_do_get()
347 i = lookup_index = (offset / c->table_size * 4) % c->size; in qcow2_cache_do_get()
349 const Qcow2CachedTable *t = &c->entries[i]; in qcow2_cache_do_get()
357 if (++i == c->size) { in qcow2_cache_do_get()
371 c == s->l2_table_cache, i); in qcow2_cache_do_get()
373 ret = qcow2_cache_entry_flush(bs, c, i); in qcow2_cache_do_get()
379 c == s->l2_table_cache, i); in qcow2_cache_do_get()
380 c->entries[i].offset = 0; in qcow2_cache_do_get()
382 if (c == s->l2_table_cache) { in qcow2_cache_do_get()
386 ret = bdrv_pread(bs->file, offset, c->table_size, in qcow2_cache_do_get()
387 qcow2_cache_get_table_addr(c, i), 0); in qcow2_cache_do_get()
393 c->entries[i].offset = offset; in qcow2_cache_do_get()
397 c->entries[i].ref++; in qcow2_cache_do_get()
398 *table = qcow2_cache_get_table_addr(c, i); in qcow2_cache_do_get()
401 c == s->l2_table_cache, i); in qcow2_cache_do_get()
406 int qcow2_cache_get(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset, in qcow2_cache_get() argument
409 return qcow2_cache_do_get(bs, c, offset, table, true); in qcow2_cache_get()
412 int qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset, in qcow2_cache_get_empty() argument
415 return qcow2_cache_do_get(bs, c, offset, table, false); in qcow2_cache_get_empty()
418 void qcow2_cache_put(Qcow2Cache *c, void **table) in qcow2_cache_put() argument
420 int i = qcow2_cache_get_table_idx(c, *table); in qcow2_cache_put()
422 c->entries[i].ref--; in qcow2_cache_put()
425 if (c->entries[i].ref == 0) { in qcow2_cache_put()
426 c->entries[i].lru_counter = ++c->lru_counter; in qcow2_cache_put()
429 assert(c->entries[i].ref >= 0); in qcow2_cache_put()
432 void qcow2_cache_entry_mark_dirty(Qcow2Cache *c, void *table) in qcow2_cache_entry_mark_dirty() argument
434 int i = qcow2_cache_get_table_idx(c, table); in qcow2_cache_entry_mark_dirty()
435 assert(c->entries[i].offset != 0); in qcow2_cache_entry_mark_dirty()
436 c->entries[i].dirty = true; in qcow2_cache_entry_mark_dirty()
439 void *qcow2_cache_is_table_offset(Qcow2Cache *c, uint64_t offset) in qcow2_cache_is_table_offset() argument
443 for (i = 0; i < c->size; i++) { in qcow2_cache_is_table_offset()
444 if (c->entries[i].offset == offset) { in qcow2_cache_is_table_offset()
445 return qcow2_cache_get_table_addr(c, i); in qcow2_cache_is_table_offset()
451 void qcow2_cache_discard(Qcow2Cache *c, void *table) in qcow2_cache_discard() argument
453 int i = qcow2_cache_get_table_idx(c, table); in qcow2_cache_discard()
455 assert(c->entries[i].ref == 0); in qcow2_cache_discard()
457 c->entries[i].offset = 0; in qcow2_cache_discard()
458 c->entries[i].lru_counter = 0; in qcow2_cache_discard()
459 c->entries[i].dirty = false; in qcow2_cache_discard()
461 qcow2_cache_table_release(c, i, 1); in qcow2_cache_discard()