s3:g_lock: remove an unreached code path.
[amitay/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 #endif
39 #define HAVE_GROUP_QUOTA
40 #else /* IRIX */
41 #include <sys/quota.h> 
42 #endif
43
44 /* on IRIX */
45 #ifndef Q_XQUOTAON
46 #define Q_XQUOTAON Q_QUOTAON
47 #endif /* Q_XQUOTAON */
48 #ifndef Q_XQUOTAOFF
49 #define Q_XQUOTAOFF Q_QUOTAOFF
50 #endif /* Q_XQUOTAOFF */
51 #ifndef Q_XGETQSTAT
52 #define Q_XGETQSTAT Q_GETQSTAT
53 #endif /* Q_XGETQSTAT */
54
55 /* currently doesn't support Group and Project quotas on IRIX 
56  */
57
58 #ifndef QCMD
59 #define QCMD(x,y) x
60 #endif
61
62 /*
63  * IRIX has BBSIZE in <sys/param.h>
64  */
65 #ifndef BBSHIFT
66 #define BBSHIFT         9
67 #endif /* BBSHIFT */
68 #ifndef BBSIZE
69 #define BBSIZE          (1<<BBSHIFT)
70 #endif /* BBSIZE */
71
72 /****************************************************************************
73  Abstract out the XFS Quota Manager quota get call.
74 ****************************************************************************/
75 int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
76 {
77         int ret = -1;
78         uint32 qflags = 0;
79         uint64_t bsize = (uint64_t)BBSIZE;
80         struct fs_disk_quota D;
81         struct fs_quota_stat F;
82         ZERO_STRUCT(D);
83         ZERO_STRUCT(F);
84
85         if (!bdev||!dp)
86                 smb_panic("sys_get_xfs_quota: called with NULL pointer");
87                 
88         ZERO_STRUCT(*dp);
89         dp->qtype = qtype;
90                 
91         switch (qtype) {
92                 case SMB_USER_QUOTA_TYPE:
93                         DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
94                                 path, bdev, (unsigned)id.uid));
95
96                         if ((ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D)))
97                                 return ret;
98                         break;
99 #ifdef HAVE_GROUP_QUOTA
100                 case SMB_GROUP_QUOTA_TYPE:
101                         DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
102                                 path, bdev, (unsigned)id.gid));
103
104                         if ((ret=quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D)))
105                                 return ret;
106                         break;
107 #endif /* HAVE_GROUP_QUOTA */
108                 case SMB_USER_FS_QUOTA_TYPE:
109                         DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
110                                 path, bdev, (unsigned)id.uid));
111
112                         quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F);
113
114                         if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) {
115                                 qflags |= QUOTAS_DENY_DISK;
116                         }
117                         else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) {
118                                 qflags |= QUOTAS_ENABLED;
119                         }
120
121                         ret = 0;
122
123                         break;
124 #ifdef HAVE_GROUP_QUOTA
125                 case SMB_GROUP_FS_QUOTA_TYPE:
126                         DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
127                                 path, bdev, (unsigned)id.gid));
128
129                         quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F);
130
131                         if (F.qs_flags & XFS_QUOTA_GDQ_ENFD) {
132                                 qflags |= QUOTAS_DENY_DISK;
133                         }
134                         else if (F.qs_flags & XFS_QUOTA_GDQ_ACCT) {
135                                 qflags |= QUOTAS_ENABLED;
136                         }
137
138                         ret = 0;
139
140                         break;
141 #endif /* HAVE_GROUP_QUOTA */
142                 default:
143                         errno = ENOSYS;
144                         return -1;
145         }
146
147         dp->bsize = bsize;
148         dp->softlimit = (uint64_t)D.d_blk_softlimit;
149         dp->hardlimit = (uint64_t)D.d_blk_hardlimit;
150         dp->ihardlimit = (uint64_t)D.d_ino_hardlimit;
151         dp->isoftlimit = (uint64_t)D.d_ino_softlimit;
152         dp->curinodes = (uint64_t)D.d_icount;
153         dp->curblocks = (uint64_t)D.d_bcount;
154         dp->qflags = qflags;
155
156         return ret;
157 }
158
159 /****************************************************************************
160  Abstract out the XFS Quota Manager quota set call.
161 ****************************************************************************/
162 int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
163 {
164         int ret = -1;
165         uint32 qflags = 0;
166         uint64_t bsize = (uint64_t)BBSIZE;
167         struct fs_disk_quota D;
168         struct fs_quota_stat F;
169         int q_on = 0;
170         int q_off = 0;
171         ZERO_STRUCT(D);
172         ZERO_STRUCT(F);
173
174         if (!bdev||!dp)
175                 smb_panic("sys_set_xfs_quota: called with NULL pointer");
176         
177         if (bsize == dp->bsize) {
178                 D.d_blk_softlimit = dp->softlimit;
179                 D.d_blk_hardlimit = dp->hardlimit;
180                 D.d_ino_hardlimit = dp->ihardlimit;
181                 D.d_ino_softlimit = dp->isoftlimit;
182         } else {
183                 D.d_blk_softlimit = (dp->softlimit*dp->bsize)/bsize;
184                 D.d_blk_hardlimit = (dp->hardlimit*dp->bsize)/bsize;
185                 D.d_ino_hardlimit = (dp->ihardlimit*dp->bsize)/bsize;
186                 D.d_ino_softlimit = (dp->isoftlimit*dp->bsize)/bsize;           
187         }
188
189         qflags = dp->qflags;
190
191         switch (qtype) {
192                 case SMB_USER_QUOTA_TYPE:
193                         DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
194                                 path, bdev, (unsigned)id.uid));
195
196                         D.d_fieldmask |= FS_DQ_LIMIT_MASK;
197                         ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (caddr_t)&D);
198                         break;
199 #ifdef HAVE_GROUP_QUOTA
200                 case SMB_GROUP_QUOTA_TYPE:
201                         DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
202                                 path, bdev, (unsigned)id.gid));
203
204                         D.d_fieldmask |= FS_DQ_LIMIT_MASK;
205                         ret = quotactl(QCMD(Q_XSETQLIM,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
206                         break;
207 #endif /* HAVE_GROUP_QUOTA */
208                 case SMB_USER_FS_QUOTA_TYPE:
209                         DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
210                                 path, bdev, (unsigned)id.uid));
211
212                         quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F);
213                         
214                         if (qflags & QUOTAS_DENY_DISK) {
215                                 if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD))
216                                         q_on |= XFS_QUOTA_UDQ_ENFD;
217                                 if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
218                                         q_on |= XFS_QUOTA_UDQ_ACCT;
219                                 
220                                 if (q_on != 0) {
221                                         ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on);
222                                 } else {
223                                         ret = 0;
224                                 }
225
226                         } else if (qflags & QUOTAS_ENABLED) {
227                                 if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
228                                         q_off |= XFS_QUOTA_UDQ_ENFD;
229
230                                 if (q_off != 0) {
231                                         ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off);
232                                 } else {
233                                         ret = 0;
234                                 }
235
236                                 if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
237                                         q_on |= XFS_QUOTA_UDQ_ACCT;
238
239                                 if (q_on != 0) {
240                                         ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on);
241                                 } else {
242                                         ret = 0;
243                                 }
244                         } else {
245 #if 0
246                         /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
247                          * only swittching off XFS_QUOTA_UDQ_ACCT work
248                          */
249                                 if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
250                                         q_off |= XFS_QUOTA_UDQ_ENFD;
251                                 if (F.qs_flags & XFS_QUOTA_UDQ_ACCT)
252                                         q_off |= XFS_QUOTA_UDQ_ACCT;
253
254                                 if (q_off !=0) {
255                                         ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off);
256                                 } else {
257                                         ret = 0;
258                                 }
259 #else
260                                 ret = -1;
261 #endif
262                         }
263
264                         break;
265 #ifdef HAVE_GROUP_QUOTA
266                 case SMB_GROUP_FS_QUOTA_TYPE:
267                         DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
268                                 path, bdev, (unsigned)id.gid));
269
270                         quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F);
271                         
272                         if (qflags & QUOTAS_DENY_DISK) {
273                                 if (!(F.qs_flags & XFS_QUOTA_GDQ_ENFD))
274                                         q_on |= XFS_QUOTA_GDQ_ENFD;
275                                 if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
276                                         q_on |= XFS_QUOTA_GDQ_ACCT;
277                                 
278                                 if (q_on != 0) {
279                                         ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on);
280                                 } else {
281                                         ret = 0;
282                                 }
283
284                         } else if (qflags & QUOTAS_ENABLED) {
285                                 if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
286                                         q_off |= XFS_QUOTA_GDQ_ENFD;
287
288                                 if (q_off != 0) {
289                                         ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off);
290                                 } else {
291                                         ret = 0;
292                                 }
293
294                                 if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
295                                         q_on |= XFS_QUOTA_GDQ_ACCT;
296
297                                 if (q_on != 0) {
298                                         ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on);
299                                 } else {
300                                         ret = 0;
301                                 }
302                         } else {
303 #if 0
304                         /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
305                          * only swittching off XFS_QUOTA_UDQ_ACCT work
306                          */
307                                 if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
308                                         q_off |= XFS_QUOTA_GDQ_ENFD;
309                                 if (F.qs_flags & XFS_QUOTA_GDQ_ACCT)
310                                         q_off |= XFS_QUOTA_GDQ_ACCT;
311
312                                 if (q_off !=0) {
313                                         ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off);
314                                 } else {
315                                         ret = 0;
316                                 }
317 #else
318                                 ret = -1;
319 #endif
320                         }
321
322                         break;
323 #endif /* HAVE_GROUP_QUOTA */
324                 default:
325                         errno = ENOSYS;
326                         return -1;
327         }
328
329         return ret;
330 }
331
332 #else /* HAVE_XFS_QUOTAS */
333  void dummy_sysquotas_xfs(void);
334
335  void dummy_sysquotas_xfs(void){}
336 #endif /* HAVE_XFS_QUOTAS */