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  * Copyright (c) 2012, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * Implementation of cl_device, cl_req for OSC layer.
37  *
38  *   Author: Nikita Danilov <nikita.danilov@sun.com>
39  */
40 
41 #define DEBUG_SUBSYSTEM S_OSC
42 
43 /* class_name2obd() */
44 #include "../include/obd_class.h"
45 
46 #include "osc_cl_internal.h"
47 
48 /** \addtogroup osc
49  * @{
50  */
51 
52 struct kmem_cache *osc_lock_kmem;
53 struct kmem_cache *osc_object_kmem;
54 struct kmem_cache *osc_thread_kmem;
55 struct kmem_cache *osc_session_kmem;
56 struct kmem_cache *osc_req_kmem;
57 struct kmem_cache *osc_extent_kmem;
58 struct kmem_cache *osc_quota_kmem;
59 
60 struct lu_kmem_descr osc_caches[] = {
61 	{
62 		.ckd_cache = &osc_lock_kmem,
63 		.ckd_name  = "osc_lock_kmem",
64 		.ckd_size  = sizeof(struct osc_lock)
65 	},
66 	{
67 		.ckd_cache = &osc_object_kmem,
68 		.ckd_name  = "osc_object_kmem",
69 		.ckd_size  = sizeof(struct osc_object)
70 	},
71 	{
72 		.ckd_cache = &osc_thread_kmem,
73 		.ckd_name  = "osc_thread_kmem",
74 		.ckd_size  = sizeof(struct osc_thread_info)
75 	},
76 	{
77 		.ckd_cache = &osc_session_kmem,
78 		.ckd_name  = "osc_session_kmem",
79 		.ckd_size  = sizeof(struct osc_session)
80 	},
81 	{
82 		.ckd_cache = &osc_req_kmem,
83 		.ckd_name  = "osc_req_kmem",
84 		.ckd_size  = sizeof(struct osc_req)
85 	},
86 	{
87 		.ckd_cache = &osc_extent_kmem,
88 		.ckd_name  = "osc_extent_kmem",
89 		.ckd_size  = sizeof(struct osc_extent)
90 	},
91 	{
92 		.ckd_cache = &osc_quota_kmem,
93 		.ckd_name  = "osc_quota_kmem",
94 		.ckd_size  = sizeof(struct osc_quota_info)
95 	},
96 	{
97 		.ckd_cache = NULL
98 	}
99 };
100 
101 struct lock_class_key osc_ast_guard_class;
102 
103 /*****************************************************************************
104  *
105  * Type conversions.
106  *
107  */
108 
osc2lu_dev(struct osc_device * osc)109 static struct lu_device *osc2lu_dev(struct osc_device *osc)
110 {
111 	return &osc->od_cl.cd_lu_dev;
112 }
113 
114 /*****************************************************************************
115  *
116  * Osc device and device type functions.
117  *
118  */
119 
osc_key_init(const struct lu_context * ctx,struct lu_context_key * key)120 static void *osc_key_init(const struct lu_context *ctx,
121 			  struct lu_context_key *key)
122 {
123 	struct osc_thread_info *info;
124 
125 	info = kmem_cache_alloc(osc_thread_kmem, GFP_NOFS | __GFP_ZERO);
126 	if (info == NULL)
127 		info = ERR_PTR(-ENOMEM);
128 	return info;
129 }
130 
osc_key_fini(const struct lu_context * ctx,struct lu_context_key * key,void * data)131 static void osc_key_fini(const struct lu_context *ctx,
132 			 struct lu_context_key *key, void *data)
133 {
134 	struct osc_thread_info *info = data;
135 
136 	kmem_cache_free(osc_thread_kmem, info);
137 }
138 
139 struct lu_context_key osc_key = {
140 	.lct_tags = LCT_CL_THREAD,
141 	.lct_init = osc_key_init,
142 	.lct_fini = osc_key_fini
143 };
144 
osc_session_init(const struct lu_context * ctx,struct lu_context_key * key)145 static void *osc_session_init(const struct lu_context *ctx,
146 			      struct lu_context_key *key)
147 {
148 	struct osc_session *info;
149 
150 	info = kmem_cache_alloc(osc_session_kmem, GFP_NOFS | __GFP_ZERO);
151 	if (info == NULL)
152 		info = ERR_PTR(-ENOMEM);
153 	return info;
154 }
155 
osc_session_fini(const struct lu_context * ctx,struct lu_context_key * key,void * data)156 static void osc_session_fini(const struct lu_context *ctx,
157 			     struct lu_context_key *key, void *data)
158 {
159 	struct osc_session *info = data;
160 
161 	kmem_cache_free(osc_session_kmem, info);
162 }
163 
164 struct lu_context_key osc_session_key = {
165 	.lct_tags = LCT_SESSION,
166 	.lct_init = osc_session_init,
167 	.lct_fini = osc_session_fini
168 };
169 
170 /* type constructor/destructor: osc_type_{init,fini,start,stop}(). */
171 LU_TYPE_INIT_FINI(osc, &osc_key, &osc_session_key);
172 
osc_cl_process_config(const struct lu_env * env,struct lu_device * d,struct lustre_cfg * cfg)173 static int osc_cl_process_config(const struct lu_env *env,
174 				 struct lu_device *d, struct lustre_cfg *cfg)
175 {
176 	return osc_process_config_base(d->ld_obd, cfg);
177 }
178 
179 static const struct lu_device_operations osc_lu_ops = {
180 	.ldo_object_alloc      = osc_object_alloc,
181 	.ldo_process_config    = osc_cl_process_config,
182 	.ldo_recovery_complete = NULL
183 };
184 
185 static const struct cl_device_operations osc_cl_ops = {
186 	.cdo_req_init = osc_req_init
187 };
188 
osc_device_init(const struct lu_env * env,struct lu_device * d,const char * name,struct lu_device * next)189 static int osc_device_init(const struct lu_env *env, struct lu_device *d,
190 			   const char *name, struct lu_device *next)
191 {
192 	return 0;
193 }
194 
osc_device_fini(const struct lu_env * env,struct lu_device * d)195 static struct lu_device *osc_device_fini(const struct lu_env *env,
196 					 struct lu_device *d)
197 {
198 	return NULL;
199 }
200 
osc_device_free(const struct lu_env * env,struct lu_device * d)201 static struct lu_device *osc_device_free(const struct lu_env *env,
202 					 struct lu_device *d)
203 {
204 	struct osc_device *od = lu2osc_dev(d);
205 
206 	cl_device_fini(lu2cl_dev(d));
207 	kfree(od);
208 	return NULL;
209 }
210 
osc_device_alloc(const struct lu_env * env,struct lu_device_type * t,struct lustre_cfg * cfg)211 static struct lu_device *osc_device_alloc(const struct lu_env *env,
212 					  struct lu_device_type *t,
213 					  struct lustre_cfg *cfg)
214 {
215 	struct lu_device *d;
216 	struct osc_device *od;
217 	struct obd_device *obd;
218 	int rc;
219 
220 	od = kzalloc(sizeof(*od), GFP_NOFS);
221 	if (!od)
222 		return ERR_PTR(-ENOMEM);
223 
224 	cl_device_init(&od->od_cl, t);
225 	d = osc2lu_dev(od);
226 	d->ld_ops = &osc_lu_ops;
227 	od->od_cl.cd_ops = &osc_cl_ops;
228 
229 	/* Setup OSC OBD */
230 	obd = class_name2obd(lustre_cfg_string(cfg, 0));
231 	LASSERT(obd != NULL);
232 	rc = osc_setup(obd, cfg);
233 	if (rc) {
234 		osc_device_free(env, d);
235 		return ERR_PTR(rc);
236 	}
237 	od->od_exp = obd->obd_self_export;
238 	return d;
239 }
240 
241 static const struct lu_device_type_operations osc_device_type_ops = {
242 	.ldto_init = osc_type_init,
243 	.ldto_fini = osc_type_fini,
244 
245 	.ldto_start = osc_type_start,
246 	.ldto_stop  = osc_type_stop,
247 
248 	.ldto_device_alloc = osc_device_alloc,
249 	.ldto_device_free  = osc_device_free,
250 
251 	.ldto_device_init = osc_device_init,
252 	.ldto_device_fini = osc_device_fini
253 };
254 
255 struct lu_device_type osc_device_type = {
256 	.ldt_tags = LU_DEVICE_CL,
257 	.ldt_name = LUSTRE_OSC_NAME,
258 	.ldt_ops = &osc_device_type_ops,
259 	.ldt_ctx_tags = LCT_CL_THREAD
260 };
261 
262 /** @} osc */
263