source: branches/samba-3.5.x/source3/lib/sysquotas_xfs.c

Last change on this file was 738, checked in by Silvan Scherrer, 13 years ago

Samba Server 3.5: update branche to 3.5.18

File size: 9.3 KB
Line 
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****************************************************************************/
87int 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****************************************************************************/
174int 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 */
Note: See TracBrowser for help on using the repository browser.