2 Unix SMB/CIFS implementation.
3 System QUOTA function wrappers for XFS
4 Copyright (C) Stefan (metze) Metzmacher 2003
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.
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.
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.
24 #ifndef HAVE_SYS_QUOTAS
25 #ifdef HAVE_XFS_QUOTAS
26 #undef HAVE_XFS_QUOTAS
30 #ifdef HAVE_XFS_QUOTAS
32 #ifdef HAVE_LINUX_XFS_QUOTAS
33 #include "samba_linux_quota.h"
34 #include "samba_xfs_quota.h"
35 #define HAVE_GROUP_QUOTA
37 #include <sys/quota.h>
42 #define Q_XQUOTAON Q_QUOTAON
43 #endif /* Q_XQUOTAON */
45 #define Q_XQUOTAOFF Q_QUOTAOFF
46 #endif /* Q_XQUOTAOFF */
48 #define Q_XGETQSTAT Q_GETQSTAT
49 #endif /* Q_XGETQSTAT */
51 /* currently doesn't support Group and Project quotas on IRIX
59 * IRIX has BBSIZE in <sys/param.h>
65 #define BBSIZE (1<<BBSHIFT)
68 /****************************************************************************
69 Abstract out the XFS Quota Manager quota get call.
70 ****************************************************************************/
71 int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
75 SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE;
76 struct fs_disk_quota D;
77 struct fs_quota_stat F;
82 smb_panic("sys_get_xfs_quota: called with NULL pointer");
88 case SMB_USER_QUOTA_TYPE:
89 if ((ret=quotactl(QCMD(Q_XGETQUOTA,XFS_USER_QUOTA), bdev, id.uid, (caddr_t)&D)))
92 #ifdef HAVE_GROUP_QUOTA
93 case SMB_GROUP_QUOTA_TYPE:
94 if ((ret=quotactl(QCMD(Q_XGETQUOTA,XFS_GROUP_QUOTA), bdev, id.gid, (caddr_t)&D)))
97 #endif /* HAVE_GROUP_QUOTA */
98 case SMB_USER_FS_QUOTA_TYPE:
99 quotactl(QCMD(Q_XGETQSTAT,XFS_USER_QUOTA), bdev, -1, (caddr_t)&F);
101 if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) {
102 qflags |= QUOTAS_DENY_DISK;
104 else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) {
105 qflags |= QUOTAS_ENABLED;
111 #ifdef HAVE_GROUP_QUOTA
112 case SMB_GROUP_FS_QUOTA_TYPE:
113 quotactl(QCMD(Q_XGETQSTAT,XFS_GROUP_QUOTA), bdev, -1, (caddr_t)&F);
115 if (F.qs_flags & XFS_QUOTA_GDQ_ENFD) {
116 qflags |= QUOTAS_DENY_DISK;
118 else if (F.qs_flags & XFS_QUOTA_GDQ_ACCT) {
119 qflags |= QUOTAS_ENABLED;
125 #endif /* HAVE_GROUP_QUOTA */
132 dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit;
133 dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit;
134 dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit;
135 dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit;
136 dp->curinodes = (SMB_BIG_UINT)D.d_icount;
137 dp->curblocks = (SMB_BIG_UINT)D.d_bcount;
143 /****************************************************************************
144 Abstract out the XFS Quota Manager quota set call.
145 ****************************************************************************/
146 int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
150 SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE;
151 struct fs_disk_quota D;
152 struct fs_quota_stat F;
159 smb_panic("sys_set_xfs_quota: called with NULL pointer");
161 if (bsize == dp->bsize) {
162 D.d_blk_softlimit = dp->softlimit;
163 D.d_blk_hardlimit = dp->hardlimit;
164 D.d_ino_hardlimit = dp->ihardlimit;
165 D.d_ino_softlimit = dp->isoftlimit;
167 D.d_blk_softlimit = (dp->softlimit*dp->bsize)/bsize;
168 D.d_blk_hardlimit = (dp->hardlimit*dp->bsize)/bsize;
169 D.d_ino_hardlimit = (dp->ihardlimit*dp->bsize)/bsize;
170 D.d_ino_softlimit = (dp->isoftlimit*dp->bsize)/bsize;
176 case SMB_USER_QUOTA_TYPE:
177 D.d_fieldmask |= FS_DQ_LIMIT_MASK;
178 ret = quotactl(QCMD(Q_XSETQLIM,XFS_USER_QUOTA), bdev, id.uid, (caddr_t)&D);
180 #ifdef HAVE_GROUP_QUOTA
181 case SMB_GROUP_QUOTA_TYPE:
182 D.d_fieldmask |= FS_DQ_LIMIT_MASK;
183 ret = quotactl(QCMD(Q_XSETQLIM,XFS_GROUP_QUOTA), bdev, id.gid, (caddr_t)&D);
185 #endif /* HAVE_GROUP_QUOTA */
186 case SMB_USER_FS_QUOTA_TYPE:
187 quotactl(QCMD(Q_XGETQSTAT,XFS_USER_QUOTA), bdev, -1, (caddr_t)&F);
189 if (qflags & QUOTAS_DENY_DISK) {
190 if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD))
191 q_on |= XFS_QUOTA_UDQ_ENFD;
192 if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
193 q_on |= XFS_QUOTA_UDQ_ACCT;
196 ret = quotactl(QCMD(Q_XQUOTAON,XFS_USER_QUOTA),bdev, -1, (caddr_t)&q_on);
201 } else if (qflags & QUOTAS_ENABLED) {
202 if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
203 q_off |= XFS_QUOTA_UDQ_ENFD;
206 ret = quotactl(QCMD(Q_XQUOTAOFF,XFS_USER_QUOTA),bdev, -1, (caddr_t)&q_off);
211 if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
212 q_on |= XFS_QUOTA_UDQ_ACCT;
215 ret = quotactl(QCMD(Q_XQUOTAON,XFS_USER_QUOTA),bdev, -1, (caddr_t)&q_on);
221 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
222 * only swittching off XFS_QUOTA_UDQ_ACCT work
224 if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
225 q_off |= XFS_QUOTA_UDQ_ENFD;
226 if (F.qs_flags & XFS_QUOTA_UDQ_ACCT)
227 q_off |= XFS_QUOTA_UDQ_ACCT;
230 ret = quotactl(QCMD(Q_XQUOTAOFF,XFS_USER_QUOTA),bdev, -1, (caddr_t)&q_off);
240 #ifdef HAVE_GROUP_QUOTA
241 case SMB_GROUP_FS_QUOTA_TYPE:
242 quotactl(QCMD(Q_XGETQSTAT,XFS_GROUP_QUOTA), bdev, -1, (caddr_t)&F);
244 if (qflags & QUOTAS_DENY_DISK) {
245 if (!(F.qs_flags & XFS_QUOTA_GDQ_ENFD))
246 q_on |= XFS_QUOTA_GDQ_ENFD;
247 if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
248 q_on |= XFS_QUOTA_GDQ_ACCT;
251 ret = quotactl(QCMD(Q_XQUOTAON,XFS_GROUP_QUOTA),bdev, -1, (caddr_t)&q_on);
256 } else if (qflags & QUOTAS_ENABLED) {
257 if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
258 q_off |= XFS_QUOTA_GDQ_ENFD;
261 ret = quotactl(QCMD(Q_XQUOTAOFF,XFS_GROUP_QUOTA),bdev, -1, (caddr_t)&q_off);
266 if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
267 q_on |= XFS_QUOTA_GDQ_ACCT;
270 ret = quotactl(QCMD(Q_XQUOTAON,XFS_GROUP_QUOTA),bdev, -1, (caddr_t)&q_on);
276 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
277 * only swittching off XFS_QUOTA_UDQ_ACCT work
279 if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
280 q_off |= XFS_QUOTA_GDQ_ENFD;
281 if (F.qs_flags & XFS_QUOTA_GDQ_ACCT)
282 q_off |= XFS_QUOTA_GDQ_ACCT;
285 ret = quotactl(QCMD(Q_XQUOTAOFF,XFS_GROUP_QUOTA),bdev, -1, (caddr_t)&q_off);
295 #endif /* HAVE_GROUP_QUOTA */
304 #else /* HAVE_XFS_QUOTAS */
305 void dummy_sysquotas_xfs(void){}
306 #endif /* HAVE_XFS_QUOTAS */