Whamcloud - gitweb
LU-1222 ldlm: Fix the race in AST sender vs multiple arriving RPCs
[fs/lustre-release.git] / lustre / lmv / lmv_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) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
30  * Use is subject to license terms.
31  *
32  * Copyright (c) 2011, Whamcloud, Inc.
33  */
34 /*
35  * This file is part of Lustre, http://www.lustre.org/
36  * Lustre is a trademark of Sun Microsystems, Inc.
37  */
38
39 #ifndef _LMV_INTERNAL_H_
40 #define _LMV_INTERNAL_H_
41
42 #include <lustre/lustre_idl.h>
43 #include <obd.h>
44
45 #define LMV_MAX_TGT_COUNT 128
46
47 #define lmv_init_lock(lmv)   cfs_down(&lmv->init_sem);
48 #define lmv_init_unlock(lmv) cfs_up(&lmv->init_sem);
49
50 #define LL_IT2STR(it)                                   \
51         ((it) ? ldlm_it2str((it)->it_op) : "0")
52
53 struct lmv_stripe {
54         /**
55          * Dir stripe fid.
56          */
57         struct lu_fid           ls_fid;
58         /**
59          * Cached home mds number for \a li_fid.
60          */
61         mdsno_t                 ls_mds;
62         /**
63          * Stripe object size.
64          */
65         unsigned long           ls_size;
66         /**
67          * Stripe flags.
68          */
69         int                     ls_flags;
70 };
71
72 #define O_FREEING               (1 << 0)
73
74 struct lmv_object {
75         /**
76          * Link to global objects list.
77          */
78         cfs_list_t              lo_list;
79         /**
80          * Sema for protecting fields.
81          */
82         cfs_semaphore_t         lo_guard;
83         /**
84          * Object state like O_FREEING.
85          */
86         int                     lo_state;
87         /**
88          * Object ref counter.
89          */
90         cfs_atomic_t            lo_count;
91         /**
92          * Object master fid.
93          */
94         struct lu_fid           lo_fid;
95         /**
96          * Object hash type to find stripe by name.
97          */
98         __u32                   lo_hashtype;
99         /**
100          * Number of stripes.
101          */
102         int                     lo_objcount;
103         /**
104          * Array of sub-objs.
105          */
106         struct lmv_stripe      *lo_stripes;
107         /**
108          * Pointer to LMV obd.
109          */
110         struct obd_device      *lo_obd;
111 };
112
113 int lmv_object_setup(struct obd_device *obd);
114 void lmv_object_cleanup(struct obd_device *obd);
115
116 static inline void
117 lmv_object_lock(struct lmv_object *obj)
118 {
119         LASSERT(obj);
120         cfs_down(&obj->lo_guard);
121 }
122
123 static inline void
124 lmv_object_unlock(struct lmv_object *obj)
125 {
126         LASSERT(obj);
127         cfs_up(&obj->lo_guard);
128 }
129
130 void lmv_object_add(struct lmv_object *obj);
131 void lmv_object_del(struct lmv_object *obj);
132
133 void lmv_object_put(struct lmv_object *obj);
134 void lmv_object_put_unlock(struct lmv_object *obj);
135 void lmv_object_free(struct lmv_object *obj);
136
137 struct lmv_object *lmv_object_get(struct lmv_object *obj);
138
139 struct lmv_object *lmv_object_find(struct obd_device *obd,
140                                    const struct lu_fid *fid);
141
142 struct lmv_object *lmv_object_find_lock(struct obd_device *obd,
143                                         const struct lu_fid *fid);
144
145 struct lmv_object *lmv_object_alloc(struct obd_device *obd,
146                                     const struct lu_fid *fid,
147                                     struct lmv_stripe_md *mea);
148
149 struct lmv_object *lmv_object_create(struct obd_export *exp,
150                                      const struct lu_fid *fid,
151                                      struct lmv_stripe_md *mea);
152
153 int lmv_object_delete(struct obd_export *exp,
154                       const struct lu_fid *fid);
155
156 int lmv_check_connect(struct obd_device *obd);
157
158 int lmv_intent_lock(struct obd_export *exp, struct md_op_data *op_data,
159                     void *lmm, int lmmsize, struct lookup_intent *it,
160                     int flags, struct ptlrpc_request **reqp,
161                     ldlm_blocking_callback cb_blocking,
162                     int extra_lock_flags);
163
164 int lmv_intent_lookup(struct obd_export *exp, struct md_op_data *op_data,
165                       void *lmm, int lmmsize, struct lookup_intent *it,
166                       int flags, struct ptlrpc_request **reqp,
167                       ldlm_blocking_callback cb_blocking,
168                       int extra_lock_flags);
169
170 int lmv_intent_open(struct obd_export *exp, struct md_op_data *op_data,
171                     void *lmm, int lmmsize, struct lookup_intent *it,
172                     int flags, struct ptlrpc_request **reqp,
173                     ldlm_blocking_callback cb_blocking,
174                     int extra_lock_flags);
175
176 int lmv_allocate_slaves(struct obd_device *obd, struct lu_fid *pid,
177                         struct md_op_data *op, struct lu_fid *fid);
178
179 int lmv_revalidate_slaves(struct obd_export *, struct ptlrpc_request **,
180                           const struct lu_fid *, struct lookup_intent *, int,
181                           ldlm_blocking_callback cb_blocking,
182                           int extra_lock_flags);
183
184 int lmv_handle_split(struct obd_export *, const struct lu_fid *);
185 int lmv_blocking_ast(struct ldlm_lock *, struct ldlm_lock_desc *,
186                      void *, int);
187 int lmv_fld_lookup(struct lmv_obd *lmv, const struct lu_fid *fid,
188                    mdsno_t *mds);
189 int __lmv_fid_alloc(struct lmv_obd *lmv, struct lu_fid *fid,
190                     mdsno_t mds);
191 int lmv_fid_alloc(struct obd_export *exp, struct lu_fid *fid,
192                   struct md_op_data *op_data);
193
194 static inline struct lmv_stripe_md *lmv_get_mea(struct ptlrpc_request *req)
195 {
196         struct mdt_body         *body;
197         struct lmv_stripe_md    *mea;
198
199         LASSERT(req != NULL);
200
201         body = req_capsule_server_get(&req->rq_pill, &RMF_MDT_BODY);
202
203         if (!body || !S_ISDIR(body->mode) || !body->eadatasize)
204                 return NULL;
205
206         mea = req_capsule_server_sized_get(&req->rq_pill, &RMF_MDT_MD,
207                                            body->eadatasize);
208         LASSERT(mea != NULL);
209
210         if (mea->mea_count == 0)
211                 return NULL;
212         if( mea->mea_magic != MEA_MAGIC_LAST_CHAR &&
213                 mea->mea_magic != MEA_MAGIC_ALL_CHARS &&
214                 mea->mea_magic != MEA_MAGIC_HASH_SEGMENT)
215                 return NULL;
216
217         return mea;
218 }
219
220 static inline int lmv_get_easize(struct lmv_obd *lmv)
221 {
222         return sizeof(struct lmv_stripe_md) +
223                 lmv->desc.ld_tgt_count *
224                 sizeof(struct lu_fid);
225 }
226
227 static inline struct lmv_tgt_desc *
228 lmv_get_target(struct lmv_obd *lmv, mdsno_t mds)
229 {
230         return &lmv->tgts[mds];
231 }
232
233 static inline struct lmv_tgt_desc *
234 lmv_find_target(struct lmv_obd *lmv, const struct lu_fid *fid)
235 {
236         mdsno_t mds = 0;
237         int rc;
238
239         if (lmv->desc.ld_tgt_count > 1) {
240                 rc = lmv_fld_lookup(lmv, fid, &mds);
241                 if (rc)
242                         return ERR_PTR(rc);
243         }
244
245         return lmv_get_target(lmv, mds);
246 }
247
248 /* lproc_lmv.c */
249 #ifdef LPROCFS
250 void lprocfs_lmv_init_vars(struct lprocfs_static_vars *lvars);
251 #else
252 static inline void lprocfs_lmv_init_vars(struct lprocfs_static_vars *lvars)
253 {
254         memset(lvars, 0, sizeof(*lvars));
255 }
256 #endif
257 extern struct file_operations lmv_proc_target_fops;
258
259 #endif