2 Unix SMB/CIFS implementation.
3 System QUOTA function wrappers for QUOTACTL_4A
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.
25 #define DBGC_CLASS DBGC_QUOTA
27 #ifdef HAVE_QUOTACTL_4A
28 /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */
29 /* this is used by: HPUX,IRIX */
31 #ifdef HAVE_SYS_TYPES_H
32 #include <sys/types.h>
35 #ifdef HAVE_ASM_TYPES_H
36 #include <asm/types.h>
39 #ifdef HAVE_SYS_QUOTA_H
40 #include <sys/quota.h>
44 #define Q_SETQLIM Q_SETQUOTA
56 #define HAVE_GROUP_QUOTA
59 #ifndef QUOTABLOCK_SIZE
60 #define QUOTABLOCK_SIZE DEV_BSIZE
63 #ifdef HAVE_DQB_FSOFTLIMIT
64 #define dqb_isoftlimit dqb_fsoftlimit
65 #define dqb_ihardlimit dqb_fhardlimit
66 #define dqb_curinodes dqb_curfiles
70 #define USERQUOTAFILE_EXTENSION ".user"
72 #define USERQUOTAFILE_EXTENSION ""
75 #if !defined(QUOTAFILENAME) && defined(QFILENAME)
76 #define QUOTAFILENAME QFILENAME
79 /****************************************************************************
80 Abstract out the quotactl_4A get calls.
81 ****************************************************************************/
82 int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
87 SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
94 case SMB_USER_QUOTA_TYPE:
95 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
96 path, bdev, (unsigned)id.uid));
98 if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D))&&errno != EDQUOT) {
102 if ((D.dqb_curblocks==0)&&
103 (D.dqb_bsoftlimit==0)&&
104 (D.dqb_bhardlimit==0)) {
105 /* the upper layer functions don't want empty quota records...*/
110 #ifdef HAVE_GROUP_QUOTA
111 case SMB_GROUP_QUOTA_TYPE:
112 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
113 path, bdev, (unsigned)id.gid));
115 if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (void *)&D))&&errno != EDQUOT) {
119 if ((D.dqb_curblocks==0)&&
120 (D.dqb_bsoftlimit==0)&&
121 (D.dqb_bhardlimit==0)) {
122 /* the upper layer functions don't want empty quota records...*/
127 #endif /* HAVE_GROUP_QUOTA */
128 case SMB_USER_FS_QUOTA_TYPE:
131 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
132 path, bdev, (unsigned)id.uid));
134 if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D))==0) {
135 qflags |= QUOTAS_DENY_DISK;
140 #ifdef HAVE_GROUP_QUOTA
141 case SMB_GROUP_FS_QUOTA_TYPE:
144 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
145 path, bdev, (unsigned)id.gid));
147 if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (void *)&D))==0) {
148 qflags |= QUOTAS_DENY_DISK;
153 #endif /* HAVE_GROUP_QUOTA */
160 dp->softlimit = (SMB_BIG_UINT)D.dqb_bsoftlimit;
161 dp->hardlimit = (SMB_BIG_UINT)D.dqb_bhardlimit;
162 dp->ihardlimit = (SMB_BIG_UINT)D.dqb_ihardlimit;
163 dp->isoftlimit = (SMB_BIG_UINT)D.dqb_isoftlimit;
164 dp->curinodes = (SMB_BIG_UINT)D.dqb_curinodes;
165 dp->curblocks = (SMB_BIG_UINT)D.dqb_curblocks;
173 /****************************************************************************
174 Abstract out the quotactl_4A set calls.
175 ****************************************************************************/
176 int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
180 uint32 oldqflags = 0;
182 SMB_BIG_UINT bsize = (SMB_BIG_UINT)QUOTABLOCK_SIZE;
186 if (bsize == dp->bsize) {
187 D.dqb_bsoftlimit = dp->softlimit;
188 D.dqb_bhardlimit = dp->hardlimit;
189 D.dqb_ihardlimit = dp->ihardlimit;
190 D.dqb_isoftlimit = dp->isoftlimit;
192 D.dqb_bsoftlimit = (dp->softlimit*dp->bsize)/bsize;
193 D.dqb_bhardlimit = (dp->hardlimit*dp->bsize)/bsize;
194 D.dqb_ihardlimit = (dp->ihardlimit*dp->bsize)/bsize;
195 D.dqb_isoftlimit = (dp->isoftlimit*dp->bsize)/bsize;
201 case SMB_USER_QUOTA_TYPE:
202 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
203 path, bdev, (unsigned)id.uid));
205 ret = quotactl(QCMD(Q_SETQLIM,USRQUOTA), bdev, id.uid, (void *)&D);
207 #ifdef HAVE_GROUP_QUOTA
208 case SMB_GROUP_QUOTA_TYPE:
209 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
210 path, bdev, (unsigned)id.gid));
212 ret = quotactl(QCMD(Q_SETQLIM,GRPQUOTA), bdev, id.gid, (void *)&D);
214 #endif /* HAVE_GROUP_QUOTA */
215 case SMB_USER_FS_QUOTA_TYPE:
216 /* this stuff didn't work as it should:
217 * switching on/off quota via quotactl()
219 * So we just return 0
222 * On HPUX we didn't have the mount path,
223 * we need to fix sys_path_to_bdev()
227 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
228 path, bdev, (unsigned)id.uid));
231 ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D);
233 if ((qflags"AS_DENY_DISK)||(qflags"AS_ENABLED)) {
235 char *quota_file = NULL;
237 asprintf("a_file,"/%s/%s%s",path, QUOTAFILENAME,USERQUOTAFILE_EXTENSION);
238 if (quota_file == NULL) {
239 DEBUG(0,("asprintf() failed!\n"));
244 ret = quotactl(QCMD(Q_QUOTAON,USRQUOTA), bdev, -1,(void *)quota_file);
251 ret = quotactl(QCMD(Q_QUOTAOFF,USRQUOTA), bdev, -1, (void *)0);
257 DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
258 ret,errno,strerror(errno),id.uid,bdev));
260 if ((ret = quotactl(QCMD(Q_GETQUOTA,USRQUOTA), bdev, id.uid, (void *)&D))==0) {
261 oldqflags |= QUOTAS_DENY_DISK;
264 if (oldqflags == qflags) {
271 #ifdef HAVE_GROUP_QUOTA
272 case SMB_GROUP_FS_QUOTA_TYPE:
273 /* this stuff didn't work as it should:
274 * switching on/off quota via quotactl()
276 * So we just return 0
279 * On HPUX we didn't have the mount path,
280 * we need to fix sys_path_to_bdev()
284 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
285 path, bdev, (unsigned)id.gid));
288 ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id, (void *)&D);
290 if ((qflags"AS_DENY_DISK)||(qflags"AS_ENABLED)) {
292 char *quota_file = NULL;
294 asprintf("a_file,"/%s/%s%s",path, QUOTAFILENAME,GROUPQUOTAFILE_EXTENSION);
295 if (quota_file == NULL) {
296 DEBUG(0,("asprintf() failed!\n"));
301 ret = quotactl(QCMD(Q_QUOTAON,GRPQUOTA), bdev, -1,(void *)quota_file);
308 ret = quotactl(QCMD(Q_QUOTAOFF,GRPQUOTA), bdev, -1, (void *)0);
314 DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
315 ret,errno,strerror(errno),id.gid,bdev));
317 if ((ret = quotactl(QCMD(Q_GETQUOTA,GRPQUOTA), bdev, id.gid, (void *)&D))==0) {
318 oldqflags |= QUOTAS_DENY_DISK;
321 if (oldqflags == qflags) {
328 #endif /* HAVE_GROUP_QUOTA */
337 #else /* HAVE_QUOTACTL_4A */
338 void dummy_sysquotas_4A(void);
340 void dummy_sysquotas_4A(void){}
341 #endif /* HAVE_QUOTACTL_4A */