quota: fix build of sysquote_xfs on
[samba.git] / source3 / lib / sysquotas_xfs.c
1 /* 
2    Unix SMB/CIFS implementation.
3    System QUOTA function wrappers for XFS
4    Copyright (C) Stefan (metze) Metzmacher      2003
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 as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20
21 #include "includes.h"
22
23 #undef DBGC_CLASS
24 #define DBGC_CLASS DBGC_QUOTA
25
26 #ifndef HAVE_SYS_QUOTAS
27 #ifdef HAVE_XFS_QUOTAS
28 #undef HAVE_XFS_QUOTAS
29 #endif
30 #endif
31
32 #ifdef HAVE_XFS_QUOTAS
33
34 #ifdef HAVE_LINUX_XFS_QUOTAS
35 #include "samba_linux_quota.h"
36 #ifdef HAVE_LINUX_DQBLK_XFS_H
37 #include <linux/dqblk_xfs.h>
38 #ifndef XFS_QUOTA_UDQ_ACCT
39 #define XFS_QUOTA_UDQ_ACCT FS_QUOTA_UDQ_ACCT
40 #endif
41 #ifndef XFS_QUOTA_UDQ_ENFD
42 #define XFS_QUOTA_UDQ_ENFD FS_QUOTA_UDQ_ENFD
43 #endif
44 #ifndef XFS_QUOTA_GDQ_ACCT
45 #define XFS_QUOTA_GDQ_ACCT FS_QUOTA_GDQ_ACCT
46 #endif
47 #ifndef XFS_QUOTA_GDQ_ENFD
48 #define XFS_QUOTA_GDQ_ENFD FS_QUOTA_GDQ_ENFD
49 #endif
50 #endif
51 #define HAVE_GROUP_QUOTA
52 #else /* IRIX */
53 #include <sys/quota.h> 
54 #endif
55
56 /* on IRIX */
57 #ifndef Q_XQUOTAON
58 #define Q_XQUOTAON Q_QUOTAON
59 #endif /* Q_XQUOTAON */
60 #ifndef Q_XQUOTAOFF
61 #define Q_XQUOTAOFF Q_QUOTAOFF
62 #endif /* Q_XQUOTAOFF */
63 #ifndef Q_XGETQSTAT
64 #define Q_XGETQSTAT Q_GETQSTAT
65 #endif /* Q_XGETQSTAT */
66
67 /* currently doesn't support Group and Project quotas on IRIX 
68  */
69
70 #ifndef QCMD
71 #define QCMD(x,y) x
72 #endif
73
74 /*
75  * IRIX has BBSIZE in <sys/param.h>
76  */
77 #ifndef BBSHIFT
78 #define BBSHIFT         9
79 #endif /* BBSHIFT */
80 #ifndef BBSIZE
81 #define BBSIZE          (1<<BBSHIFT)
82 #endif /* BBSIZE */
83
84 /****************************************************************************
85  Abstract out the XFS Quota Manager quota get call.
86 ****************************************************************************/
87 int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
88 {
89         int ret = -1;
90         uint32 qflags = 0;
91         uint64_t bsize = (uint64_t)BBSIZE;
92         struct fs_disk_quota D;
93         struct fs_quota_stat F;
94         ZERO_STRUCT(D);
95         ZERO_STRUCT(F);
96
97         if (!bdev||!dp)
98                 smb_panic("sys_get_xfs_quota: called with NULL pointer");
99                 
100         ZERO_STRUCT(*dp);
101         dp->qtype = qtype;
102                 
103         switch (qtype) {
104                 case SMB_USER_QUOTA_TYPE:
105                         DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
106                                 path, bdev, (unsigned)id.uid));
107
108                         if ((ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D)))
109                                 return ret;
110                         break;
111 #ifdef HAVE_GROUP_QUOTA
112                 case SMB_GROUP_QUOTA_TYPE:
113                         DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
114                                 path, bdev, (unsigned)id.gid));
115
116                         if ((ret=quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D)))
117                                 return ret;
118                         break;
119 #endif /* HAVE_GROUP_QUOTA */
120                 case SMB_USER_FS_QUOTA_TYPE:
121                         DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
122                                 path, bdev, (unsigned)id.uid));
123
124                         quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F);
125
126                         if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) {
127                                 qflags |= QUOTAS_DENY_DISK;
128                         }
129                         else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) {
130                                 qflags |= QUOTAS_ENABLED;
131                         }
132
133                         ret = 0;
134
135                         break;
136 #ifdef HAVE_GROUP_QUOTA
137                 case SMB_GROUP_FS_QUOTA_TYPE:
138                         DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
139                                 path, bdev, (unsigned)id.gid));
140
141                         quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F);
142
143                         if (F.qs_flags & XFS_QUOTA_GDQ_ENFD) {
144                                 qflags |= QUOTAS_DENY_DISK;
145                         }
146                         else if (F.qs_flags & XFS_QUOTA_GDQ_ACCT) {
147                                 qflags |= QUOTAS_ENABLED;
148                         }
149
150                         ret = 0;
151
152                         break;
153 #endif /* HAVE_GROUP_QUOTA */
154                 default:
155                         errno = ENOSYS;
156                         return -1;
157         }
158
159         dp->bsize = bsize;
160         dp->softlimit = (uint64_t)D.d_blk_softlimit;
161         dp->hardlimit = (uint64_t)D.d_blk_hardlimit;
162         dp->ihardlimit = (uint64_t)D.d_ino_hardlimit;
163         dp->isoftlimit = (uint64_t)D.d_ino_softlimit;
164         dp->curinodes = (uint64_t)D.d_icount;
165         dp->curblocks = (uint64_t)D.d_bcount;
166         dp->qflags = qflags;
167
168         return ret;
169 }
170
171 /****************************************************************************
172  Abstract out the XFS Quota Manager quota set call.
173 ****************************************************************************/
174 int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
175 {
176         int ret = -1;
177         uint32 qflags = 0;
178         uint64_t bsize = (uint64_t)BBSIZE;
179         struct fs_disk_quota D;
180         struct fs_quota_stat F;
181         int q_on = 0;
182         int q_off = 0;
183         ZERO_STRUCT(D);
184         ZERO_STRUCT(F);
185
186         if (!bdev||!dp)
187                 smb_panic("sys_set_xfs_quota: called with NULL pointer");
188         
189         if (bsize == dp->bsize) {
190                 D.d_blk_softlimit = dp->softlimit;
191                 D.d_blk_hardlimit = dp->hardlimit;
192                 D.d_ino_hardlimit = dp->ihardlimit;
193                 D.d_ino_softlimit = dp->isoftlimit;
194         } else {
195                 D.d_blk_softlimit = (dp->softlimit*dp->bsize)/bsize;
196                 D.d_blk_hardlimit = (dp->hardlimit*dp->bsize)/bsize;
197                 D.d_ino_hardlimit = (dp->ihardlimit*dp->bsize)/bsize;
198                 D.d_ino_softlimit = (dp->isoftlimit*dp->bsize)/bsize;           
199         }
200
201         qflags = dp->qflags;
202
203         switch (qtype) {
204                 case SMB_USER_QUOTA_TYPE:
205                         DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
206                                 path, bdev, (unsigned)id.uid));
207
208                         D.d_fieldmask |= FS_DQ_LIMIT_MASK;
209                         ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (caddr_t)&D);
210                         break;
211 #ifdef HAVE_GROUP_QUOTA
212                 case SMB_GROUP_QUOTA_TYPE:
213                         DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
214                                 path, bdev, (unsigned)id.gid));
215
216                         D.d_fieldmask |= FS_DQ_LIMIT_MASK;
217                         ret = quotactl(QCMD(Q_XSETQLIM,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
218                         break;
219 #endif /* HAVE_GROUP_QUOTA */
220                 case SMB_USER_FS_QUOTA_TYPE:
221                         DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
222                                 path, bdev, (unsigned)id.uid));
223
224                         quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F);
225                         
226                         if (qflags & QUOTAS_DENY_DISK) {
227                                 if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD))
228                                         q_on |= XFS_QUOTA_UDQ_ENFD;
229                                 if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
230                                         q_on |= XFS_QUOTA_UDQ_ACCT;
231                                 
232                                 if (q_on != 0) {
233                                         ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on);
234                                 } else {
235                                         ret = 0;
236                                 }
237
238                         } else if (qflags & QUOTAS_ENABLED) {
239                                 if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
240                                         q_off |= XFS_QUOTA_UDQ_ENFD;
241
242                                 if (q_off != 0) {
243                                         ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off);
244                                 } else {
245                                         ret = 0;
246                                 }
247
248                                 if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
249                                         q_on |= XFS_QUOTA_UDQ_ACCT;
250
251                                 if (q_on != 0) {
252                                         ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on);
253                                 } else {
254                                         ret = 0;
255                                 }
256                         } else {
257 #if 0
258                         /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
259                          * only swittching off XFS_QUOTA_UDQ_ACCT work
260                          */
261                                 if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
262                                         q_off |= XFS_QUOTA_UDQ_ENFD;
263                                 if (F.qs_flags & XFS_QUOTA_UDQ_ACCT)
264                                         q_off |= XFS_QUOTA_UDQ_ACCT;
265
266                                 if (q_off !=0) {
267                                         ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off);
268                                 } else {
269                                         ret = 0;
270                                 }
271 #else
272                                 ret = -1;
273 #endif
274                         }
275
276                         break;
277 #ifdef HAVE_GROUP_QUOTA
278                 case SMB_GROUP_FS_QUOTA_TYPE:
279                         DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
280                                 path, bdev, (unsigned)id.gid));
281
282                         quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F);
283                         
284                         if (qflags & QUOTAS_DENY_DISK) {
285                                 if (!(F.qs_flags & XFS_QUOTA_GDQ_ENFD))
286                                         q_on |= XFS_QUOTA_GDQ_ENFD;
287                                 if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
288                                         q_on |= XFS_QUOTA_GDQ_ACCT;
289                                 
290                                 if (q_on != 0) {
291                                         ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on);
292                                 } else {
293                                         ret = 0;
294                                 }
295
296                         } else if (qflags & QUOTAS_ENABLED) {
297                                 if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
298                                         q_off |= XFS_QUOTA_GDQ_ENFD;
299
300                                 if (q_off != 0) {
301                                         ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off);
302                                 } else {
303                                         ret = 0;
304                                 }
305
306                                 if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
307                                         q_on |= XFS_QUOTA_GDQ_ACCT;
308
309                                 if (q_on != 0) {
310                                         ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on);
311                                 } else {
312                                         ret = 0;
313                                 }
314                         } else {
315 #if 0
316                         /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
317                          * only swittching off XFS_QUOTA_UDQ_ACCT work
318                          */
319                                 if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
320                                         q_off |= XFS_QUOTA_GDQ_ENFD;
321                                 if (F.qs_flags & XFS_QUOTA_GDQ_ACCT)
322                                         q_off |= XFS_QUOTA_GDQ_ACCT;
323
324                                 if (q_off !=0) {
325                                         ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off);
326                                 } else {
327                                         ret = 0;
328                                 }
329 #else
330                                 ret = -1;
331 #endif
332                         }
333
334                         break;
335 #endif /* HAVE_GROUP_QUOTA */
336                 default:
337                         errno = ENOSYS;
338                         return -1;
339         }
340
341         return ret;
342 }
343
344 #else /* HAVE_XFS_QUOTAS */
345  void dummy_sysquotas_xfs(void);
346
347  void dummy_sysquotas_xfs(void){}
348 #endif /* HAVE_XFS_QUOTAS */