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 | |
18 | * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf | |
19 | * | |
20 | * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
21 | * CA 95054 USA or visit www.sun.com if you need additional information or | |
22 | * have any questions. | |
23 | * | |
24 | * GPL HEADER END | |
25 | */ | |
26 | /* | |
27 | * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. | |
28 | * Use is subject to license terms. | |
29 | */ | |
30 | /* | |
31 | * This file is part of Lustre, http://www.lustre.org/ | |
32 | * Lustre is a trademark of Sun Microsystems, Inc. | |
33 | * | |
34 | * Implementation of cl_device and cl_device_type for LOVSUB layer. | |
35 | * | |
36 | * Author: Nikita Danilov <nikita.danilov@sun.com> | |
37 | */ | |
38 | ||
39 | #define DEBUG_SUBSYSTEM S_LOV | |
40 | ||
41 | #include "lov_cl_internal.h" | |
42 | ||
43 | /** \addtogroup lov | |
44 | * @{ | |
45 | */ | |
46 | ||
47 | /***************************************************************************** | |
48 | * | |
49 | * Lovsub transfer operations. | |
50 | * | |
51 | */ | |
52 | ||
53 | static void lovsub_req_completion(const struct lu_env *env, | |
54 | const struct cl_req_slice *slice, int ioret) | |
55 | { | |
56 | struct lovsub_req *lsr; | |
57 | ||
d7e09d03 PT |
58 | lsr = cl2lovsub_req(slice); |
59 | OBD_SLAB_FREE_PTR(lsr, lovsub_req_kmem); | |
d7e09d03 PT |
60 | } |
61 | ||
62 | /** | |
63 | * Implementation of struct cl_req_operations::cro_attr_set() for lovsub | |
64 | * layer. Lov and lovsub are responsible only for struct obdo::o_stripe_idx | |
65 | * field, which is filled there. | |
66 | */ | |
67 | static void lovsub_req_attr_set(const struct lu_env *env, | |
68 | const struct cl_req_slice *slice, | |
69 | const struct cl_object *obj, | |
70 | struct cl_req_attr *attr, obd_valid flags) | |
71 | { | |
72 | struct lovsub_object *subobj; | |
73 | ||
d7e09d03 PT |
74 | subobj = cl2lovsub(obj); |
75 | /* | |
76 | * There is no OBD_MD_* flag for obdo::o_stripe_idx, so set it | |
77 | * unconditionally. It never changes anyway. | |
78 | */ | |
79 | attr->cra_oa->o_stripe_idx = subobj->lso_index; | |
d7e09d03 PT |
80 | } |
81 | ||
82 | static const struct cl_req_operations lovsub_req_ops = { | |
83 | .cro_attr_set = lovsub_req_attr_set, | |
84 | .cro_completion = lovsub_req_completion | |
85 | }; | |
86 | ||
87 | /***************************************************************************** | |
88 | * | |
89 | * Lov-sub device and device type functions. | |
90 | * | |
91 | */ | |
92 | ||
93 | static int lovsub_device_init(const struct lu_env *env, struct lu_device *d, | |
94 | const char *name, struct lu_device *next) | |
95 | { | |
96 | struct lovsub_device *lsd = lu2lovsub_dev(d); | |
97 | struct lu_device_type *ldt; | |
98 | int rc; | |
99 | ||
d7e09d03 PT |
100 | next->ld_site = d->ld_site; |
101 | ldt = next->ld_type; | |
102 | LASSERT(ldt != NULL); | |
103 | rc = ldt->ldt_ops->ldto_device_init(env, next, ldt->ldt_name, NULL); | |
104 | if (rc) { | |
105 | next->ld_site = NULL; | |
0a3bdb00 | 106 | return rc; |
d7e09d03 PT |
107 | } |
108 | ||
109 | lu_device_get(next); | |
110 | lu_ref_add(&next->ld_reference, "lu-stack", &lu_site_init); | |
111 | lsd->acid_next = lu2cl_dev(next); | |
0a3bdb00 | 112 | return rc; |
d7e09d03 PT |
113 | } |
114 | ||
115 | static struct lu_device *lovsub_device_fini(const struct lu_env *env, | |
116 | struct lu_device *d) | |
117 | { | |
118 | struct lu_device *next; | |
119 | struct lovsub_device *lsd; | |
120 | ||
d7e09d03 PT |
121 | lsd = lu2lovsub_dev(d); |
122 | next = cl2lu_dev(lsd->acid_next); | |
123 | lsd->acid_super = NULL; | |
124 | lsd->acid_next = NULL; | |
0a3bdb00 | 125 | return next; |
d7e09d03 PT |
126 | } |
127 | ||
128 | static struct lu_device *lovsub_device_free(const struct lu_env *env, | |
129 | struct lu_device *d) | |
130 | { | |
131 | struct lovsub_device *lsd = lu2lovsub_dev(d); | |
132 | struct lu_device *next = cl2lu_dev(lsd->acid_next); | |
133 | ||
134 | cl_device_fini(lu2cl_dev(d)); | |
135 | OBD_FREE_PTR(lsd); | |
136 | return next; | |
137 | } | |
138 | ||
139 | static int lovsub_req_init(const struct lu_env *env, struct cl_device *dev, | |
140 | struct cl_req *req) | |
141 | { | |
142 | struct lovsub_req *lsr; | |
143 | int result; | |
144 | ||
145 | OBD_SLAB_ALLOC_PTR_GFP(lsr, lovsub_req_kmem, __GFP_IO); | |
146 | if (lsr != NULL) { | |
147 | cl_req_slice_add(req, &lsr->lsrq_cl, dev, &lovsub_req_ops); | |
148 | result = 0; | |
149 | } else | |
150 | result = -ENOMEM; | |
151 | return result; | |
152 | } | |
153 | ||
154 | static const struct lu_device_operations lovsub_lu_ops = { | |
155 | .ldo_object_alloc = lovsub_object_alloc, | |
156 | .ldo_process_config = NULL, | |
157 | .ldo_recovery_complete = NULL | |
158 | }; | |
159 | ||
160 | static const struct cl_device_operations lovsub_cl_ops = { | |
161 | .cdo_req_init = lovsub_req_init | |
162 | }; | |
163 | ||
164 | static struct lu_device *lovsub_device_alloc(const struct lu_env *env, | |
165 | struct lu_device_type *t, | |
166 | struct lustre_cfg *cfg) | |
167 | { | |
168 | struct lu_device *d; | |
169 | struct lovsub_device *lsd; | |
170 | ||
171 | OBD_ALLOC_PTR(lsd); | |
172 | if (lsd != NULL) { | |
173 | int result; | |
174 | ||
175 | result = cl_device_init(&lsd->acid_cl, t); | |
176 | if (result == 0) { | |
177 | d = lovsub2lu_dev(lsd); | |
178 | d->ld_ops = &lovsub_lu_ops; | |
179 | lsd->acid_cl.cd_ops = &lovsub_cl_ops; | |
180 | } else | |
181 | d = ERR_PTR(result); | |
182 | } else | |
183 | d = ERR_PTR(-ENOMEM); | |
184 | return d; | |
185 | } | |
186 | ||
187 | static const struct lu_device_type_operations lovsub_device_type_ops = { | |
188 | .ldto_device_alloc = lovsub_device_alloc, | |
189 | .ldto_device_free = lovsub_device_free, | |
190 | ||
191 | .ldto_device_init = lovsub_device_init, | |
192 | .ldto_device_fini = lovsub_device_fini | |
193 | }; | |
194 | ||
195 | #define LUSTRE_LOVSUB_NAME "lovsub" | |
196 | ||
197 | struct lu_device_type lovsub_device_type = { | |
198 | .ldt_tags = LU_DEVICE_CL, | |
199 | .ldt_name = LUSTRE_LOVSUB_NAME, | |
200 | .ldt_ops = &lovsub_device_type_ops, | |
201 | .ldt_ctx_tags = LCT_CL_THREAD | |
202 | }; | |
203 | ||
204 | ||
205 | /** @} lov */ |