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 #if defined(HAVE_SYS_QUOTAS) && defined(HAVE_XFS_QUOTAS)
28 #ifdef HAVE_SYS_QUOTA_H
29 #include <sys/quota.h>
32 /* this one should actually come from glibc: */
33 /* #include "samba_linux_quota.h" */
39 #define HAVE_GROUP_QUOTA
43 #define Q_XQUOTAON Q_QUOTAON
44 #endif /* Q_XQUOTAON */
46 #define Q_XQUOTAOFF Q_QUOTAOFF
47 #endif /* Q_XQUOTAOFF */
49 #define Q_XGETQSTAT Q_GETQSTAT
50 #endif /* Q_XGETQSTAT */
52 /* currently doesn't support Group and Project quotas on IRIX
60 * IRIX has BBSIZE in <sys/param.h>
66 #define BBSIZE (1<<BBSHIFT)
69 /****************************************************************************
70 Abstract out the XFS Quota Manager quota get call.
71 ****************************************************************************/
72 int sys_get_xfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
76 uint64_t bsize
= (uint64_t)BBSIZE
;
77 struct fs_disk_quota D
;
78 struct fs_quota_stat F
;
83 smb_panic("sys_get_xfs_quota: called with NULL pointer");
89 case SMB_USER_QUOTA_TYPE
:
90 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
91 path
, bdev
, (unsigned)id
.uid
));
93 if ((ret
=quotactl(QCMD(Q_XGETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (caddr_t
)&D
)))
96 #ifdef HAVE_GROUP_QUOTA
97 case SMB_GROUP_QUOTA_TYPE
:
98 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
99 path
, bdev
, (unsigned)id
.gid
));
101 if ((ret
=quotactl(QCMD(Q_XGETQUOTA
,GRPQUOTA
), bdev
, id
.gid
, (caddr_t
)&D
)))
104 #endif /* HAVE_GROUP_QUOTA */
105 case SMB_USER_FS_QUOTA_TYPE
:
106 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
107 path
, bdev
, (unsigned)id
.uid
));
109 quotactl(QCMD(Q_XGETQSTAT
,USRQUOTA
), bdev
, -1, (caddr_t
)&F
);
111 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
) {
112 qflags
|= QUOTAS_DENY_DISK
;
114 else if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
) {
115 qflags
|= QUOTAS_ENABLED
;
121 #ifdef HAVE_GROUP_QUOTA
122 case SMB_GROUP_FS_QUOTA_TYPE
:
123 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
124 path
, bdev
, (unsigned)id
.gid
));
126 quotactl(QCMD(Q_XGETQSTAT
,GRPQUOTA
), bdev
, -1, (caddr_t
)&F
);
128 if (F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
) {
129 qflags
|= QUOTAS_DENY_DISK
;
131 else if (F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
) {
132 qflags
|= QUOTAS_ENABLED
;
138 #endif /* HAVE_GROUP_QUOTA */
145 dp
->softlimit
= (uint64_t)D
.d_blk_softlimit
;
146 dp
->hardlimit
= (uint64_t)D
.d_blk_hardlimit
;
147 dp
->ihardlimit
= (uint64_t)D
.d_ino_hardlimit
;
148 dp
->isoftlimit
= (uint64_t)D
.d_ino_softlimit
;
149 dp
->curinodes
= (uint64_t)D
.d_icount
;
150 dp
->curblocks
= (uint64_t)D
.d_bcount
;
156 /****************************************************************************
157 Abstract out the XFS Quota Manager quota set call.
158 ****************************************************************************/
159 int sys_set_xfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
163 uint64_t bsize
= (uint64_t)BBSIZE
;
164 struct fs_disk_quota D
;
165 struct fs_quota_stat F
;
172 smb_panic("sys_set_xfs_quota: called with NULL pointer");
174 if (bsize
== dp
->bsize
) {
175 D
.d_blk_softlimit
= dp
->softlimit
;
176 D
.d_blk_hardlimit
= dp
->hardlimit
;
177 D
.d_ino_hardlimit
= dp
->ihardlimit
;
178 D
.d_ino_softlimit
= dp
->isoftlimit
;
180 D
.d_blk_softlimit
= (dp
->softlimit
*dp
->bsize
)/bsize
;
181 D
.d_blk_hardlimit
= (dp
->hardlimit
*dp
->bsize
)/bsize
;
182 D
.d_ino_hardlimit
= (dp
->ihardlimit
*dp
->bsize
)/bsize
;
183 D
.d_ino_softlimit
= (dp
->isoftlimit
*dp
->bsize
)/bsize
;
189 case SMB_USER_QUOTA_TYPE
:
190 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
191 path
, bdev
, (unsigned)id
.uid
));
193 D
.d_fieldmask
|= FS_DQ_LIMIT_MASK
;
194 ret
= quotactl(QCMD(Q_XSETQLIM
,USRQUOTA
), bdev
, id
.uid
, (caddr_t
)&D
);
196 #ifdef HAVE_GROUP_QUOTA
197 case SMB_GROUP_QUOTA_TYPE
:
198 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
199 path
, bdev
, (unsigned)id
.gid
));
201 D
.d_fieldmask
|= FS_DQ_LIMIT_MASK
;
202 ret
= quotactl(QCMD(Q_XSETQLIM
,GRPQUOTA
), bdev
, id
.gid
, (caddr_t
)&D
);
204 #endif /* HAVE_GROUP_QUOTA */
205 case SMB_USER_FS_QUOTA_TYPE
:
206 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
207 path
, bdev
, (unsigned)id
.uid
));
209 quotactl(QCMD(Q_XGETQSTAT
,USRQUOTA
), bdev
, -1, (caddr_t
)&F
);
211 if (qflags
& QUOTAS_DENY_DISK
) {
212 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
))
213 q_on
|= XFS_QUOTA_UDQ_ENFD
;
214 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
215 q_on
|= XFS_QUOTA_UDQ_ACCT
;
218 ret
= quotactl(QCMD(Q_XQUOTAON
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
223 } else if (qflags
& QUOTAS_ENABLED
) {
224 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
225 q_off
|= XFS_QUOTA_UDQ_ENFD
;
228 ret
= quotactl(QCMD(Q_XQUOTAOFF
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
233 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
234 q_on
|= XFS_QUOTA_UDQ_ACCT
;
237 ret
= quotactl(QCMD(Q_XQUOTAON
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
243 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
244 * only swittching off XFS_QUOTA_UDQ_ACCT work
246 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
247 q_off
|= XFS_QUOTA_UDQ_ENFD
;
248 if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
)
249 q_off
|= XFS_QUOTA_UDQ_ACCT
;
252 ret
= quotactl(QCMD(Q_XQUOTAOFF
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
262 #ifdef HAVE_GROUP_QUOTA
263 case SMB_GROUP_FS_QUOTA_TYPE
:
264 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
265 path
, bdev
, (unsigned)id
.gid
));
267 quotactl(QCMD(Q_XGETQSTAT
,GRPQUOTA
), bdev
, -1, (caddr_t
)&F
);
269 if (qflags
& QUOTAS_DENY_DISK
) {
270 if (!(F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
))
271 q_on
|= XFS_QUOTA_GDQ_ENFD
;
272 if (!(F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
))
273 q_on
|= XFS_QUOTA_GDQ_ACCT
;
276 ret
= quotactl(QCMD(Q_XQUOTAON
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
281 } else if (qflags
& QUOTAS_ENABLED
) {
282 if (F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
)
283 q_off
|= XFS_QUOTA_GDQ_ENFD
;
286 ret
= quotactl(QCMD(Q_XQUOTAOFF
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
291 if (!(F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
))
292 q_on
|= XFS_QUOTA_GDQ_ACCT
;
295 ret
= quotactl(QCMD(Q_XQUOTAON
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
301 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
302 * only swittching off XFS_QUOTA_UDQ_ACCT work
304 if (F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
)
305 q_off
|= XFS_QUOTA_GDQ_ENFD
;
306 if (F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
)
307 q_off
|= XFS_QUOTA_GDQ_ACCT
;
310 ret
= quotactl(QCMD(Q_XQUOTAOFF
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
320 #endif /* HAVE_GROUP_QUOTA */
329 #else /* HAVE_XFS_QUOTAS */
330 void dummy_sysquotas_xfs(void);
332 void dummy_sysquotas_xfs(void){}
333 #endif /* HAVE_XFS_QUOTAS */