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