Whamcloud - gitweb
53b631253299733d209072c1c4a73358c48a9b6c
[fs/lustre-release.git] / lustre / include / lustre_quota.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, 2017, Intel Corporation.
25  * Use is subject to license terms.
26  */
27
28 #ifndef _LUSTRE_QUOTA_H
29 #define _LUSTRE_QUOTA_H
30
31 /** \defgroup quota quota
32  *
33  */
34
35 #include <linux/fs.h>
36 #include <linux/quota.h>
37 #include <linux/quotaops.h>
38 #include <linux/sort.h>
39 #include <dt_object.h>
40 #include <lustre_fid.h>
41 #include <lustre_dlm.h>
42
43 #ifndef MAX_IQ_TIME
44 #define MAX_IQ_TIME  604800     /* (7*24*60*60) 1 week */
45 #endif
46
47 #ifndef MAX_DQ_TIME
48 #define MAX_DQ_TIME  604800     /* (7*24*60*60) 1 week */
49 #endif
50
51 struct lquota_id_info;
52 struct lquota_trans;
53
54 /* Gather all quota record type in an union that can be used to read any records
55  * from disk. All fields of these records must be 64-bit aligned, otherwise the
56  * OSD layer may swab them incorrectly. */
57 union lquota_rec {
58         struct lquota_glb_rec   lqr_glb_rec;
59         struct lquota_slv_rec   lqr_slv_rec;
60         struct lquota_acct_rec  lqr_acct_rec;
61 };
62
63 /* flags for inode/block quota accounting */
64 enum osd_qid_declare_flags {
65         OSD_QID_INODE   = BIT(0),
66         OSD_QID_BLK     = BIT(1),
67         OSD_QID_FORCE   = BIT(2),
68 };
69
70 /* Index features supported by the global index objects
71  * Only used for migration purpose and should be removed once on-disk migration
72  * is no longer needed */
73 extern struct dt_index_features dt_quota_iusr_features;
74 extern struct dt_index_features dt_quota_busr_features;
75 extern struct dt_index_features dt_quota_igrp_features;
76 extern struct dt_index_features dt_quota_bgrp_features;
77
78 /* Name used in the configuration logs to identify the default metadata pool
79  * (composed of all the MDTs, with pool ID 0) and the default data pool (all
80  * the OSTs, with pool ID 0 too). */
81 #define QUOTA_METAPOOL_NAME   "mdt="
82 #define QUOTA_DATAPOOL_NAME   "ost="
83
84 /*
85  * Quota Master Target support
86  */
87
88 /* Request handlers for quota master operations.
89  * This is used by the MDT to pass quota/lock requests to the quota master
90  * target. This won't be needed any more once the QMT is a real target and
91  * does not rely any more on the MDT service threads and namespace. */
92 struct qmt_handlers {
93         /* Handle quotactl request from client. */
94         int (*qmth_quotactl)(const struct lu_env *, struct lu_device *,
95                              struct obd_quotactl *);
96
97         /* Handle dqacq/dqrel request from slave. */
98         int (*qmth_dqacq)(const struct lu_env *, struct lu_device *,
99                           struct ptlrpc_request *);
100
101         /* LDLM intent policy associated with quota locks */
102         int (*qmth_intent_policy)(const struct lu_env *, struct lu_device *,
103                                   struct ptlrpc_request *, struct ldlm_lock **,
104                                   int);
105
106         /* Initialize LVB of ldlm resource associated with quota objects */
107         int (*qmth_lvbo_init)(struct lu_device *, struct ldlm_resource *);
108
109         /* Update LVB of ldlm resource associated with quota objects */
110         int (*qmth_lvbo_update)(struct lu_device *, struct ldlm_resource *,
111                                 struct ptlrpc_request *, int);
112
113         /* Return size of LVB to be packed in ldlm message */
114         int (*qmth_lvbo_size)(struct lu_device *, struct ldlm_lock *);
115
116         /* Fill request buffer with lvb */
117         int (*qmth_lvbo_fill)(struct lu_device *, struct ldlm_lock *, void *,
118                               int);
119
120         /* Free lvb associated with ldlm resource */
121         int (*qmth_lvbo_free)(struct lu_device *, struct ldlm_resource *);
122 };
123
124 /* actual handlers are defined in lustre/quota/qmt_handler.c */
125 extern struct qmt_handlers qmt_hdls;
126
127 /*
128  * Quota enforcement support on slaves
129  */
130
131 struct qsd_instance;
132
133 /* The quota slave feature is implemented under the form of a library.
134  * The API is the following:
135  *
136  * - qsd_init(): the user (mostly the OSD layer) should first allocate a qsd
137  *               instance via qsd_init(). This creates all required structures
138  *               to manage quota enforcement for this target and performs all
139  *               low-level initialization which does not involve any lustre
140  *               object. qsd_init() should typically be called when the OSD
141  *               is being set up.
142  *
143  * - qsd_prepare(): This sets up on-disk objects associated with the quota slave
144  *                  feature and initiates the quota reintegration procedure if
145  *                  needed. qsd_prepare() should typically be called when
146  *                  ->ldo_prepare is invoked.
147  *
148  * - qsd_start(): a qsd instance should be started once recovery is completed
149  *                (i.e. when ->ldo_recovery_complete is called). This is used
150  *                to notify the qsd layer that quota should now be enforced
151  *                again via the qsd_op_begin/end functions. The last step of the
152  *                reintegration prodecure (namely usage reconciliation) will be
153  *                completed during start.
154  *
155  * - qsd_fini(): is used to release a qsd_instance structure allocated with
156  *               qsd_init(). This releases all quota slave objects and frees the
157  *               structures associated with the qsd_instance.
158  *
159  * - qsd_op_begin(): is used to enforce quota, it must be called in the
160  *                   declaration of each operation. qsd_op_end() should then be
161  *                   invoked later once all operations have been completed in
162  *                   order to release/adjust the quota space.
163  *                   Running qsd_op_begin() before qsd_start() isn't fatal and
164  *                   will return success.
165  *                   Once qsd_start() has been run, qsd_op_begin() will block
166  *                   until the reintegration procedure is completed.
167  *
168  * - qsd_op_end(): performs the post operation quota processing. This must be
169  *                 called after the operation transaction stopped.
170  *                 While qsd_op_begin() must be invoked each time a new
171  *                 operation is declared, qsd_op_end() should be called only
172  *                 once for the whole transaction.
173  *
174  * - qsd_op_adjust(): triggers pre-acquire/release if necessary.
175  *
176  * Below are the function prototypes to be used by OSD layer to manage quota
177  * enforcement. Arguments are documented where each function is defined.  */
178
179 /* flags for quota local enforcement */
180 enum osd_quota_local_flags {
181         QUOTA_FL_OVER_USRQUOTA  = BIT(0),
182         QUOTA_FL_OVER_GRPQUOTA  = BIT(1),
183         QUOTA_FL_SYNC           = BIT(2),
184         QUOTA_FL_OVER_PRJQUOTA  = BIT(3),
185 };
186
187 struct qsd_instance *qsd_init(const struct lu_env *, char *, struct dt_device *,
188                               struct proc_dir_entry *, bool is_md);
189 int qsd_prepare(const struct lu_env *, struct qsd_instance *);
190 int qsd_start(const struct lu_env *, struct qsd_instance *);
191 void qsd_fini(const struct lu_env *, struct qsd_instance *);
192 int qsd_op_begin(const struct lu_env *, struct qsd_instance *,
193                  struct lquota_trans *, struct lquota_id_info *,
194                  enum osd_quota_local_flags *);
195 void qsd_op_end(const struct lu_env *, struct qsd_instance *,
196                 struct lquota_trans *);
197 void qsd_op_adjust(const struct lu_env *, struct qsd_instance *,
198                    union lquota_id *, int);
199 int qsd_reserve_or_free_quota(const struct lu_env *env,
200                               struct qsd_instance *qsd,
201                               struct lquota_id_info *qi);
202
203 /*
204  * Quota information attached to a transaction
205  */
206
207 struct lquota_entry;
208
209 struct lquota_id_info {
210         /* quota identifier */
211         union lquota_id          lqi_id;
212
213         /* USRQUOTA or GRPQUOTA for now, could be expanded for
214          * directory quota or other types later.  */
215         int                      lqi_type;
216
217         /* inodes or kbytes to be consumed or released, it could
218          * be negative when releasing space.  */
219         long long                lqi_space;
220
221         /* quota slave entry structure associated with this ID */
222         struct lquota_entry     *lqi_qentry;
223
224         /* whether we are reporting blocks or inodes */
225         bool                     lqi_is_blk;
226 };
227
228 /* With the DoM, both inode quota in meta pool and block quota in data pool
229  * will be enforced at MDT, there are at most 4 quota ids being enforced in
230  * a single transaction for inode and block quota, which is chown transaction:
231  * original uid and gid, new uid and gid.
232  *
233  * This value might need to be revised when directory quota is added.  */
234 #define QUOTA_MAX_TRANSIDS    8
235
236 /* all qids involved in a single transaction */
237 struct lquota_trans {
238         unsigned short          lqt_id_cnt;
239         struct lquota_id_info   lqt_ids[QUOTA_MAX_TRANSIDS];
240 };
241
242 #define IS_LQUOTA_RES(res)                                              \
243         (res->lr_name.name[LUSTRE_RES_ID_SEQ_OFF] == FID_SEQ_QUOTA ||   \
244          res->lr_name.name[LUSTRE_RES_ID_SEQ_OFF] == FID_SEQ_QUOTA_GLB)
245
246 /* helper function used by MDT & OFD to retrieve quota accounting information
247  * on slave */
248 int lquotactl_slv(const struct lu_env *, struct dt_device *,
249                   struct obd_quotactl *);
250
251 static inline int quota_reserve_or_free(const struct lu_env *env,
252                                         struct qsd_instance *qsd,
253                                         struct lquota_id_info *qi,
254                                         enum quota_type type, __u64 uid,
255                                         __u64 gid, __s64 count, bool is_md)
256 {
257         qi->lqi_type = type;
258         if (count > 0)
259                 qi->lqi_space = toqb(count);
260         else
261                 qi->lqi_space = -toqb(-count);
262
263         if (is_md)
264                 qi->lqi_is_blk = false;
265         else
266                 qi->lqi_is_blk = true;
267
268         qi->lqi_id.qid_uid = uid;
269         qi->lqi_id.qid_gid = gid;
270
271         return qsd_reserve_or_free_quota(env, qsd, qi);
272 }
273
274 /** @} quota */
275 #endif /* _LUSTRE_QUOTA_H */