Whamcloud - gitweb
2b26e244b0a97ae4121526d552e77b04566f07a5
[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  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see
20  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36
37 #ifndef _LUSTRE_QUOTA_H
38 #define _LUSTRE_QUOTA_H
39
40 #if defined(__linux__)
41 #include <linux/lustre_quota.h>
42 #elif defined(__APPLE__)
43 #include <darwin/lustre_quota.h>
44 #elif defined(__WINNT__)
45 #include <winnt/lustre_quota.h>
46 #else
47 #error Unsupported operating system.
48 #endif
49
50 #include <lustre/lustre_idl.h>
51 #include <lustre_net.h>
52 #include <lvfs.h>
53
54 struct obd_device;
55 struct client_obd;
56
57 #ifndef NR_DQHASH
58 #define NR_DQHASH 45
59 #endif
60
61 #ifdef HAVE_QUOTA_SUPPORT
62
63 #ifdef __KERNEL__
64
65 /* structures to access admin quotafile */
66 struct lustre_mem_dqinfo {
67         unsigned int dqi_bgrace;
68         unsigned int dqi_igrace;
69         unsigned long dqi_flags;
70         unsigned int dqi_blocks;
71         unsigned int dqi_free_blk;
72         unsigned int dqi_free_entry;
73 };
74
75 struct lustre_quota_info {
76         struct file *qi_files[MAXQUOTAS];
77         struct lustre_mem_dqinfo qi_info[MAXQUOTAS];
78 };
79
80 #define DQ_STATUS_AVAIL         0x0     /* Available dquot */
81 #define DQ_STATUS_SET           0x01    /* Sombody is setting dquot */
82 #define DQ_STATUS_RECOVERY      0x02    /* dquot is in recovery */
83
84 struct lustre_dquot {
85         /* Hash list in memory, protect by dquot_hash_lock */
86         struct list_head dq_hash;
87         /* Protect the data in lustre_dquot */
88         struct semaphore dq_sem;
89         /* Use count */
90         int dq_refcnt;
91         /* Pointer of quota info it belongs to */
92         struct lustre_quota_info *dq_info;
93         
94         loff_t dq_off;                  /* Offset of dquot on disk */
95         unsigned int dq_id;             /* ID this applies to (uid, gid) */
96         int dq_type;                    /* Type fo quota (USRQUOTA, GRPQUOUTA) */
97         unsigned short dq_status;       /* See DQ_STATUS_ */
98         unsigned long dq_flags;         /* See DQ_ in quota.h */
99         struct mem_dqblk dq_dqb;        /* Diskquota usage */
100 };
101
102 struct dquot_id {
103         struct list_head        di_link;
104         __u32                   di_id;
105 };
106
107 #define QFILE_CHK               1
108 #define QFILE_RD_INFO           2
109 #define QFILE_WR_INFO           3
110 #define QFILE_INIT_INFO         4
111 #define QFILE_RD_DQUOT          5
112 #define QFILE_WR_DQUOT          6
113
114 /* admin quotafile operations */
115 int lustre_check_quota_file(struct lustre_quota_info *lqi, int type);
116 int lustre_read_quota_info(struct lustre_quota_info *lqi, int type);
117 int lustre_write_quota_info(struct lustre_quota_info *lqi, int type);
118 int lustre_read_dquot(struct lustre_dquot *dquot);
119 int lustre_commit_dquot(struct lustre_dquot *dquot);
120 int lustre_init_quota_info(struct lustre_quota_info *lqi, int type);
121 int lustre_get_qids(struct file *file, struct inode *inode, int type, 
122                     struct list_head *list);
123
124 #define LL_DQUOT_OFF(sb)    DQUOT_OFF(sb)
125
126 typedef int (*dqacq_handler_t) (struct obd_device * obd, struct qunit_data * qd,
127                                 int opc);
128 struct lustre_quota_ctxt {
129         struct super_block *lqc_sb;     /* superblock this applies to */
130         struct obd_import *lqc_import;  /* import used to send dqacq/dqrel RPC */
131         dqacq_handler_t lqc_handler;    /* dqacq/dqrel RPC handler, only for quota master */ 
132         unsigned long lqc_recovery:1,   /* Doing recovery */ 
133                       lqc_atype:2,      /* Turn on user/group quota at setup automatically, 
134                                          * 0: none, 1: user quota, 2: group quota, 3: both */
135                       lqc_status:1;     /* Quota status. 0:Off, 1:On */
136         unsigned long lqc_iunit_sz;     /* Unit size of file quota */
137         unsigned long lqc_itune_sz;     /* Trigger dqacq when available file quota less than
138                                          * this value, trigger dqrel when available file quota
139                                          * more than this value + 1 iunit */
140         unsigned long lqc_bunit_sz;     /* Unit size of block quota */
141         unsigned long lqc_btune_sz;     /* See comment of lqc_itune_sz */
142 };
143
144 #else
145
146 struct lustre_quota_info {
147 };
148
149 struct lustre_quota_ctxt {
150 };
151
152 #endif  /* !__KERNEL__ */
153
154 #else
155
156 #define LL_DQUOT_OFF(sb) do {} while(0)
157
158 struct lustre_quota_info {
159 };
160
161 struct lustre_quota_ctxt {
162 };
163
164 #endif /* !HAVE_QUOTA_SUPPORT */
165
166 /* If the (quota limit < qunit * slave count), the slave which can't
167  * acquire qunit should set it's local limit as MIN_QLIMIT */
168 #define MIN_QLIMIT      1
169
170 struct quotacheck_thread_args {
171         struct obd_export   *qta_exp;   /* obd export */
172         struct obd_quotactl  qta_oqctl; /* obd_quotactl args */
173         struct super_block  *qta_sb;    /* obd super block */
174         atomic_t            *qta_sem;   /* obt_quotachecking */
175 };
176
177 typedef struct {
178         int (*quota_init) (void);
179         int (*quota_exit) (void);
180         int (*quota_setup) (struct obd_device *);
181         int (*quota_cleanup) (struct obd_device *);
182         /* For quota master, close admin quota files */
183         int (*quota_fs_cleanup) (struct obd_device *);
184         int (*quota_ctl) (struct obd_export *, struct obd_quotactl *);
185         int (*quota_check) (struct obd_export *, struct obd_quotactl *);
186         int (*quota_recovery) (struct obd_device *);
187         
188         /* For quota master/slave, adjust quota limit after fs operation */
189         int (*quota_adjust) (struct obd_device *, unsigned int[], 
190                              unsigned int[], int, int); 
191         
192         /* For quota slave, set import, trigger quota recovery */
193         int (*quota_setinfo) (struct obd_export *, struct obd_device *);
194         
195         /* For quota slave, set proper thread resoure capability */
196         int (*quota_enforce) (struct obd_device *, unsigned int);
197         
198         /* For quota slave, check whether specified uid/gid is over quota */
199         int (*quota_getflag) (struct obd_device *, struct obdo *);
200         
201         /* For quota slave, acquire/release quota from master if needed */
202         int (*quota_acquire) (struct obd_device *, unsigned int, unsigned int);
203         
204         /* For quota slave, check whether specified uid/gid's remaining quota
205          * can finish a write rpc */
206         int (*quota_chkquota) (struct obd_device *, unsigned int, unsigned int,
207                                int);
208
209         /* For quota client, poll if the quota check done */
210         int (*quota_poll_check) (struct obd_export *, struct if_quotacheck *);
211         
212         /* For quota client, check whether specified uid/gid is over quota */
213         int (*quota_chkdq) (struct client_obd *, unsigned int, unsigned int);
214         
215         /* For quota client, set over quota flag for specifed uid/gid */
216         int (*quota_setdq) (struct client_obd *, unsigned int, unsigned int,
217                             obd_flag, obd_flag);
218 } quota_interface_t;
219
220 #define Q_COPY(out, in, member) (out)->member = (in)->member
221
222 #define QUOTA_OP(interface, op) interface->quota_ ## op         
223
224 #define QUOTA_CHECK_OP(interface, op)                           \
225 do {                                                            \
226         if (!interface)                                         \
227                 RETURN(0);                                      \
228         if (!QUOTA_OP(interface, op)) {                         \
229                 CERROR("no quota operation: " #op "\n");        \
230                 RETURN(-EOPNOTSUPP);                            \
231         }                                                       \
232 } while(0)
233
234 static inline int lquota_init(quota_interface_t *interface)
235 {
236         int rc;
237         ENTRY;
238         
239         QUOTA_CHECK_OP(interface, init);
240         rc = QUOTA_OP(interface, init)();
241         RETURN(rc);
242 }
243
244 static inline int lquota_exit(quota_interface_t *interface) 
245 {
246         int rc;
247         ENTRY;
248         
249         QUOTA_CHECK_OP(interface, exit);
250         rc = QUOTA_OP(interface, exit)();
251         RETURN(rc);
252 }
253
254 static inline int lquota_setup(quota_interface_t *interface,
255                                struct obd_device *obd) 
256 {
257         int rc;
258         ENTRY;
259         
260         QUOTA_CHECK_OP(interface, setup);
261         rc = QUOTA_OP(interface, setup)(obd);
262         RETURN(rc);
263 }
264
265 static inline int lquota_cleanup(quota_interface_t *interface,
266                                  struct obd_device *obd) 
267 {
268         int rc;
269         ENTRY;
270         
271         QUOTA_CHECK_OP(interface, cleanup);
272         rc = QUOTA_OP(interface, cleanup)(obd);
273         RETURN(rc);
274 }
275
276 static inline int lquota_fs_cleanup(quota_interface_t *interface,
277                                     struct obd_device *obd)
278 {
279         int rc;
280         ENTRY;
281         
282         QUOTA_CHECK_OP(interface, fs_cleanup);
283         rc = QUOTA_OP(interface, fs_cleanup)(obd);
284         RETURN(rc);
285 }
286
287 static inline int lquota_recovery(quota_interface_t *interface,
288                                   struct obd_device *obd) 
289 {        
290         int rc;
291         ENTRY;
292         
293         QUOTA_CHECK_OP(interface, recovery);
294         rc = QUOTA_OP(interface, recovery)(obd);
295         RETURN(rc);
296 }
297
298 static inline int lquota_adjust(quota_interface_t *interface,
299                                 struct obd_device *obd, 
300                                 unsigned int qcids[], 
301                                 unsigned int qpids[], 
302                                 int rc, int opc) 
303 {
304         int ret;
305         ENTRY;
306         
307         QUOTA_CHECK_OP(interface, adjust);
308         ret = QUOTA_OP(interface, adjust)(obd, qcids, qpids, rc, opc);
309         RETURN(ret);
310 }
311
312 static inline int lquota_chkdq(quota_interface_t *interface,
313                                struct client_obd *cli,
314                                unsigned int uid, unsigned int gid)
315 {
316         int rc;
317         ENTRY;
318         
319         QUOTA_CHECK_OP(interface, chkdq);
320         rc = QUOTA_OP(interface, chkdq)(cli, uid, gid);
321         RETURN(rc);
322 }
323
324 static inline int lquota_setdq(quota_interface_t *interface,
325                                struct client_obd *cli,
326                                unsigned int uid, unsigned int gid,
327                                obd_flag valid, obd_flag flags)
328 {
329         int rc;
330         ENTRY;
331         
332         QUOTA_CHECK_OP(interface, setdq);
333         rc = QUOTA_OP(interface, setdq)(cli, uid, gid, valid, flags);
334         RETURN(rc);
335 }
336
337 static inline int lquota_poll_check(quota_interface_t *interface,
338                                     struct obd_export *exp,
339                                     struct if_quotacheck *qchk)
340 {
341         int rc;
342         ENTRY;
343         
344         QUOTA_CHECK_OP(interface, poll_check);
345         rc = QUOTA_OP(interface, poll_check)(exp, qchk);
346         RETURN(rc);
347 }
348
349        
350 static inline int lquota_setinfo(quota_interface_t *interface,
351                                  struct obd_export *exp, 
352                                  struct obd_device *obd) 
353 {
354         int rc;
355         ENTRY;
356
357         QUOTA_CHECK_OP(interface, setinfo);
358         rc = QUOTA_OP(interface, setinfo)(exp, obd);
359         RETURN(rc);
360 }
361
362 static inline int lquota_enforce(quota_interface_t *interface, 
363                                  struct obd_device *obd,
364                                  unsigned int ignore)
365 {
366         int rc;
367         ENTRY;
368
369         QUOTA_CHECK_OP(interface, enforce);
370         rc = QUOTA_OP(interface, enforce)(obd, ignore);
371         RETURN(rc);
372 }
373
374 static inline int lquota_getflag(quota_interface_t *interface,
375                                  struct obd_device *obd, struct obdo *oa)
376 {
377         int rc;
378         ENTRY;
379
380         QUOTA_CHECK_OP(interface, getflag);
381         rc = QUOTA_OP(interface, getflag)(obd, oa);
382         RETURN(rc);
383 }
384         
385 static inline int lquota_acquire(quota_interface_t *interface,
386                                  struct obd_device *obd, 
387                                  unsigned int uid, unsigned int gid)
388 {
389         int rc;
390         ENTRY;
391
392         QUOTA_CHECK_OP(interface, acquire);
393         rc = QUOTA_OP(interface, acquire)(obd, uid, gid);
394         RETURN(rc);
395 }
396
397 static inline int lquota_chkquota(quota_interface_t *interface,
398                                   struct obd_device *obd,
399                                   unsigned int uid, unsigned int gid,
400                                   int npage)
401 {
402         int rc;
403         ENTRY;
404         
405         QUOTA_CHECK_OP(interface, chkquota);
406         rc = QUOTA_OP(interface, chkquota)(obd, uid, gid, npage);
407         RETURN(rc);
408 }
409
410 int lprocfs_rd_bunit(char *page, char **start, off_t off, int count, 
411                      int *eof, void *data);
412 int lprocfs_rd_iunit(char *page, char **start, off_t off, int count, 
413                      int *eof, void *data);
414 int lprocfs_wr_bunit(struct file *file, const char *buffer,
415                      unsigned long count, void *data);
416 int lprocfs_wr_iunit(struct file *file, const char *buffer,
417                      unsigned long count, void *data);
418 int lprocfs_rd_btune(char *page, char **start, off_t off, int count, 
419                      int *eof, void *data);
420 int lprocfs_rd_itune(char *page, char **start, off_t off, int count, 
421                      int *eof, void *data);
422 int lprocfs_wr_btune(struct file *file, const char *buffer,
423                      unsigned long count, void *data);
424 int lprocfs_wr_itune(struct file *file, const char *buffer,
425                      unsigned long count, void *data);
426 int lprocfs_rd_type(char *page, char **start, off_t off, int count, 
427                     int *eof, void *data);
428 int lprocfs_wr_type(struct file *file, const char *buffer,
429                     unsigned long count, void *data);
430
431 #ifndef __KERNEL__
432 extern quota_interface_t osc_quota_interface;
433 extern quota_interface_t mdc_quota_interface;
434 extern quota_interface_t lov_quota_interface;
435 #endif
436
437 #endif /* _LUSTRE_QUOTA_H */