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