1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
4 #ifndef _LUSTRE_QUOTA_H
5 #define _LUSTRE_QUOTA_H
8 #include <linux/lustre_quota.h>
9 #elif defined(__APPLE__)
10 #include <darwin/lustre_quota.h>
11 #elif defined(__WINNT__)
12 #include <winnt/lustre_quota.h>
14 #error Unsupported operating system.
17 #include <lustre/lustre_idl.h>
18 #include <lustre_net.h>
20 #include <obd_support.h>
29 #ifdef HAVE_QUOTA_SUPPORT
33 /* structures to access admin quotafile */
34 struct lustre_mem_dqinfo {
35 unsigned int dqi_bgrace;
36 unsigned int dqi_igrace;
37 unsigned long dqi_flags;
38 unsigned int dqi_blocks;
39 unsigned int dqi_free_blk;
40 unsigned int dqi_free_entry;
43 struct lustre_quota_info {
44 struct file *qi_files[MAXQUOTAS];
45 struct lustre_mem_dqinfo qi_info[MAXQUOTAS];
46 lustre_quota_version_t qi_version;
49 #define DQ_STATUS_AVAIL 0x0 /* Available dquot */
50 #define DQ_STATUS_SET 0x01 /* Sombody is setting dquot */
51 #define DQ_STATUS_RECOVERY 0x02 /* dquot is in recovery */
53 struct lustre_mem_dqblk {
54 __u64 dqb_bhardlimit; /* absolute limit on disk blks alloc */
55 __u64 dqb_bsoftlimit; /* preferred limit on disk blks */
56 __u64 dqb_curspace; /* current used space */
57 __u64 dqb_ihardlimit; /* absolute limit on allocated inodes */
58 __u64 dqb_isoftlimit; /* preferred inode limit */
59 __u64 dqb_curinodes; /* current # allocated inodes */
60 time_t dqb_btime; /* time limit for excessive disk use */
61 time_t dqb_itime; /* time limit for excessive inode use */
65 /* Hash list in memory, protect by dquot_hash_lock */
66 struct list_head dq_hash;
67 /* Protect the data in lustre_dquot */
68 struct semaphore dq_sem;
71 /* Pointer of quota info it belongs to */
72 struct lustre_quota_info *dq_info;
74 loff_t dq_off; /* Offset of dquot on disk */
75 unsigned int dq_id; /* ID this applies to (uid, gid) */
76 int dq_type; /* Type fo quota (USRQUOTA, GRPQUOUTA) */
77 unsigned short dq_status; /* See DQ_STATUS_ */
78 unsigned long dq_flags; /* See DQ_ in quota.h */
79 struct lustre_mem_dqblk dq_dqb; /* Diskquota usage */
83 struct list_head di_link;
88 #define QFILE_RD_INFO 2
89 #define QFILE_WR_INFO 3
90 #define QFILE_INIT_INFO 4
91 #define QFILE_RD_DQUOT 5
92 #define QFILE_WR_DQUOT 6
93 #define QFILE_CONVERT 7
95 /* admin quotafile operations */
96 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
97 int lustre_check_quota_file(struct lustre_quota_info *lqi, int type);
98 int lustre_read_quota_info(struct lustre_quota_info *lqi, int type);
99 int lustre_write_quota_info(struct lustre_quota_info *lqi, int type);
100 int lustre_read_dquot(struct lustre_dquot *dquot);
101 int lustre_commit_dquot(struct lustre_dquot *dquot);
102 int lustre_init_quota_info(struct lustre_quota_info *lqi, int type);
103 int lustre_get_qids(struct file *file, struct inode *inode, int type,
104 struct list_head *list);
105 int lustre_quota_convert(struct lustre_quota_info *lqi, int type);
112 static inline int lustre_check_quota_file(struct lustre_quota_info *lqi,
117 static inline int lustre_read_quota_info(struct lustre_quota_info *lqi,
122 static inline int lustre_write_quota_info(struct lustre_quota_info *lqi,
127 static inline int lustre_read_dquot(struct lustre_dquot *dquot)
131 static inline int lustre_commit_dquot(struct lustre_dquot *dquot)
135 static inline int lustre_init_quota_info(struct lustre_quota_info *lqi,
140 static inline int lustre_quota_convert(struct lustre_quota_info *lqi,
145 #endif /* KERNEL_VERSION(2,5,0) */
147 #define LL_DQUOT_OFF(sb) DQUOT_OFF(sb)
149 typedef int (*dqacq_handler_t) (struct obd_device * obd, struct qunit_data * qd,
151 struct lustre_quota_ctxt {
152 struct super_block *lqc_sb; /* superblock this applies to */
153 struct obd_import *lqc_import; /* import used to send dqacq/dqrel RPC */
154 dqacq_handler_t lqc_handler; /* dqacq/dqrel RPC handler, only for quota master */
155 unsigned long lqc_recovery:1, /* Doing recovery */
156 lqc_atype:2, /* Turn on user/group quota at setup automatically,
157 * 0: none, 1: user quota, 2: group quota, 3: both */
158 lqc_status:1, /* Quota status. 0:Off, 1:On */
159 lqc_switch_qs:1; /* the function of change qunit size
161 unsigned long lqc_iunit_sz; /* original unit size of file quota and
162 * upper limitation for adjust file
164 unsigned long lqc_itune_sz; /* Trigger dqacq when available file
165 * quota less than this value, trigger
166 * dqrel when available file quota
167 * more than this value + 1 iunit */
168 unsigned long lqc_bunit_sz; /* original unit size of block quota and
169 * upper limitation for adjust block
171 unsigned long lqc_btune_sz; /* See comment of lqc_itune_sz */
172 struct lustre_class_hash_body *lqc_lqs_hash_body;
173 /* all lustre_qunit_size structure in
175 /* the values below are relative to how master change its qunit sizes */
176 unsigned long lqc_cqs_boundary_factor; /* this affects the boundary of
177 * shrinking and enlarging qunit
179 unsigned long lqc_cqs_least_bunit; /* the least value of block qunit */
180 unsigned long lqc_cqs_least_iunit; /* the least value of inode qunit */
181 unsigned long lqc_cqs_qs_factor; /* when enlarging, qunit size will
182 * mutilple it; when shrinking,
183 * qunit size will divide it */
184 int lqc_switch_seconds; /* avoid ping-pong effect of
185 * adjusting qunit size. How many
186 * seconds must be waited between
187 * enlarging and shinking qunit */
188 spinlock_t lqc_lock; /* guard lqc_imp_valid now */
191 #define LQC_HASH_BODY(qctxt) (qctxt->lqc_lqs_hash_body)
193 struct lustre_qunit_size {
194 struct hlist_node lqs_hash; /* the hash entry */
195 unsigned int lqs_id; /* id of user/group */
196 unsigned long lqs_flags; /* is user/group; FULLBUF or LESSBUF */
197 unsigned long lqs_iunit_sz; /* Unit size of file quota currently */
198 unsigned long lqs_itune_sz; /* Trigger dqacq when available file quota
199 * less than this value, trigger dqrel
200 * when more than this value + 1 iunit */
201 unsigned long lqs_bunit_sz; /* Unit size of block quota currently */
202 unsigned long lqs_btune_sz; /* See comment of lqs itune sz */
203 unsigned long lqs_bwrite_pending; /* the blocks reached ost and don't
205 unsigned long lqs_iwrite_pending; /* the inodes reached mds and don't
207 long long lqs_ino_rec; /* when inodes are allocated/released,
208 * this value will record it */
209 long long lqs_blk_rec; /* when blocks are allocated/released,
210 * this value will record it */
211 atomic_t lqs_refcount;
212 cfs_time_t lqs_last_bshrink; /* time of last block shrink */
213 cfs_time_t lqs_last_ishrink; /* time of last inode shrink */
217 #define LQS_IS_GRP(lqs) ((lqs)->lqs_flags & LQUOTA_FLAGS_GRP)
218 #define LQS_IS_ADJBLK(lqs) ((lqs)->lqs_flags & LQUOTA_FLAGS_ADJBLK)
219 #define LQS_IS_ADJINO(lqs) ((lqs)->lqs_flags & LQUOTA_FLAGS_ADJINO)
221 #define LQS_SET_GRP(lqs) ((lqs)->lqs_flags |= LQUOTA_FLAGS_GRP)
222 #define LQS_SET_ADJBLK(lqs) ((lqs)->lqs_flags |= LQUOTA_FLAGS_ADJBLK)
223 #define LQS_SET_ADJINO(lqs) ((lqs)->lqs_flags |= LQUOTA_FLAGS_ADJINO)
225 static inline void lqs_getref(struct lustre_qunit_size *lqs)
227 atomic_inc(&lqs->lqs_refcount);
230 static inline void lqs_putref(struct lustre_qunit_size *lqs)
232 if (atomic_dec_and_test(&lqs->lqs_refcount)) {
233 spin_lock(&lqs->lqs_lock);
234 hlist_del_init(&lqs->lqs_hash);
235 spin_unlock(&lqs->lqs_lock);
240 static inline void lqs_initref(struct lustre_qunit_size *lqs)
242 atomic_set(&lqs->lqs_refcount, 0);
247 struct lustre_quota_info {
250 struct lustre_quota_ctxt {
253 #endif /* !__KERNEL__ */
257 #define LL_DQUOT_OFF(sb) do {} while(0)
259 struct lustre_quota_info {
262 struct lustre_quota_ctxt {
265 #endif /* !HAVE_QUOTA_SUPPORT */
267 /* If the (quota limit < qunit * slave count), the slave which can't
268 * acquire qunit should set it's local limit as MIN_QLIMIT */
271 struct quotacheck_thread_args {
272 struct obd_export *qta_exp; /* obd export */
273 struct obd_quotactl qta_oqctl; /* obd_quotactl args */
274 struct super_block *qta_sb; /* obd super block */
275 atomic_t *qta_sem; /* obt_quotachecking */
278 typedef int (*quota_acquire)(struct obd_device *obd,
279 unsigned int uid, unsigned int gid);
282 int (*quota_init) (void);
283 int (*quota_exit) (void);
284 int (*quota_setup) (struct obd_device *);
285 int (*quota_cleanup) (struct obd_device *);
286 /* For quota master, close admin quota files */
287 int (*quota_fs_cleanup) (struct obd_device *);
288 int (*quota_ctl) (struct obd_export *, struct obd_quotactl *);
289 int (*quota_check) (struct obd_export *, struct obd_quotactl *);
290 int (*quota_recovery) (struct obd_device *);
292 /* For quota master/slave, adjust quota limit after fs operation */
293 int (*quota_adjust) (struct obd_device *, unsigned int[],
294 unsigned int[], int, int);
296 /* For quota slave, set import, trigger quota recovery */
297 int (*quota_setinfo) (struct obd_export *, struct obd_device *);
299 /* For quota slave, clear import when relative import is invalid */
300 int (*quota_clearinfo) (struct obd_export *, struct obd_device *);
302 /* For quota slave, set proper thread resoure capability */
303 int (*quota_enforce) (struct obd_device *, unsigned int);
305 /* For quota slave, check whether specified uid/gid is over quota */
306 int (*quota_getflag) (struct obd_device *, struct obdo *);
308 /* For quota slave, acquire/release quota from master if needed */
309 int (*quota_acquire) (struct obd_device *, unsigned int, unsigned int);
311 /* For quota slave, check whether specified uid/gid's remaining quota
312 * can finish a block_write or inode_create rpc. It updates the pending
313 * record of block and inode, acquires quota if necessary */
314 int (*quota_chkquota) (struct obd_device *, unsigned int, unsigned int,
315 int, int *, quota_acquire);
317 /* For quota client, poll if the quota check done */
318 int (*quota_poll_check) (struct obd_export *, struct if_quotacheck *);
320 /* For quota client, check whether specified uid/gid is over quota */
321 int (*quota_chkdq) (struct client_obd *, unsigned int, unsigned int);
323 /* For quota client, the actions after the pending write is committed */
324 int (*quota_pending_commit) (struct obd_device *, unsigned int,
327 /* For quota client, set over quota flag for specifed uid/gid */
328 int (*quota_setdq) (struct client_obd *, unsigned int, unsigned int,
331 /* For adjusting qunit size b=10600 */
332 int (*quota_adjust_qunit) (struct obd_export *exp, struct
333 quota_adjust_qunit *oqaq);
337 #define Q_COPY(out, in, member) (out)->member = (in)->member
339 #define QUOTA_OP(interface, op) interface->quota_ ## op
341 #define QUOTA_CHECK_OP(interface, op) \
345 if (!QUOTA_OP(interface, op)) { \
346 CERROR("no quota operation: " #op "\n"); \
347 RETURN(-EOPNOTSUPP); \
351 static inline int lquota_init(quota_interface_t *interface)
356 QUOTA_CHECK_OP(interface, init);
357 rc = QUOTA_OP(interface, init)();
361 static inline int lquota_exit(quota_interface_t *interface)
366 QUOTA_CHECK_OP(interface, exit);
367 rc = QUOTA_OP(interface, exit)();
371 static inline int lquota_setup(quota_interface_t *interface,
372 struct obd_device *obd)
377 QUOTA_CHECK_OP(interface, setup);
378 rc = QUOTA_OP(interface, setup)(obd);
382 static inline int lquota_cleanup(quota_interface_t *interface,
383 struct obd_device *obd)
388 QUOTA_CHECK_OP(interface, cleanup);
389 rc = QUOTA_OP(interface, cleanup)(obd);
393 static inline int lquota_fs_cleanup(quota_interface_t *interface,
394 struct obd_device *obd)
399 QUOTA_CHECK_OP(interface, fs_cleanup);
400 rc = QUOTA_OP(interface, fs_cleanup)(obd);
404 static inline int lquota_recovery(quota_interface_t *interface,
405 struct obd_device *obd)
410 QUOTA_CHECK_OP(interface, recovery);
411 rc = QUOTA_OP(interface, recovery)(obd);
415 static inline int lquota_adjust(quota_interface_t *interface,
416 struct obd_device *obd,
417 unsigned int qcids[],
418 unsigned int qpids[],
424 QUOTA_CHECK_OP(interface, adjust);
425 ret = QUOTA_OP(interface, adjust)(obd, qcids, qpids, rc, opc);
429 static inline int lquota_chkdq(quota_interface_t *interface,
430 struct client_obd *cli,
431 unsigned int uid, unsigned int gid)
436 QUOTA_CHECK_OP(interface, chkdq);
437 rc = QUOTA_OP(interface, chkdq)(cli, uid, gid);
441 static inline int lquota_setdq(quota_interface_t *interface,
442 struct client_obd *cli,
443 unsigned int uid, unsigned int gid,
444 obd_flag valid, obd_flag flags)
449 QUOTA_CHECK_OP(interface, setdq);
450 rc = QUOTA_OP(interface, setdq)(cli, uid, gid, valid, flags);
454 static inline int lquota_poll_check(quota_interface_t *interface,
455 struct obd_export *exp,
456 struct if_quotacheck *qchk)
461 QUOTA_CHECK_OP(interface, poll_check);
462 rc = QUOTA_OP(interface, poll_check)(exp, qchk);
466 static inline int lquota_setinfo(quota_interface_t *interface,
467 struct obd_export *exp,
468 struct obd_device *obd)
473 QUOTA_CHECK_OP(interface, setinfo);
474 rc = QUOTA_OP(interface, setinfo)(exp, obd);
478 static inline int lquota_clearinfo(quota_interface_t *interface,
479 struct obd_export *exp,
480 struct obd_device *obd)
485 QUOTA_CHECK_OP(interface, clearinfo);
486 rc = QUOTA_OP(interface, clearinfo)(exp, obd);
490 static inline int lquota_enforce(quota_interface_t *interface,
491 struct obd_device *obd,
497 QUOTA_CHECK_OP(interface, enforce);
498 rc = QUOTA_OP(interface, enforce)(obd, ignore);
502 static inline int lquota_getflag(quota_interface_t *interface,
503 struct obd_device *obd, struct obdo *oa)
508 QUOTA_CHECK_OP(interface, getflag);
509 rc = QUOTA_OP(interface, getflag)(obd, oa);
513 static inline int lquota_acquire(quota_interface_t *interface,
514 struct obd_device *obd,
515 unsigned int uid, unsigned int gid)
520 QUOTA_CHECK_OP(interface, acquire);
521 rc = QUOTA_OP(interface, acquire)(obd, uid, gid);
525 static inline int lquota_chkquota(quota_interface_t *interface,
526 struct obd_device *obd,
527 unsigned int uid, unsigned int gid,
528 int count, int *flag)
533 QUOTA_CHECK_OP(interface, chkquota);
534 QUOTA_CHECK_OP(interface, acquire);
535 rc = QUOTA_OP(interface, chkquota)(obd, uid, gid, count, flag,
536 QUOTA_OP(interface, acquire));
540 static inline int lquota_pending_commit(quota_interface_t *interface,
541 struct obd_device *obd,
542 unsigned int uid, unsigned int gid,
548 QUOTA_CHECK_OP(interface, pending_commit);
549 rc = QUOTA_OP(interface, pending_commit)(obd, uid, gid, npage);
553 int lprocfs_quota_rd_bunit(char *page, char **start, off_t off, int count,
554 int *eof, void *data);
555 int lprocfs_quota_wr_bunit(struct file *file, const char *buffer,
556 unsigned long count, void *data);
557 int lprocfs_quota_rd_btune(char *page, char **start, off_t off, int count,
558 int *eof, void *data);
559 int lprocfs_quota_wr_btune(struct file *file, const char *buffer,
560 unsigned long count, void *data);
561 int lprocfs_quota_rd_iunit(char *page, char **start, off_t off, int count,
562 int *eof, void *data);
563 int lprocfs_quota_wr_iunit(struct file *file, const char *buffer,
564 unsigned long count, void *data);
565 int lprocfs_quota_rd_itune(char *page, char **start, off_t off, int count,
566 int *eof, void *data);
567 int lprocfs_quota_wr_itune(struct file *file, const char *buffer,
568 unsigned long count, void *data);
569 int lprocfs_quota_rd_type(char *page, char **start, off_t off, int count,
570 int *eof, void *data);
571 int lprocfs_quota_wr_type(struct file *file, const char *buffer,
572 unsigned long count, void *data);
573 int lprocfs_quota_rd_switch_seconds(char *page, char **start, off_t off,
574 int count, int *eof, void *data);
575 int lprocfs_quota_wr_switch_seconds(struct file *file, const char *buffer,
576 unsigned long count, void *data);
579 extern quota_interface_t osc_quota_interface;
580 extern quota_interface_t mdc_quota_interface;
581 extern quota_interface_t lov_quota_interface;
584 #define LUSTRE_ADMIN_QUOTAFILES_V1 {\
585 "admin_quotafile.usr", /* user admin quotafile */\
586 "admin_quotafile.grp" /* group admin quotafile */\
589 #define LUSTRE_ADMIN_QUOTAFILES_V2 {\
590 "admin_quotafile_v2.usr", /* user admin quotafile */\
591 "admin_quotafile_v2.grp" /* group admin quotafile */\
594 #endif /* _LUSTRE_QUOTA_H */