Whamcloud - gitweb
LU-1842 quota: add quotactl support on qmt
[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, Inc.
25  * Use is subject to license terms.
26  */
27
28 #include "lquota_internal.h"
29
30 #ifndef _QMT_INTERNAL_H
31 #define _QMT_INTERNAL_H
32
33 /*
34  * The Quota Master Target Device.
35  * The qmt is responsible for:
36  * - all interactions with MDT0 (provide request handlers, share ldlm namespace,
37  *   manage ldlm lvbo, ...)
38  * - all quota lock management (i.e. global quota locks as well as per-ID locks)
39  * - manage the quota pool configuration
40  *
41  * That's the structure MDT0 connects to in mdt_quota_init().
42  */
43 struct qmt_device {
44         /* Super-class. dt_device/lu_device for this master target */
45         struct dt_device        qmt_dt_dev;
46
47         /* service name of this qmt */
48         char                    qmt_svname[MAX_OBD_NAME];
49
50         /* Reference to the next device in the side stack
51          * The child device is actually the OSD device where we store the quota
52          * index files */
53         struct obd_export       *qmt_child_exp;
54         struct dt_device        *qmt_child;
55
56         /* pointer to ldlm namespace to be used for quota locks */
57         struct ldlm_namespace   *qmt_ns;
58
59         /* Hash table containing a qmt_pool_info structure for each pool
60          * this quota master is in charge of. We only have 2 pools in this
61          * hash for the time being:
62          * - one for quota management on the default metadata pool
63          * - one for quota managment on the default data pool
64          *
65          * Once we support quota on non-default pools, then more pools will
66          * be added to this hash table and pool master setup would have to be
67          * handled via configuration logs */
68         cfs_hash_t              *qmt_pool_hash;
69
70         /* List of pools managed by this master target */
71         cfs_list_t               qmt_pool_list;
72
73         /* procfs root directory for this qmt */
74         cfs_proc_dir_entry_t    *qmt_proc;
75
76         unsigned long            qmt_stopping:1; /* qmt is stopping */
77
78 };
79
80 /*
81  * Per-pool quota information.
82  * The qmt creates one such structure for each pool
83  * with quota enforced. All the structures are kept in a hash which is used to
84  * determine whether or not quota is enforced for a given pool.
85  * We currently only support the default data pool and default metadata pool
86  * with the pool_id 0.
87  */
88 struct qmt_pool_info {
89         /* link to qmt's pool hash */
90         cfs_hlist_node_t         qpi_hash;
91
92         /* chained list of all pools managed by the same qmt */
93         cfs_list_t               qpi_linkage;
94
95         /* Pool key composed of pool_id | (pool_type << 16)
96          * Only pool ID 0 is supported for now and the pool type is either
97          * QUOTA_RES_MD or QUOTA_RES_DT.
98          * immutable after creation. */
99         __u32                    qpi_key;
100
101         /* track users of this pool instance */
102         cfs_atomic_t             qpi_ref;
103
104         /* back pointer to master target
105          * immutable after creation. */
106         struct qmt_device       *qpi_qmt;
107
108         /* pointer to dt object associated with global indexes for both user
109          * and group quota */
110         struct dt_object        *qpi_glb_obj[MAXQUOTAS];
111
112         /* A pool supports two different quota types: user and group quota.
113          * Each quota type has its own global index and lquota_entry hash table.
114          */
115         struct lquota_site      *qpi_site[MAXQUOTAS];
116
117         /* number of slaves registered for each quota types */
118         int                      qpi_slv_nr[MAXQUOTAS];
119
120         /* procfs root directory for this pool */
121         cfs_proc_dir_entry_t    *qpi_proc;
122
123         /* pool directory where all indexes related to this pool instance are
124          * stored */
125         struct dt_object        *qpi_root;
126
127         /* Global quota parameters which apply to all quota type */
128         /* the least value of qunit */
129         unsigned long            qpi_least_qunit;
130 };
131
132 /*
133  * Helper routines and prototypes
134  */
135
136 /* helper routine to find qmt_pool_info associated a lquota_entry */
137 static inline struct qmt_pool_info *lqe2qpi(struct lquota_entry *lqe)
138 {
139         LASSERT(lqe_is_master(lqe));
140         return (struct qmt_pool_info *)lqe->lqe_site->lqs_parent;
141 }
142
143 /* return true if someone holds either a read or write lock on the lqe */
144 static inline bool lqe_is_locked(struct lquota_entry *lqe)
145 {
146         LASSERT(lqe_is_master(lqe));
147         if (cfs_down_write_trylock(&lqe->lqe_sem) == 0)
148                 return true;
149         lqe_write_unlock(lqe);
150         return false;
151 }
152
153 /* value to be restored if someone wrong happens during lqe writeback */
154 struct qmt_lqe_restore {
155         __u64   qlr_hardlimit;
156         __u64   qlr_softlimit;
157         __u64   qlr_gracetime;
158         __u64   qlr_granted;
159         __u64   qlr_qunit;
160 };
161
162 /* Common data shared by qmt handlers */
163 struct qmt_thread_info {
164         union lquota_rec        qti_rec;
165         union lquota_id         qti_id;
166         union lquota_id         qti_id_bis;
167         char                    qti_buf[MTI_NAME_MAXLEN];
168         struct lu_fid           qti_fid;
169         struct ldlm_res_id      qti_resid;
170         union ldlm_gl_desc      qti_gl_desc;
171         struct quota_body       qti_body;
172         struct quota_body       qti_repbody;
173         struct qmt_lqe_restore  qti_restore;
174 };
175
176 extern struct lu_context_key qmt_thread_key;
177
178 /* helper function to extract qmt_thread_info from current environment */
179 static inline
180 struct qmt_thread_info *qmt_info(const struct lu_env *env)
181 {
182         struct qmt_thread_info  *info;
183
184         info = lu_context_key_get(&env->le_ctx, &qmt_thread_key);
185         if (info == NULL) {
186                 lu_env_refill((struct lu_env *)env);
187                 info = lu_context_key_get(&env->le_ctx, &qmt_thread_key);
188         }
189         LASSERT(info);
190         return info;
191 }
192
193 /* helper routine to convert a lu_device into a qmt_device */
194 static inline struct qmt_device *lu2qmt_dev(struct lu_device *ld)
195 {
196         return container_of0(lu2dt_dev(ld), struct qmt_device, qmt_dt_dev);
197 }
198
199 /* helper routine to convert a qmt_device into lu_device */
200 static inline struct lu_device *qmt2lu_dev(struct qmt_device *qmt)
201 {
202         return &qmt->qmt_dt_dev.dd_lu_dev;
203 }
204
205 #define LQE_ROOT(lqe)    (lqe2qpi(lqe)->qpi_root)
206 #define LQE_GLB_OBJ(lqe) (lqe2qpi(lqe)->qpi_glb_obj[lqe->lqe_site->lqs_qtype])
207
208 static inline void qmt_restore(struct lquota_entry *lqe,
209                                struct qmt_lqe_restore *restore)
210 {
211         lqe->lqe_hardlimit = restore->qlr_hardlimit;
212         lqe->lqe_softlimit = restore->qlr_softlimit;
213         lqe->lqe_gracetime = restore->qlr_gracetime;
214         lqe->lqe_granted   = restore->qlr_granted;
215         lqe->lqe_qunit     = restore->qlr_qunit;
216 }
217
218 /* qmt_pool.c */
219 void qmt_pool_fini(const struct lu_env *, struct qmt_device *);
220 int qmt_pool_init(const struct lu_env *, struct qmt_device *);
221 int qmt_pool_prepare(const struct lu_env *, struct qmt_device *,
222                    struct dt_object *);
223 int qmt_pool_new_conn(const struct lu_env *, struct qmt_device *,
224                       struct lu_fid *, struct lu_fid *, __u64 *,
225                       struct obd_uuid *);
226 struct lquota_entry *qmt_pool_lqe_lookup(const struct lu_env *,
227                                          struct qmt_device *, int, int, int,
228                                          union lquota_id *);
229 /* qmt_entry.c */
230 extern struct lquota_entry_operations qmt_lqe_ops;
231 struct thandle *qmt_trans_start_with_slv(const struct lu_env *,
232                                          struct lquota_entry *,
233                                          struct dt_object *,
234                                          struct qmt_lqe_restore *);
235 struct thandle *qmt_trans_start(const struct lu_env *, struct lquota_entry *,
236                                 struct qmt_lqe_restore *);
237 int qmt_glb_write(const struct lu_env *, struct thandle *,
238                   struct lquota_entry *, __u32, __u64 *);
239 int qmt_slv_write(const struct lu_env *, struct thandle *,
240                   struct lquota_entry *, struct dt_object *, __u32, __u64 *,
241                   __u64);
242 int qmt_slv_read(const struct lu_env *, struct lquota_entry *,
243                  struct dt_object *, __u64 *);
244 int qmt_validate_limits(struct lquota_entry *, __u64, __u64);
245
246 /* qmt_lock.c */
247 int qmt_intent_policy(const struct lu_env *, struct lu_device *,
248                       struct ptlrpc_request *, struct ldlm_lock **, int);
249 int qmt_lvbo_init(struct lu_device *, struct ldlm_resource *);
250 int qmt_lvbo_update(struct lu_device *, struct ldlm_resource *,
251                     struct ptlrpc_request *, int);
252 int qmt_lvbo_size(struct lu_device *, struct ldlm_lock *);
253 int qmt_lvbo_fill(struct lu_device *, struct ldlm_lock *, void *, int);
254 int qmt_lvbo_free(struct lu_device *, struct ldlm_resource *);
255 #endif /* _QMT_INTERNAL_H */