[go: nahoru, domu]

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) 2011, 2012, 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
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
51struct lquota_id_info;
52struct 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. */
57union 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/* Index features supported by the global index objects
64 * Only used for migration purpose and should be removed once on-disk migration
65 * is no longer needed */
66extern struct dt_index_features dt_quota_iusr_features;
67extern struct dt_index_features dt_quota_busr_features;
68extern struct dt_index_features dt_quota_igrp_features;
69extern struct dt_index_features dt_quota_bgrp_features;
70
71/* Name used in the configuration logs to identify the default metadata pool
72 * (composed of all the MDTs, with pool ID 0) and the default data pool (all
73 * the OSTs, with pool ID 0 too). */
74#define QUOTA_METAPOOL_NAME   "mdt="
75#define QUOTA_DATAPOOL_NAME   "ost="
76
77/*
78 * Quota Master Target support
79 */
80
81/* Request handlers for quota master operations.
82 * This is used by the MDT to pass quota/lock requests to the quota master
83 * target. This won't be needed any more once the QMT is a real target and
84 * does not rely any more on the MDT service threads and namespace. */
85struct qmt_handlers {
86	/* Handle quotactl request from client. */
87	int (*qmth_quotactl)(const struct lu_env *, struct lu_device *,
88			     struct obd_quotactl *);
89
90	/* Handle dqacq/dqrel request from slave. */
91	int (*qmth_dqacq)(const struct lu_env *, struct lu_device *,
92			  struct ptlrpc_request *);
93
94	/* LDLM intent policy associated with quota locks */
95	int (*qmth_intent_policy)(const struct lu_env *, struct lu_device *,
96				  struct ptlrpc_request *, struct ldlm_lock **,
97				  int);
98
99	/* Initialize LVB of ldlm resource associated with quota objects */
100	int (*qmth_lvbo_init)(struct lu_device *, struct ldlm_resource *);
101
102	/* Update LVB of ldlm resource associated with quota objects */
103	int (*qmth_lvbo_update)(struct lu_device *, struct ldlm_resource *,
104				struct ptlrpc_request *, int);
105
106	/* Return size of LVB to be packed in ldlm message */
107	int (*qmth_lvbo_size)(struct lu_device *, struct ldlm_lock *);
108
109	/* Fill request buffer with lvb */
110	int (*qmth_lvbo_fill)(struct lu_device *, struct ldlm_lock *, void *,
111			      int);
112
113	/* Free lvb associated with ldlm resource */
114	int (*qmth_lvbo_free)(struct lu_device *, struct ldlm_resource *);
115};
116
117/* actual handlers are defined in lustre/quota/qmt_handler.c */
118extern struct qmt_handlers qmt_hdls;
119
120/*
121 * Quota enforcement support on slaves
122 */
123
124struct qsd_instance;
125
126/* The quota slave feature is implemented under the form of a library.
127 * The API is the following:
128 *
129 * - qsd_init(): the user (mostly the OSD layer) should first allocate a qsd
130 *	       instance via qsd_init(). This creates all required structures
131 *	       to manage quota enforcement for this target and performs all
132 *	       low-level initialization which does not involve any lustre
133 *	       object. qsd_init() should typically be called when the OSD
134 *	       is being set up.
135 *
136 * - qsd_prepare(): This sets up on-disk objects associated with the quota slave
137 *		  feature and initiates the quota reintegration procedure if
138 *		  needed. qsd_prepare() should typically be called when
139 *		  ->ldo_prepare is invoked.
140 *
141 * - qsd_start(): a qsd instance should be started once recovery is completed
142 *		(i.e. when ->ldo_recovery_complete is called). This is used
143 *		to notify the qsd layer that quota should now be enforced
144 *		again via the qsd_op_begin/end functions. The last step of the
145 *		reintegration procedure (namely usage reconciliation) will be
146 *		completed during start.
147 *
148 * - qsd_fini(): is used to release a qsd_instance structure allocated with
149 *	       qsd_init(). This releases all quota slave objects and frees the
150 *	       structures associated with the qsd_instance.
151 *
152 * - qsd_op_begin(): is used to enforce quota, it must be called in the
153 *		   declaration of each operation. qsd_op_end() should then be
154 *		   invoked later once all operations have been completed in
155 *		   order to release/adjust the quota space.
156 *		   Running qsd_op_begin() before qsd_start() isn't fatal and
157 *		   will return success.
158 *		   Once qsd_start() has been run, qsd_op_begin() will block
159 *		   until the reintegration procedure is completed.
160 *
161 * - qsd_op_end(): performs the post operation quota processing. This must be
162 *		 called after the operation transaction stopped.
163 *		 While qsd_op_begin() must be invoked each time a new
164 *		 operation is declared, qsd_op_end() should be called only
165 *		 once for the whole transaction.
166 *
167 * - qsd_op_adjust(): triggers pre-acquire/release if necessary.
168 *
169 * Below are the function prototypes to be used by OSD layer to manage quota
170 * enforcement. Arguments are documented where each function is defined.  */
171
172struct qsd_instance *qsd_init(const struct lu_env *, char *, struct dt_device *,
173			      struct proc_dir_entry *);
174int qsd_prepare(const struct lu_env *, struct qsd_instance *);
175int qsd_start(const struct lu_env *, struct qsd_instance *);
176void qsd_fini(const struct lu_env *, struct qsd_instance *);
177int qsd_op_begin(const struct lu_env *, struct qsd_instance *,
178		 struct lquota_trans *, struct lquota_id_info *, int *);
179void qsd_op_end(const struct lu_env *, struct qsd_instance *,
180		struct lquota_trans *);
181void qsd_op_adjust(const struct lu_env *, struct qsd_instance *,
182		   union lquota_id *, int);
183/* This is exported for the ldiskfs quota migration only,
184 * see convert_quota_file() */
185int lquota_disk_write_glb(const struct lu_env *, struct dt_object *,
186			  __u64, struct lquota_glb_rec *);
187
188/*
189 * Quota information attached to a transaction
190 */
191
192struct lquota_entry;
193
194struct lquota_id_info {
195	/* quota identifier */
196	union lquota_id		 lqi_id;
197
198	/* USRQUOTA or GRPQUOTA for now, could be expanded for
199	 * directory quota or other types later.  */
200	int			 lqi_type;
201
202	/* inodes or kbytes to be consumed or released, it could
203	 * be negative when releasing space.  */
204	long long		 lqi_space;
205
206	/* quota slave entry structure associated with this ID */
207	struct lquota_entry	*lqi_qentry;
208
209	/* whether we are reporting blocks or inodes */
210	bool			 lqi_is_blk;
211};
212
213/* Since we enforce only inode quota in meta pool (MDTs), and block quota in
214 * data pool (OSTs), there are at most 4 quota ids being enforced in a single
215 * transaction, which is chown transaction:
216 * original uid and gid, new uid and gid.
217 *
218 * This value might need to be revised when directory quota is added.  */
219#define QUOTA_MAX_TRANSIDS    4
220
221/* all qids involved in a single transaction */
222struct lquota_trans {
223	unsigned short		lqt_id_cnt;
224	struct lquota_id_info	lqt_ids[QUOTA_MAX_TRANSIDS];
225};
226
227/* flags for quota local enforcement */
228#define QUOTA_FL_OVER_USRQUOTA  0x01
229#define QUOTA_FL_OVER_GRPQUOTA  0x02
230#define QUOTA_FL_SYNC	   0x04
231
232#define IS_LQUOTA_RES(res)						\
233	(res->lr_name.name[LUSTRE_RES_ID_SEQ_OFF] == FID_SEQ_QUOTA ||	\
234	 res->lr_name.name[LUSTRE_RES_ID_SEQ_OFF] == FID_SEQ_QUOTA_GLB)
235
236/* helper function used by MDT & OFD to retrieve quota accounting information
237 * on slave */
238int lquotactl_slv(const struct lu_env *, struct dt_device *,
239		  struct obd_quotactl *);
240/** @} quota */
241#endif /* _LUSTRE_QUOTA_H */
242