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 #ifndef HAVE_SYS_QUOTAS
28 #ifdef HAVE_QUOTACTL_4A
29 #undef HAVE_QUOTACTL_4A
33 #ifdef HAVE_QUOTACTL_4A
34 /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */
35 /* this is used by: HPUX,IRIX */
37 #ifdef HAVE_SYS_TYPES_H
38 #include <sys/types.h>
41 #ifdef HAVE_ASM_TYPES_H
42 #include <asm/types.h>
45 #ifdef HAVE_SYS_QUOTA_H
46 #include <sys/quota.h>
50 #define Q_SETQLIM Q_SETQUOTA
62 #define HAVE_GROUP_QUOTA
65 #ifndef QUOTABLOCK_SIZE
66 #define QUOTABLOCK_SIZE DEV_BSIZE
69 #ifdef HAVE_DQB_FSOFTLIMIT
70 #define dqb_isoftlimit dqb_fsoftlimit
71 #define dqb_ihardlimit dqb_fhardlimit
72 #define dqb_curinodes dqb_curfiles
76 #define USERQUOTAFILE_EXTENSION ".user"
78 #define USERQUOTAFILE_EXTENSION ""
81 #if !defined(QUOTAFILENAME) && defined(QFILENAME)
82 #define QUOTAFILENAME QFILENAME
85 /****************************************************************************
86 Abstract out the quotactl_4A get calls.
87 ****************************************************************************/
88 int sys_get_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
93 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)QUOTABLOCK_SIZE
;
100 case SMB_USER_QUOTA_TYPE
:
101 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
102 path
, bdev
, (unsigned)id
.uid
));
104 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), (caddr_t
)bdev
, id
.uid
, (void *)&D
))&&errno
!= EDQUOT
) {
108 if ((D
.dqb_curblocks
==0)&&
109 (D
.dqb_bsoftlimit
==0)&&
110 (D
.dqb_bhardlimit
==0)) {
111 /* the upper layer functions don't want empty quota records...*/
116 #ifdef HAVE_GROUP_QUOTA
117 case SMB_GROUP_QUOTA_TYPE
:
118 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
119 path
, bdev
, (unsigned)id
.gid
));
121 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), (caddr_t
)bdev
, id
.gid
, (void *)&D
))&&errno
!= EDQUOT
) {
125 if ((D
.dqb_curblocks
==0)&&
126 (D
.dqb_bsoftlimit
==0)&&
127 (D
.dqb_bhardlimit
==0)) {
128 /* the upper layer functions don't want empty quota records...*/
133 #endif /* HAVE_GROUP_QUOTA */
134 case SMB_USER_FS_QUOTA_TYPE
:
137 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
138 path
, (caddr_t
)bdev
, (unsigned)id
.uid
));
140 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), (caddr_t
)bdev
, id
.uid
, (void *)&D
))==0) {
141 qflags
|= QUOTAS_DENY_DISK
;
146 #ifdef HAVE_GROUP_QUOTA
147 case SMB_GROUP_FS_QUOTA_TYPE
:
150 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
151 path
, bdev
, (unsigned)id
.gid
));
153 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), (caddr_t
)bdev
, id
.gid
, (void *)&D
))==0) {
154 qflags
|= QUOTAS_DENY_DISK
;
159 #endif /* HAVE_GROUP_QUOTA */
166 dp
->softlimit
= (SMB_BIG_UINT
)D
.dqb_bsoftlimit
;
167 dp
->hardlimit
= (SMB_BIG_UINT
)D
.dqb_bhardlimit
;
168 dp
->ihardlimit
= (SMB_BIG_UINT
)D
.dqb_ihardlimit
;
169 dp
->isoftlimit
= (SMB_BIG_UINT
)D
.dqb_isoftlimit
;
170 dp
->curinodes
= (SMB_BIG_UINT
)D
.dqb_curinodes
;
171 dp
->curblocks
= (SMB_BIG_UINT
)D
.dqb_curblocks
;
179 /****************************************************************************
180 Abstract out the quotactl_4A set calls.
181 ****************************************************************************/
182 int sys_set_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
186 uint32 oldqflags
= 0;
188 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)QUOTABLOCK_SIZE
;
192 if (bsize
== dp
->bsize
) {
193 D
.dqb_bsoftlimit
= dp
->softlimit
;
194 D
.dqb_bhardlimit
= dp
->hardlimit
;
195 D
.dqb_ihardlimit
= dp
->ihardlimit
;
196 D
.dqb_isoftlimit
= dp
->isoftlimit
;
198 D
.dqb_bsoftlimit
= (dp
->softlimit
*dp
->bsize
)/bsize
;
199 D
.dqb_bhardlimit
= (dp
->hardlimit
*dp
->bsize
)/bsize
;
200 D
.dqb_ihardlimit
= (dp
->ihardlimit
*dp
->bsize
)/bsize
;
201 D
.dqb_isoftlimit
= (dp
->isoftlimit
*dp
->bsize
)/bsize
;
207 case SMB_USER_QUOTA_TYPE
:
208 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
209 path
, bdev
, (unsigned)id
.uid
));
211 ret
= quotactl(QCMD(Q_SETQLIM
,USRQUOTA
), (caddr_t
)bdev
, id
.uid
, (void *)&D
);
213 #ifdef HAVE_GROUP_QUOTA
214 case SMB_GROUP_QUOTA_TYPE
:
215 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
216 path
, bdev
, (unsigned)id
.gid
));
218 ret
= quotactl(QCMD(Q_SETQLIM
,GRPQUOTA
), (caddr_t
)bdev
, id
.gid
, (void *)&D
);
220 #endif /* HAVE_GROUP_QUOTA */
221 case SMB_USER_FS_QUOTA_TYPE
:
222 /* this stuff didn't work as it should:
223 * switching on/off quota via quotactl()
225 * So we just return 0
228 * On HPUX we didn't have the mount path,
229 * we need to fix sys_path_to_bdev()
233 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
234 path
, bdev
, (unsigned)id
.uid
));
237 ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), (caddr_t
)bdev
, id
.uid
, (void *)&D
);
239 if ((qflags
"AS_DENY_DISK
)||(qflags
"AS_ENABLED
)) {
241 char *quota_file
= NULL
;
243 asprintf("a_file
,"/%s/%s%s",path
, QUOTAFILENAME
,USERQUOTAFILE_EXTENSION
);
244 if (quota_file
== NULL
) {
245 DEBUG(0,("asprintf() failed!\n"));
250 ret
= quotactl(QCMD(Q_QUOTAON
,USRQUOTA
), (caddr_t
)bdev
, -1,(void *)quota_file
);
257 ret
= quotactl(QCMD(Q_QUOTAOFF
,USRQUOTA
), (caddr_t
)bdev
, -1, (void *)0);
263 DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
264 ret
,errno
,strerror(errno
),id
.uid
,bdev
));
266 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), (caddr_t
)bdev
, id
.uid
, (void *)&D
))==0) {
267 oldqflags
|= QUOTAS_DENY_DISK
;
270 if (oldqflags
== qflags
) {
277 #ifdef HAVE_GROUP_QUOTA
278 case SMB_GROUP_FS_QUOTA_TYPE
:
279 /* this stuff didn't work as it should:
280 * switching on/off quota via quotactl()
282 * So we just return 0
285 * On HPUX we didn't have the mount path,
286 * we need to fix sys_path_to_bdev()
290 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
291 path
, bdev
, (unsigned)id
.gid
));
294 ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), bdev
, id
, (void *)&D
);
296 if ((qflags
"AS_DENY_DISK
)||(qflags
"AS_ENABLED
)) {
298 char *quota_file
= NULL
;
300 asprintf("a_file
,"/%s/%s%s",path
, QUOTAFILENAME
,GROUPQUOTAFILE_EXTENSION
);
301 if (quota_file
== NULL
) {
302 DEBUG(0,("asprintf() failed!\n"));
307 ret
= quotactl(QCMD(Q_QUOTAON
,GRPQUOTA
), (caddr_t
)bdev
, -1,(void *)quota_file
);
314 ret
= quotactl(QCMD(Q_QUOTAOFF
,GRPQUOTA
), (caddr_t
)bdev
, -1, (void *)0);
320 DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
321 ret
,errno
,strerror(errno
),id
.gid
,bdev
));
323 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), (caddr_t
)bdev
, id
.gid
, (void *)&D
))==0) {
324 oldqflags
|= QUOTAS_DENY_DISK
;
327 if (oldqflags
== qflags
) {
334 #endif /* HAVE_GROUP_QUOTA */
343 #else /* HAVE_QUOTACTL_4A */
344 void dummy_sysquotas_4A(void);
346 void dummy_sysquotas_4A(void){}
347 #endif /* HAVE_QUOTACTL_4A */