2 Unix SMB/CIFS implementation.
3 System QUOTA function wrappers for LINUX
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_LINUX
28 #undef HAVE_QUOTACTL_LINUX
32 #ifdef HAVE_QUOTACTL_LINUX
34 #include <sys/quota.h>
36 /****************************************************************************
37 Linux quota get calls.
38 ****************************************************************************/
39 int sys_get_vfs_quota(const char *path
, const char *bdev
,
40 enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
45 uint64_t bsize
= (uint64_t)QUOTABLOCK_SIZE
;
47 if (!path
|| !bdev
|| !dp
) {
48 smb_panic("sys_get_vfs_quota: called with NULL pointer");
57 case SMB_USER_QUOTA_TYPE
:
58 DEBUG(10, ("sys_get_vfs_quota: path[%s] bdev[%s] "
59 "SMB_USER_QUOTA_TYPE uid[%u]\n",
60 path
, bdev
, (unsigned)id
.uid
));
62 if ((ret
= quotactl(QCMD(Q_GETQUOTA
, USRQUOTA
), bdev
,
63 id
.uid
, (caddr_t
)&D
))) {
68 case SMB_GROUP_QUOTA_TYPE
:
69 DEBUG(10, ("sys_get_vfs_quota: path[%s] bdev[%s] "
70 "SMB_GROUP_QUOTA_TYPE gid[%u]\n",
71 path
, bdev
, (unsigned)id
.gid
));
73 if ((ret
= quotactl(QCMD(Q_GETQUOTA
, GRPQUOTA
), bdev
,
74 id
.gid
, (caddr_t
)&D
))) {
79 case SMB_USER_FS_QUOTA_TYPE
:
80 DEBUG(10, ("sys_get_vfs_quota: path[%s] bdev[%s] "
81 "SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
82 path
, bdev
, (unsigned)geteuid()));
84 if ((ret
= quotactl(QCMD(Q_GETQUOTA
, USRQUOTA
), bdev
,
85 geteuid(), (caddr_t
)&D
)) == 0) {
86 qflags
|= QUOTAS_DENY_DISK
;
92 case SMB_GROUP_FS_QUOTA_TYPE
:
93 DEBUG(10, ("sys_get_vfs_quota: path[%s] bdev[%s] "
94 "SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
95 path
, bdev
, (unsigned)getegid()));
97 if ((ret
= quotactl(QCMD(Q_GETQUOTA
, GRPQUOTA
), bdev
,
98 getegid(), (caddr_t
)&D
)) == 0) {
99 qflags
|= QUOTAS_DENY_DISK
;
110 dp
->softlimit
= (uint64_t)D
.dqb_bsoftlimit
;
111 dp
->hardlimit
= (uint64_t)D
.dqb_bhardlimit
;
112 dp
->ihardlimit
= (uint64_t)D
.dqb_ihardlimit
;
113 dp
->isoftlimit
= (uint64_t)D
.dqb_isoftlimit
;
114 dp
->curinodes
= (uint64_t)D
.dqb_curinodes
;
115 dp
->curblocks
= (uint64_t)D
.dqb_curspace
/bsize
;
123 /****************************************************************************
124 Linux quota set calls.
125 ****************************************************************************/
126 int sys_set_vfs_quota(const char *path
, const char *bdev
,
127 enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
131 uint64_t bsize
= (uint64_t)QUOTABLOCK_SIZE
;
132 bool cur_enf
, new_enf
;
134 if (!path
|| !bdev
|| !dp
) {
135 smb_panic("sys_set_vfs_quota: called with NULL pointer");
140 if (bsize
== dp
->bsize
) {
141 D
.dqb_bsoftlimit
= dp
->softlimit
;
142 D
.dqb_bhardlimit
= dp
->hardlimit
;
143 D
.dqb_ihardlimit
= dp
->ihardlimit
;
144 D
.dqb_isoftlimit
= dp
->isoftlimit
;
146 D
.dqb_bsoftlimit
= (dp
->softlimit
*dp
->bsize
)/bsize
;
147 D
.dqb_bhardlimit
= (dp
->hardlimit
*dp
->bsize
)/bsize
;
148 D
.dqb_ihardlimit
= (dp
->ihardlimit
*dp
->bsize
)/bsize
;
149 D
.dqb_isoftlimit
= (dp
->isoftlimit
*dp
->bsize
)/bsize
;
151 D
.dqb_valid
= QIF_LIMITS
;
154 case SMB_USER_QUOTA_TYPE
:
155 DEBUG(10, ("sys_set_vfs_quota: path[%s] bdev[%s] "
156 "SMB_USER_QUOTA_TYPE uid[%u]\n",
157 path
, bdev
, (unsigned)id
.uid
));
159 ret
= quotactl(QCMD(Q_SETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (caddr_t
)&D
);
161 case SMB_GROUP_QUOTA_TYPE
:
162 DEBUG(10, ("sys_set_vfs_quota: path[%s] bdev[%s] "
163 "SMB_GROUP_QUOTA_TYPE gid[%u]\n",
164 path
, bdev
, (unsigned)id
.gid
));
166 ret
= quotactl(QCMD(Q_SETQUOTA
,GRPQUOTA
), bdev
, id
.gid
, (caddr_t
)&D
);
168 case SMB_USER_FS_QUOTA_TYPE
:
169 DEBUG(10, ("sys_set_vfs_quota: path[%s] bdev[%s] "
170 "SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
171 path
, bdev
, (unsigned)geteuid()));
173 ret
= quotactl(QCMD(Q_GETQUOTA
, USRQUOTA
), bdev
,
174 geteuid(), (caddr_t
)&D
);
175 cur_enf
= (ret
== 0);
176 new_enf
= ((dp
->qflags
& QUOTAS_DENY_DISK
) != 0);
177 /* We're not changing quota enforcement, so return
179 * IFF the wanted state is identical to the current
181 if (cur_enf
== new_enf
) {
189 case SMB_GROUP_FS_QUOTA_TYPE
:
190 DEBUG(10, ("sys_set_vfs_quota: path[%s] bdev[%s] "
191 "SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
192 path
, bdev
, (unsigned)getegid()));
194 ret
= quotactl(QCMD(Q_GETQUOTA
, GRPQUOTA
), bdev
,
195 getegid(), (caddr_t
)&D
);
196 cur_enf
= (ret
== 0);
197 new_enf
= ((dp
->qflags
& QUOTAS_DENY_DISK
) != 0);
198 /* We're not changing quota enforcement, so return
200 * IFF the wanted state is identical to the current
202 if (cur_enf
== new_enf
) {
218 #else /* HAVE_QUOTACTL_LINUX */
219 void dummy_sysquotas_linux(void);
221 void dummy_sysquotas_linux(void){}
222 #endif /* HAVE_QUOTACTL_LINUX */