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 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_XFS_QUOTAS
29 #undef HAVE_XFS_QUOTAS
33 #ifdef HAVE_XFS_QUOTAS
35 #ifdef HAVE_LINUX_XFS_QUOTAS
36 #include "samba_linux_quota.h"
37 #include "samba_xfs_quota.h"
38 #define HAVE_GROUP_QUOTA
40 #include <sys/quota.h>
45 #define Q_XQUOTAON Q_QUOTAON
46 #endif /* Q_XQUOTAON */
48 #define Q_XQUOTAOFF Q_QUOTAOFF
49 #endif /* Q_XQUOTAOFF */
51 #define Q_XGETQSTAT Q_GETQSTAT
52 #endif /* Q_XGETQSTAT */
54 /* currently doesn't support Group and Project quotas on IRIX
62 * IRIX has BBSIZE in <sys/param.h>
68 #define BBSIZE (1<<BBSHIFT)
71 /****************************************************************************
72 Abstract out the XFS Quota Manager quota get call.
73 ****************************************************************************/
74 int sys_get_xfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
78 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)BBSIZE
;
79 struct fs_disk_quota D
;
80 struct fs_quota_stat F
;
85 smb_panic("sys_get_xfs_quota: called with NULL pointer");
91 case SMB_USER_QUOTA_TYPE
:
92 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
93 path
, bdev
, (unsigned)id
.uid
));
95 if ((ret
=quotactl(QCMD(Q_XGETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (caddr_t
)&D
)))
98 #ifdef HAVE_GROUP_QUOTA
99 case SMB_GROUP_QUOTA_TYPE
:
100 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
101 path
, bdev
, (unsigned)id
.gid
));
103 if ((ret
=quotactl(QCMD(Q_XGETQUOTA
,GRPQUOTA
), bdev
, id
.gid
, (caddr_t
)&D
)))
106 #endif /* HAVE_GROUP_QUOTA */
107 case SMB_USER_FS_QUOTA_TYPE
:
108 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
109 path
, bdev
, (unsigned)id
.uid
));
111 quotactl(QCMD(Q_XGETQSTAT
,USRQUOTA
), bdev
, -1, (caddr_t
)&F
);
113 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
) {
114 qflags
|= QUOTAS_DENY_DISK
;
116 else if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
) {
117 qflags
|= QUOTAS_ENABLED
;
123 #ifdef HAVE_GROUP_QUOTA
124 case SMB_GROUP_FS_QUOTA_TYPE
:
125 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
126 path
, bdev
, (unsigned)id
.gid
));
128 quotactl(QCMD(Q_XGETQSTAT
,GRPQUOTA
), bdev
, -1, (caddr_t
)&F
);
130 if (F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
) {
131 qflags
|= QUOTAS_DENY_DISK
;
133 else if (F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
) {
134 qflags
|= QUOTAS_ENABLED
;
140 #endif /* HAVE_GROUP_QUOTA */
147 dp
->softlimit
= (SMB_BIG_UINT
)D
.d_blk_softlimit
;
148 dp
->hardlimit
= (SMB_BIG_UINT
)D
.d_blk_hardlimit
;
149 dp
->ihardlimit
= (SMB_BIG_UINT
)D
.d_ino_hardlimit
;
150 dp
->isoftlimit
= (SMB_BIG_UINT
)D
.d_ino_softlimit
;
151 dp
->curinodes
= (SMB_BIG_UINT
)D
.d_icount
;
152 dp
->curblocks
= (SMB_BIG_UINT
)D
.d_bcount
;
158 /****************************************************************************
159 Abstract out the XFS Quota Manager quota set call.
160 ****************************************************************************/
161 int sys_set_xfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
165 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)BBSIZE
;
166 struct fs_disk_quota D
;
167 struct fs_quota_stat F
;
174 smb_panic("sys_set_xfs_quota: called with NULL pointer");
176 if (bsize
== dp
->bsize
) {
177 D
.d_blk_softlimit
= dp
->softlimit
;
178 D
.d_blk_hardlimit
= dp
->hardlimit
;
179 D
.d_ino_hardlimit
= dp
->ihardlimit
;
180 D
.d_ino_softlimit
= dp
->isoftlimit
;
182 D
.d_blk_softlimit
= (dp
->softlimit
*dp
->bsize
)/bsize
;
183 D
.d_blk_hardlimit
= (dp
->hardlimit
*dp
->bsize
)/bsize
;
184 D
.d_ino_hardlimit
= (dp
->ihardlimit
*dp
->bsize
)/bsize
;
185 D
.d_ino_softlimit
= (dp
->isoftlimit
*dp
->bsize
)/bsize
;
191 case SMB_USER_QUOTA_TYPE
:
192 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
193 path
, bdev
, (unsigned)id
.uid
));
195 D
.d_fieldmask
|= FS_DQ_LIMIT_MASK
;
196 ret
= quotactl(QCMD(Q_XSETQLIM
,USRQUOTA
), bdev
, id
.uid
, (caddr_t
)&D
);
198 #ifdef HAVE_GROUP_QUOTA
199 case SMB_GROUP_QUOTA_TYPE
:
200 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
201 path
, bdev
, (unsigned)id
.gid
));
203 D
.d_fieldmask
|= FS_DQ_LIMIT_MASK
;
204 ret
= quotactl(QCMD(Q_XSETQLIM
,GRPQUOTA
), bdev
, id
.gid
, (caddr_t
)&D
);
206 #endif /* HAVE_GROUP_QUOTA */
207 case SMB_USER_FS_QUOTA_TYPE
:
208 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
209 path
, bdev
, (unsigned)id
.uid
));
211 quotactl(QCMD(Q_XGETQSTAT
,USRQUOTA
), bdev
, -1, (caddr_t
)&F
);
213 if (qflags
& QUOTAS_DENY_DISK
) {
214 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
))
215 q_on
|= XFS_QUOTA_UDQ_ENFD
;
216 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
217 q_on
|= XFS_QUOTA_UDQ_ACCT
;
220 ret
= quotactl(QCMD(Q_XQUOTAON
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
225 } else if (qflags
& QUOTAS_ENABLED
) {
226 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
227 q_off
|= XFS_QUOTA_UDQ_ENFD
;
230 ret
= quotactl(QCMD(Q_XQUOTAOFF
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
235 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
236 q_on
|= XFS_QUOTA_UDQ_ACCT
;
239 ret
= quotactl(QCMD(Q_XQUOTAON
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
245 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
246 * only swittching off XFS_QUOTA_UDQ_ACCT work
248 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
249 q_off
|= XFS_QUOTA_UDQ_ENFD
;
250 if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
)
251 q_off
|= XFS_QUOTA_UDQ_ACCT
;
254 ret
= quotactl(QCMD(Q_XQUOTAOFF
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
264 #ifdef HAVE_GROUP_QUOTA
265 case SMB_GROUP_FS_QUOTA_TYPE
:
266 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
267 path
, bdev
, (unsigned)id
.gid
));
269 quotactl(QCMD(Q_XGETQSTAT
,GRPQUOTA
), bdev
, -1, (caddr_t
)&F
);
271 if (qflags
& QUOTAS_DENY_DISK
) {
272 if (!(F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
))
273 q_on
|= XFS_QUOTA_GDQ_ENFD
;
274 if (!(F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
))
275 q_on
|= XFS_QUOTA_GDQ_ACCT
;
278 ret
= quotactl(QCMD(Q_XQUOTAON
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
283 } else if (qflags
& QUOTAS_ENABLED
) {
284 if (F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
)
285 q_off
|= XFS_QUOTA_GDQ_ENFD
;
288 ret
= quotactl(QCMD(Q_XQUOTAOFF
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
293 if (!(F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
))
294 q_on
|= XFS_QUOTA_GDQ_ACCT
;
297 ret
= quotactl(QCMD(Q_XQUOTAON
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
303 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
304 * only swittching off XFS_QUOTA_UDQ_ACCT work
306 if (F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
)
307 q_off
|= XFS_QUOTA_GDQ_ENFD
;
308 if (F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
)
309 q_off
|= XFS_QUOTA_GDQ_ACCT
;
312 ret
= quotactl(QCMD(Q_XQUOTAOFF
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
322 #endif /* HAVE_GROUP_QUOTA */
331 #else /* HAVE_XFS_QUOTAS */
332 void dummy_sysquotas_xfs(void);
334 void dummy_sysquotas_xfs(void){}
335 #endif /* HAVE_XFS_QUOTAS */