]>
Commit | Line | Data |
---|---|---|
d7e09d03 PT |
1 | /* |
2 | * GPL HEADER START | |
3 | * | |
4 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or modify | |
7 | * it under the terms of the GNU General Public License version 2 only, | |
8 | * as published by the Free Software Foundation. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, but | |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | * General Public License version 2 for more details (a copy is included | |
14 | * in the LICENSE file that accompanied this code). | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * version 2 along with this program; If not, see | |
6a5b99a4 | 18 | * http://www.gnu.org/licenses/gpl-2.0.html |
d7e09d03 | 19 | * |
d7e09d03 PT |
20 | * GPL HEADER END |
21 | */ | |
22 | /* | |
23 | * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. | |
24 | * Use is subject to license terms. | |
25 | * | |
1dc563a6 | 26 | * Copyright (c) 2012, 2015 Intel Corporation. |
d7e09d03 PT |
27 | */ |
28 | /* | |
29 | * This file is part of Lustre, http://www.lustre.org/ | |
30 | * Lustre is a trademark of Sun Microsystems, Inc. | |
31 | */ | |
32 | /* | |
33 | * This file is part of Lustre, http://www.lustre.org/ | |
34 | * Lustre is a trademark of Sun Microsystems, Inc. | |
35 | * | |
36 | * Internal interfaces of LOV layer. | |
37 | * | |
38 | * Author: Nikita Danilov <nikita.danilov@sun.com> | |
39 | * Author: Jinshan Xiong <jinshan.xiong@intel.com> | |
40 | */ | |
41 | ||
42 | #ifndef LOV_CL_INTERNAL_H | |
43 | #define LOV_CL_INTERNAL_H | |
44 | ||
9fdaf8c0 | 45 | #include "../../include/linux/libcfs/libcfs.h" |
d7e09d03 | 46 | |
0cf0f7a7 GKH |
47 | #include "../include/obd.h" |
48 | #include "../include/cl_object.h" | |
d7e09d03 PT |
49 | #include "lov_internal.h" |
50 | ||
51 | /** \defgroup lov lov | |
52 | * Logical object volume layer. This layer implements data striping (raid0). | |
53 | * | |
54 | * At the lov layer top-entity (object, page, lock, io) is connected to one or | |
55 | * more sub-entities: top-object, representing a file is connected to a set of | |
56 | * sub-objects, each representing a stripe, file-level top-lock is connected | |
57 | * to a set of per-stripe sub-locks, top-page is connected to a (single) | |
58 | * sub-page, and a top-level IO is connected to a set of (potentially | |
59 | * concurrent) sub-IO's. | |
60 | * | |
61 | * Sub-object, sub-page, and sub-io have well-defined top-object and top-page | |
62 | * respectively, while a single sub-lock can be part of multiple top-locks. | |
63 | * | |
64 | * Reference counting models are different for different types of entities: | |
65 | * | |
66 | * - top-object keeps a reference to its sub-objects, and destroys them | |
67 | * when it is destroyed. | |
68 | * | |
69 | * - top-page keeps a reference to its sub-page, and destroys it when it | |
70 | * is destroyed. | |
71 | * | |
d7e09d03 PT |
72 | * - IO's are not reference counted. |
73 | * | |
74 | * To implement a connection between top and sub entities, lov layer is split | |
75 | * into two pieces: lov ("upper half"), and lovsub ("bottom half"), both | |
76 | * implementing full set of cl-interfaces. For example, top-object has vvp and | |
77 | * lov layers, and it's sub-object has lovsub and osc layers. lovsub layer is | |
78 | * used to track child-parent relationship. | |
79 | * | |
80 | * @{ | |
81 | */ | |
82 | ||
83 | struct lovsub_device; | |
84 | struct lovsub_object; | |
85 | struct lovsub_lock; | |
86 | ||
87 | enum lov_device_flags { | |
88 | LOV_DEV_INITIALIZED = 1 << 0 | |
89 | }; | |
90 | ||
91 | /* | |
92 | * Upper half. | |
93 | */ | |
94 | ||
95 | /** | |
96 | * Resources that are used in memory-cleaning path, and whose allocation | |
97 | * cannot fail even when memory is tight. They are preallocated in sufficient | |
98 | * quantities in lov_device::ld_emerg[], and access to them is serialized | |
99 | * lov_device::ld_mutex. | |
100 | */ | |
101 | struct lov_device_emerg { | |
102 | /** | |
103 | * Page list used to submit IO when memory is in pressure. | |
104 | */ | |
105 | struct cl_page_list emrg_page_list; | |
106 | /** | |
107 | * sub-io's shared by all threads accessing this device when memory is | |
108 | * too low to allocate sub-io's dynamically. | |
109 | */ | |
110 | struct cl_io emrg_subio; | |
111 | /** | |
112 | * Environments used by sub-io's in | |
113 | * lov_device_emerg::emrg_subio. | |
114 | */ | |
115 | struct lu_env *emrg_env; | |
116 | /** | |
117 | * Refchecks for lov_device_emerg::emrg_env. | |
118 | * | |
119 | * \see cl_env_get() | |
120 | */ | |
3ee45c7e | 121 | u16 emrg_refcheck; |
d7e09d03 PT |
122 | }; |
123 | ||
124 | struct lov_device { | |
125 | /* | |
126 | * XXX Locking of lov-private data is missing. | |
127 | */ | |
128 | struct cl_device ld_cl; | |
129 | struct lov_obd *ld_lov; | |
130 | /** size of lov_device::ld_target[] array */ | |
131 | __u32 ld_target_nr; | |
132 | struct lovsub_device **ld_target; | |
133 | __u32 ld_flags; | |
134 | ||
135 | /** Emergency resources used in memory-cleansing paths. */ | |
136 | struct lov_device_emerg **ld_emrg; | |
137 | /** | |
138 | * Serializes access to lov_device::ld_emrg in low-memory | |
139 | * conditions. | |
140 | */ | |
141 | struct mutex ld_mutex; | |
142 | }; | |
143 | ||
144 | /** | |
145 | * Layout type. | |
146 | */ | |
147 | enum lov_layout_type { | |
5dd16419 JX |
148 | LLT_EMPTY, /** empty file without body (mknod + truncate) */ |
149 | LLT_RAID0, /** striped file */ | |
150 | LLT_RELEASED, /** file with no objects (data in HSM) */ | |
d7e09d03 PT |
151 | LLT_NR |
152 | }; | |
153 | ||
48d23e61 JX |
154 | static inline char *llt2str(enum lov_layout_type llt) |
155 | { | |
156 | switch (llt) { | |
157 | case LLT_EMPTY: | |
158 | return "EMPTY"; | |
159 | case LLT_RAID0: | |
160 | return "RAID0"; | |
161 | case LLT_RELEASED: | |
162 | return "RELEASED"; | |
163 | case LLT_NR: | |
164 | LBUG(); | |
165 | } | |
166 | LBUG(); | |
167 | return ""; | |
168 | } | |
169 | ||
d7e09d03 PT |
170 | /** |
171 | * lov-specific file state. | |
172 | * | |
173 | * lov object has particular layout type, determining how top-object is built | |
174 | * on top of sub-objects. Layout type can change dynamically. When this | |
175 | * happens, lov_object::lo_type_guard semaphore is taken in exclusive mode, | |
176 | * all state pertaining to the old layout type is destroyed, and new state is | |
177 | * constructed. All object methods take said semaphore in the shared mode, | |
178 | * providing serialization against transition between layout types. | |
179 | * | |
180 | * To avoid multiple `if' or `switch' statements, selecting behavior for the | |
181 | * current layout type, object methods perform double-dispatch, invoking | |
182 | * function corresponding to the current layout type. | |
183 | */ | |
184 | struct lov_object { | |
185 | struct cl_object lo_cl; | |
186 | /** | |
187 | * Serializes object operations with transitions between layout types. | |
188 | * | |
189 | * This semaphore is taken in shared mode by all object methods, and | |
190 | * is taken in exclusive mode when object type is changed. | |
191 | * | |
192 | * \see lov_object::lo_type | |
193 | */ | |
194 | struct rw_semaphore lo_type_guard; | |
195 | /** | |
196 | * Type of an object. Protected by lov_object::lo_type_guard. | |
197 | */ | |
198 | enum lov_layout_type lo_type; | |
199 | /** | |
200 | * True if layout is invalid. This bit is cleared when layout lock | |
201 | * is lost. | |
202 | */ | |
203 | bool lo_layout_invalid; | |
204 | /** | |
205 | * How many IOs are on going on this object. Layout can be changed | |
206 | * only if there is no active IO. | |
207 | */ | |
208 | atomic_t lo_active_ios; | |
209 | /** | |
210 | * Waitq - wait for no one else is using lo_lsm | |
211 | */ | |
212 | wait_queue_head_t lo_waitq; | |
213 | /** | |
214 | * Layout metadata. NULL if empty layout. | |
215 | */ | |
216 | struct lov_stripe_md *lo_lsm; | |
217 | ||
218 | union lov_layout_state { | |
219 | struct lov_layout_raid0 { | |
84d7238f | 220 | unsigned int lo_nr; |
d7e09d03 PT |
221 | /** |
222 | * When this is true, lov_object::lo_attr contains | |
223 | * valid up to date attributes for a top-level | |
224 | * object. This field is reset to 0 when attributes of | |
225 | * any sub-object change. | |
226 | */ | |
227 | int lo_attr_valid; | |
228 | /** | |
229 | * Array of sub-objects. Allocated when top-object is | |
230 | * created (lov_init_raid0()). | |
231 | * | |
232 | * Top-object is a strict master of its sub-objects: | |
233 | * it is created before them, and outlives its | |
234 | * children (this later is necessary so that basic | |
235 | * functions like cl_object_top() always | |
236 | * work). Top-object keeps a reference on every | |
237 | * sub-object. | |
238 | * | |
239 | * When top-object is destroyed (lov_delete_raid0()) | |
240 | * it releases its reference to a sub-object and waits | |
241 | * until the latter is finally destroyed. | |
242 | */ | |
243 | struct lovsub_object **lo_sub; | |
244 | /** | |
245 | * protect lo_sub | |
246 | */ | |
247 | spinlock_t lo_sub_lock; | |
248 | /** | |
249 | * Cached object attribute, built from sub-object | |
250 | * attributes. | |
251 | */ | |
252 | struct cl_attr lo_attr; | |
253 | } raid0; | |
254 | struct lov_layout_state_empty { | |
255 | } empty; | |
5dd16419 JX |
256 | struct lov_layout_state_released { |
257 | } released; | |
d7e09d03 PT |
258 | } u; |
259 | /** | |
260 | * Thread that acquired lov_object::lo_type_guard in an exclusive | |
261 | * mode. | |
262 | */ | |
68b636b6 | 263 | struct task_struct *lo_owner; |
d7e09d03 PT |
264 | }; |
265 | ||
d7e09d03 PT |
266 | /** |
267 | * State lov_lock keeps for each sub-lock. | |
268 | */ | |
269 | struct lov_lock_sub { | |
270 | /** sub-lock itself */ | |
06563b56 JX |
271 | struct cl_lock sub_lock; |
272 | /** Set if the sublock has ever been enqueued, meaning it may | |
273 | * hold resources of underlying layers | |
274 | */ | |
275 | unsigned int sub_is_enqueued:1, | |
276 | sub_initialized:1; | |
d7e09d03 | 277 | int sub_stripe; |
d7e09d03 PT |
278 | }; |
279 | ||
280 | /** | |
281 | * lov-specific lock state. | |
282 | */ | |
283 | struct lov_lock { | |
284 | struct cl_lock_slice lls_cl; | |
285 | /** Number of sub-locks in this lock */ | |
286 | int lls_nr; | |
06563b56 JX |
287 | /** sublock array */ |
288 | struct lov_lock_sub lls_sub[0]; | |
d7e09d03 PT |
289 | }; |
290 | ||
291 | struct lov_page { | |
96c53363 JX |
292 | struct cl_page_slice lps_cl; |
293 | unsigned int lps_stripe; /* stripe index */ | |
d7e09d03 PT |
294 | }; |
295 | ||
296 | /* | |
297 | * Bottom half. | |
298 | */ | |
299 | ||
300 | struct lovsub_device { | |
301 | struct cl_device acid_cl; | |
302 | struct lov_device *acid_super; | |
303 | int acid_idx; | |
304 | struct cl_device *acid_next; | |
305 | }; | |
306 | ||
307 | struct lovsub_object { | |
308 | struct cl_object_header lso_header; | |
309 | struct cl_object lso_cl; | |
310 | struct lov_object *lso_super; | |
311 | int lso_index; | |
312 | }; | |
313 | ||
314 | /** | |
315 | * A link between a top-lock and a sub-lock. Separate data-structure is | |
316 | * necessary, because top-locks and sub-locks are in M:N relationship. | |
317 | * | |
318 | * \todo This can be optimized for a (by far) most frequent case of a single | |
319 | * top-lock per sub-lock. | |
320 | */ | |
321 | struct lov_lock_link { | |
322 | struct lov_lock *lll_super; | |
323 | /** An index within parent lock. */ | |
324 | int lll_idx; | |
325 | /** | |
326 | * A linkage into per sub-lock list of all corresponding top-locks, | |
327 | * hanging off lovsub_lock::lss_parents. | |
328 | */ | |
329 | struct list_head lll_list; | |
330 | }; | |
331 | ||
332 | /** | |
333 | * Lock state at lovsub layer. | |
334 | */ | |
335 | struct lovsub_lock { | |
336 | struct cl_lock_slice lss_cl; | |
337 | /** | |
338 | * List of top-locks that have given sub-lock as their part. Protected | |
339 | * by cl_lock::cll_guard mutex. | |
340 | */ | |
341 | struct list_head lss_parents; | |
342 | /** | |
343 | * Top-lock that initiated current operation on this sub-lock. This is | |
344 | * only set during top-to-bottom lock operations like enqueue, and is | |
345 | * used to optimize state change notification. Protected by | |
346 | * cl_lock::cll_guard mutex. | |
347 | * | |
348 | * \see lovsub_lock_state_one(). | |
349 | */ | |
350 | struct cl_lock *lss_active; | |
351 | }; | |
352 | ||
353 | /** | |
354 | * Describe the environment settings for sublocks. | |
355 | */ | |
356 | struct lov_sublock_env { | |
357 | const struct lu_env *lse_env; | |
358 | struct cl_io *lse_io; | |
359 | struct lov_io_sub *lse_sub; | |
360 | }; | |
361 | ||
362 | struct lovsub_page { | |
363 | struct cl_page_slice lsb_cl; | |
364 | }; | |
365 | ||
d7e09d03 PT |
366 | struct lov_thread_info { |
367 | struct cl_object_conf lti_stripe_conf; | |
368 | struct lu_fid lti_fid; | |
369 | struct cl_lock_descr lti_ldescr; | |
370 | struct ost_lvb lti_lvb; | |
371 | struct cl_2queue lti_cl2q; | |
77605e41 | 372 | struct cl_page_list lti_plist; |
ac6424b9 | 373 | wait_queue_entry_t lti_waiter; |
77605e41 | 374 | struct cl_attr lti_attr; |
d7e09d03 PT |
375 | }; |
376 | ||
377 | /** | |
378 | * State that lov_io maintains for every sub-io. | |
379 | */ | |
380 | struct lov_io_sub { | |
3ee45c7e | 381 | u16 sub_stripe; |
d7e09d03 | 382 | /** |
3ee45c7e YS |
383 | * environment's refcheck. |
384 | * | |
385 | * \see cl_env_get() | |
d7e09d03 | 386 | */ |
3ee45c7e YS |
387 | u16 sub_refcheck; |
388 | u16 sub_reenter; | |
d7e09d03 PT |
389 | /** |
390 | * true, iff cl_io_init() was successfully executed against | |
391 | * lov_io_sub::sub_io. | |
392 | */ | |
3ee45c7e | 393 | u16 sub_io_initialized:1, |
d7e09d03 PT |
394 | /** |
395 | * True, iff lov_io_sub::sub_io and lov_io_sub::sub_env weren't | |
396 | * allocated, but borrowed from a per-device emergency pool. | |
397 | */ | |
3ee45c7e | 398 | sub_borrowed:1; |
d7e09d03 | 399 | /** |
3ee45c7e YS |
400 | * Linkage into a list (hanging off lov_io::lis_active) of all |
401 | * sub-io's active for the current IO iteration. | |
d7e09d03 | 402 | */ |
3ee45c7e | 403 | struct list_head sub_linkage; |
d7e09d03 | 404 | /** |
3ee45c7e YS |
405 | * sub-io for a stripe. Ideally sub-io's can be stopped and resumed |
406 | * independently, with lov acting as a scheduler to maximize overall | |
407 | * throughput. | |
408 | */ | |
409 | struct cl_io *sub_io; | |
410 | /** | |
411 | * environment, in which sub-io executes. | |
d7e09d03 | 412 | */ |
3ee45c7e | 413 | struct lu_env *sub_env; |
d7e09d03 PT |
414 | }; |
415 | ||
416 | /** | |
417 | * IO state private for LOV. | |
418 | */ | |
419 | struct lov_io { | |
420 | /** super-class */ | |
421 | struct cl_io_slice lis_cl; | |
422 | /** | |
423 | * Pointer to the object slice. This is a duplicate of | |
424 | * lov_io::lis_cl::cis_object. | |
425 | */ | |
426 | struct lov_object *lis_object; | |
427 | /** | |
428 | * Original end-of-io position for this IO, set by the upper layer as | |
429 | * cl_io::u::ci_rw::pos + cl_io::u::ci_rw::count. lov remembers this, | |
430 | * changes pos and count to fit IO into a single stripe and uses saved | |
431 | * value to determine when IO iterations have to stop. | |
432 | * | |
433 | * This is used only for CIT_READ and CIT_WRITE io's. | |
434 | */ | |
435 | loff_t lis_io_endpos; | |
436 | ||
437 | /** | |
438 | * starting position within a file, for the current io loop iteration | |
439 | * (stripe), used by ci_io_loop(). | |
440 | */ | |
21aef7d9 | 441 | u64 lis_pos; |
d7e09d03 PT |
442 | /** |
443 | * end position with in a file, for the current stripe io. This is | |
444 | * exclusive (i.e., next offset after last byte affected by io). | |
445 | */ | |
21aef7d9 | 446 | u64 lis_endpos; |
d7e09d03 PT |
447 | |
448 | int lis_mem_frozen; | |
449 | int lis_stripe_count; | |
450 | int lis_active_subios; | |
451 | ||
452 | /** | |
453 | * the index of ls_single_subio in ls_subios array | |
454 | */ | |
455 | int lis_single_subio_index; | |
456 | struct cl_io lis_single_subio; | |
457 | ||
458 | /** | |
459 | * size of ls_subios array, actually the highest stripe # | |
460 | */ | |
461 | int lis_nr_subios; | |
462 | struct lov_io_sub *lis_subs; | |
463 | /** | |
464 | * List of active sub-io's. | |
465 | */ | |
466 | struct list_head lis_active; | |
467 | }; | |
468 | ||
469 | struct lov_session { | |
470 | struct lov_io ls_io; | |
471 | struct lov_sublock_env ls_subenv; | |
472 | }; | |
473 | ||
d7e09d03 PT |
474 | extern struct lu_device_type lov_device_type; |
475 | extern struct lu_device_type lovsub_device_type; | |
476 | ||
477 | extern struct lu_context_key lov_key; | |
478 | extern struct lu_context_key lov_session_key; | |
479 | ||
480 | extern struct kmem_cache *lov_lock_kmem; | |
481 | extern struct kmem_cache *lov_object_kmem; | |
482 | extern struct kmem_cache *lov_thread_kmem; | |
483 | extern struct kmem_cache *lov_session_kmem; | |
d7e09d03 PT |
484 | |
485 | extern struct kmem_cache *lovsub_lock_kmem; | |
486 | extern struct kmem_cache *lovsub_object_kmem; | |
d7e09d03 PT |
487 | |
488 | extern struct kmem_cache *lov_lock_link_kmem; | |
489 | ||
f1564f16 OD |
490 | int lov_object_init(const struct lu_env *env, struct lu_object *obj, |
491 | const struct lu_object_conf *conf); | |
492 | int lovsub_object_init(const struct lu_env *env, struct lu_object *obj, | |
493 | const struct lu_object_conf *conf); | |
494 | int lov_lock_init(const struct lu_env *env, struct cl_object *obj, | |
495 | struct cl_lock *lock, const struct cl_io *io); | |
496 | int lov_io_init(const struct lu_env *env, struct cl_object *obj, | |
497 | struct cl_io *io); | |
498 | int lovsub_lock_init(const struct lu_env *env, struct cl_object *obj, | |
499 | struct cl_lock *lock, const struct cl_io *io); | |
500 | ||
501 | int lov_lock_init_raid0(const struct lu_env *env, struct cl_object *obj, | |
502 | struct cl_lock *lock, const struct cl_io *io); | |
503 | int lov_lock_init_empty(const struct lu_env *env, struct cl_object *obj, | |
504 | struct cl_lock *lock, const struct cl_io *io); | |
505 | int lov_io_init_raid0(const struct lu_env *env, struct cl_object *obj, | |
506 | struct cl_io *io); | |
507 | int lov_io_init_empty(const struct lu_env *env, struct cl_object *obj, | |
508 | struct cl_io *io); | |
509 | int lov_io_init_released(const struct lu_env *env, struct cl_object *obj, | |
510 | struct cl_io *io); | |
511 | void lov_lock_unlink(const struct lu_env *env, struct lov_lock_link *link, | |
512 | struct lovsub_lock *sub); | |
d7e09d03 PT |
513 | |
514 | struct lov_io_sub *lov_sub_get(const struct lu_env *env, struct lov_io *lio, | |
515 | int stripe); | |
f1564f16 OD |
516 | void lov_sub_put(struct lov_io_sub *sub); |
517 | int lov_sublock_modify(const struct lu_env *env, struct lov_lock *lov, | |
518 | struct lovsub_lock *sublock, | |
519 | const struct cl_lock_descr *d, int idx); | |
520 | ||
521 | int lov_page_init(const struct lu_env *env, struct cl_object *ob, | |
7addf402 | 522 | struct cl_page *page, pgoff_t index); |
f1564f16 | 523 | int lovsub_page_init(const struct lu_env *env, struct cl_object *ob, |
7addf402 | 524 | struct cl_page *page, pgoff_t index); |
f1564f16 | 525 | int lov_page_init_empty(const struct lu_env *env, struct cl_object *obj, |
7addf402 | 526 | struct cl_page *page, pgoff_t index); |
f1564f16 | 527 | int lov_page_init_raid0(const struct lu_env *env, struct cl_object *obj, |
7addf402 | 528 | struct cl_page *page, pgoff_t index); |
66e7a94a | 529 | struct lu_object *lov_object_alloc(const struct lu_env *env, |
f1564f16 OD |
530 | const struct lu_object_header *hdr, |
531 | struct lu_device *dev); | |
d7e09d03 PT |
532 | struct lu_object *lovsub_object_alloc(const struct lu_env *env, |
533 | const struct lu_object_header *hdr, | |
534 | struct lu_device *dev); | |
535 | ||
536 | struct lov_lock_link *lov_lock_link_find(const struct lu_env *env, | |
537 | struct lov_lock *lck, | |
538 | struct lovsub_lock *sub); | |
f1564f16 OD |
539 | struct lov_io_sub *lov_page_subio(const struct lu_env *env, struct lov_io *lio, |
540 | const struct cl_page_slice *slice); | |
a33fdc0d BJ |
541 | |
542 | struct lov_stripe_md *lov_lsm_addref(struct lov_object *lov); | |
fd7444fe | 543 | int lov_page_stripe(const struct cl_page *page); |
d7e09d03 | 544 | |
d7e09d03 PT |
545 | #define lov_foreach_target(lov, var) \ |
546 | for (var = 0; var < lov_targets_nr(lov); ++var) | |
547 | ||
548 | /***************************************************************************** | |
549 | * | |
550 | * Type conversions. | |
551 | * | |
552 | * Accessors. | |
553 | * | |
554 | */ | |
555 | ||
556 | static inline struct lov_session *lov_env_session(const struct lu_env *env) | |
557 | { | |
558 | struct lov_session *ses; | |
559 | ||
560 | ses = lu_context_key_get(env->le_ses, &lov_session_key); | |
00697c43 | 561 | LASSERT(ses); |
d7e09d03 PT |
562 | return ses; |
563 | } | |
564 | ||
565 | static inline struct lov_io *lov_env_io(const struct lu_env *env) | |
566 | { | |
567 | return &lov_env_session(env)->ls_io; | |
568 | } | |
569 | ||
570 | static inline int lov_is_object(const struct lu_object *obj) | |
571 | { | |
572 | return obj->lo_dev->ld_type == &lov_device_type; | |
573 | } | |
574 | ||
575 | static inline int lovsub_is_object(const struct lu_object *obj) | |
576 | { | |
577 | return obj->lo_dev->ld_type == &lovsub_device_type; | |
578 | } | |
579 | ||
580 | static inline struct lu_device *lov2lu_dev(struct lov_device *lov) | |
581 | { | |
582 | return &lov->ld_cl.cd_lu_dev; | |
583 | } | |
584 | ||
585 | static inline struct lov_device *lu2lov_dev(const struct lu_device *d) | |
586 | { | |
587 | LINVRNT(d->ld_type == &lov_device_type); | |
588 | return container_of0(d, struct lov_device, ld_cl.cd_lu_dev); | |
589 | } | |
590 | ||
591 | static inline struct cl_device *lovsub2cl_dev(struct lovsub_device *lovsub) | |
592 | { | |
593 | return &lovsub->acid_cl; | |
594 | } | |
595 | ||
596 | static inline struct lu_device *lovsub2lu_dev(struct lovsub_device *lovsub) | |
597 | { | |
598 | return &lovsub2cl_dev(lovsub)->cd_lu_dev; | |
599 | } | |
600 | ||
601 | static inline struct lovsub_device *lu2lovsub_dev(const struct lu_device *d) | |
602 | { | |
603 | LINVRNT(d->ld_type == &lovsub_device_type); | |
604 | return container_of0(d, struct lovsub_device, acid_cl.cd_lu_dev); | |
605 | } | |
606 | ||
607 | static inline struct lovsub_device *cl2lovsub_dev(const struct cl_device *d) | |
608 | { | |
609 | LINVRNT(d->cd_lu_dev.ld_type == &lovsub_device_type); | |
610 | return container_of0(d, struct lovsub_device, acid_cl); | |
611 | } | |
612 | ||
613 | static inline struct lu_object *lov2lu(struct lov_object *lov) | |
614 | { | |
615 | return &lov->lo_cl.co_lu; | |
616 | } | |
617 | ||
618 | static inline struct cl_object *lov2cl(struct lov_object *lov) | |
619 | { | |
620 | return &lov->lo_cl; | |
621 | } | |
622 | ||
623 | static inline struct lov_object *lu2lov(const struct lu_object *obj) | |
624 | { | |
625 | LINVRNT(lov_is_object(obj)); | |
626 | return container_of0(obj, struct lov_object, lo_cl.co_lu); | |
627 | } | |
628 | ||
629 | static inline struct lov_object *cl2lov(const struct cl_object *obj) | |
630 | { | |
631 | LINVRNT(lov_is_object(&obj->co_lu)); | |
632 | return container_of0(obj, struct lov_object, lo_cl); | |
633 | } | |
634 | ||
635 | static inline struct lu_object *lovsub2lu(struct lovsub_object *los) | |
636 | { | |
637 | return &los->lso_cl.co_lu; | |
638 | } | |
639 | ||
640 | static inline struct cl_object *lovsub2cl(struct lovsub_object *los) | |
641 | { | |
642 | return &los->lso_cl; | |
643 | } | |
644 | ||
645 | static inline struct lovsub_object *cl2lovsub(const struct cl_object *obj) | |
646 | { | |
647 | LINVRNT(lovsub_is_object(&obj->co_lu)); | |
648 | return container_of0(obj, struct lovsub_object, lso_cl); | |
649 | } | |
650 | ||
651 | static inline struct lovsub_object *lu2lovsub(const struct lu_object *obj) | |
652 | { | |
653 | LINVRNT(lovsub_is_object(obj)); | |
654 | return container_of0(obj, struct lovsub_object, lso_cl.co_lu); | |
655 | } | |
656 | ||
657 | static inline struct lovsub_lock * | |
658 | cl2lovsub_lock(const struct cl_lock_slice *slice) | |
659 | { | |
660 | LINVRNT(lovsub_is_object(&slice->cls_obj->co_lu)); | |
661 | return container_of(slice, struct lovsub_lock, lss_cl); | |
662 | } | |
663 | ||
664 | static inline struct lovsub_lock *cl2sub_lock(const struct cl_lock *lock) | |
665 | { | |
666 | const struct cl_lock_slice *slice; | |
667 | ||
668 | slice = cl_lock_at(lock, &lovsub_device_type); | |
00697c43 | 669 | LASSERT(slice); |
d7e09d03 PT |
670 | return cl2lovsub_lock(slice); |
671 | } | |
672 | ||
673 | static inline struct lov_lock *cl2lov_lock(const struct cl_lock_slice *slice) | |
674 | { | |
675 | LINVRNT(lov_is_object(&slice->cls_obj->co_lu)); | |
676 | return container_of(slice, struct lov_lock, lls_cl); | |
677 | } | |
678 | ||
679 | static inline struct lov_page *cl2lov_page(const struct cl_page_slice *slice) | |
680 | { | |
681 | LINVRNT(lov_is_object(&slice->cpl_obj->co_lu)); | |
682 | return container_of0(slice, struct lov_page, lps_cl); | |
683 | } | |
684 | ||
d7e09d03 PT |
685 | static inline struct lovsub_page * |
686 | cl2lovsub_page(const struct cl_page_slice *slice) | |
687 | { | |
688 | LINVRNT(lovsub_is_object(&slice->cpl_obj->co_lu)); | |
689 | return container_of0(slice, struct lovsub_page, lsb_cl); | |
690 | } | |
691 | ||
d7e09d03 | 692 | static inline struct lov_io *cl2lov_io(const struct lu_env *env, |
f1564f16 | 693 | const struct cl_io_slice *ios) |
d7e09d03 PT |
694 | { |
695 | struct lov_io *lio; | |
696 | ||
697 | lio = container_of(ios, struct lov_io, lis_cl); | |
698 | LASSERT(lio == lov_env_io(env)); | |
699 | return lio; | |
700 | } | |
701 | ||
702 | static inline int lov_targets_nr(const struct lov_device *lov) | |
703 | { | |
704 | return lov->ld_lov->desc.ld_tgt_count; | |
705 | } | |
706 | ||
707 | static inline struct lov_thread_info *lov_env_info(const struct lu_env *env) | |
708 | { | |
709 | struct lov_thread_info *info; | |
710 | ||
711 | info = lu_context_key_get(&env->le_ctx, &lov_key); | |
00697c43 | 712 | LASSERT(info); |
d7e09d03 PT |
713 | return info; |
714 | } | |
715 | ||
716 | static inline struct lov_layout_raid0 *lov_r0(struct lov_object *lov) | |
717 | { | |
718 | LASSERT(lov->lo_type == LLT_RAID0); | |
01cd98ff JH |
719 | LASSERT(lov->lo_lsm->lsm_magic == LOV_MAGIC || |
720 | lov->lo_lsm->lsm_magic == LOV_MAGIC_V3); | |
d7e09d03 PT |
721 | return &lov->u.raid0; |
722 | } | |
723 | ||
a33fdc0d BJ |
724 | /* lov_pack.c */ |
725 | int lov_getstripe(struct lov_object *obj, struct lov_stripe_md *lsm, | |
726 | struct lov_user_md __user *lump); | |
727 | ||
d7e09d03 PT |
728 | /** @} lov */ |
729 | ||
730 | #endif |