Lines Matching full:ps

170 static int alloc_area(struct pstore *ps)  in alloc_area()  argument
175 len = ps->store->chunk_size << SECTOR_SHIFT; in alloc_area()
181 ps->area = vmalloc(len); in alloc_area()
182 if (!ps->area) in alloc_area()
185 ps->zero_area = vzalloc(len); in alloc_area()
186 if (!ps->zero_area) in alloc_area()
189 ps->header_area = vmalloc(len); in alloc_area()
190 if (!ps->header_area) in alloc_area()
196 vfree(ps->zero_area); in alloc_area()
199 vfree(ps->area); in alloc_area()
205 static void free_area(struct pstore *ps) in free_area() argument
207 vfree(ps->area); in free_area()
208 ps->area = NULL; in free_area()
209 vfree(ps->zero_area); in free_area()
210 ps->zero_area = NULL; in free_area()
211 vfree(ps->header_area); in free_area()
212 ps->header_area = NULL; in free_area()
232 static int chunk_io(struct pstore *ps, void *area, chunk_t chunk, blk_opf_t opf, in chunk_io() argument
236 .bdev = dm_snap_cow(ps->store->snap)->bdev, in chunk_io()
237 .sector = ps->store->chunk_size * chunk, in chunk_io()
238 .count = ps->store->chunk_size, in chunk_io()
244 .client = ps->io_client, in chunk_io()
260 queue_work(ps->metadata_wq, &req.work); in chunk_io()
261 flush_workqueue(ps->metadata_wq); in chunk_io()
270 static chunk_t area_location(struct pstore *ps, chunk_t area) in area_location() argument
272 return NUM_SNAPSHOT_HDR_CHUNKS + ((ps->exceptions_per_area + 1) * area); in area_location()
275 static void skip_metadata(struct pstore *ps) in skip_metadata() argument
277 uint32_t stride = ps->exceptions_per_area + 1; in skip_metadata()
278 chunk_t next_free = ps->next_free; in skip_metadata()
281 ps->next_free++; in skip_metadata()
288 static int area_io(struct pstore *ps, blk_opf_t opf) in area_io() argument
290 chunk_t chunk = area_location(ps, ps->current_area); in area_io()
292 return chunk_io(ps, ps->area, chunk, opf, 0); in area_io()
295 static void zero_memory_area(struct pstore *ps) in zero_memory_area() argument
297 memset(ps->area, 0, ps->store->chunk_size << SECTOR_SHIFT); in zero_memory_area()
300 static int zero_disk_area(struct pstore *ps, chunk_t area) in zero_disk_area() argument
302 return chunk_io(ps, ps->zero_area, area_location(ps, area), in zero_disk_area()
306 static int read_header(struct pstore *ps, int *new_snapshot) in read_header() argument
318 if (!ps->store->chunk_size) { in read_header()
319 ps->store->chunk_size = max(DM_CHUNK_SIZE_DEFAULT_SECTORS, in read_header()
320 bdev_logical_block_size(dm_snap_cow(ps->store->snap)-> in read_header()
322 ps->store->chunk_mask = ps->store->chunk_size - 1; in read_header()
323 ps->store->chunk_shift = __ffs(ps->store->chunk_size); in read_header()
327 ps->io_client = dm_io_client_create(); in read_header()
328 if (IS_ERR(ps->io_client)) in read_header()
329 return PTR_ERR(ps->io_client); in read_header()
331 r = alloc_area(ps); in read_header()
335 r = chunk_io(ps, ps->header_area, 0, REQ_OP_READ, 1); in read_header()
339 dh = ps->header_area; in read_header()
353 ps->valid = le32_to_cpu(dh->valid); in read_header()
354 ps->version = le32_to_cpu(dh->version); in read_header()
357 if (ps->store->chunk_size == chunk_size) in read_header()
362 chunk_size, ps->store->chunk_size); in read_header()
365 free_area(ps); in read_header()
367 r = dm_exception_store_set_chunk_size(ps->store, chunk_size, in read_header()
375 r = alloc_area(ps); in read_header()
379 free_area(ps); in read_header()
383 static int write_header(struct pstore *ps) in write_header() argument
387 memset(ps->header_area, 0, ps->store->chunk_size << SECTOR_SHIFT); in write_header()
389 dh = ps->header_area; in write_header()
391 dh->valid = cpu_to_le32(ps->valid); in write_header()
392 dh->version = cpu_to_le32(ps->version); in write_header()
393 dh->chunk_size = cpu_to_le32(ps->store->chunk_size); in write_header()
395 return chunk_io(ps, ps->header_area, 0, REQ_OP_WRITE, 1); in write_header()
401 static struct disk_exception *get_exception(struct pstore *ps, void *ps_area, in get_exception() argument
404 BUG_ON(index >= ps->exceptions_per_area); in get_exception()
409 static void read_exception(struct pstore *ps, void *ps_area, in read_exception() argument
412 struct disk_exception *de = get_exception(ps, ps_area, index); in read_exception()
419 static void write_exception(struct pstore *ps, in write_exception() argument
422 struct disk_exception *de = get_exception(ps, ps->area, index); in write_exception()
429 static void clear_exception(struct pstore *ps, uint32_t index) in clear_exception() argument
431 struct disk_exception *de = get_exception(ps, ps->area, index); in clear_exception()
443 static int insert_exceptions(struct pstore *ps, void *ps_area, in insert_exceptions() argument
456 for (i = 0; i < ps->exceptions_per_area; i++) { in insert_exceptions()
457 read_exception(ps, ps_area, i, &e); in insert_exceptions()
466 ps->current_committed = i; in insert_exceptions()
474 if (ps->next_free <= e.new_chunk) in insert_exceptions()
475 ps->next_free = e.new_chunk + 1; in insert_exceptions()
488 static int read_exceptions(struct pstore *ps, in read_exceptions() argument
497 client = dm_bufio_client_create(dm_snap_cow(ps->store->snap)->bdev, in read_exceptions()
498 ps->store->chunk_size << SECTOR_SHIFT, in read_exceptions()
513 for (ps->current_area = 0; full; ps->current_area++) { in read_exceptions()
518 if (unlikely(prefetch_area < ps->current_area)) in read_exceptions()
519 prefetch_area = ps->current_area; in read_exceptions()
523 chunk_t pf_chunk = area_location(ps, prefetch_area); in read_exceptions()
531 } while (prefetch_area <= ps->current_area + DM_PREFETCH_CHUNKS); in read_exceptions()
534 chunk = area_location(ps, ps->current_area); in read_exceptions()
542 r = insert_exceptions(ps, area, callback, callback_context, in read_exceptions()
546 memcpy(ps->area, area, ps->store->chunk_size << SECTOR_SHIFT); in read_exceptions()
556 ps->current_area--; in read_exceptions()
558 skip_metadata(ps); in read_exceptions()
578 struct pstore *ps = get_info(store); in persistent_usage() local
580 *sectors_allocated = ps->next_free * store->chunk_size; in persistent_usage()
585 * Then there are (ps->current_area + 1) metadata chunks, each one in persistent_usage()
586 * separated from the next by ps->exceptions_per_area data chunks. in persistent_usage()
588 *metadata_sectors = (ps->current_area + 1 + NUM_SNAPSHOT_HDR_CHUNKS) * in persistent_usage()
594 struct pstore *ps = get_info(store); in persistent_dtr() local
596 destroy_workqueue(ps->metadata_wq); in persistent_dtr()
599 if (ps->io_client) in persistent_dtr()
600 dm_io_client_destroy(ps->io_client); in persistent_dtr()
601 free_area(ps); in persistent_dtr()
604 kvfree(ps->callbacks); in persistent_dtr()
606 kfree(ps); in persistent_dtr()
615 struct pstore *ps = get_info(store); in persistent_read_metadata() local
620 r = read_header(ps, &new_snapshot); in persistent_read_metadata()
627 ps->exceptions_per_area = (ps->store->chunk_size << SECTOR_SHIFT) / in persistent_read_metadata()
629 ps->callbacks = kvcalloc(ps->exceptions_per_area, in persistent_read_metadata()
630 sizeof(*ps->callbacks), GFP_KERNEL); in persistent_read_metadata()
631 if (!ps->callbacks) in persistent_read_metadata()
638 r = write_header(ps); in persistent_read_metadata()
644 ps->current_area = 0; in persistent_read_metadata()
645 zero_memory_area(ps); in persistent_read_metadata()
646 r = zero_disk_area(ps, 0); in persistent_read_metadata()
654 if (ps->version != SNAPSHOT_DISK_VERSION) { in persistent_read_metadata()
656 ps->version); in persistent_read_metadata()
663 if (!ps->valid) in persistent_read_metadata()
669 r = read_exceptions(ps, callback, callback_context); in persistent_read_metadata()
677 struct pstore *ps = get_info(store); in persistent_prepare_exception() local
681 if (size < ((ps->next_free + 1) * store->chunk_size)) in persistent_prepare_exception()
684 e->new_chunk = ps->next_free; in persistent_prepare_exception()
690 ps->next_free++; in persistent_prepare_exception()
691 skip_metadata(ps); in persistent_prepare_exception()
693 atomic_inc(&ps->pending_count); in persistent_prepare_exception()
703 struct pstore *ps = get_info(store); in persistent_commit_exception() local
708 ps->valid = 0; in persistent_commit_exception()
712 write_exception(ps, ps->current_committed++, &ce); in persistent_commit_exception()
720 cb = ps->callbacks + ps->callback_count++; in persistent_commit_exception()
728 if (!atomic_dec_and_test(&ps->pending_count) && in persistent_commit_exception()
729 (ps->current_committed != ps->exceptions_per_area)) in persistent_commit_exception()
735 if ((ps->current_committed == ps->exceptions_per_area) && in persistent_commit_exception()
736 zero_disk_area(ps, ps->current_area + 1)) in persistent_commit_exception()
737 ps->valid = 0; in persistent_commit_exception()
742 if (ps->valid && area_io(ps, REQ_OP_WRITE | REQ_PREFLUSH | REQ_FUA | in persistent_commit_exception()
744 ps->valid = 0; in persistent_commit_exception()
749 if (ps->current_committed == ps->exceptions_per_area) { in persistent_commit_exception()
750 ps->current_committed = 0; in persistent_commit_exception()
751 ps->current_area++; in persistent_commit_exception()
752 zero_memory_area(ps); in persistent_commit_exception()
755 for (i = 0; i < ps->callback_count; i++) { in persistent_commit_exception()
756 cb = ps->callbacks + i; in persistent_commit_exception()
757 cb->callback(cb->context, ps->valid); in persistent_commit_exception()
760 ps->callback_count = 0; in persistent_commit_exception()
767 struct pstore *ps = get_info(store); in persistent_prepare_merge() local
775 if (!ps->current_committed) { in persistent_prepare_merge()
779 if (!ps->current_area) in persistent_prepare_merge()
782 ps->current_area--; in persistent_prepare_merge()
783 r = area_io(ps, REQ_OP_READ); in persistent_prepare_merge()
786 ps->current_committed = ps->exceptions_per_area; in persistent_prepare_merge()
789 read_exception(ps, ps->area, ps->current_committed - 1, &ce); in persistent_prepare_merge()
797 for (nr_consecutive = 1; nr_consecutive < ps->current_committed; in persistent_prepare_merge()
799 read_exception(ps, ps->area, in persistent_prepare_merge()
800 ps->current_committed - 1 - nr_consecutive, &ce); in persistent_prepare_merge()
813 struct pstore *ps = get_info(store); in persistent_commit_merge() local
815 BUG_ON(nr_merged > ps->current_committed); in persistent_commit_merge()
818 clear_exception(ps, ps->current_committed - 1 - i); in persistent_commit_merge()
820 r = area_io(ps, REQ_OP_WRITE | REQ_PREFLUSH | REQ_FUA); in persistent_commit_merge()
824 ps->current_committed -= nr_merged; in persistent_commit_merge()
827 * At this stage, only persistent_usage() uses ps->next_free, so in persistent_commit_merge()
828 * we make no attempt to keep ps->next_free strictly accurate in persistent_commit_merge()
833 * ps->current_area does not get reduced by prepare_merge() until in persistent_commit_merge()
836 ps->next_free = area_location(ps, ps->current_area) + in persistent_commit_merge()
837 ps->current_committed + 1; in persistent_commit_merge()
844 struct pstore *ps = get_info(store); in persistent_drop_snapshot() local
846 ps->valid = 0; in persistent_drop_snapshot()
847 if (write_header(ps)) in persistent_drop_snapshot()
853 struct pstore *ps; in persistent_ctr() local
857 ps = kzalloc(sizeof(*ps), GFP_KERNEL); in persistent_ctr()
858 if (!ps) in persistent_ctr()
861 ps->store = store; in persistent_ctr()
862 ps->valid = 1; in persistent_ctr()
863 ps->version = SNAPSHOT_DISK_VERSION; in persistent_ctr()
864 ps->area = NULL; in persistent_ctr()
865 ps->zero_area = NULL; in persistent_ctr()
866 ps->header_area = NULL; in persistent_ctr()
867 ps->next_free = NUM_SNAPSHOT_HDR_CHUNKS + 1; /* header and 1st area */ in persistent_ctr()
868 ps->current_committed = 0; in persistent_ctr()
870 ps->callback_count = 0; in persistent_ctr()
871 atomic_set(&ps->pending_count, 0); in persistent_ctr()
872 ps->callbacks = NULL; in persistent_ctr()
874 ps->metadata_wq = alloc_workqueue("ksnaphd", WQ_MEM_RECLAIM, 0); in persistent_ctr()
875 if (!ps->metadata_wq) { in persistent_ctr()
893 store->context = ps; in persistent_ctr()
898 destroy_workqueue(ps->metadata_wq); in persistent_ctr()
900 kfree(ps); in persistent_ctr()