Whamcloud - gitweb
LU-1770 ptlrpc: introducing OBD_CONNECT_FLOCK_OWNER flag
[fs/lustre-release.git] / lustre / cmm / cmm_internal.h
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) 2007, 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  * lustre/cmm/cmm_internal.h
35  *
36  * Lustre Cluster Metadata Manager (cmm)
37  *
38  * Author: Mike Pershin <tappro@clusterfs.com>
39  */
40 /**
41  * \defgroup cmm cmm
42  * Cluster Metadata Manager.
43  * Implementation of md interface to provide operation between MDS-es.
44  *
45  * CMM has two set of md methods, one is for local operation which uses MDD,
46  * second is for remote operations to call different MDS.
47  * When object is allocated then proper set of methods are set for it. *
48  * @{
49  */
50 #ifndef _CMM_INTERNAL_H
51 #define _CMM_INTERNAL_H
52
53 #if defined(__KERNEL__)
54
55 #include <obd.h>
56 #include <lustre_fld.h>
57 #include <md_object.h>
58 #include <lustre_acl.h>
59
60 /**
61  * md_device extention for CMM layer.
62  */
63 struct cmm_device {
64         /** md_device instance */
65         struct md_device        cmm_md_dev;
66         /** device flags, taken from enum cmm_flags */
67         __u32                   cmm_flags;
68         /** underlaying device in MDS stack, usually MDD */
69         struct md_device       *cmm_child;
70         /** FLD client to talk to FLD */
71         struct lu_client_fld   *cmm_fld;
72         /** Number of this MDS server in cluster */
73         mdsno_t                 cmm_local_num;
74         /** Total number of other MDS */
75         __u32                   cmm_tgt_count;
76         /** linked list of all remove MDS clients */
77         cfs_list_t              cmm_targets;
78         /** lock for cmm_device::cmm_targets operations */
79         cfs_spinlock_t          cmm_tgt_guard;
80         /** /proc entry with CMM data */
81         cfs_proc_dir_entry_t   *cmm_proc_entry;
82         /** CMM statistic */
83         struct lprocfs_stats   *cmm_stats;
84 };
85
86 /**
87  * CMM flags
88  */
89 enum cmm_flags {
90         /** Device initialization complete. */
91         CMM_INITIALIZED = 1 << 0
92 };
93
94 /**
95  * Wrapper for md_device::md_ops of underlaying device cmm_child.
96  */
97 static inline const struct md_device_operations *
98 cmm_child_ops(struct cmm_device *d)
99 {
100         return d->cmm_child->md_ops;
101 }
102
103 /** Wrapper to get cmm_device by contained md_device */
104 static inline struct cmm_device *md2cmm_dev(struct md_device *m)
105 {
106         return container_of0(m, struct cmm_device, cmm_md_dev);
107 }
108
109 /** Wrapper to get cmm_device by contained lu_device */
110 static inline struct cmm_device *lu2cmm_dev(struct lu_device *d)
111 {
112         return container_of0(d, struct cmm_device, cmm_md_dev.md_lu_dev);
113 }
114
115 /** Wrapper to get lu_device from cmm_device */
116 static inline struct lu_device *cmm2lu_dev(struct cmm_device *d)
117 {
118         return (&d->cmm_md_dev.md_lu_dev);
119 }
120
121 #ifdef HAVE_SPLIT_SUPPORT
122 /**
123  * \ingroup split
124  * States of split operation.
125  */
126 enum cmm_split_state {
127         CMM_SPLIT_UNKNOWN,
128         CMM_SPLIT_NONE,
129         CMM_SPLIT_NEEDED,
130         CMM_SPLIT_DONE,
131         CMM_SPLIT_DENIED
132 };
133 #endif
134
135 /** CMM container for md_object. */
136 struct cmm_object {
137         struct md_object cmo_obj;
138 };
139
140 /**
141  * \defgroup cml cml
142  * CMM local operations.
143  * @{
144  */
145 /**
146  * Local CMM object.
147  */
148 struct cml_object {
149         /** cmm_object instance. */
150         struct cmm_object    cmm_obj;
151 #ifdef HAVE_SPLIT_SUPPORT
152         /** split state of object (for dirs only) */
153         enum cmm_split_state clo_split;
154 #endif
155 };
156 /** @} */
157
158 /**
159  * \defgroup cmr cmr
160  * CMM remote operations.
161  * @{
162  */
163 /**
164  * Remote CMM object.
165  */
166 struct cmr_object {
167         /** cmm_object instance */
168         struct cmm_object cmm_obj;
169         /** mds number where object is placed */
170         mdsno_t           cmo_num;
171 };
172 /** @} */
173
174 enum {
175         CMM_SPLIT_PAGE_COUNT = 1
176 };
177
178 /**
179  * CMM thread info.
180  * This is storage for all variables used in CMM functions and it is needed as
181  * stack replacement.
182  */
183 struct cmm_thread_info {
184         struct md_attr        cmi_ma;
185         struct lu_buf         cmi_buf;
186         struct lu_fid         cmi_fid; /* used for le/cpu conversions */
187         struct lu_rdpg        cmi_rdpg;
188         /** pointers to pages for readpage. */
189         struct page          *cmi_pages[CMM_SPLIT_PAGE_COUNT];
190         struct md_op_spec     cmi_spec;
191         struct lmv_stripe_md  cmi_lmv;
192         char                  cmi_xattr_buf[LUSTRE_POSIX_ACL_MAX_SIZE];
193         /** Ops object filename */
194         struct lu_name        cti_name;
195 };
196
197 /**
198  * Wrapper to get cmm_device from cmm_object.
199  */
200 static inline struct cmm_device *cmm_obj2dev(struct cmm_object *c)
201 {
202         return (md2cmm_dev(md_obj2dev(&c->cmo_obj)));
203 }
204
205 /**
206  * Get cmm_device from related lu_device.
207  */
208 static inline struct cmm_object *lu2cmm_obj(struct lu_object *o)
209 {
210         //LASSERT(lu_device_is_cmm(o->lo_dev));
211         return container_of0(o, struct cmm_object, cmo_obj.mo_lu);
212 }
213
214 /**
215  * Get cmm object from corresponding md_object.
216  */
217 static inline struct cmm_object *md2cmm_obj(struct md_object *o)
218 {
219         return container_of0(o, struct cmm_object, cmo_obj);
220 }
221
222 /**
223  * Get next lower-layer md_object from current cmm_object.
224  */
225 static inline struct md_object *cmm2child_obj(struct cmm_object *o)
226 {
227         return (o ? lu2md(lu_object_next(&o->cmo_obj.mo_lu)) : NULL);
228 }
229
230 /**
231  * Extract lu_fid from corresponding cmm_object.
232  */
233 static inline struct lu_fid* cmm2fid(struct cmm_object *obj)
234 {
235        return &(obj->cmo_obj.mo_lu.lo_header->loh_fid);
236 }
237
238 struct cmm_thread_info *cmm_env_info(const struct lu_env *env);
239 struct lu_object *cmm_object_alloc(const struct lu_env *env,
240                                    const struct lu_object_header *hdr,
241                                    struct lu_device *);
242 /**
243  * \addtogroup cml
244  * @{
245  */
246 /** Get cml_object from lu_object. */
247 static inline struct cml_object *lu2cml_obj(struct lu_object *o)
248 {
249         return container_of0(o, struct cml_object, cmm_obj.cmo_obj.mo_lu);
250 }
251 /** Get cml_object from md_object. */
252 static inline struct cml_object *md2cml_obj(struct md_object *mo)
253 {
254         return container_of0(mo, struct cml_object, cmm_obj.cmo_obj);
255 }
256 /** Get cml_object from cmm_object */
257 static inline struct cml_object *cmm2cml_obj(struct cmm_object *co)
258 {
259         return container_of0(co, struct cml_object, cmm_obj);
260 }
261 /** @} */
262
263 int cmm_upcall(const struct lu_env *env, struct md_device *md,
264                enum md_upcall_event ev, void *data);
265
266 #ifdef HAVE_SPLIT_SUPPORT
267 /**
268  * \defgroup split split
269  * @{
270  */
271
272 #define CMM_MD_SIZE(stripes)  (sizeof(struct lmv_stripe_md) +  \
273                                (stripes) * sizeof(struct lu_fid))
274
275 /** Get and initialize lu_bug from cmm_thread_info. */
276 static inline struct lu_buf *cmm_buf_get(const struct lu_env *env,
277                                          void *area, ssize_t len)
278 {
279         struct lu_buf *buf;
280
281         buf = &cmm_env_info(env)->cmi_buf;
282         buf->lb_buf = area;
283         buf->lb_len = len;
284         return buf;
285 }
286
287 int cmm_split_check(const struct lu_env *env, struct md_object *mp,
288                     const char *name);
289 int cmm_split_expect(const struct lu_env *env, struct md_object *mo,
290                      struct md_attr *ma, int *split);
291 int cmm_split_dir(const struct lu_env *env, struct md_object *mo);
292 int cmm_split_access(const struct lu_env *env, struct md_object *mo,
293                      mdl_mode_t lm);
294 /** @} */
295 #endif
296
297 int cmm_fld_lookup(struct cmm_device *cm, const struct lu_fid *fid,
298                    mdsno_t *mds, const struct lu_env *env);
299
300 int cmm_procfs_init(struct cmm_device *cmm, const char *name);
301 int cmm_procfs_fini(struct cmm_device *cmm);
302
303 void cmm_lprocfs_time_start(const struct lu_env *env);
304 void cmm_lprocfs_time_end(const struct lu_env *env, struct cmm_device *cmm,
305                           int idx);
306 /**
307  * CMM counters.
308  */
309 enum {
310         LPROC_CMM_SPLIT_CHECK,
311         LPROC_CMM_SPLIT,
312         LPROC_CMM_LOOKUP,
313         LPROC_CMM_CREATE,
314         LPROC_CMM_NR
315 };
316
317 #endif /* __KERNEL__ */
318 #endif /* _CMM_INTERNAL_H */
319 /** @} */