1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2012 STRATO AG. All rights reserved. 23 */ 24 #include <sys/zfs_context.h> 25 #include <sys/errno.h> 26 #include <sys/fits_impl.h> 27 28 int 29 fits_add_count(fits_counter_t *fc, uint64_t ino, uint64_t inc, 30 uint64_t aux, uint64_t *new_count, uint64_t *old_aux) 31 { 32 fits_count_elem_t *fce = fc->fc_head; 33 34 while (fce && fce->fce_ino != ino) 35 fce = fce->fce_next; 36 37 if (!fce) { 38 fce = kmem_alloc(sizeof(*fce), KM_SLEEP); 39 fce->fce_ino = ino; 40 fce->fce_count = 0; 41 fce->fce_next = fc->fc_head; 42 fc->fc_head = fce; 43 } 44 45 if (old_aux) { 46 *old_aux = fce->fce_aux; 47 fce->fce_aux = aux; 48 } 49 fce->fce_count += inc; 50 51 if (new_count) 52 *new_count = fce->fce_count; 53 54 return 0; 55 } 56 57 int 58 fits_get_count(fits_counter_t *fc, uint64_t ino, uint64_t *new_count, 59 uint64_t *old_aux) 60 { 61 fits_count_elem_t *fce = fc->fc_head; 62 63 while (fce && fce->fce_ino != ino) 64 fce = fce->fce_next; 65 66 if (!fce) { 67 if (new_count) 68 *new_count = 0; 69 if (old_aux) 70 *old_aux = 0; 71 return ENOENT; 72 } else { 73 if (new_count) 74 *new_count = fce->fce_count; 75 if (old_aux) 76 *old_aux = fce->fce_aux; 77 } 78 79 return 0; 80 } 81 82 void 83 fits_free_count(fits_counter_t *fc, uint64_t ino) 84 { 85 fits_count_elem_t *fce = fc->fc_head; 86 fits_count_elem_t *prev = NULL; 87 88 while (fce && fce->fce_ino != ino) { 89 prev = fce; 90 fce = fce->fce_next; 91 } 92 93 if (!fce) 94 return; 95 96 if (prev) 97 prev->fce_next = fce->fce_next; 98 else 99 fc->fc_head = fce->fce_next; 100 101 kmem_free(fce, sizeof(*fce)); 102 } 103 104 int 105 fits_assert_count_empty(fits_counter_t *fc) 106 { 107 fits_count_elem_t *fce = fc->fc_head; 108 int ret = 0; 109 110 while (fce) { 111 printf("!fits_assert_count_empty: %s ino %"PRIu64" count %"PRIu64"\n", 112 fc->fc_name, fce->fce_ino, fce->fce_count); 113 if (fce->fce_count != 0) 114 ++ret; 115 fce = fce->fce_next; 116 /* XXX TODO free count */ 117 /* XXX known leftover: if a file had > 1 links and be replaced 118 * by a file with > 1 link, but no same_name replacements, the 119 * link_add_cnt leaks with being 0 120 */ 121 } 122 123 return ret; 124 }