r2599: avoid free()ing our static unalloceted memory that ends up in memory corruption.
[tprouty/samba.git] / source / lib / sysquotas_linux.c
1 /* 
2    Unix SMB/CIFS implementation.
3    System QUOTA function wrappers for LINUX
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 2 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, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21
22 #include "includes.h"
23
24 #undef DBGC_CLASS
25 #define DBGC_CLASS DBGC_QUOTA
26
27 #ifdef HAVE_QUOTACTL_LINUX 
28
29 #include "samba_linux_quota.h"
30
31 /****************************************************************************
32  Abstract out the v1 Linux quota get calls.
33 ****************************************************************************/
34 static int sys_get_linux_v1_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
35 {
36         int ret = -1;
37         uint32 qflags = 0;
38         struct v1_kern_dqblk D;
39         SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
40
41         ZERO_STRUCT(D);
42
43         switch (qtype) {
44                 case SMB_USER_QUOTA_TYPE:
45                         DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
46                                 path, bdev, (unsigned)id.uid));
47
48                         if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))&&errno != EDQUOT) {
49                                 return ret;
50                         }
51
52                         break;
53                 case SMB_GROUP_QUOTA_TYPE:
54                         DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
55                                 path, bdev, (unsigned)id.gid));
56
57                         if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))&&errno != EDQUOT) {
58                                 return ret;
59                         }
60
61                         break;
62                 case SMB_USER_FS_QUOTA_TYPE:
63                         DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
64                                 path, bdev, (unsigned)id.uid));
65
66                         if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) {
67                                 qflags |= QUOTAS_DENY_DISK;
68                         }
69
70                         break;
71                 case SMB_GROUP_FS_QUOTA_TYPE:
72                         DEBUG(10,("sys_get_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
73                                 path, bdev, (unsigned)id.gid));
74
75                         if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) {
76                                 qflags |= QUOTAS_DENY_DISK;
77                         }
78
79                         break;
80                 default:
81                         errno = ENOSYS;
82                         return -1;
83         }
84
85         dp->bsize = bsize;
86         dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
87         dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
88         dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
89         dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
90         dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
91         dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks;
92
93
94         dp->qflags = qflags;
95
96         return ret;
97 }
98
99 /****************************************************************************
100  Abstract out the v1 Linux quota set calls.
101 ****************************************************************************/
102 static int sys_set_linux_v1_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
103 {
104         int ret = -1;
105         uint32 qflags = 0;
106         uint32 oldqflags = 0;
107         struct v1_kern_dqblk D;
108         SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
109
110         ZERO_STRUCT(D);
111
112         if (bsize == dp->bsize) {
113                 D.dqb_bsoftlimit = dp->softlimit;
114                 D.dqb_bhardlimit = dp->hardlimit;
115                 D.dqb_ihardlimit = dp->ihardlimit;
116                 D.dqb_isoftlimit = dp->isoftlimit;
117         } else {
118                 D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
119                 D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
120                 D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize;
121                 D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize;
122         }
123
124         qflags = dp->qflags;
125
126         switch (qtype) {
127                 case SMB_USER_QUOTA_TYPE:
128                         DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
129                                 path, bdev, (unsigned)id.uid));
130
131                         ret = quotactl(QCMD(Q_V1_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D);
132                         break;
133                 case SMB_GROUP_QUOTA_TYPE:
134                         DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
135                                 path, bdev, (unsigned)id.gid));
136
137                         ret = quotactl(QCMD(Q_V1_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
138                         break;
139                 case SMB_USER_FS_QUOTA_TYPE:
140                         DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
141                                 path, bdev, (unsigned)id.uid));
142
143                         if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) {
144                                 oldqflags |= QUOTAS_DENY_DISK;
145                         }
146
147                         break;
148                 case SMB_GROUP_FS_QUOTA_TYPE:
149                         DEBUG(10,("sys_set_linux_v1_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
150                                 path, bdev, (unsigned)id.gid));
151
152                         if ((ret = quotactl(QCMD(Q_V1_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) {
153                                 oldqflags |= QUOTAS_DENY_DISK;
154                         }
155
156                         break;
157                 default:
158                         errno = ENOSYS;
159                         return -1;
160         }
161
162         return ret;
163 }
164
165 /****************************************************************************
166  Abstract out the v2 Linux quota get calls.
167 ****************************************************************************/
168 static int sys_get_linux_v2_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
169 {
170         int ret = -1;
171         uint32 qflags = 0;
172         struct v2_kern_dqblk D;
173         SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
174
175         ZERO_STRUCT(D);
176
177         switch (qtype) {
178                 case SMB_USER_QUOTA_TYPE:
179                         DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
180                                 path, bdev, (unsigned)id.uid));
181
182                         if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))&&errno != EDQUOT) {
183                                 return ret;
184                         }
185
186                         break;
187                 case SMB_GROUP_QUOTA_TYPE:
188                         DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
189                                 path, bdev, (unsigned)id.gid));
190
191                         if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))&&errno != EDQUOT) {
192                                 return ret;
193                         }
194
195                         break;
196                 case SMB_USER_FS_QUOTA_TYPE:
197                         DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
198                                 path, bdev, (unsigned)id.uid));
199
200                         if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) {
201                                 qflags |= QUOTAS_DENY_DISK;
202                         }
203
204                         break;
205                 case SMB_GROUP_FS_QUOTA_TYPE:
206                         DEBUG(10,("sys_get_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
207                                 path, bdev, (unsigned)id.gid));
208
209                         if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) {
210                                 qflags |= QUOTAS_DENY_DISK;
211                         }
212
213                         break;
214                 default:
215                         errno = ENOSYS;
216                         return -1;
217         }
218
219         dp->bsize = bsize;
220         dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
221         dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
222         dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
223         dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
224         dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
225         dp->curblocks = (SMB_BIG_UINT)D.dqb_curspace/bsize;
226
227
228         dp->qflags = qflags;
229
230         return ret;
231 }
232
233 /****************************************************************************
234  Abstract out the v2 Linux quota set calls.
235 ****************************************************************************/
236 static int sys_set_linux_v2_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
237 {
238         int ret = -1;
239         uint32 qflags = 0;
240         uint32 oldqflags = 0;
241         struct v2_kern_dqblk D;
242         SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
243
244         ZERO_STRUCT(D);
245
246         if (bsize == dp->bsize) {
247                 D.dqb_bsoftlimit = dp->softlimit;
248                 D.dqb_bhardlimit = dp->hardlimit;
249                 D.dqb_ihardlimit = dp->ihardlimit;
250                 D.dqb_isoftlimit = dp->isoftlimit;
251         } else {
252                 D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
253                 D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
254                 D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize;
255                 D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize;
256         }
257
258         qflags = dp->qflags;
259
260         switch (qtype) {
261                 case SMB_USER_QUOTA_TYPE:
262                         DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
263                                 path, bdev, (unsigned)id.uid));
264
265                         ret = quotactl(QCMD(Q_V2_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D);
266                         break;
267                 case SMB_GROUP_QUOTA_TYPE:
268                         DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
269                                 path, bdev, (unsigned)id.gid));
270
271                         ret = quotactl(QCMD(Q_V2_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
272                         break;
273                 case SMB_USER_FS_QUOTA_TYPE:
274                         DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
275                                 path, bdev, (unsigned)id.uid));
276
277                         if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) {
278                                 oldqflags |= QUOTAS_DENY_DISK;
279                         }
280
281                         break;
282                 case SMB_GROUP_FS_QUOTA_TYPE:
283                         DEBUG(10,("sys_set_linux_v2_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
284                                 path, bdev, (unsigned)id.gid));
285
286                         if ((ret = quotactl(QCMD(Q_V2_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) {
287                                 oldqflags |= QUOTAS_DENY_DISK;
288                         }
289
290                         break;
291                 default:
292                         errno = ENOSYS;
293                         return -1;
294         }
295
296         return ret;
297 }
298
299 /****************************************************************************
300  Abstract out the generic Linux quota get calls.
301 ****************************************************************************/
302 static int sys_get_linux_gen_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
303 {
304         int ret = -1;
305         uint32 qflags = 0;
306         struct if_dqblk D;
307         SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
308
309         ZERO_STRUCT(D);
310
311         switch (qtype) {
312                 case SMB_USER_QUOTA_TYPE:
313                         DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
314                                 path, bdev, (unsigned)id.uid));
315
316                         if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))&&errno != EDQUOT) {
317                                 return ret;
318                         }
319
320                         break;
321                 case SMB_GROUP_QUOTA_TYPE:
322                         DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
323                                 path, bdev, (unsigned)id.gid));
324
325                         if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))&&errno != EDQUOT) {
326                                 return ret;
327                         }
328
329                         break;
330                 case SMB_USER_FS_QUOTA_TYPE:
331                         DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
332                                 path, bdev, (unsigned)id.uid));
333
334                         if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) {
335                                 qflags |= QUOTAS_DENY_DISK;
336                         }
337
338                         break;
339                 case SMB_GROUP_FS_QUOTA_TYPE:
340                         DEBUG(10,("sys_get_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
341                                 path, bdev, (unsigned)id.gid));
342
343                         if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) {
344                                 qflags |= QUOTAS_DENY_DISK;
345                         }
346
347                         break;
348                 default:
349                         errno = ENOSYS;
350                         return -1;
351         }
352
353         dp->bsize = bsize;
354         dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
355         dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
356         dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
357         dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
358         dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
359         dp->curblocks = (SMB_BIG_UINT)D.dqb_curspace/bsize;
360
361
362         dp->qflags = qflags;
363
364         return ret;
365 }
366
367 /****************************************************************************
368  Abstract out the gen Linux quota set calls.
369 ****************************************************************************/
370 static int sys_set_linux_gen_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
371 {
372         int ret = -1;
373         uint32 qflags = 0;
374         uint32 oldqflags = 0;
375         struct if_dqblk D;
376         SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
377
378         ZERO_STRUCT(D);
379
380         if (bsize == dp->bsize) {
381                 D.dqb_bsoftlimit = dp->softlimit;
382                 D.dqb_bhardlimit = dp->hardlimit;
383                 D.dqb_ihardlimit = dp->ihardlimit;
384                 D.dqb_isoftlimit = dp->isoftlimit;
385         } else {
386                 D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
387                 D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
388                 D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize;
389                 D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize;
390         }
391
392         qflags = dp->qflags;
393
394         switch (qtype) {
395                 case SMB_USER_QUOTA_TYPE:
396                         DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
397                                 path, bdev, (unsigned)id.uid));
398
399                         ret = quotactl(QCMD(Q_SETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D);
400                         break;
401                 case SMB_GROUP_QUOTA_TYPE:
402                         DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
403                                 path, bdev, (unsigned)id.gid));
404
405                         ret = quotactl(QCMD(Q_SETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
406                         break;
407                 case SMB_USER_FS_QUOTA_TYPE:
408                         DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
409                                 path, bdev, (unsigned)id.uid));
410
411                         if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D))==0) {
412                                 oldqflags |= QUOTAS_DENY_DISK;
413                         }
414
415                         break;
416                 case SMB_GROUP_FS_QUOTA_TYPE:
417                         DEBUG(10,("sys_set_linux_gen_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
418                                 path, bdev, (unsigned)id.gid));
419
420                         if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D))==0) {
421                                 oldqflags |= QUOTAS_DENY_DISK;
422                         }
423
424                         break;
425                 default:
426                         errno = ENOSYS;
427                         return -1;
428         }
429
430         return ret;
431 }
432
433 /****************************************************************************
434  Abstract out the Linux quota get calls.
435 ****************************************************************************/
436 int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
437 {
438         int ret = -1;
439
440         if (!path||!bdev||!dp)
441                 smb_panic("sys_set_vfs_quota: called with NULL pointer");
442
443         ZERO_STRUCT(*dp);
444         dp->qtype = qtype;
445
446         switch (qtype) {
447                 case SMB_USER_QUOTA_TYPE:
448                 case SMB_GROUP_QUOTA_TYPE:
449                         if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) {
450                                 if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) {
451                                         if ((ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) {
452                                                 return ret;
453                                         }
454                                 }
455                         }
456
457                         if ((dp->curblocks==0)&&
458                                 (dp->softlimit==0)&&
459                                 (dp->hardlimit==0)) {
460                                 /* the upper layer functions don't want empty quota records...*/
461                                 return -1;
462                         }
463
464                         break;
465                 case SMB_USER_FS_QUOTA_TYPE:
466                         id.uid = getuid();
467
468                         if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) {
469                                 if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) {
470                                         ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp);
471                                 }
472                         }
473
474                         ret = 0;
475                         break;
476                 case SMB_GROUP_FS_QUOTA_TYPE:
477                         id.gid = getgid();
478
479                         if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) {
480                                 if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))&&errno != EDQUOT) {
481                                         ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp);
482                                 }
483                         }
484
485                         ret = 0;
486                         break;
487                 default:
488                         errno = ENOSYS;
489                         return -1;
490         }
491
492         return ret;
493 }
494
495 /****************************************************************************
496  Abstract out the Linux quota set calls.
497 ****************************************************************************/
498 int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
499 {
500         int ret = -1;
501         uint32 oldqflags = 0;
502
503         if (!path||!bdev||!dp)
504                 smb_panic("sys_set_vfs_quota: called with NULL pointer");
505
506         oldqflags = dp->qflags;
507
508         switch (qtype) {
509                 case SMB_USER_QUOTA_TYPE:
510                 case SMB_GROUP_QUOTA_TYPE:
511                         if ((ret=sys_set_linux_gen_quota(path, bdev, qtype, id, dp))) {
512                                 if ((ret=sys_set_linux_v2_quota(path, bdev, qtype, id, dp))) {
513                                         if ((ret=sys_set_linux_v1_quota(path, bdev, qtype, id, dp))) {
514                                                 return ret;
515                                         }
516                                 }
517                         }
518                         break;
519                 case SMB_USER_FS_QUOTA_TYPE:
520                         id.uid = getuid();
521
522                         if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))) {
523                                 if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))) {
524                                         ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp);
525                                 }
526                         }
527
528                         if (oldqflags == dp->qflags) {
529                                 ret = 0;
530                         } else {
531                                 ret = -1;
532                         }
533                         break;
534                 case SMB_GROUP_FS_QUOTA_TYPE:
535                         id.gid = getgid();
536
537                         if ((ret=sys_get_linux_gen_quota(path, bdev, qtype, id, dp))) {
538                                 if ((ret=sys_get_linux_v2_quota(path, bdev, qtype, id, dp))) {
539                                         ret=sys_get_linux_v1_quota(path, bdev, qtype, id, dp);
540                                 }
541                         }
542
543                         if (oldqflags == dp->qflags) {
544                                 ret = 0;
545                         } else {
546                                 ret = -1;
547                         }
548
549                         break;
550                 default:
551                         errno = ENOSYS;
552                         return -1;
553         }
554
555         return ret;
556 }
557
558 #else /* HAVE_QUOTACTL_LINUX */
559  void dummy_sysquotas_linux(void){}
560 #endif /* HAVE_QUOTACTL_LINUX */