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 3 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, see <http://www.gnu.org/licenses/>.
24 #define DBGC_CLASS DBGC_QUOTA
26 #ifndef HAVE_SYS_QUOTAS
27 #ifdef HAVE_XFS_QUOTAS
28 #undef HAVE_XFS_QUOTAS
32 #ifdef HAVE_XFS_QUOTAS
34 #ifdef HAVE_LINUX_XFS_QUOTAS
35 #include "samba_linux_quota.h"
36 #include "samba_xfs_quota.h"
37 #define HAVE_GROUP_QUOTA
39 #include <sys/quota.h>
44 #define Q_XQUOTAON Q_QUOTAON
45 #endif /* Q_XQUOTAON */
47 #define Q_XQUOTAOFF Q_QUOTAOFF
48 #endif /* Q_XQUOTAOFF */
50 #define Q_XGETQSTAT Q_GETQSTAT
51 #endif /* Q_XGETQSTAT */
53 /* currently doesn't support Group and Project quotas on IRIX
61 * IRIX has BBSIZE in <sys/param.h>
67 #define BBSIZE (1<<BBSHIFT)
70 /****************************************************************************
71 Abstract out the XFS Quota Manager quota get call.
72 ****************************************************************************/
73 int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
77 SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE;
78 struct fs_disk_quota D;
79 struct fs_quota_stat F;
84 smb_panic("sys_get_xfs_quota: called with NULL pointer");
90 case SMB_USER_QUOTA_TYPE:
91 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
92 path, bdev, (unsigned)id.uid));
94 if ((ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D)))
97 #ifdef HAVE_GROUP_QUOTA
98 case SMB_GROUP_QUOTA_TYPE:
99 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
100 path, bdev, (unsigned)id.gid));
102 if ((ret=quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D)))
105 #endif /* HAVE_GROUP_QUOTA */
106 case SMB_USER_FS_QUOTA_TYPE:
107 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
108 path, bdev, (unsigned)id.uid));
110 quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F);
112 if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) {
113 qflags |= QUOTAS_DENY_DISK;
115 else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) {
116 qflags |= QUOTAS_ENABLED;
122 #ifdef HAVE_GROUP_QUOTA
123 case SMB_GROUP_FS_QUOTA_TYPE:
124 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
125 path, bdev, (unsigned)id.gid));
127 quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F);
129 if (F.qs_flags & XFS_QUOTA_GDQ_ENFD) {
130 qflags |= QUOTAS_DENY_DISK;
132 else if (F.qs_flags & XFS_QUOTA_GDQ_ACCT) {
133 qflags |= QUOTAS_ENABLED;
139 #endif /* HAVE_GROUP_QUOTA */
146 dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit;
147 dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit;
148 dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit;
149 dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit;
150 dp->curinodes = (SMB_BIG_UINT)D.d_icount;
151 dp->curblocks = (SMB_BIG_UINT)D.d_bcount;
157 /****************************************************************************
158 Abstract out the XFS Quota Manager quota set call.
159 ****************************************************************************/
160 int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
164 SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE;
165 struct fs_disk_quota D;
166 struct fs_quota_stat F;
173 smb_panic("sys_set_xfs_quota: called with NULL pointer");
175 if (bsize == dp->bsize) {
176 D.d_blk_softlimit = dp->softlimit;
177 D.d_blk_hardlimit = dp->hardlimit;
178 D.d_ino_hardlimit = dp->ihardlimit;
179 D.d_ino_softlimit = dp->isoftlimit;
181 D.d_blk_softlimit = (dp->softlimit*dp->bsize)/bsize;
182 D.d_blk_hardlimit = (dp->hardlimit*dp->bsize)/bsize;
183 D.d_ino_hardlimit = (dp->ihardlimit*dp->bsize)/bsize;
184 D.d_ino_softlimit = (dp->isoftlimit*dp->bsize)/bsize;
190 case SMB_USER_QUOTA_TYPE:
191 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
192 path, bdev, (unsigned)id.uid));
194 D.d_fieldmask |= FS_DQ_LIMIT_MASK;
195 ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (caddr_t)&D);
197 #ifdef HAVE_GROUP_QUOTA
198 case SMB_GROUP_QUOTA_TYPE:
199 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
200 path, bdev, (unsigned)id.gid));
202 D.d_fieldmask |= FS_DQ_LIMIT_MASK;
203 ret = quotactl(QCMD(Q_XSETQLIM,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
205 #endif /* HAVE_GROUP_QUOTA */
206 case SMB_USER_FS_QUOTA_TYPE:
207 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
208 path, bdev, (unsigned)id.uid));
210 quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F);
212 if (qflags & QUOTAS_DENY_DISK) {
213 if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD))
214 q_on |= XFS_QUOTA_UDQ_ENFD;
215 if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
216 q_on |= XFS_QUOTA_UDQ_ACCT;
219 ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on);
224 } else if (qflags & QUOTAS_ENABLED) {
225 if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
226 q_off |= XFS_QUOTA_UDQ_ENFD;
229 ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off);
234 if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
235 q_on |= XFS_QUOTA_UDQ_ACCT;
238 ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on);
244 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
245 * only swittching off XFS_QUOTA_UDQ_ACCT work
247 if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
248 q_off |= XFS_QUOTA_UDQ_ENFD;
249 if (F.qs_flags & XFS_QUOTA_UDQ_ACCT)
250 q_off |= XFS_QUOTA_UDQ_ACCT;
253 ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off);
263 #ifdef HAVE_GROUP_QUOTA
264 case SMB_GROUP_FS_QUOTA_TYPE:
265 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
266 path, bdev, (unsigned)id.gid));
268 quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F);
270 if (qflags & QUOTAS_DENY_DISK) {
271 if (!(F.qs_flags & XFS_QUOTA_GDQ_ENFD))
272 q_on |= XFS_QUOTA_GDQ_ENFD;
273 if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
274 q_on |= XFS_QUOTA_GDQ_ACCT;
277 ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on);
282 } else if (qflags & QUOTAS_ENABLED) {
283 if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
284 q_off |= XFS_QUOTA_GDQ_ENFD;
287 ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off);
292 if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
293 q_on |= XFS_QUOTA_GDQ_ACCT;
296 ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on);
302 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
303 * only swittching off XFS_QUOTA_UDQ_ACCT work
305 if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
306 q_off |= XFS_QUOTA_GDQ_ENFD;
307 if (F.qs_flags & XFS_QUOTA_GDQ_ACCT)
308 q_off |= XFS_QUOTA_GDQ_ACCT;
311 ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off);
321 #endif /* HAVE_GROUP_QUOTA */
330 #else /* HAVE_XFS_QUOTAS */
331 void dummy_sysquotas_xfs(void);
333 void dummy_sysquotas_xfs(void){}
334 #endif /* HAVE_XFS_QUOTAS */