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 }