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