Mercurial > nomad > experimental
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 |
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 | 25 #include <jeffpc/error.h> |
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 } |