4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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.
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).
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
24 * Copyright (c) 2012, 2017, Intel Corporation.
25 * Use is subject to license terms.
28 #ifndef _LUSTRE_QUOTA_H
29 #define _LUSTRE_QUOTA_H
31 /** \defgroup quota quota
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>
44 #define MAX_IQ_TIME 604800 /* (7*24*60*60) 1 week */
48 #define MAX_DQ_TIME 604800 /* (7*24*60*60) 1 week */
51 struct lquota_id_info;
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. */
58 struct lquota_glb_rec lqr_glb_rec;
59 struct lquota_slv_rec lqr_slv_rec;
60 struct lquota_acct_rec lqr_acct_rec;
63 /* flags for inode/block quota accounting */
64 enum osd_qid_declare_flags {
65 OSD_QID_INODE = BIT(0),
67 OSD_QID_FORCE = BIT(2),
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;
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="
85 * Quota Master Target support
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. */
93 /* Handle quotactl request from client. */
94 int (*qmth_quotactl)(const struct lu_env *, struct lu_device *,
95 struct obd_quotactl *);
97 /* Handle dqacq/dqrel request from slave. */
98 int (*qmth_dqacq)(const struct lu_env *, struct lu_device *,
99 struct ptlrpc_request *);
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 **,
106 /* Initialize LVB of ldlm resource associated with quota objects */
107 int (*qmth_lvbo_init)(struct lu_device *, struct ldlm_resource *);
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);
113 /* Return size of LVB to be packed in ldlm message */
114 int (*qmth_lvbo_size)(struct lu_device *, struct ldlm_lock *);
116 /* Fill request buffer with lvb */
117 int (*qmth_lvbo_fill)(struct lu_device *, struct ldlm_lock *, void *,
120 /* Free lvb associated with ldlm resource */
121 int (*qmth_lvbo_free)(struct lu_device *, struct ldlm_resource *);
124 /* actual handlers are defined in lustre/quota/qmt_handler.c */
125 extern struct qmt_handlers qmt_hdls;
128 * Quota enforcement support on slaves
133 /* The quota slave feature is implemented under the form of a library.
134 * The API is the following:
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
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.
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.
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.
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.
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.
174 * - qsd_op_adjust(): triggers pre-acquire/release if necessary.
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. */
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),
187 struct qsd_instance *qsd_init(const struct lu_env *, char *, struct dt_device *,
188 struct proc_dir_entry *, bool is_md, bool excl);
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_transfer(const struct lu_env *env, struct qsd_instance *qsd,
200 struct lquota_trans *trans, unsigned int qtype,
201 u64 orig_id, u64 new_id, u64 bspace,
202 struct lquota_id_info *qi);
203 int qsd_reserve_or_free_quota(const struct lu_env *env,
204 struct qsd_instance *qsd,
205 struct lquota_id_info *qi);
208 * Quota information attached to a transaction
213 struct lquota_id_info {
214 /* quota identifier */
215 union lquota_id lqi_id;
217 /* USRQUOTA or GRPQUOTA for now, could be expanded for
218 * directory quota or other types later. */
221 /* inodes or kbytes to be consumed or released, it could
222 * be negative when releasing space. */
225 /* quota slave entry structure associated with this ID */
226 struct lquota_entry *lqi_qentry;
228 /* whether we are reporting blocks or inodes */
232 /* With the DoM, both inode quota in meta pool and block quota in data pool
233 * will be enforced at MDT, there are at most 4 quota ids being enforced in
234 * a single transaction for inode and block quota, which is chown transaction:
235 * original uid and gid, new uid and gid.
237 * This value might need to be revised when directory quota is added. */
238 #define QUOTA_MAX_TRANSIDS 8
240 /* all qids involved in a single transaction */
241 struct lquota_trans {
242 unsigned short lqt_id_cnt;
243 struct lquota_id_info lqt_ids[QUOTA_MAX_TRANSIDS];
246 #define IS_LQUOTA_RES(res) \
247 (res->lr_name.name[LUSTRE_RES_ID_SEQ_OFF] == FID_SEQ_QUOTA || \
248 res->lr_name.name[LUSTRE_RES_ID_SEQ_OFF] == FID_SEQ_QUOTA_GLB)
250 /* helper function used by MDT & OFD to retrieve quota accounting information
252 int lquotactl_slv(const struct lu_env *, struct dt_device *,
253 struct obd_quotactl *);
255 static inline int quota_reserve_or_free(const struct lu_env *env,
256 struct qsd_instance *qsd,
257 struct lquota_id_info *qi,
258 enum quota_type type, __u64 uid,
259 __u64 gid, __s64 count, bool is_md)
263 qi->lqi_space = toqb(count);
265 qi->lqi_space = -toqb(-count);
268 qi->lqi_is_blk = false;
270 qi->lqi_is_blk = true;
272 qi->lqi_id.qid_uid = uid;
273 qi->lqi_id.qid_gid = gid;
275 return qsd_reserve_or_free_quota(env, qsd, qi);
279 #endif /* _LUSTRE_QUOTA_H */