1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41#define DEBUG_SUBSYSTEM S_LOV
42
43#include "lov_cl_internal.h"
44
45
46
47
48
49
50
51
52
53
54
55static int lov_page_invariant(const struct cl_page_slice *slice)
56{
57 const struct cl_page *page = slice->cpl_page;
58 const struct cl_page *sub = lov_sub_page(slice);
59
60 return ergo(sub != NULL,
61 page->cp_child == sub &&
62 sub->cp_parent == page &&
63 page->cp_state == sub->cp_state);
64}
65
66static void lov_page_fini(const struct lu_env *env,
67 struct cl_page_slice *slice)
68{
69 struct cl_page *sub = lov_sub_page(slice);
70
71 LINVRNT(lov_page_invariant(slice));
72 ENTRY;
73
74 if (sub != NULL) {
75 LASSERT(sub->cp_state == CPS_FREEING);
76 lu_ref_del(&sub->cp_reference, "lov", sub->cp_parent);
77 sub->cp_parent = NULL;
78 slice->cpl_page->cp_child = NULL;
79 cl_page_put(env, sub);
80 }
81 EXIT;
82}
83
84static int lov_page_own(const struct lu_env *env,
85 const struct cl_page_slice *slice, struct cl_io *io,
86 int nonblock)
87{
88 struct lov_io *lio = lov_env_io(env);
89 struct lov_io_sub *sub;
90
91 LINVRNT(lov_page_invariant(slice));
92 LINVRNT(!cl2lov_page(slice)->lps_invalid);
93 ENTRY;
94
95 sub = lov_page_subio(env, lio, slice);
96 if (!IS_ERR(sub)) {
97 lov_sub_page(slice)->cp_owner = sub->sub_io;
98 lov_sub_put(sub);
99 } else
100 LBUG();
101 RETURN(0);
102}
103
104static void lov_page_assume(const struct lu_env *env,
105 const struct cl_page_slice *slice, struct cl_io *io)
106{
107 lov_page_own(env, slice, io, 0);
108}
109
110static int lov_page_cache_add(const struct lu_env *env,
111 const struct cl_page_slice *slice,
112 struct cl_io *io)
113{
114 struct lov_io *lio = lov_env_io(env);
115 struct lov_io_sub *sub;
116 int rc = 0;
117
118 LINVRNT(lov_page_invariant(slice));
119 LINVRNT(!cl2lov_page(slice)->lps_invalid);
120 ENTRY;
121
122 sub = lov_page_subio(env, lio, slice);
123 if (!IS_ERR(sub)) {
124 rc = cl_page_cache_add(sub->sub_env, sub->sub_io,
125 slice->cpl_page->cp_child, CRT_WRITE);
126 lov_sub_put(sub);
127 } else {
128 rc = PTR_ERR(sub);
129 CL_PAGE_DEBUG(D_ERROR, env, slice->cpl_page, "rc = %d\n", rc);
130 }
131 RETURN(rc);
132}
133
134static int lov_page_print(const struct lu_env *env,
135 const struct cl_page_slice *slice,
136 void *cookie, lu_printer_t printer)
137{
138 struct lov_page *lp = cl2lov_page(slice);
139
140 return (*printer)(env, cookie, LUSTRE_LOV_NAME"-page@%p\n", lp);
141}
142
143static const struct cl_page_operations lov_page_ops = {
144 .cpo_fini = lov_page_fini,
145 .cpo_own = lov_page_own,
146 .cpo_assume = lov_page_assume,
147 .io = {
148 [CRT_WRITE] = {
149 .cpo_cache_add = lov_page_cache_add
150 }
151 },
152 .cpo_print = lov_page_print
153};
154
155static void lov_empty_page_fini(const struct lu_env *env,
156 struct cl_page_slice *slice)
157{
158 LASSERT(slice->cpl_page->cp_child == NULL);
159}
160
161int lov_page_init_raid0(const struct lu_env *env, struct cl_object *obj,
162 struct cl_page *page, struct page *vmpage)
163{
164 struct lov_object *loo = cl2lov(obj);
165 struct lov_layout_raid0 *r0 = lov_r0(loo);
166 struct lov_io *lio = lov_env_io(env);
167 struct cl_page *subpage;
168 struct cl_object *subobj;
169 struct lov_io_sub *sub;
170 struct lov_page *lpg = cl_object_page_slice(obj, page);
171 loff_t offset;
172 obd_off suboff;
173 int stripe;
174 int rc;
175 ENTRY;
176
177 offset = cl_offset(obj, page->cp_index);
178 stripe = lov_stripe_number(loo->lo_lsm, offset);
179 LASSERT(stripe < r0->lo_nr);
180 rc = lov_stripe_offset(loo->lo_lsm, offset, stripe,
181 &suboff);
182 LASSERT(rc == 0);
183
184 lpg->lps_invalid = 1;
185 cl_page_slice_add(page, &lpg->lps_cl, obj, &lov_page_ops);
186
187 sub = lov_sub_get(env, lio, stripe);
188 if (IS_ERR(sub))
189 GOTO(out, rc = PTR_ERR(sub));
190
191 subobj = lovsub2cl(r0->lo_sub[stripe]);
192 subpage = cl_page_find_sub(sub->sub_env, subobj,
193 cl_index(subobj, suboff), vmpage, page);
194 lov_sub_put(sub);
195 if (IS_ERR(subpage))
196 GOTO(out, rc = PTR_ERR(subpage));
197
198 if (likely(subpage->cp_parent == page)) {
199 lu_ref_add(&subpage->cp_reference, "lov", page);
200 lpg->lps_invalid = 0;
201 rc = 0;
202 } else {
203 CL_PAGE_DEBUG(D_ERROR, env, page, "parent page\n");
204 CL_PAGE_DEBUG(D_ERROR, env, subpage, "child page\n");
205 LASSERT(0);
206 }
207
208 EXIT;
209out:
210 return rc;
211}
212
213
214static const struct cl_page_operations lov_empty_page_ops = {
215 .cpo_fini = lov_empty_page_fini,
216 .cpo_print = lov_page_print
217};
218
219int lov_page_init_empty(const struct lu_env *env, struct cl_object *obj,
220 struct cl_page *page, struct page *vmpage)
221{
222 struct lov_page *lpg = cl_object_page_slice(obj, page);
223 void *addr;
224 ENTRY;
225
226 cl_page_slice_add(page, &lpg->lps_cl, obj, &lov_empty_page_ops);
227 addr = kmap(vmpage);
228 memset(addr, 0, cl_page_size(obj));
229 kunmap(vmpage);
230 cl_page_export(env, page, 1);
231 RETURN(0);
232}
233
234
235
236