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.
29 #include <dt_object.h>
30 #include <lustre_quota.h>
32 #ifndef _LQUOTA_INTERNAL_H
33 #define _LQUOTA_INTERNAL_H
35 #define RES_NAME(res) ((res) == LQUOTA_RES_MD ? "md" : "dt")
37 #define QIF_IFLAGS (QIF_INODES | QIF_ITIME | QIF_ILIMITS)
38 #define QIF_BFLAGS (QIF_SPACE | QIF_BTIME | QIF_BLIMITS)
40 /* The biggest filename are the one used for slave index which are in the form
41 * of 0x%x-%s,glb_fid.f_oid,slv_uuid, that's to say:
42 * 2(0x) + 8(f_oid) + 1(-) + 40(UUID_MAX) which means 51 chars + '\0' */
43 #define LQUOTA_NAME_MAX 52
45 /* reserved OID in FID_SEQ_QUOTA for local objects */
46 enum lquota_local_oid {
47 LQUOTA_USR_OID = 1UL, /* slave index copy for user quota */
48 LQUOTA_GRP_OID = 2UL, /* slave index copy for group quota */
49 LQUOTA_PRJ_OID = 3UL, /* slave index copy for project quota */
50 /* all OIDs after this are allocated dynamically by the QMT */
51 LQUOTA_GENERATED_OID = 4096UL,
54 static inline __u32 qtype2slv_oid(int qtype)
58 return LQUOTA_USR_OID;
60 return LQUOTA_GRP_OID;
62 return LQUOTA_PRJ_OID;
65 /* should not come here, just make compile happy */
66 return LQUOTA_USR_OID;
70 * lquota_entry support
73 /* Common operations supported by a lquota_entry */
74 struct lquota_entry_operations {
75 /* Initialize specific fields of a lquota entry */
76 void (*lqe_init)(struct lquota_entry *, void *arg);
78 /* Read quota settings from disk and update lquota entry */
79 int (*lqe_read)(const struct lu_env *, struct lquota_entry *,
80 void *arg, bool find);
82 /* Print debug information about a given lquota entry */
83 void (*lqe_debug)(struct lquota_entry *, void *,
84 struct libcfs_debug_msg_data *,
85 struct va_format *vaf);
88 /* Per-ID information specific to the quota master target */
89 struct lquota_mst_entry {
90 /* global hard limit, in inodes or kbytes */
93 /* global quota soft limit, in inodes or kbytes */
96 /* grace time, in seconds */
99 /* last time we glimpsed */
100 time64_t lme_revoke_time;
102 /* r/w semaphore used to protect concurrent access to the quota
103 * parameters which are stored on disk */
104 struct rw_semaphore lme_sem;
106 /* quota space that may be released after glimpse */
110 /* Per-ID information specific to the quota slave */
111 struct lquota_slv_entry {
112 /* [ib]tune size, inodes or kbytes */
115 /* per-ID lock handle */
116 struct lustre_handle lse_lockh;
118 /* pending write which were granted quota space but haven't completed
119 * yet, in inodes or kbytes. */
120 __u64 lse_pending_write;
122 /* writes waiting for quota space, in inodes or kbytes. */
123 __u64 lse_waiting_write;
125 /* pending release, in inodes or kbytes */
126 __u64 lse_pending_rel;
128 /* pending dqacq/dqrel requests. */
129 unsigned int lse_pending_req;
131 /* rw spinlock protecting in-memory counters (i.e. lse_pending*) */
134 /* waiter for pending request done */
135 wait_queue_head_t lse_waiters;
137 /* hint on current on-disk usage, in inodes or kbytes */
140 /* time to trigger quota adjust */
141 time64_t lse_adjust_time;
143 /* return code of latest acquire RPC */
146 /* when latest acquire RPC completed */
147 time64_t lse_acq_time;
149 /* when latest edquot set */
150 time64_t lse_edquot_time;
153 /* In-memory entry for each enforced quota id
154 * A lquota_entry structure belong to a single lquota_site */
155 struct lquota_entry {
156 /* link to site hash table */
157 struct hlist_node lqe_hash;
159 /* quota identifier associated with this entry */
160 union lquota_id lqe_id;
162 /* site this quota entry belongs to */
163 struct lquota_site *lqe_site;
165 /* reference counter */
168 /* linked to list of lqes which:
169 * - need quota space adjustment on slave
170 * - need glimpse to be sent on master */
171 struct list_head lqe_link;
173 /* current quota settings/usage of this ID */
174 __u64 lqe_granted; /* granted limit, inodes or kbytes */
175 /* used in quota pool recalc process (only on QMT) */
176 __u64 lqe_recalc_granted;
177 __u64 lqe_qunit; /* [ib]unit size, inodes or kbytes */
179 struct lquota_mst_entry me; /* params specific to QMT */
180 struct lquota_slv_entry se; /* params specific to QSD */
183 /* flags describing the state of the lquota_entry */
184 unsigned long lqe_enforced:1, /* quota enforced or not */
185 lqe_uptodate:1, /* successfully read from disk */
186 lqe_edquot:1, /* id out of quota space on QMT */
187 lqe_gl:1, /* glimpse is in progress */
188 lqe_nopreacq:1, /* pre-acquire disabled */
189 lqe_is_default:1, /* the default quota is used */
190 lqe_is_global:1, /* lqe belongs to global pool "0x0"*/
191 lqe_is_deleted:1, /* lqe will be deleted soon */
192 lqe_is_reset:1, /* lqe has been reset */
193 lqe_revoke:1; /* all extra grant will be revoked */
195 /* the lock to protect lqe_glbl_data */
196 struct mutex lqe_glbl_data_lock;
197 struct lqe_glbl_data *lqe_glbl_data;
200 #define lqe_qtype(lqe) (lqe->lqe_site->lqs_qtype)
201 #define lqe_rtype(lqe) (lqe2qpi(lqe)->qpi_rtype)
203 struct lqe_glbl_entry {
205 unsigned long lge_idx:16,
206 /* index of target */
208 /* true when minimum qunit is set */
210 /* qunit or edquot is changed - need
211 * to send glimpse to appropriate slave */
216 struct lqe_glbl_data {
217 struct lqe_glbl_entry *lqeg_arr;
218 /* number of initialised entries */
220 /* number of allocated entries */
224 /* Compartment within which lquota_entry are unique.
225 * lquota_entry structures are kept in a hash table and read from disk if not
228 /* Hash table storing lquota_entry structures */
229 struct cfs_hash *lqs_hash;
231 /* Quota type, either user or group. */
234 /* Record whether this site is for a QMT or a slave */
237 /* Vector of operations which can be done on lquota entry belonging to
239 const struct lquota_entry_operations *lqs_ops;
241 /* Backpointer to parent structure, either QMT pool info for master or
246 #define lqe_hardlimit u.me.lme_hardlimit
247 #define lqe_softlimit u.me.lme_softlimit
248 #define lqe_gracetime u.me.lme_gracetime
249 #define lqe_revoke_time u.me.lme_revoke_time
250 #define lqe_sem u.me.lme_sem
251 #define lqe_may_rel u.me.lme_may_rel
253 #define lqe_qtune u.se.lse_qtune
254 #define lqe_pending_write u.se.lse_pending_write
255 #define lqe_waiting_write u.se.lse_waiting_write
256 #define lqe_pending_rel u.se.lse_pending_rel
257 #define lqe_pending_req u.se.lse_pending_req
258 #define lqe_waiters u.se.lse_waiters
259 #define lqe_lock u.se.lse_lock
260 #define lqe_usage u.se.lse_usage
261 #define lqe_adjust_time u.se.lse_adjust_time
262 #define lqe_lockh u.se.lse_lockh
263 #define lqe_acq_rc u.se.lse_acq_rc
264 #define lqe_acq_time u.se.lse_acq_time
265 #define lqe_edquot_time u.se.lse_edquot_time
267 #define LQUOTA_BUMP_VER 0x1
268 #define LQUOTA_SET_VER 0x2
270 extern struct kmem_cache *lqe_kmem;
272 /* helper routine to get/put reference on lquota_entry */
273 static inline void lqe_getref(struct lquota_entry *lqe)
275 LASSERT(lqe != NULL);
276 atomic_inc(&lqe->lqe_ref);
279 static inline void lqe_putref(struct lquota_entry *lqe)
281 LASSERT(lqe != NULL);
282 LASSERT(atomic_read(&lqe->lqe_ref) > 0);
283 if (atomic_dec_and_test(&lqe->lqe_ref))
284 OBD_SLAB_FREE_PTR(lqe, lqe_kmem);
287 static inline int lqe_is_master(struct lquota_entry *lqe)
289 return lqe->lqe_site->lqs_is_mst;
292 /* lqe locking helpers */
293 static inline void lqe_write_lock(struct lquota_entry *lqe)
295 if (lqe_is_master(lqe))
296 down_write(&lqe->lqe_sem);
298 write_lock(&lqe->lqe_lock);
301 static inline void lqe_write_unlock(struct lquota_entry *lqe)
303 if (lqe_is_master(lqe))
304 up_write(&lqe->lqe_sem);
306 write_unlock(&lqe->lqe_lock);
309 static inline void lqe_read_lock(struct lquota_entry *lqe)
311 if (lqe_is_master(lqe))
312 down_read(&lqe->lqe_sem);
314 read_lock(&lqe->lqe_lock);
317 static inline void lqe_read_unlock(struct lquota_entry *lqe)
319 if (lqe_is_master(lqe))
320 up_read(&lqe->lqe_sem);
322 read_unlock(&lqe->lqe_lock);
326 * Helper functions & prototypes
329 /* minimum qunit size, 1K inode for metadata pool and 1MB for data pool */
330 #define LQUOTA_LEAST_QUNIT(type) \
331 (type == LQUOTA_RES_MD ? (1 << 10) : toqb(OFD_MAX_BRW_SIZE))
333 static inline enum osd_quota_local_flags lquota_over_fl(int qtype)
337 return QUOTA_FL_OVER_USRQUOTA;
339 return QUOTA_FL_OVER_GRPQUOTA;
341 return QUOTA_FL_OVER_PRJQUOTA;
344 /* should not come here, just make compile happy */
345 return QUOTA_FL_OVER_USRQUOTA;
348 /* Common data shared by quota-level handlers. This is allocated per-thread to
349 * reduce stack consumption */
350 struct lquota_thread_info {
351 union lquota_rec qti_rec;
352 struct lu_buf qti_lb;
353 struct lu_attr qti_attr;
354 struct dt_object_format qti_dof;
355 struct lu_fid qti_fid;
356 char qti_buf[LQUOTA_NAME_MAX];
359 #define qti_glb_rec qti_rec.lqr_glb_rec
360 #define qti_acct_rec qti_rec.lqr_acct_rec
361 #define qti_slv_rec qti_rec.lqr_slv_rec
363 #define LQUOTA_BUMP_VER 0x1
364 #define LQUOTA_SET_VER 0x2
366 extern struct lu_context_key lquota_thread_key;
368 /* extract lquota_threa_info context from environment */
370 struct lquota_thread_info *lquota_info(const struct lu_env *env)
372 return lu_env_info(env, &lquota_thread_key);
375 #define req_is_acq(flags) ((flags & QUOTA_DQACQ_FL_ACQ) != 0)
376 #define req_is_preacq(flags) ((flags & QUOTA_DQACQ_FL_PREACQ) != 0)
377 #define req_is_rel(flags) ((flags & QUOTA_DQACQ_FL_REL) != 0)
378 #define req_has_rep(flags) ((flags & QUOTA_DQACQ_FL_REPORT) != 0)
380 /* debugging macros */
382 #define lquota_lqe_debug(msgdata, mask, cdls, lqe, fmt, a...) do { \
383 if (((mask) & D_CANTMASK) != 0 || \
384 ((libcfs_debug & (mask)) != 0 && \
385 (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0)) \
386 lquota_lqe_debug0(lqe, msgdata, fmt, ##a); \
389 void lquota_lqe_debug0(struct lquota_entry *lqe,
390 struct libcfs_debug_msg_data *data, const char *fmt, ...)
391 __attribute__ ((format (printf, 3, 4)));
393 #define LQUOTA_DEBUG_LIMIT(mask, lqe, fmt, a...) do { \
394 static struct cfs_debug_limit_state _lquota_cdls; \
395 LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, &_lquota_cdls); \
396 lquota_lqe_debug(&msgdata, mask, &_lquota_cdls, lqe, "$$$ "fmt" ", \
400 #define LQUOTA_ERROR(lqe, fmt, a...) LQUOTA_DEBUG_LIMIT(D_ERROR, lqe, fmt, ## a)
401 #define LQUOTA_WARN(lqe, fmt, a...) \
402 LQUOTA_DEBUG_LIMIT(D_WARNING, lqe, fmt, ## a)
403 #define LQUOTA_CONSOLE(lqe, fmt, a...) \
404 LQUOTA_DEBUG_LIMIT(D_CONSOLE, lqe, fmt, ## a)
406 #define LQUOTA_ELEVEL_LQES(level, env, fmt, a...) do { \
408 for (i = 0; i < qti_lqes_cnt(env); i++) { \
409 LQUOTA_##level(qti_lqes(env)[i], fmt, ##a); \
412 #define LQUOTA_WARN_LQES(lqe, fmt, a...) \
413 LQUOTA_ELEVEL_LQES(WARN, env, fmt, ##a)
414 #define LQUOTA_CONSOLE_LQES(lqe, fmt, a...) \
415 LQUOTA_ELEVEL_LQES(CONSOLE, env, fmt, ##a)
416 #define LQUOTA_ERROR_LQES(lqe, fmt, a...) \
417 LQUOTA_ELEVEL_LQES(ERROR, env, fmt, ##a)
419 #define LQUOTA_DEBUG(lqe, fmt, a...) do { \
420 LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_QUOTA, NULL); \
421 lquota_lqe_debug(&msgdata, D_QUOTA, NULL, lqe, "$$$ "fmt" ", ##a); \
424 #define LQUOTA_DEBUG_LQES(env, fmt, a...) do { \
426 for (i = 0; i < qti_lqes_cnt(env); i++) { \
427 LQUOTA_DEBUG(qti_lqes(env)[i], fmt, ##a); \
432 #else /* !LIBCFS_DEBUG */
433 # define LQUOTA_DEBUG_LQES(lqe, fmt, a...) ((void)0)
434 # define LQUOTA_ERROR_LQES(lqe, fmt, a...) ((void)0)
435 # define LQUOTA_WARN_LQES(lqe, fmt, a...) ((void)0)
436 # define LQUOTA_CONSOLE_LQES(lqe, fmt, a...) ((void)0)
437 # define LQUOTA_DEBUG(lqe, fmt, a...) ((void)0)
438 # define LQUOTA_ERROR(lqe, fmt, a...) ((void)0)
439 # define LQUOTA_WARN(lqe, fmt, a...) ((void)0)
440 # define LQUOTA_CONSOLE(lqe, fmt, a...) ((void)0)
441 # define lquota_lqe_debug(cdls, level, lqe, file, func, line, fmt, a...) \
446 struct dt_object *acct_obj_lookup(const struct lu_env *, struct dt_device *,
448 void lquota_generate_fid(struct lu_fid *, int, int);
449 int lquota_extract_fid(const struct lu_fid *, int *, int *);
450 const struct dt_index_features *glb_idx_feature(struct lu_fid *);
453 /* site create/destroy */
454 struct lquota_site *lquota_site_alloc(const struct lu_env *env, void *parent,
455 bool master, short qtype,
456 const struct lquota_entry_operations *op);
457 void lquota_site_free(const struct lu_env *, struct lquota_site *);
458 /* quota entry operations */
459 #define lqe_locate(env, site, id) lqe_locate_find(env, site, id, false)
460 #define lqe_find(env, site, id) lqe_locate_find(env, site, id, true)
461 struct lquota_entry *lqe_locate_find(const struct lu_env *,
462 struct lquota_site *,
463 union lquota_id *, bool);
465 static inline void lqe_set_deleted(struct lquota_entry *lqe)
467 lqe->lqe_enforced = 0;
469 lqe->lqe_is_default = 0;
470 lqe->lqe_hardlimit = 0;
471 lqe->lqe_softlimit = 0;
472 lqe->lqe_gracetime = 0;
474 lqe->lqe_is_deleted = 1;
478 struct dt_object *lquota_disk_dir_find_create(const struct lu_env *,
480 struct dt_object *, const char *);
481 struct dt_object *lquota_disk_glb_find_create(const struct lu_env *,
484 struct lu_fid *, bool);
485 struct dt_object *lquota_disk_slv_find_create(const struct lu_env *,
489 struct obd_uuid *, bool);
490 typedef int (*lquota_disk_slv_cb_t) (const struct lu_env *, struct lu_fid *,
491 char *, struct lu_fid *, void *);
492 int lquota_disk_for_each_slv(const struct lu_env *, struct dt_object *,
493 struct lu_fid *, lquota_disk_slv_cb_t, void *);
494 struct dt_object *lquota_disk_slv_find(const struct lu_env *,
495 struct dt_device *, struct dt_object *,
496 const struct lu_fid *,
498 int lquota_disk_read(const struct lu_env *, struct dt_object *,
499 union lquota_id *, struct dt_rec *);
500 int lquota_disk_declare_write(const struct lu_env *, struct thandle *,
501 struct dt_object *, union lquota_id *);
502 int lquota_disk_write(const struct lu_env *, struct thandle *,
503 struct dt_object *, union lquota_id *, struct dt_rec *,
505 int lquota_disk_delete(const struct lu_env *env, struct thandle *th,
506 struct dt_object *obj, __u64 qid, __u64 *ver);
507 int lquota_disk_update_ver(const struct lu_env *, struct dt_device *,
508 struct dt_object *, __u64);
509 int lquota_disk_write_glb(const struct lu_env *, struct dt_object *, __u64,
510 struct lquota_glb_rec *);
513 int qmt_glb_init(void);
514 void qmt_glb_fini(void);
517 extern const struct proc_ops lprocfs_quota_seq_fops;
520 int qsd_glb_init(void);
521 void qsd_glb_fini(void);
522 #endif /* _LQUOTA_INTERNAL_H */