annotate src/objstore/obj.c @ 669:c0730cae0a8e

objstore: require initobj op Without it, we have no way of knowing how many versions an object has, and what its heads are. We assume that we know both for every object. Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Mon, 04 Mar 2019 17:20:27 -0500
parents 10364796fb99
children 9dfdc42bf860
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
144
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
1 /*
641
c084bb2edf3c objstore: ensure cached attrs have zero inode numbers
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 616
diff changeset
2 * Copyright (c) 2015-2019 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
144
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
3 *
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
5 * of this software and associated documentation files (the "Software"), to deal
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
6 * in the Software without restriction, including without limitation the rights
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
8 * copies of the Software, and to permit persons to whom the Software is
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
9 * furnished to do so, subject to the following conditions:
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
10 *
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
11 * The above copyright notice and this permission notice shall be included in
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
12 * all copies or substantial portions of the Software.
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
13 *
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
20 * SOFTWARE.
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
21 */
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
22
267
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
23 #include <stddef.h>
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
24
195
d623d3200631 use libjeffpc
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 165
diff changeset
25 #include <jeffpc/error.h>
d623d3200631 use libjeffpc
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 165
diff changeset
26
588
41497496e857 objstore: move the impl header out of the include directory
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 559
diff changeset
27 #include "objstore_impl.h"
144
b3d800982276 objstore: clean up & reorganize getattr
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff changeset
28
327
52cd514e990e use libjeffpc's mem cache
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 298
diff changeset
29 struct mem_cache *obj_cache;
52cd514e990e use libjeffpc's mem cache
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 298
diff changeset
30 struct mem_cache *objver_cache;
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
31 struct mem_cache *open_obj_cache;
266
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
32
457
a7f73decf2a2 objstore: use LOCK_CLASS macro to instantiate lock classs
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 428
diff changeset
33 static LOCK_CLASS(obj_lc);
424
7934ebdc7093 update to new libjeffpc lock API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 422
diff changeset
34
267
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
35 static int ver_cmp(const void *va, const void *vb)
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
36 {
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
37 const struct objver *a = va;
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
38 const struct objver *b = vb;
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
39
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
40 return nvclock_cmp_total(a->clock, b->clock);
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
41 }
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
42
266
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
43 /*
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
44 * Allocate a new generic object structure.
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
45 */
591
32a60cd03dee objstore: use consistent naming for obj/objver alloc/free functions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 590
diff changeset
46 struct obj *obj_alloc(void)
266
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
47 {
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
48 struct obj *obj;
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
49
327
52cd514e990e use libjeffpc's mem cache
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 298
diff changeset
50 obj = mem_cache_alloc(obj_cache);
266
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
51 if (!obj)
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
52 return NULL;
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
53
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
54 memset(&obj->oid, 0, sizeof(obj->oid));
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
55
428
e1fe08f7f57a convert to libjeffpc's red-black tree
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 424
diff changeset
56 rb_create(&obj->versions, ver_cmp, sizeof(struct objver),
613
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
57 offsetof(struct objver, all_node));
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
58 rb_create(&obj->heads, ver_cmp, sizeof(struct objver),
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
59 offsetof(struct objver, head_node));
267
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
60
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
61 obj->nversions = 0;
266
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
62 obj->nlink = 0;
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
63 obj->private = NULL;
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
64 obj->state = OBJ_STATE_NEW;
360
2807b6e76ab4 objstore: objects should reference a volume (not a vdev)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 355
diff changeset
65 obj->vol = NULL;
266
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
66 obj->ops = NULL;
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
67
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
68 refcnt_init(&obj->refcnt, 1);
424
7934ebdc7093 update to new libjeffpc lock API
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 422
diff changeset
69 MXINIT(&obj->lock, &obj_lc);
266
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
70
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
71 return obj;
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
72 }
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
73
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
74 /*
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
75 * Free a generic object structure.
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
76 */
591
32a60cd03dee objstore: use consistent naming for obj/objver alloc/free functions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 590
diff changeset
77 void obj_free(struct obj *obj)
266
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
78 {
612
a480f75291cd objstore: don't leak objvers when freeing struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 599
diff changeset
79 struct rb_cookie cookie;
a480f75291cd objstore: don't leak objvers when freeing struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 599
diff changeset
80 struct objver *ver;
a480f75291cd objstore: don't leak objvers when freeing struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 599
diff changeset
81
266
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
82 if (!obj)
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
83 return;
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
84
275
ea552c27c7c1 objstore: turn object freeing op from a volume op to an object op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 274
diff changeset
85 if (obj->ops && obj->ops->free)
ea552c27c7c1 objstore: turn object freeing op from a volume op to an object op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 274
diff changeset
86 obj->ops->free(obj);
ea552c27c7c1 objstore: turn object freeing op from a volume op to an object op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 274
diff changeset
87
612
a480f75291cd objstore: don't leak objvers when freeing struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 599
diff changeset
88 memset(&cookie, 0, sizeof(struct rb_cookie));
a480f75291cd objstore: don't leak objvers when freeing struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 599
diff changeset
89 while ((ver = rb_destroy_nodes(&obj->versions, &cookie)))
a480f75291cd objstore: don't leak objvers when freeing struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 599
diff changeset
90 objver_free(ver);
a480f75291cd objstore: don't leak objvers when freeing struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 599
diff changeset
91
422
9d9e84e611d1 global: use mutex macros instead of functions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 360
diff changeset
92 MXDESTROY(&obj->lock);
360
2807b6e76ab4 objstore: objects should reference a volume (not a vdev)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 355
diff changeset
93 vol_putref(obj->vol);
428
e1fe08f7f57a convert to libjeffpc's red-black tree
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 424
diff changeset
94 rb_destroy(&obj->versions);
327
52cd514e990e use libjeffpc's mem cache
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 298
diff changeset
95 mem_cache_free(obj_cache, obj);
266
3111f9a8faf3 objstore: define a generic object structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 255
diff changeset
96 }
267
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
97
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
98 /*
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
99 * Allocate a new generic object version structure.
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
100 */
591
32a60cd03dee objstore: use consistent naming for obj/objver alloc/free functions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 590
diff changeset
101 struct objver *objver_alloc(void)
267
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
102 {
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
103 struct objver *ver;
559
fb115cf03a67 objstore: keep track of qualified vs. unqualified opens separately
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 554
diff changeset
104 size_t i;
267
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
105 int ret;
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
106
327
52cd514e990e use libjeffpc's mem cache
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 298
diff changeset
107 ver = mem_cache_alloc(objver_cache);
267
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
108 if (!ver)
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
109 return ERR_PTR(-ENOMEM);
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
110
338
1f0e31291915 common: new vclocks should be optionally non-zero
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 327
diff changeset
111 ver->clock = nvclock_alloc(false);
267
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
112 if (!ver->clock) {
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
113 ret = -ENOMEM;
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
114 goto err;
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
115 }
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
116
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
117 memset(&ver->attrs, 0, sizeof(ver->attrs));
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
118
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
119 ver->private = NULL;
559
fb115cf03a67 objstore: keep track of qualified vs. unqualified opens separately
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 554
diff changeset
120 for (i = 0; i < ARRAY_LEN(ver->open); i++)
fb115cf03a67 objstore: keep track of qualified vs. unqualified opens separately
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 554
diff changeset
121 ver->open[i] = NULL;
267
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
122 ver->obj = NULL;
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
123
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
124 return ver;
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
125
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
126 err:
327
52cd514e990e use libjeffpc's mem cache
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 298
diff changeset
127 mem_cache_free(objver_cache, ver);
267
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
128
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
129 return ERR_PTR(ret);
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
130 }
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
131
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
132 /*
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
133 * Free a generic object version structure.
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
134 */
591
32a60cd03dee objstore: use consistent naming for obj/objver alloc/free functions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 590
diff changeset
135 void objver_free(struct objver *ver)
267
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
136 {
559
fb115cf03a67 objstore: keep track of qualified vs. unqualified opens separately
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 554
diff changeset
137 size_t i;
fb115cf03a67 objstore: keep track of qualified vs. unqualified opens separately
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 554
diff changeset
138
267
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
139 if (!ver)
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
140 return;
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
141
552
859734a2053a objstore: allocate & free open-object struct as needed
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 457
diff changeset
142 /* we shouldn't be freeing open objects */
559
fb115cf03a67 objstore: keep track of qualified vs. unqualified opens separately
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 554
diff changeset
143 for (i = 0; i < ARRAY_LEN(ver->open); i++)
fb115cf03a67 objstore: keep track of qualified vs. unqualified opens separately
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 554
diff changeset
144 ASSERT3P(ver->open[i], ==, NULL);
552
859734a2053a objstore: allocate & free open-object struct as needed
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 457
diff changeset
145
267
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
146 nvclock_free(ver->clock);
327
52cd514e990e use libjeffpc's mem cache
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 298
diff changeset
147 mem_cache_free(objver_cache, ver);
267
038228fce5e1 objstore: define a generic object version structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 266
diff changeset
148 }
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
149
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
150 /*
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
151 * Find the object with oid, if there isn't one, allocate one and add it to
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
152 * the vol's list of objects.
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
153 *
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
154 * Returns obj (locked and referenced) on success, negated errno on failure.
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
155 */
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
156 static struct obj *__find_or_alloc(struct objstore *vol, const struct noid *oid)
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
157 {
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
158 struct obj key = {
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
159 .oid = *oid,
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
160 };
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
161 struct obj *obj, *newobj;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
162 struct rb_cookie where;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
163 bool inserted;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
164
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
165 inserted = false;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
166 newobj = NULL;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
167
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
168 for (;;) {
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
169 MXLOCK(&vol->lock);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
170
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
171 /* try to find the object */
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
172 obj = obj_getref(rb_find(&vol->objs, &key, &where));
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
173
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
174 /* not found and this is the second attempt -> insert it */
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
175 if (!obj && newobj) {
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
176 rb_insert_here(&vol->objs, obj_getref(newobj), &where);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
177 obj = newobj;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
178 newobj = NULL;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
179 inserted = true;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
180 }
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
181
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
182 MXUNLOCK(&vol->lock);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
183
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
184 /* found or inserted -> we're done */
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
185 if (obj) {
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
186 /* newly inserted objects are already locked */
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
187 if (!inserted)
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
188 MXLOCK(&obj->lock);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
189
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
190 if (obj->state == OBJ_STATE_DEAD) {
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
191 /* this is a dead one, try again */
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
192 MXUNLOCK(&obj->lock);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
193 obj_putref(obj);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
194 continue;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
195 }
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
196
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
197 if (newobj) {
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
198 MXUNLOCK(&newobj->lock);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
199 obj_putref(newobj);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
200 }
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
201
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
202 break;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
203 }
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
204
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
205 /* allocate a new object */
591
32a60cd03dee objstore: use consistent naming for obj/objver alloc/free functions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 590
diff changeset
206 newobj = obj_alloc();
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
207 if (!newobj)
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
208 return ERR_PTR(-ENOMEM);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
209
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
210 MXLOCK(&newobj->lock);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
211
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
212 newobj->oid = *oid;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
213 newobj->vol = vol_getref(vol);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
214
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
215 /* retry the search, and insert if necessary */
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
216 }
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
217
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
218 return obj;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
219 }
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
220
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
221 /*
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
222 * Given a vol and an oid, find the corresponding object structure.
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
223 *
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
224 * Return with the object locked and referenced.
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
225 */
592
5710a019ee3d objstore: use consistent naming for obj/objver get functions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 591
diff changeset
226 struct obj *obj_by_oid(struct objstore *vol, const struct noid *oid)
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
227 {
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
228 struct obj *obj;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
229 int ret;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
230
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
231 obj = __find_or_alloc(vol, oid);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
232 if (IS_ERR(obj)) {
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
233 ret = PTR_ERR(obj);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
234 goto err;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
235 }
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
236
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
237 switch (obj->state) {
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
238 case OBJ_STATE_NEW:
669
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
239 if (!vol->ops || !vol->ops->initobj) {
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
240 ret = -ENOTSUP;
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
241 goto err_obj_new;
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
242 }
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
243
669
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
244 ret = vol->ops->initobj(obj);
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
245 if (ret)
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
246 goto err_obj_new;
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
247
664
10364796fb99 objstore: assert that initialized objs have at least one version & head
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 653
diff changeset
248 /* must have at least one version & head */
10364796fb99 objstore: assert that initialized objs have at least one version & head
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 653
diff changeset
249 ASSERT3U(obj->nversions, >=, 1);
10364796fb99 objstore: assert that initialized objs have at least one version & head
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 653
diff changeset
250 ASSERT3U(rb_numnodes(&obj->heads), >=, 1);
10364796fb99 objstore: assert that initialized objs have at least one version & head
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 653
diff changeset
251
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
252 obj->state = OBJ_STATE_LIVE;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
253 break;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
254 case OBJ_STATE_LIVE:
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
255 break;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
256 case OBJ_STATE_DEAD:
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
257 ret = -EINVAL;
669
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
258 goto err_obj_dead;
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
259 }
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
260
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
261 return obj;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
262
669
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
263 err_obj_new:
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
264 /* the initobj op failed, mark the obj dead */
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
265 obj->state = OBJ_STATE_DEAD;
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
266
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
267 /* remove the object from the objs list */
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
268 MXLOCK(&vol->lock);
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
269 rb_remove(&vol->objs, obj);
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
270 MXUNLOCK(&vol->lock);
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
271
c0730cae0a8e objstore: require initobj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 664
diff changeset
272 err_obj_dead:
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
273 MXUNLOCK(&obj->lock);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
274 obj_putref(obj);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
275
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
276 err:
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
277 return ERR_PTR(ret);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
278 }
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
279
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
280 /*
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
281 * Fetch a version from the backend, adding it to the cached versions tree.
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
282 */
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
283 static struct objver *__fetch_ver(struct obj *obj, const struct nvclock *clock)
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
284 {
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
285 int ret;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
286
599
4b1b3fffdf7b objstore: replace getversion obj op with checkversion obj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 596
diff changeset
287 if (!obj || !obj->ops)
4b1b3fffdf7b objstore: replace getversion obj op with checkversion obj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 596
diff changeset
288 return ERR_PTR(-ENOTSUP);
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
289
599
4b1b3fffdf7b objstore: replace getversion obj op with checkversion obj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 596
diff changeset
290 if (obj->ops->checkversion) {
4b1b3fffdf7b objstore: replace getversion obj op with checkversion obj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 596
diff changeset
291 ret = obj->ops->checkversion(obj, clock);
4b1b3fffdf7b objstore: replace getversion obj op with checkversion obj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 596
diff changeset
292 if (ret)
4b1b3fffdf7b objstore: replace getversion obj op with checkversion obj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 596
diff changeset
293 return ERR_PTR(ret);
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
294 }
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
295
599
4b1b3fffdf7b objstore: replace getversion obj op with checkversion obj op
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 596
diff changeset
296 return obj_add_version(obj, clock);
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
297 }
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
298
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
299 /*
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
300 * Given a vol, an oid, and a vector clock, find the corresponding object
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
301 * version structure.
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
302 *
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
303 * Return the found version, with the object referenced and locked.
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
304 */
592
5710a019ee3d objstore: use consistent naming for obj/objver get functions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 591
diff changeset
305 struct objver *objver_by_clock(struct objstore *vol, const struct noid *oid,
5710a019ee3d objstore: use consistent naming for obj/objver get functions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 591
diff changeset
306 const struct nvclock *clock)
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
307 {
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
308 struct objver *ver;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
309 struct obj *obj;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
310
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
311 /*
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
312 * First, find the object based on the oid.
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
313 */
592
5710a019ee3d objstore: use consistent naming for obj/objver get functions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 591
diff changeset
314 obj = obj_by_oid(vol, oid);
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
315 if (IS_ERR(obj))
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
316 return ERR_CAST(obj);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
317
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
318 /*
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
319 * Second, find the right version of the object.
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
320 */
615
7476345dbe01 objstore: assume & assert that nversions is never zero
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 614
diff changeset
321 if (!nvclock_is_null(clock)) {
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
322 /*
616
ebb7808a7df6 objstore: improve version finding comments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 615
diff changeset
323 * Qualified open
ebb7808a7df6 objstore: improve version finding comments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 615
diff changeset
324 *
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
325 * We are looking for a specific version. Since the
616
ebb7808a7df6 objstore: improve version finding comments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 615
diff changeset
326 * obj->versions red-black tree is only a cache, it may not
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
327 * contain it. If it doesn't we need to call into the
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
328 * backend to fetch it.
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
329 */
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
330 struct objver key = {
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
331 .clock = (struct nvclock *) clock,
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
332 };
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
333
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
334 /* check the cache */
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
335 ver = rb_find(&obj->versions, &key, NULL);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
336 if (ver)
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
337 return ver;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
338
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
339 /* try to fetch the version from the backend */
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
340 ver = __fetch_ver(obj, clock);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
341 if (!IS_ERR(ver))
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
342 return ver;
614
be5d61e30d01 objstore: unqualified open should check the number of heads not versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 613
diff changeset
343 } else if (rb_numnodes(&obj->heads) == 1) {
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
344 /*
616
ebb7808a7df6 objstore: improve version finding comments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 615
diff changeset
345 * Unqualified open with one head
ebb7808a7df6 objstore: improve version finding comments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 615
diff changeset
346 *
614
be5d61e30d01 objstore: unqualified open should check the number of heads not versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 613
diff changeset
347 * We are *not* looking for a specific version, but there is
be5d61e30d01 objstore: unqualified open should check the number of heads not versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 613
diff changeset
348 * only one head, so we return that. We require that the
be5d61e30d01 objstore: unqualified open should check the number of heads not versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 613
diff changeset
349 * initobj obj op pre-caches all heads, so we are certain
be5d61e30d01 objstore: unqualified open should check the number of heads not versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 613
diff changeset
350 * that there are no other heads that haven't been cached.
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
351 */
614
be5d61e30d01 objstore: unqualified open should check the number of heads not versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 613
diff changeset
352 ver = rb_first(&obj->heads);
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
353
594
23dfc03a9b89 objstore: skip version fetch for unqualified opens of objs with only one version
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 593
diff changeset
354 ASSERT3P(ver, !=, NULL);
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
355
594
23dfc03a9b89 objstore: skip version fetch for unqualified opens of objs with only one version
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 593
diff changeset
356 return ver;
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
357 } else {
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
358 /*
616
ebb7808a7df6 objstore: improve version finding comments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 615
diff changeset
359 * Unqualified open with multiple heads
ebb7808a7df6 objstore: improve version finding comments
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 615
diff changeset
360 *
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
361 * We are *not* looking for a specific version, and there
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
362 * are two or more versions.
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
363 */
615
7476345dbe01 objstore: assume & assert that nversions is never zero
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 614
diff changeset
364 ASSERT3U(obj->nversions, !=, 0);
7476345dbe01 objstore: assume & assert that nversions is never zero
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 614
diff changeset
365
590
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
366 ver = ERR_PTR(-ENOTUNIQ);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
367 }
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
368
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
369 MXUNLOCK(&obj->lock);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
370 obj_putref(obj);
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
371 return ver;
2e89f3ca8957 objstore: split up the oversized vol.c
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 589
diff changeset
372 }
596
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
373
613
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
374 /* check new version against currently known heads & update as necessary */
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
375 static void __add_head(struct obj *obj, struct objver *new)
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
376 {
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
377 struct objver *head;
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
378 bool found_descendant;
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
379
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
380 found_descendant = false;
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
381
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
382 /*
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
383 * The set of heads is a set of versions that are all pair-wise
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
384 * divergent.
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
385 *
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
386 * When adding a head, we want to accomplish three things which can
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
387 * be reasoned about independently:
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
388 *
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
389 * (1) We want remove all heads that are less than the version being
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
390 * added.
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
391 *
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
392 * (2) We want to keep all heads that are greater than the version
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
393 * being added.
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
394 *
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
395 * (3) We want to keep all heads that are divergent from the version
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
396 * being added.
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
397 *
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
398 * (4) We want to add the new version as a head iff all the
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
399 * remaining heads are divergent with it.
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
400 */
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
401
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
402 restart:
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
403 rb_for_each(&obj->heads, head) {
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
404 ASSERT3P(head, !=, new);
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
405
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
406 switch (nvclock_cmp(head->clock, new->clock)) {
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
407 case NVC_EQ:
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
408 panic("found duplicate head version");
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
409 case NVC_LT:
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
410 /* head is less than new - remove it */
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
411 rb_remove(&obj->heads, head);
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
412 goto restart;
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
413 case NVC_GT:
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
414 /* head is greater than new - not a new head */
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
415 found_descendant = true;
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
416 break;
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
417 case NVC_DIV:
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
418 /* head is unrelated to new - nothing to do */
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
419 break;
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
420 }
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
421 }
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
422
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
423 /*
653
3ed1b2a6b2e9 objstore: fix __add_head never adding new heads
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 641
diff changeset
424 * Add the new version as a head if we haven't found any heads that
3ed1b2a6b2e9 objstore: fix __add_head never adding new heads
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 641
diff changeset
425 * are our descendants.
613
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
426 */
653
3ed1b2a6b2e9 objstore: fix __add_head never adding new heads
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 641
diff changeset
427 if (!found_descendant)
613
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
428 rb_add(&obj->heads, new);
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
429 }
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
430
596
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
431 struct objver *obj_add_version(struct obj *obj, const struct nvclock *clock)
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
432 {
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
433 struct objver *ver;
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
434 int ret;
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
435
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
436 if (!obj->ops || !obj->ops->getattr)
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
437 return ERR_PTR(-ENOTSUP);
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
438
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
439 ver = objver_alloc();
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
440 if (IS_ERR(ver))
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
441 return ver;
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
442
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
443 ver->obj = obj;
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
444 nvclock_copy(ver->clock, clock);
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
445
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
446 ret = obj->ops->getattr(ver, &ver->attrs);
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
447 if (ret)
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
448 goto err;
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
449
641
c084bb2edf3c objstore: ensure cached attrs have zero inode numbers
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 616
diff changeset
450 /* objstore doesn't track inode numbers */
c084bb2edf3c objstore: ensure cached attrs have zero inode numbers
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 616
diff changeset
451 ver->attrs.ino = 0;
c084bb2edf3c objstore: ensure cached attrs have zero inode numbers
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 616
diff changeset
452
596
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
453 if (rb_insert(&obj->versions, ver)) {
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
454 ret = -EEXIST;
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
455 goto err;
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
456 }
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
457
613
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
458 __add_head(obj, ver);
0e7e00acfe88 objstore: maintain a tree of head object versions
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 612
diff changeset
459
596
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
460 return ver;
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
461
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
462 err:
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
463 objver_free(ver);
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
464
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
465 return ERR_PTR(ret);
6646b1736dd8 objstore: add helper to easily add objvers to struct obj
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents: 595
diff changeset
466 }