Whamcloud - gitweb
b=15284
[fs/lustre-release.git] / lustre / include / lustre_quota.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  */
4 #ifndef _LUSTRE_QUOTA_H
5 #define _LUSTRE_QUOTA_H
6
7 #if defined(__linux__)
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>
13 #else
14 #error Unsupported operating system.
15 #endif
16
17 #include <lustre/lustre_idl.h>
18 #include <lustre_net.h>
19 #include <lvfs.h>
20 #include <obd_support.h>
21
22 struct obd_device;
23 struct client_obd;
24
25 #ifndef NR_DQHASH
26 #define NR_DQHASH 45
27 #endif
28
29 #ifdef HAVE_QUOTA_SUPPORT
30
31 #ifdef __KERNEL__
32
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;
41 };
42
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;
47 };
48
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 */
52
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 */
62 };
63
64 struct lustre_dquot {
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;
69         /* Use count */
70         int dq_refcnt;
71         /* Pointer of quota info it belongs to */
72         struct lustre_quota_info *dq_info;
73
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 */
80 };
81
82 struct dquot_id {
83         struct list_head        di_link;
84         __u32                   di_id;
85 };
86
87 #define QFILE_CHK               1
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
94
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);
106 #else
107
108 #ifndef DQ_FAKE_B
109 #define DQ_FAKE_B       6
110 #endif
111
112 static inline int lustre_check_quota_file(struct lustre_quota_info *lqi,
113                                           int type)
114 {
115         return 0;
116 }
117 static inline int lustre_read_quota_info(struct lustre_quota_info *lqi,
118                                          int type)
119 {
120         return 0;
121 }
122 static inline int lustre_write_quota_info(struct lustre_quota_info *lqi,
123                                           int type)
124 {
125         return 0;
126 }
127 static inline int lustre_read_dquot(struct lustre_dquot *dquot)
128 {
129         return 0;
130 }
131 static inline int lustre_commit_dquot(struct lustre_dquot *dquot)
132 {
133         return 0;
134 }
135 static inline int lustre_init_quota_info(struct lustre_quota_info *lqi,
136                                          int type)
137 {
138         return 0;
139 }
140 static inline int lustre_quota_convert(struct lustre_quota_info *lqi,
141                                        int type)
142 {
143         return 0;
144 }
145 #endif  /* KERNEL_VERSION(2,5,0) */
146
147 #define LL_DQUOT_OFF(sb)    DQUOT_OFF(sb)
148
149 typedef int (*dqacq_handler_t) (struct obd_device * obd, struct qunit_data * qd,
150                                 int opc);
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
160                                          * 0:Off, 1:On */
161         unsigned long lqc_iunit_sz;     /* original unit size of file quota and
162                                          * upper limitation for adjust file
163                                          * qunit */
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
170                                          * qunit */
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
174                                          * it */
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
178                                                 * size. default=4 */
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 */
189 };
190
191 #define LQC_HASH_BODY(qctxt) (qctxt->lqc_lqs_hash_body)
192
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
204                                            * finish */
205         unsigned long lqs_iwrite_pending; /* the inodes reached mds and don't
206                                            * finish */
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 */
214         spinlock_t lqs_lock;
215 };
216
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)
220
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)
224
225 static inline void lqs_getref(struct lustre_qunit_size *lqs)
226 {
227         atomic_inc(&lqs->lqs_refcount);
228 }
229
230 static inline void lqs_putref(struct lustre_qunit_size *lqs)
231 {
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);
236                 OBD_FREE_PTR(lqs);
237         }
238 }
239
240 static inline void lqs_initref(struct lustre_qunit_size *lqs)
241 {
242         atomic_set(&lqs->lqs_refcount, 0);
243 }
244
245 #else
246
247 struct lustre_quota_info {
248 };
249
250 struct lustre_quota_ctxt {
251 };
252
253 #endif  /* !__KERNEL__ */
254
255 #else
256
257 #define LL_DQUOT_OFF(sb) do {} while(0)
258
259 struct lustre_quota_info {
260 };
261
262 struct lustre_quota_ctxt {
263 };
264
265 #endif /* !HAVE_QUOTA_SUPPORT */
266
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 */
269 #define MIN_QLIMIT      1
270
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 */
276 };
277
278 typedef int (*quota_acquire)(struct obd_device *obd,
279                              unsigned int uid, unsigned int gid);
280
281 typedef struct {
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 *);
291
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);
295
296         /* For quota slave, set import, trigger quota recovery */
297         int (*quota_setinfo) (struct obd_export *, struct obd_device *);
298
299         /* For quota slave, clear import when relative import is invalid */
300         int (*quota_clearinfo) (struct obd_export *, struct obd_device *);
301
302         /* For quota slave, set proper thread resoure capability */
303         int (*quota_enforce) (struct obd_device *, unsigned int);
304
305         /* For quota slave, check whether specified uid/gid is over quota */
306         int (*quota_getflag) (struct obd_device *, struct obdo *);
307
308         /* For quota slave, acquire/release quota from master if needed */
309         int (*quota_acquire) (struct obd_device *, unsigned int, unsigned int);
310
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);
316
317         /* For quota client, poll if the quota check done */
318         int (*quota_poll_check) (struct obd_export *, struct if_quotacheck *);
319
320         /* For quota client, check whether specified uid/gid is over quota */
321         int (*quota_chkdq) (struct client_obd *, unsigned int, unsigned int);
322
323         /* For quota client, the actions after the pending write is committed */
324         int (*quota_pending_commit) (struct obd_device *, unsigned int,
325                                      unsigned int, int);
326
327         /* For quota client, set over quota flag for specifed uid/gid */
328         int (*quota_setdq) (struct client_obd *, unsigned int, unsigned int,
329                             obd_flag, obd_flag);
330
331         /* For adjusting qunit size b=10600 */
332         int (*quota_adjust_qunit) (struct obd_export *exp, struct
333                                    quota_adjust_qunit *oqaq);
334
335 } quota_interface_t;
336
337 #define Q_COPY(out, in, member) (out)->member = (in)->member
338
339 #define QUOTA_OP(interface, op) interface->quota_ ## op
340
341 #define QUOTA_CHECK_OP(interface, op)                           \
342 do {                                                            \
343         if (!interface)                                         \
344                 RETURN(0);                                      \
345         if (!QUOTA_OP(interface, op)) {                         \
346                 CERROR("no quota operation: " #op "\n");        \
347                 RETURN(-EOPNOTSUPP);                            \
348         }                                                       \
349 } while(0)
350
351 static inline int lquota_init(quota_interface_t *interface)
352 {
353         int rc;
354         ENTRY;
355
356         QUOTA_CHECK_OP(interface, init);
357         rc = QUOTA_OP(interface, init)();
358         RETURN(rc);
359 }
360
361 static inline int lquota_exit(quota_interface_t *interface)
362 {
363         int rc;
364         ENTRY;
365
366         QUOTA_CHECK_OP(interface, exit);
367         rc = QUOTA_OP(interface, exit)();
368         RETURN(rc);
369 }
370
371 static inline int lquota_setup(quota_interface_t *interface,
372                                struct obd_device *obd)
373 {
374         int rc;
375         ENTRY;
376
377         QUOTA_CHECK_OP(interface, setup);
378         rc = QUOTA_OP(interface, setup)(obd);
379         RETURN(rc);
380 }
381
382 static inline int lquota_cleanup(quota_interface_t *interface,
383                                  struct obd_device *obd)
384 {
385         int rc;
386         ENTRY;
387
388         QUOTA_CHECK_OP(interface, cleanup);
389         rc = QUOTA_OP(interface, cleanup)(obd);
390         RETURN(rc);
391 }
392
393 static inline int lquota_fs_cleanup(quota_interface_t *interface,
394                                     struct obd_device *obd)
395 {
396         int rc;
397         ENTRY;
398
399         QUOTA_CHECK_OP(interface, fs_cleanup);
400         rc = QUOTA_OP(interface, fs_cleanup)(obd);
401         RETURN(rc);
402 }
403
404 static inline int lquota_recovery(quota_interface_t *interface,
405                                   struct obd_device *obd)
406 {
407         int rc;
408         ENTRY;
409
410         QUOTA_CHECK_OP(interface, recovery);
411         rc = QUOTA_OP(interface, recovery)(obd);
412         RETURN(rc);
413 }
414
415 static inline int lquota_adjust(quota_interface_t *interface,
416                                 struct obd_device *obd,
417                                 unsigned int qcids[],
418                                 unsigned int qpids[],
419                                 int rc, int opc)
420 {
421         int ret;
422         ENTRY;
423
424         QUOTA_CHECK_OP(interface, adjust);
425         ret = QUOTA_OP(interface, adjust)(obd, qcids, qpids, rc, opc);
426         RETURN(ret);
427 }
428
429 static inline int lquota_chkdq(quota_interface_t *interface,
430                                struct client_obd *cli,
431                                unsigned int uid, unsigned int gid)
432 {
433         int rc;
434         ENTRY;
435
436         QUOTA_CHECK_OP(interface, chkdq);
437         rc = QUOTA_OP(interface, chkdq)(cli, uid, gid);
438         RETURN(rc);
439 }
440
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)
445 {
446         int rc;
447         ENTRY;
448
449         QUOTA_CHECK_OP(interface, setdq);
450         rc = QUOTA_OP(interface, setdq)(cli, uid, gid, valid, flags);
451         RETURN(rc);
452 }
453
454 static inline int lquota_poll_check(quota_interface_t *interface,
455                                     struct obd_export *exp,
456                                     struct if_quotacheck *qchk)
457 {
458         int rc;
459         ENTRY;
460
461         QUOTA_CHECK_OP(interface, poll_check);
462         rc = QUOTA_OP(interface, poll_check)(exp, qchk);
463         RETURN(rc);
464 }
465
466 static inline int lquota_setinfo(quota_interface_t *interface,
467                                  struct obd_export *exp,
468                                  struct obd_device *obd)
469 {
470         int rc;
471         ENTRY;
472
473         QUOTA_CHECK_OP(interface, setinfo);
474         rc = QUOTA_OP(interface, setinfo)(exp, obd);
475         RETURN(rc);
476 }
477
478 static inline int lquota_clearinfo(quota_interface_t *interface,
479                                    struct obd_export *exp,
480                                    struct obd_device *obd)
481 {
482         int rc;
483         ENTRY;
484
485         QUOTA_CHECK_OP(interface, clearinfo);
486         rc = QUOTA_OP(interface, clearinfo)(exp, obd);
487         RETURN(rc);
488 }
489
490 static inline int lquota_enforce(quota_interface_t *interface,
491                                  struct obd_device *obd,
492                                  unsigned int ignore)
493 {
494         int rc;
495         ENTRY;
496
497         QUOTA_CHECK_OP(interface, enforce);
498         rc = QUOTA_OP(interface, enforce)(obd, ignore);
499         RETURN(rc);
500 }
501
502 static inline int lquota_getflag(quota_interface_t *interface,
503                                  struct obd_device *obd, struct obdo *oa)
504 {
505         int rc;
506         ENTRY;
507
508         QUOTA_CHECK_OP(interface, getflag);
509         rc = QUOTA_OP(interface, getflag)(obd, oa);
510         RETURN(rc);
511 }
512
513 static inline int lquota_acquire(quota_interface_t *interface,
514                                  struct obd_device *obd,
515                                  unsigned int uid, unsigned int gid)
516 {
517         int rc;
518         ENTRY;
519
520         QUOTA_CHECK_OP(interface, acquire);
521         rc = QUOTA_OP(interface, acquire)(obd, uid, gid);
522         RETURN(rc);
523 }
524
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)
529 {
530         int rc;
531         ENTRY;
532
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));
537         RETURN(rc);
538 }
539
540 static inline int lquota_pending_commit(quota_interface_t *interface,
541                                         struct obd_device *obd,
542                                         unsigned int uid, unsigned int gid,
543                                         int npage)
544 {
545         int rc;
546         ENTRY;
547
548         QUOTA_CHECK_OP(interface, pending_commit);
549         rc = QUOTA_OP(interface, pending_commit)(obd, uid, gid, npage);
550         RETURN(rc);
551 }
552
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);
577
578 #ifndef __KERNEL__
579 extern quota_interface_t osc_quota_interface;
580 extern quota_interface_t mdc_quota_interface;
581 extern quota_interface_t lov_quota_interface;
582 #endif
583
584 #define LUSTRE_ADMIN_QUOTAFILES_V1 {\
585         "admin_quotafile.usr",  /* user admin quotafile */\
586         "admin_quotafile.grp"   /* group admin quotafile */\
587 }
588
589 #define LUSTRE_ADMIN_QUOTAFILES_V2 {\
590         "admin_quotafile_v2.usr",       /* user admin quotafile */\
591         "admin_quotafile_v2.grp"        /* group admin quotafile */\
592 }
593
594 #endif /* _LUSTRE_QUOTA_H */