Whamcloud - gitweb
LU-1330 fld: prepare FLD module for client server split
[fs/lustre-release.git] / lustre / quota / qmt_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, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 021110-1307, USA
20  *
21  * GPL HEADER END
22  */
23 /*
24  * Copyright (c) 2012, Intel Corporation.
25  * Use is subject to license terms.
26  */
27
28 #ifndef _QMT_INTERNAL_H
29 #define _QMT_INTERNAL_H
30
31 #include <lustre_mdt.h> /* err_serious() */
32 #include "lquota_internal.h"
33
34 /*
35  * The Quota Master Target Device.
36  * The qmt is responsible for:
37  * - all interactions with MDT0 (provide request handlers, share ldlm namespace,
38  *   manage ldlm lvbo, ...)
39  * - all quota lock management (i.e. global quota locks as well as per-ID locks)
40  * - manage the quota pool configuration
41  *
42  * That's the structure MDT0 connects to in mdt_quota_init().
43  */
44 struct qmt_device {
45         /* Super-class. dt_device/lu_device for this master target */
46         struct dt_device        qmt_dt_dev;
47
48         /* service name of this qmt */
49         char                    qmt_svname[MAX_OBD_NAME];
50
51         /* Reference to the next device in the side stack
52          * The child device is actually the OSD device where we store the quota
53          * index files */
54         struct obd_export       *qmt_child_exp;
55         struct dt_device        *qmt_child;
56
57         /* pointer to ldlm namespace to be used for quota locks */
58         struct ldlm_namespace   *qmt_ns;
59
60         /* Hash table containing a qmt_pool_info structure for each pool
61          * this quota master is in charge of. We only have 2 pools in this
62          * hash for the time being:
63          * - one for quota management on the default metadata pool
64          * - one for quota managment on the default data pool
65          *
66          * Once we support quota on non-default pools, then more pools will
67          * be added to this hash table and pool master setup would have to be
68          * handled via configuration logs */
69         cfs_hash_t              *qmt_pool_hash;
70
71         /* List of pools managed by this master target */
72         cfs_list_t               qmt_pool_list;
73
74         /* procfs root directory for this qmt */
75         cfs_proc_dir_entry_t    *qmt_proc;
76
77         /* dedicated thread in charge of space rebalancing */
78         struct ptlrpc_thread     qmt_reba_thread;
79
80         /* list of lqe entry which need space rebalancing */
81         cfs_list_t               qmt_reba_list;
82
83         /* lock protecting rebalancing list */
84         spinlock_t               qmt_reba_lock;
85
86         unsigned long            qmt_stopping:1; /* qmt is stopping */
87
88 };
89
90 /*
91  * Per-pool quota information.
92  * The qmt creates one such structure for each pool
93  * with quota enforced. All the structures are kept in a hash which is used to
94  * determine whether or not quota is enforced for a given pool.
95  * We currently only support the default data pool and default metadata pool
96  * with the pool_id 0.
97  */
98 struct qmt_pool_info {
99         /* link to qmt's pool hash */
100         cfs_hlist_node_t         qpi_hash;
101
102         /* chained list of all pools managed by the same qmt */
103         cfs_list_t               qpi_linkage;
104
105         /* Pool key composed of pool_id | (pool_type << 16)
106          * Only pool ID 0 is supported for now and the pool type is either
107          * QUOTA_RES_MD or QUOTA_RES_DT.
108          * immutable after creation. */
109         __u32                    qpi_key;
110
111         /* track users of this pool instance */
112         cfs_atomic_t             qpi_ref;
113
114         /* back pointer to master target
115          * immutable after creation. */
116         struct qmt_device       *qpi_qmt;
117
118         /* pointer to dt object associated with global indexes for both user
119          * and group quota */
120         struct dt_object        *qpi_glb_obj[MAXQUOTAS];
121
122         /* A pool supports two different quota types: user and group quota.
123          * Each quota type has its own global index and lquota_entry hash table.
124          */
125         struct lquota_site      *qpi_site[MAXQUOTAS];
126
127         /* number of slaves registered for each quota types */
128         int                      qpi_slv_nr[MAXQUOTAS];
129
130         /* reference on lqe (ID 0) storing grace time. */
131         struct lquota_entry     *qpi_grace_lqe[MAXQUOTAS];
132
133         /* procfs root directory for this pool */
134         cfs_proc_dir_entry_t    *qpi_proc;
135
136         /* pool directory where all indexes related to this pool instance are
137          * stored */
138         struct dt_object        *qpi_root;
139
140         /* Global quota parameters which apply to all quota type */
141         /* the least value of qunit */
142         unsigned long            qpi_least_qunit;
143 };
144
145 /*
146  * Helper routines and prototypes
147  */
148
149 /* helper routine to find qmt_pool_info associated a lquota_entry */
150 static inline struct qmt_pool_info *lqe2qpi(struct lquota_entry *lqe)
151 {
152         LASSERT(lqe_is_master(lqe));
153         return (struct qmt_pool_info *)lqe->lqe_site->lqs_parent;
154 }
155
156 /* return true if someone holds either a read or write lock on the lqe */
157 static inline bool lqe_is_locked(struct lquota_entry *lqe)
158 {
159         LASSERT(lqe_is_master(lqe));
160         if (down_write_trylock(&lqe->lqe_sem) == 0)
161                 return true;
162         lqe_write_unlock(lqe);
163         return false;
164 }
165
166 /* value to be restored if someone wrong happens during lqe writeback */
167 struct qmt_lqe_restore {
168         __u64   qlr_hardlimit;
169         __u64   qlr_softlimit;
170         __u64   qlr_gracetime;
171         __u64   qlr_granted;
172         __u64   qlr_qunit;
173 };
174
175 /* Common data shared by qmt handlers */
176 struct qmt_thread_info {
177         union lquota_rec        qti_rec;
178         union lquota_id         qti_id;
179         char                    qti_buf[MTI_NAME_MAXLEN];
180         struct lu_fid           qti_fid;
181         struct ldlm_res_id      qti_resid;
182         union ldlm_gl_desc      qti_gl_desc;
183         struct quota_body       qti_body;
184         struct qmt_lqe_restore  qti_restore;
185 };
186
187 extern struct lu_context_key qmt_thread_key;
188
189 /* helper function to extract qmt_thread_info from current environment */
190 static inline
191 struct qmt_thread_info *qmt_info(const struct lu_env *env)
192 {
193         struct qmt_thread_info  *info;
194
195         info = lu_context_key_get(&env->le_ctx, &qmt_thread_key);
196         if (info == NULL) {
197                 lu_env_refill((struct lu_env *)env);
198                 info = lu_context_key_get(&env->le_ctx, &qmt_thread_key);
199         }
200         LASSERT(info);
201         return info;
202 }
203
204 /* helper routine to convert a lu_device into a qmt_device */
205 static inline struct qmt_device *lu2qmt_dev(struct lu_device *ld)
206 {
207         return container_of0(lu2dt_dev(ld), struct qmt_device, qmt_dt_dev);
208 }
209
210 /* helper routine to convert a qmt_device into lu_device */
211 static inline struct lu_device *qmt2lu_dev(struct qmt_device *qmt)
212 {
213         return &qmt->qmt_dt_dev.dd_lu_dev;
214 }
215
216 #define LQE_ROOT(lqe)    (lqe2qpi(lqe)->qpi_root)
217 #define LQE_GLB_OBJ(lqe) (lqe2qpi(lqe)->qpi_glb_obj[lqe->lqe_site->lqs_qtype])
218
219 /* helper function returning grace time to use for a given lquota entry */
220 static inline __u64 qmt_lqe_grace(struct lquota_entry *lqe)
221 {
222         struct qmt_pool_info    *pool = lqe2qpi(lqe);
223         struct lquota_entry     *grace_lqe;
224
225         grace_lqe = pool->qpi_grace_lqe[lqe->lqe_site->lqs_qtype];
226         LASSERT(grace_lqe != NULL);
227
228         return grace_lqe->lqe_gracetime;
229 }
230
231 static inline void qmt_restore(struct lquota_entry *lqe,
232                                struct qmt_lqe_restore *restore)
233 {
234         lqe->lqe_hardlimit = restore->qlr_hardlimit;
235         lqe->lqe_softlimit = restore->qlr_softlimit;
236         lqe->lqe_gracetime = restore->qlr_gracetime;
237         lqe->lqe_granted   = restore->qlr_granted;
238         lqe->lqe_qunit     = restore->qlr_qunit;
239 }
240
241 #define QMT_GRANT(lqe, slv, cnt)             \
242         do {                                 \
243                 (lqe)->lqe_granted += (cnt); \
244                 (slv) += (cnt);              \
245         } while (0)
246 #define QMT_REL(lqe, slv, cnt)               \
247         do {                                 \
248                 (lqe)->lqe_granted -= (cnt); \
249                 (slv) -= (cnt);              \
250         } while (0)
251
252 /* helper routine returning true when the id has run out of quota space, which
253  * means that it has either:
254  * - reached hardlimit
255  * OR
256  * - reached softlimit and grace time expired already */
257 static inline bool qmt_space_exhausted(struct lquota_entry *lqe, __u64 now)
258 {
259         if (lqe->lqe_hardlimit != 0 && lqe->lqe_granted >= lqe->lqe_hardlimit)
260                 return true;
261         if (lqe->lqe_softlimit != 0 && lqe->lqe_granted > lqe->lqe_softlimit &&
262             lqe->lqe_gracetime != 0 && now >= lqe->lqe_gracetime)
263                 return true;
264         return false;
265 }
266
267 /* number of seconds to wait for slaves to release quota space after
268  * rebalancing */
269 #define QMT_REBA_TIMEOUT 2
270
271 /* qmt_pool.c */
272 void qmt_pool_fini(const struct lu_env *, struct qmt_device *);
273 int qmt_pool_init(const struct lu_env *, struct qmt_device *);
274 int qmt_pool_prepare(const struct lu_env *, struct qmt_device *,
275                    struct dt_object *);
276 int qmt_pool_new_conn(const struct lu_env *, struct qmt_device *,
277                       struct lu_fid *, struct lu_fid *, __u64 *,
278                       struct obd_uuid *);
279 struct lquota_entry *qmt_pool_lqe_lookup(const struct lu_env *,
280                                          struct qmt_device *, int, int, int,
281                                          union lquota_id *);
282 /* qmt_entry.c */
283 extern struct lquota_entry_operations qmt_lqe_ops;
284 struct thandle *qmt_trans_start_with_slv(const struct lu_env *,
285                                          struct lquota_entry *,
286                                          struct dt_object *,
287                                          struct qmt_lqe_restore *);
288 struct thandle *qmt_trans_start(const struct lu_env *, struct lquota_entry *,
289                                 struct qmt_lqe_restore *);
290 int qmt_glb_write(const struct lu_env *, struct thandle *,
291                   struct lquota_entry *, __u32, __u64 *);
292 int qmt_slv_write(const struct lu_env *, struct thandle *,
293                   struct lquota_entry *, struct dt_object *, __u32, __u64 *,
294                   __u64);
295 int qmt_slv_read(const struct lu_env *, struct lquota_entry *,
296                  struct dt_object *, __u64 *);
297 int qmt_validate_limits(struct lquota_entry *, __u64, __u64);
298 void qmt_adjust_qunit(const struct lu_env *, struct lquota_entry *);
299 void qmt_adjust_edquot(struct lquota_entry *, __u64);
300 void qmt_revalidate(const struct lu_env *, struct lquota_entry *);
301 __u64 qmt_alloc_expand(struct lquota_entry *, __u64, __u64);
302
303 /* qmt_handler.c */
304 int qmt_dqacq0(const struct lu_env *, struct lquota_entry *,
305                struct qmt_device *, struct obd_uuid *, __u32, __u64, __u64,
306                struct quota_body *);
307
308 /* qmt_lock.c */
309 int qmt_intent_policy(const struct lu_env *, struct lu_device *,
310                       struct ptlrpc_request *, struct ldlm_lock **, int);
311 int qmt_lvbo_init(struct lu_device *, struct ldlm_resource *);
312 int qmt_lvbo_update(struct lu_device *, struct ldlm_resource *,
313                     struct ptlrpc_request *, int);
314 int qmt_lvbo_size(struct lu_device *, struct ldlm_lock *);
315 int qmt_lvbo_fill(struct lu_device *, struct ldlm_lock *, void *, int);
316 int qmt_lvbo_free(struct lu_device *, struct ldlm_resource *);
317 int qmt_start_reba_thread(struct qmt_device *);
318 void qmt_stop_reba_thread(struct qmt_device *);
319 void qmt_glb_lock_notify(const struct lu_env *, struct lquota_entry *, __u64);
320 void qmt_id_lock_notify(struct qmt_device *, struct lquota_entry *);
321 #endif /* _QMT_INTERNAL_H */