Whamcloud - gitweb
LU-4017 quota: add project quota support for Lustre
[fs/lustre-release.git] / lustre / quota / lquota_internal.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, 2014, Intel Corporation.
25  * Use is subject to license terms.
26  */
27
28 #include <obd.h>
29 #include <lustre_quota.h>
30
31 #ifndef _LQUOTA_INTERNAL_H
32 #define _LQUOTA_INTERNAL_H
33
34 /*
35 static inline char *qtype_name(int qtype)
36 {
37         switch (qtype) {
38         case USRQUOTA:
39                 return "usr";
40         case GRPQUOTA:
41                 return "grp";
42         case PRJQUOTA:
43                 return "prj";
44                 break;
45         }
46         return "unknown";
47 }
48 */
49
50 #define RES_NAME(res) ((res) == LQUOTA_RES_MD ? "md" : "dt")
51
52 #define QIF_IFLAGS (QIF_INODES | QIF_ITIME | QIF_ILIMITS)
53 #define QIF_BFLAGS (QIF_SPACE | QIF_BTIME | QIF_BLIMITS)
54
55 /* The biggest filename are the one used for slave index which are in the form
56  * of 0x%x-%s,glb_fid.f_oid,slv_uuid, that's to say:
57  * 2(0x) + 8(f_oid) + 1(-) + 40(UUID_MAX) which means 51 chars + '\0' */
58 #define LQUOTA_NAME_MAX 52
59
60 /* reserved OID in FID_SEQ_QUOTA for local objects */
61 enum lquota_local_oid {
62         LQUOTA_USR_OID          = 1UL, /* slave index copy for user quota */
63         LQUOTA_GRP_OID          = 2UL, /* slave index copy for group quota */
64         LQUOTA_PRJ_OID          = 3UL, /* slave index copy for project quota */
65         /* all OIDs after this are allocated dynamically by the QMT */
66         LQUOTA_GENERATED_OID    = 4096UL,
67 };
68
69 static inline __u32 qtype2slv_oid(int qtype)
70 {
71         switch (qtype) {
72         case USRQUOTA:
73                 return LQUOTA_USR_OID;
74         case GRPQUOTA:
75                 return LQUOTA_GRP_OID;
76         case PRJQUOTA:
77                 return LQUOTA_PRJ_OID;
78         }
79
80         LASSERTF(0, "invalid quota type: %d", qtype);
81         return LQUOTA_USR_OID;
82 }
83
84 /*
85  * lquota_entry support
86  */
87
88 /* Common operations supported by a lquota_entry */
89 struct lquota_entry_operations {
90         /* Initialize specific fields of a lquota entry */
91         void (*lqe_init)(struct lquota_entry *, void *arg);
92
93         /* Read quota settings from disk and update lquota entry */
94         int (*lqe_read)(const struct lu_env *, struct lquota_entry *,
95                         void *arg);
96
97         /* Print debug information about a given lquota entry */
98         void (*lqe_debug)(struct lquota_entry *, void *,
99                           struct libcfs_debug_msg_data *, const char *,
100                           va_list);
101 };
102
103 /* Per-ID information specific to the quota master target */
104 struct lquota_mst_entry {
105         /* global hard limit, in inodes or kbytes */
106         __u64                   lme_hardlimit;
107
108         /* global quota soft limit, in inodes or kbytes */
109         __u64                   lme_softlimit;
110
111         /* grace time, in seconds */
112         __u64                   lme_gracetime;
113
114         /* last time we glimpsed */
115         __u64                   lme_revoke_time;
116
117         /* r/w semaphore used to protect concurrent access to the quota
118          * parameters which are stored on disk */
119         struct rw_semaphore     lme_sem;
120
121         /* quota space that may be released after glimpse */
122         __u64                   lme_may_rel;
123 };
124
125 /* Per-ID information specific to the quota slave */
126 struct lquota_slv_entry {
127         /* [ib]tune size, inodes or kbytes */
128         __u64                   lse_qtune;
129
130         /* per-ID lock handle */
131         struct lustre_handle    lse_lockh;
132
133         /* pending write which were granted quota space but haven't completed
134          * yet, in inodes or kbytes. */
135         __u64                   lse_pending_write;
136
137         /* writes waiting for quota space, in inodes or kbytes. */
138         __u64                   lse_waiting_write;
139
140         /* pending release, in inodes or kbytes */
141         __u64                   lse_pending_rel;
142
143         /* pending dqacq/dqrel requests. */
144         unsigned int            lse_pending_req;
145
146         /* rw spinlock protecting in-memory counters (i.e. lse_pending*) */
147         rwlock_t                lse_lock;
148
149         /* waiter for pending request done */
150         wait_queue_head_t       lse_waiters;
151
152         /* hint on current on-disk usage, in inodes or kbytes */
153         __u64                   lse_usage;
154
155         /* time to trigger quota adjust */
156         __u64                   lse_adjust_time;
157
158         /* return code of latest acquire RPC */
159         int                     lse_acq_rc;
160
161         /* when latest acquire RPC completed */
162         __u64                   lse_acq_time;
163
164         /* when latest edquot set */
165         __u64                   lse_edquot_time;
166 };
167
168 /* In-memory entry for each enforced quota id
169  * A lquota_entry structure belong to a single lquota_site */
170 struct lquota_entry {
171         /* link to site hash table */
172         struct hlist_node        lqe_hash;
173
174         /* quota identifier associated with this entry */
175         union lquota_id          lqe_id;
176
177         /* site this quota entry belongs to */
178         struct lquota_site      *lqe_site;
179
180         /* reference counter */
181         atomic_t                 lqe_ref;
182
183         /* linked to list of lqes which:
184          * - need quota space adjustment on slave
185          * - need glimpse to be sent on master */
186         struct list_head         lqe_link;
187
188         /* current quota settings/usage of this ID */
189         __u64           lqe_granted; /* granted limit, inodes or kbytes */
190         __u64           lqe_qunit; /* [ib]unit size, inodes or kbytes */
191         union {
192                 struct  lquota_mst_entry me; /* params specific to QMT */
193                 struct  lquota_slv_entry se; /* params specific to QSD */
194         } u;
195
196         /* flags describing the state of the lquota_entry */
197         unsigned long   lqe_enforced:1,/* quota enforced or not */
198                         lqe_uptodate:1,/* successfully read from disk */
199                         lqe_edquot:1,  /* id out of quota space on QMT */
200                         lqe_gl:1,      /* glimpse is in progress */
201                         lqe_nopreacq:1;/* pre-acquire disabled */
202 };
203
204 /* Compartment within which lquota_entry are unique.
205  * lquota_entry structures are kept in a hash table and read from disk if not
206  * present.  */
207 struct lquota_site {
208         /* Hash table storing lquota_entry structures */
209         struct cfs_hash *lqs_hash;
210
211         /* Quota type, either user or group. */
212         int              lqs_qtype;
213
214         /* Record whether this site is for a QMT or a slave */
215         int              lqs_is_mst;
216
217         /* Vector of operations which can be done on lquota entry belonging to
218          * this quota site */
219         struct lquota_entry_operations  *lqs_ops;
220
221         /* Backpointer to parent structure, either QMT pool info for master or
222          * QSD for slave */
223         void            *lqs_parent;
224 };
225
226 #define lqe_hardlimit           u.me.lme_hardlimit
227 #define lqe_softlimit           u.me.lme_softlimit
228 #define lqe_gracetime           u.me.lme_gracetime
229 #define lqe_revoke_time         u.me.lme_revoke_time
230 #define lqe_sem                 u.me.lme_sem
231 #define lqe_may_rel             u.me.lme_may_rel
232
233 #define lqe_qtune               u.se.lse_qtune
234 #define lqe_pending_write       u.se.lse_pending_write
235 #define lqe_waiting_write       u.se.lse_waiting_write
236 #define lqe_pending_rel         u.se.lse_pending_rel
237 #define lqe_pending_req         u.se.lse_pending_req
238 #define lqe_waiters             u.se.lse_waiters
239 #define lqe_lock                u.se.lse_lock
240 #define lqe_usage               u.se.lse_usage
241 #define lqe_adjust_time         u.se.lse_adjust_time
242 #define lqe_lockh               u.se.lse_lockh
243 #define lqe_acq_rc              u.se.lse_acq_rc
244 #define lqe_acq_time            u.se.lse_acq_time
245 #define lqe_edquot_time         u.se.lse_edquot_time
246
247 #define LQUOTA_BUMP_VER 0x1
248 #define LQUOTA_SET_VER  0x2
249
250 extern struct kmem_cache *lqe_kmem;
251
252 /* helper routine to get/put reference on lquota_entry */
253 static inline void lqe_getref(struct lquota_entry *lqe)
254 {
255         LASSERT(lqe != NULL);
256         atomic_inc(&lqe->lqe_ref);
257 }
258
259 static inline void lqe_putref(struct lquota_entry *lqe)
260 {
261         LASSERT(lqe != NULL);
262         LASSERT(atomic_read(&lqe->lqe_ref) > 0);
263         if (atomic_dec_and_test(&lqe->lqe_ref))
264                 OBD_SLAB_FREE_PTR(lqe, lqe_kmem);
265 }
266
267 static inline int lqe_is_master(struct lquota_entry *lqe)
268 {
269         return lqe->lqe_site->lqs_is_mst;
270 }
271
272 /* lqe locking helpers */
273 static inline void lqe_write_lock(struct lquota_entry *lqe)
274 {
275         if (lqe_is_master(lqe))
276                 down_write(&lqe->lqe_sem);
277         else
278                 write_lock(&lqe->lqe_lock);
279 }
280
281 static inline void lqe_write_unlock(struct lquota_entry *lqe)
282 {
283         if (lqe_is_master(lqe))
284                 up_write(&lqe->lqe_sem);
285         else
286                 write_unlock(&lqe->lqe_lock);
287 }
288
289 static inline void lqe_read_lock(struct lquota_entry *lqe)
290 {
291         if (lqe_is_master(lqe))
292                 down_read(&lqe->lqe_sem);
293         else
294                 read_lock(&lqe->lqe_lock);
295 }
296
297 static inline void lqe_read_unlock(struct lquota_entry *lqe)
298 {
299         if (lqe_is_master(lqe))
300                 up_read(&lqe->lqe_sem);
301         else
302                 read_unlock(&lqe->lqe_lock);
303 }
304
305 /*
306  * Helper functions & prototypes
307  */
308
309 /* minimum qunit size, 1K inode for metadata pool and 1MB for data pool */
310 #define LQUOTA_LEAST_QUNIT(type) \
311         (type == LQUOTA_RES_MD ? (1 << 10) : toqb(OFD_MAX_BRW_SIZE))
312
313 static inline int lquota_over_fl(int qtype)
314 {
315         switch (qtype) {
316         case USRQUOTA:
317                 return QUOTA_FL_OVER_USRQUOTA;
318         case GRPQUOTA:
319                 return QUOTA_FL_OVER_GRPQUOTA;
320         case PRJQUOTA:
321                 return QUOTA_FL_OVER_PRJQUOTA;
322         }
323
324         LASSERTF(0, "invalid quota type: %d", qtype);
325         return QUOTA_FL_OVER_USRQUOTA;
326 }
327
328 /* Common data shared by quota-level handlers. This is allocated per-thread to
329  * reduce stack consumption */
330 struct lquota_thread_info {
331         union  lquota_rec       qti_rec;
332         struct lu_buf           qti_lb;
333         struct lu_attr          qti_attr;
334         struct dt_object_format qti_dof;
335         struct lu_fid           qti_fid;
336         char                    qti_buf[LQUOTA_NAME_MAX];
337 };
338
339 #define qti_glb_rec     qti_rec.lqr_glb_rec
340 #define qti_acct_rec    qti_rec.lqr_acct_rec
341 #define qti_slv_rec     qti_rec.lqr_slv_rec
342
343 #define LQUOTA_BUMP_VER 0x1
344 #define LQUOTA_SET_VER  0x2
345
346 extern struct lu_context_key lquota_thread_key;
347
348 /* extract lquota_threa_info context from environment */
349 static inline
350 struct lquota_thread_info *lquota_info(const struct lu_env *env)
351 {
352         struct lquota_thread_info       *info;
353
354         info = lu_context_key_get(&env->le_ctx, &lquota_thread_key);
355         if (info == NULL) {
356                 lu_env_refill((struct lu_env *)env);
357                 info = lu_context_key_get(&env->le_ctx, &lquota_thread_key);
358         }
359         LASSERT(info);
360         return info;
361 }
362
363 #define req_is_acq(flags)    ((flags & QUOTA_DQACQ_FL_ACQ) != 0)
364 #define req_is_preacq(flags) ((flags & QUOTA_DQACQ_FL_PREACQ) != 0)
365 #define req_is_rel(flags)    ((flags & QUOTA_DQACQ_FL_REL) != 0)
366 #define req_has_rep(flags)   ((flags & QUOTA_DQACQ_FL_REPORT) != 0)
367
368 /* debugging macros */
369 #ifdef LIBCFS_DEBUG
370 #define lquota_lqe_debug(msgdata, mask, cdls, lqe, fmt, a...) do {      \
371         CFS_CHECK_STACK(msgdata, mask, cdls);                           \
372                                                                         \
373         if (((mask) & D_CANTMASK) != 0 ||                               \
374             ((libcfs_debug & (mask)) != 0 &&                            \
375              (libcfs_subsystem_debug & DEBUG_SUBSYSTEM) != 0))          \
376                 lquota_lqe_debug0(lqe, msgdata, fmt, ##a);              \
377 } while(0)
378
379 void lquota_lqe_debug0(struct lquota_entry *lqe,
380                        struct libcfs_debug_msg_data *data, const char *fmt, ...)
381         __attribute__ ((format (printf, 3, 4)));
382
383 #define LQUOTA_DEBUG_LIMIT(mask, lqe, fmt, a...) do {                          \
384         static struct cfs_debug_limit_state _lquota_cdls;                      \
385         LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, &_lquota_cdls);              \
386         lquota_lqe_debug(&msgdata, mask, &_lquota_cdls, lqe, "$$$ "fmt" ",     \
387                          ##a);                                                 \
388 } while (0)
389
390 #define LQUOTA_ERROR(lqe, fmt, a...) LQUOTA_DEBUG_LIMIT(D_ERROR, lqe, fmt, ## a)
391 #define LQUOTA_WARN(lqe, fmt, a...) \
392         LQUOTA_DEBUG_LIMIT(D_WARNING, lqe, fmt, ## a)
393 #define LQUOTA_CONSOLE(lqe, fmt, a...) \
394         LQUOTA_DEBUG_LIMIT(D_CONSOLE, lqe, fmt, ## a)
395
396 #define LQUOTA_DEBUG(lock, fmt, a...) do {                                 \
397         LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, D_QUOTA, NULL);                \
398         lquota_lqe_debug(&msgdata, D_QUOTA, NULL, lqe, "$$$ "fmt" ", ##a); \
399 } while (0)
400 #else /* !LIBCFS_DEBUG */
401 # define LQUOTA_DEBUG(lqe, fmt, a...) ((void)0)
402 # define LQUOTA_ERROR(lqe, fmt, a...) ((void)0)
403 # define LQUOTA_WARN(lqe, fmt, a...) ((void)0)
404 # define LQUOTA_CONSOLE(lqe, fmt, a...) ((void)0)
405 # define lquota_lqe_debug(cdls, level, lqe, file, func, line, fmt, a...) \
406                 ((void)0)
407 #endif
408
409 /* lquota_lib.c */
410 struct dt_object *acct_obj_lookup(const struct lu_env *, struct dt_device *,
411                                   int);
412 void lquota_generate_fid(struct lu_fid *, int, int, int);
413 int lquota_extract_fid(const struct lu_fid *, int *, int *, int *);
414 const struct dt_index_features *glb_idx_feature(struct lu_fid *);
415
416 /* lquota_entry.c */
417 /* site create/destroy */
418 struct lquota_site *lquota_site_alloc(const struct lu_env *, void *, bool,
419                                       short, struct lquota_entry_operations *);
420 void lquota_site_free(const struct lu_env *, struct lquota_site *);
421 /* quota entry operations */
422 struct lquota_entry *lqe_locate(const struct lu_env *, struct lquota_site *,
423                                 union lquota_id *);
424
425 /* lquota_disk.c */
426 struct dt_object *lquota_disk_dir_find_create(const struct lu_env *,
427                                               struct dt_device *,
428                                               struct dt_object *, const char *);
429 struct dt_object *lquota_disk_glb_find_create(const struct lu_env *,
430                                               struct dt_device *,
431                                               struct dt_object *,
432                                               struct lu_fid *, bool);
433 struct dt_object *lquota_disk_slv_find_create(const struct lu_env *,
434                                               struct dt_device *,
435                                               struct dt_object *,
436                                               struct lu_fid *,
437                                               struct obd_uuid *, bool);
438 typedef int (*lquota_disk_slv_cb_t) (const struct lu_env *, struct lu_fid *,
439                                      char *, struct lu_fid *, void *);
440 int lquota_disk_for_each_slv(const struct lu_env *, struct dt_object *,
441                              struct lu_fid *, lquota_disk_slv_cb_t, void *);
442 struct dt_object *lquota_disk_slv_find(const struct lu_env *,
443                                        struct dt_device *, struct dt_object *,
444                                        const struct lu_fid *,
445                                        struct obd_uuid *);
446 int lquota_disk_read(const struct lu_env *, struct dt_object *,
447                      union lquota_id *, struct dt_rec *);
448 int lquota_disk_declare_write(const struct lu_env *, struct thandle *,
449                               struct dt_object *, union lquota_id *);
450 int lquota_disk_write(const struct lu_env *, struct thandle *,
451                       struct dt_object *, union lquota_id *, struct dt_rec *,
452                       __u32, __u64 *);
453 int lquota_disk_update_ver(const struct lu_env *, struct dt_device *,
454                            struct dt_object *, __u64);
455 int lquota_disk_write_glb(const struct lu_env *, struct dt_object *, __u64,
456                           struct lquota_glb_rec *);
457
458 /* qmt_dev.c */
459 int qmt_glb_init(void);
460 void qmt_glb_fini(void);
461
462 /* lproc_quota.c */
463 extern struct file_operations lprocfs_quota_seq_fops;
464
465 /* qsd_lib.c */
466 int qsd_glb_init(void);
467 void qsd_glb_fini(void);
468 #endif /* _LQUOTA_INTERNAL_H */