Whamcloud - gitweb
LU-260 Add open-unlinked dir regression test case.
[fs/lustre-release.git] / lustre / cmm / cmm_internal.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/cmm/cmm_internal.h
37  *
38  * Lustre Cluster Metadata Manager (cmm)
39  *
40  * Author: Mike Pershin <tappro@clusterfs.com>
41  */
42 /**
43  * \defgroup cmm cmm
44  * Cluster Metadata Manager.
45  * Implementation of md interface to provide operation between MDS-es.
46  *
47  * CMM has two set of md methods, one is for local operation which uses MDD,
48  * second is for remote operations to call different MDS.
49  * When object is allocated then proper set of methods are set for it. *
50  * @{
51  */
52 #ifndef _CMM_INTERNAL_H
53 #define _CMM_INTERNAL_H
54
55 #if defined(__KERNEL__)
56
57 #include <obd.h>
58 #include <lustre_fld.h>
59 #include <md_object.h>
60 #include <lustre_acl.h>
61
62 /**
63  * md_device extention for CMM layer.
64  */
65 struct cmm_device {
66         /** md_device instance */
67         struct md_device        cmm_md_dev;
68         /** device flags, taken from enum cmm_flags */
69         __u32                   cmm_flags;
70         /** underlaying device in MDS stack, usually MDD */
71         struct md_device       *cmm_child;
72         /** FLD client to talk to FLD */
73         struct lu_client_fld   *cmm_fld;
74         /** Number of this MDS server in cluster */
75         mdsno_t                 cmm_local_num;
76         /** Total number of other MDS */
77         __u32                   cmm_tgt_count;
78         /** linked list of all remove MDS clients */
79         cfs_list_t              cmm_targets;
80         /** lock for cmm_device::cmm_targets operations */
81         cfs_spinlock_t          cmm_tgt_guard;
82         /** /proc entry with CMM data */
83         cfs_proc_dir_entry_t   *cmm_proc_entry;
84         /** CMM statistic */
85         struct lprocfs_stats   *cmm_stats;
86 };
87
88 /**
89  * CMM flags
90  */
91 enum cmm_flags {
92         /** Device initialization complete. */
93         CMM_INITIALIZED = 1 << 0
94 };
95
96 /**
97  * Wrapper for md_device::md_ops of underlaying device cmm_child.
98  */
99 static inline const struct md_device_operations *
100 cmm_child_ops(struct cmm_device *d)
101 {
102         return d->cmm_child->md_ops;
103 }
104
105 /** Wrapper to get cmm_device by contained md_device */
106 static inline struct cmm_device *md2cmm_dev(struct md_device *m)
107 {
108         return container_of0(m, struct cmm_device, cmm_md_dev);
109 }
110
111 /** Wrapper to get cmm_device by contained lu_device */
112 static inline struct cmm_device *lu2cmm_dev(struct lu_device *d)
113 {
114         return container_of0(d, struct cmm_device, cmm_md_dev.md_lu_dev);
115 }
116
117 /** Wrapper to get lu_device from cmm_device */
118 static inline struct lu_device *cmm2lu_dev(struct cmm_device *d)
119 {
120         return (&d->cmm_md_dev.md_lu_dev);
121 }
122
123 #ifdef HAVE_SPLIT_SUPPORT
124 /**
125  * \ingroup split
126  * States of split operation.
127  */
128 enum cmm_split_state {
129         CMM_SPLIT_UNKNOWN,
130         CMM_SPLIT_NONE,
131         CMM_SPLIT_NEEDED,
132         CMM_SPLIT_DONE,
133         CMM_SPLIT_DENIED
134 };
135 #endif
136
137 /** CMM container for md_object. */
138 struct cmm_object {
139         struct md_object cmo_obj;
140 };
141
142 /**
143  * \defgroup cml cml
144  * CMM local operations.
145  * @{
146  */
147 /**
148  * Local CMM object.
149  */
150 struct cml_object {
151         /** cmm_object instance. */
152         struct cmm_object    cmm_obj;
153 #ifdef HAVE_SPLIT_SUPPORT
154         /** split state of object (for dirs only) */
155         enum cmm_split_state clo_split;
156 #endif
157 };
158 /** @} */
159
160 /**
161  * \defgroup cmr cmr
162  * CMM remote operations.
163  * @{
164  */
165 /**
166  * Remote CMM object.
167  */
168 struct cmr_object {
169         /** cmm_object instance */
170         struct cmm_object cmm_obj;
171         /** mds number where object is placed */
172         mdsno_t           cmo_num;
173 };
174 /** @} */
175
176 enum {
177         CMM_SPLIT_PAGE_COUNT = 1
178 };
179
180 /**
181  * CMM thread info.
182  * This is storage for all variables used in CMM functions and it is needed as
183  * stack replacement.
184  */
185 struct cmm_thread_info {
186         struct md_attr        cmi_ma;
187         struct lu_buf         cmi_buf;
188         struct lu_fid         cmi_fid; /* used for le/cpu conversions */
189         struct lu_rdpg        cmi_rdpg;
190         /** pointers to pages for readpage. */
191         struct page          *cmi_pages[CMM_SPLIT_PAGE_COUNT];
192         struct md_op_spec     cmi_spec;
193         struct lmv_stripe_md  cmi_lmv;
194         char                  cmi_xattr_buf[LUSTRE_POSIX_ACL_MAX_SIZE];
195         /** Ops object filename */
196         struct lu_name        cti_name;
197 };
198
199 /**
200  * Wrapper to get cmm_device from cmm_object.
201  */
202 static inline struct cmm_device *cmm_obj2dev(struct cmm_object *c)
203 {
204         return (md2cmm_dev(md_obj2dev(&c->cmo_obj)));
205 }
206
207 /**
208  * Get cmm_device from related lu_device.
209  */
210 static inline struct cmm_object *lu2cmm_obj(struct lu_object *o)
211 {
212         //LASSERT(lu_device_is_cmm(o->lo_dev));
213         return container_of0(o, struct cmm_object, cmo_obj.mo_lu);
214 }
215
216 /**
217  * Get cmm object from corresponding md_object.
218  */
219 static inline struct cmm_object *md2cmm_obj(struct md_object *o)
220 {
221         return container_of0(o, struct cmm_object, cmo_obj);
222 }
223
224 /**
225  * Get next lower-layer md_object from current cmm_object.
226  */
227 static inline struct md_object *cmm2child_obj(struct cmm_object *o)
228 {
229         return (o ? lu2md(lu_object_next(&o->cmo_obj.mo_lu)) : NULL);
230 }
231
232 /**
233  * Extract lu_fid from corresponding cmm_object.
234  */
235 static inline struct lu_fid* cmm2fid(struct cmm_object *obj)
236 {
237        return &(obj->cmo_obj.mo_lu.lo_header->loh_fid);
238 }
239
240 struct cmm_thread_info *cmm_env_info(const struct lu_env *env);
241 struct lu_object *cmm_object_alloc(const struct lu_env *env,
242                                    const struct lu_object_header *hdr,
243                                    struct lu_device *);
244 /**
245  * \addtogroup cml
246  * @{
247  */
248 /** Get cml_object from lu_object. */
249 static inline struct cml_object *lu2cml_obj(struct lu_object *o)
250 {
251         return container_of0(o, struct cml_object, cmm_obj.cmo_obj.mo_lu);
252 }
253 /** Get cml_object from md_object. */
254 static inline struct cml_object *md2cml_obj(struct md_object *mo)
255 {
256         return container_of0(mo, struct cml_object, cmm_obj.cmo_obj);
257 }
258 /** Get cml_object from cmm_object */
259 static inline struct cml_object *cmm2cml_obj(struct cmm_object *co)
260 {
261         return container_of0(co, struct cml_object, cmm_obj);
262 }
263 /** @} */
264
265 int cmm_upcall(const struct lu_env *env, struct md_device *md,
266                enum md_upcall_event ev, void *data);
267
268 #ifdef HAVE_SPLIT_SUPPORT
269 /**
270  * \defgroup split split
271  * @{
272  */
273
274 #define CMM_MD_SIZE(stripes)  (sizeof(struct lmv_stripe_md) +  \
275                                (stripes) * sizeof(struct lu_fid))
276
277 /** Get and initialize lu_bug from cmm_thread_info. */
278 static inline struct lu_buf *cmm_buf_get(const struct lu_env *env,
279                                          void *area, ssize_t len)
280 {
281         struct lu_buf *buf;
282
283         buf = &cmm_env_info(env)->cmi_buf;
284         buf->lb_buf = area;
285         buf->lb_len = len;
286         return buf;
287 }
288
289 int cmm_split_check(const struct lu_env *env, struct md_object *mp,
290                     const char *name);
291 int cmm_split_expect(const struct lu_env *env, struct md_object *mo,
292                      struct md_attr *ma, int *split);
293 int cmm_split_dir(const struct lu_env *env, struct md_object *mo);
294 int cmm_split_access(const struct lu_env *env, struct md_object *mo,
295                      mdl_mode_t lm);
296 /** @} */
297 #endif
298
299 int cmm_fld_lookup(struct cmm_device *cm, const struct lu_fid *fid,
300                    mdsno_t *mds, const struct lu_env *env);
301
302 int cmm_procfs_init(struct cmm_device *cmm, const char *name);
303 int cmm_procfs_fini(struct cmm_device *cmm);
304
305 void cmm_lprocfs_time_start(const struct lu_env *env);
306 void cmm_lprocfs_time_end(const struct lu_env *env, struct cmm_device *cmm,
307                           int idx);
308 /**
309  * CMM counters.
310  */
311 enum {
312         LPROC_CMM_SPLIT_CHECK,
313         LPROC_CMM_SPLIT,
314         LPROC_CMM_LOOKUP,
315         LPROC_CMM_CREATE,
316         LPROC_CMM_NR
317 };
318
319 #endif /* __KERNEL__ */
320 #endif /* _CMM_INTERNAL_H */
321 /** @} */