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 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_QUOTACTL_4A
28 #undef HAVE_QUOTACTL_4A
32 #ifdef HAVE_QUOTACTL_4A
33 /* long quotactl(int cmd, char *special, qid_t id, caddr_t addr) */
34 /* this is used by: HPUX,IRIX */
36 #ifdef HAVE_SYS_TYPES_H
37 #include <sys/types.h>
40 #ifdef HAVE_ASM_TYPES_H
41 #include <asm/types.h>
44 #ifdef HAVE_SYS_QUOTA_H
45 #include <sys/quota.h>
49 #define Q_SETQLIM Q_SETQUOTA
61 #define HAVE_GROUP_QUOTA
64 #ifndef QUOTABLOCK_SIZE
65 #define QUOTABLOCK_SIZE DEV_BSIZE
68 #ifdef HAVE_DQB_FSOFTLIMIT
69 #define dqb_isoftlimit dqb_fsoftlimit
70 #define dqb_ihardlimit dqb_fhardlimit
71 #define dqb_curinodes dqb_curfiles
75 #define USERQUOTAFILE_EXTENSION ".user"
77 #define USERQUOTAFILE_EXTENSION ""
80 #if !defined(QUOTAFILENAME) && defined(QFILENAME)
81 #define QUOTAFILENAME QFILENAME
84 /****************************************************************************
85 Abstract out the quotactl_4A get calls.
86 ****************************************************************************/
87 int sys_get_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
92 uint64_t bsize
= (uint64_t)QUOTABLOCK_SIZE
;
99 case SMB_USER_QUOTA_TYPE
:
100 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
101 path
, bdev
, (unsigned)id
.uid
));
103 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), (caddr_t
)bdev
, id
.uid
, (void *)&D
))&&errno
!= EDQUOT
) {
107 if ((D
.dqb_curblocks
==0)&&
108 (D
.dqb_bsoftlimit
==0)&&
109 (D
.dqb_bhardlimit
==0)) {
110 /* the upper layer functions don't want empty quota records...*/
115 #ifdef HAVE_GROUP_QUOTA
116 case SMB_GROUP_QUOTA_TYPE
:
117 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
118 path
, bdev
, (unsigned)id
.gid
));
120 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), (caddr_t
)bdev
, id
.gid
, (void *)&D
))&&errno
!= EDQUOT
) {
124 if ((D
.dqb_curblocks
==0)&&
125 (D
.dqb_bsoftlimit
==0)&&
126 (D
.dqb_bhardlimit
==0)) {
127 /* the upper layer functions don't want empty quota records...*/
132 #endif /* HAVE_GROUP_QUOTA */
133 case SMB_USER_FS_QUOTA_TYPE
:
136 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
137 path
, (caddr_t
)bdev
, (unsigned)id
.uid
));
139 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), (caddr_t
)bdev
, id
.uid
, (void *)&D
))==0) {
140 qflags
|= QUOTAS_DENY_DISK
;
145 #ifdef HAVE_GROUP_QUOTA
146 case SMB_GROUP_FS_QUOTA_TYPE
:
149 DEBUG(10,("sys_get_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
150 path
, bdev
, (unsigned)id
.gid
));
152 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), (caddr_t
)bdev
, id
.gid
, (void *)&D
))==0) {
153 qflags
|= QUOTAS_DENY_DISK
;
158 #endif /* HAVE_GROUP_QUOTA */
165 dp
->softlimit
= (uint64_t)D
.dqb_bsoftlimit
;
166 dp
->hardlimit
= (uint64_t)D
.dqb_bhardlimit
;
167 dp
->ihardlimit
= (uint64_t)D
.dqb_ihardlimit
;
168 dp
->isoftlimit
= (uint64_t)D
.dqb_isoftlimit
;
169 dp
->curinodes
= (uint64_t)D
.dqb_curinodes
;
170 dp
->curblocks
= (uint64_t)D
.dqb_curblocks
;
178 /****************************************************************************
179 Abstract out the quotactl_4A set calls.
180 ****************************************************************************/
181 int sys_set_vfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
185 uint32 oldqflags
= 0;
187 uint64_t bsize
= (uint64_t)QUOTABLOCK_SIZE
;
191 if (bsize
== dp
->bsize
) {
192 D
.dqb_bsoftlimit
= dp
->softlimit
;
193 D
.dqb_bhardlimit
= dp
->hardlimit
;
194 D
.dqb_ihardlimit
= dp
->ihardlimit
;
195 D
.dqb_isoftlimit
= dp
->isoftlimit
;
197 D
.dqb_bsoftlimit
= (dp
->softlimit
*dp
->bsize
)/bsize
;
198 D
.dqb_bhardlimit
= (dp
->hardlimit
*dp
->bsize
)/bsize
;
199 D
.dqb_ihardlimit
= (dp
->ihardlimit
*dp
->bsize
)/bsize
;
200 D
.dqb_isoftlimit
= (dp
->isoftlimit
*dp
->bsize
)/bsize
;
206 case SMB_USER_QUOTA_TYPE
:
207 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
208 path
, bdev
, (unsigned)id
.uid
));
210 ret
= quotactl(QCMD(Q_SETQLIM
,USRQUOTA
), (caddr_t
)bdev
, id
.uid
, (void *)&D
);
212 #ifdef HAVE_GROUP_QUOTA
213 case SMB_GROUP_QUOTA_TYPE
:
214 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
215 path
, bdev
, (unsigned)id
.gid
));
217 ret
= quotactl(QCMD(Q_SETQLIM
,GRPQUOTA
), (caddr_t
)bdev
, id
.gid
, (void *)&D
);
219 #endif /* HAVE_GROUP_QUOTA */
220 case SMB_USER_FS_QUOTA_TYPE
:
221 /* this stuff didn't work as it should:
222 * switching on/off quota via quotactl()
224 * So we just return 0
227 * On HPUX we didn't have the mount path,
228 * we need to fix sys_path_to_bdev()
232 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
233 path
, bdev
, (unsigned)id
.uid
));
236 ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), (caddr_t
)bdev
, id
.uid
, (void *)&D
);
238 if ((qflags
"AS_DENY_DISK
)||(qflags
"AS_ENABLED
)) {
240 char *quota_file
= NULL
;
242 asprintf("a_file
,"/%s/%s%s",path
, QUOTAFILENAME
,USERQUOTAFILE_EXTENSION
);
243 if (quota_file
== NULL
) {
244 DEBUG(0,("asprintf() failed!\n"));
249 ret
= quotactl(QCMD(Q_QUOTAON
,USRQUOTA
), (caddr_t
)bdev
, -1,(void *)quota_file
);
256 ret
= quotactl(QCMD(Q_QUOTAOFF
,USRQUOTA
), (caddr_t
)bdev
, -1, (void *)0);
262 DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
263 ret
,errno
,strerror(errno
),id
.uid
,bdev
));
265 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,USRQUOTA
), (caddr_t
)bdev
, id
.uid
, (void *)&D
))==0) {
266 oldqflags
|= QUOTAS_DENY_DISK
;
269 if (oldqflags
== qflags
) {
276 #ifdef HAVE_GROUP_QUOTA
277 case SMB_GROUP_FS_QUOTA_TYPE
:
278 /* this stuff didn't work as it should:
279 * switching on/off quota via quotactl()
281 * So we just return 0
284 * On HPUX we didn't have the mount path,
285 * we need to fix sys_path_to_bdev()
289 DEBUG(10,("sys_set_vfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
290 path
, bdev
, (unsigned)id
.gid
));
293 ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), bdev
, id
, (void *)&D
);
295 if ((qflags
"AS_DENY_DISK
)||(qflags
"AS_ENABLED
)) {
297 char *quota_file
= NULL
;
299 asprintf("a_file
,"/%s/%s%s",path
, QUOTAFILENAME
,GROUPQUOTAFILE_EXTENSION
);
300 if (quota_file
== NULL
) {
301 DEBUG(0,("asprintf() failed!\n"));
306 ret
= quotactl(QCMD(Q_QUOTAON
,GRPQUOTA
), (caddr_t
)bdev
, -1,(void *)quota_file
);
313 ret
= quotactl(QCMD(Q_QUOTAOFF
,GRPQUOTA
), (caddr_t
)bdev
, -1, (void *)0);
319 DEBUG(0,("sys_set_vfs_quota: ret(%d) errno(%d)[%s] uid(%d) bdev[%s]\n",
320 ret
,errno
,strerror(errno
),id
.gid
,bdev
));
322 if ((ret
= quotactl(QCMD(Q_GETQUOTA
,GRPQUOTA
), (caddr_t
)bdev
, id
.gid
, (void *)&D
))==0) {
323 oldqflags
|= QUOTAS_DENY_DISK
;
326 if (oldqflags
== qflags
) {
333 #endif /* HAVE_GROUP_QUOTA */
342 #else /* HAVE_QUOTACTL_4A */
343 void dummy_sysquotas_4A(void);
345 void dummy_sysquotas_4A(void){}
346 #endif /* HAVE_QUOTACTL_4A */