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 #ifndef HAVE_SYS_QUOTAS
27 #ifdef HAVE_XFS_QUOTAS
28 #undef HAVE_XFS_QUOTAS
32 #ifdef HAVE_XFS_QUOTAS
34 #ifdef HAVE_LINUX_XFS_QUOTAS
35 #include "samba_linux_quota.h"
36 #ifdef HAVE_LINUX_DQBLK_XFS_H
37 #include <linux/dqblk_xfs.h>
39 #define HAVE_GROUP_QUOTA
41 #include <sys/quota.h>
46 #define Q_XQUOTAON Q_QUOTAON
47 #endif /* Q_XQUOTAON */
49 #define Q_XQUOTAOFF Q_QUOTAOFF
50 #endif /* Q_XQUOTAOFF */
52 #define Q_XGETQSTAT Q_GETQSTAT
53 #endif /* Q_XGETQSTAT */
55 /* currently doesn't support Group and Project quotas on IRIX
63 * IRIX has BBSIZE in <sys/param.h>
69 #define BBSIZE (1<<BBSHIFT)
72 /****************************************************************************
73 Abstract out the XFS Quota Manager quota get call.
74 ****************************************************************************/
75 int sys_get_xfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
79 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)BBSIZE
;
80 struct fs_disk_quota D
;
81 struct fs_quota_stat F
;
86 smb_panic("sys_get_xfs_quota: called with NULL pointer");
92 case SMB_USER_QUOTA_TYPE
:
93 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
94 path
, bdev
, (unsigned)id
.uid
));
96 if ((ret
=quotactl(QCMD(Q_XGETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (caddr_t
)&D
)))
99 #ifdef HAVE_GROUP_QUOTA
100 case SMB_GROUP_QUOTA_TYPE
:
101 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
102 path
, bdev
, (unsigned)id
.gid
));
104 if ((ret
=quotactl(QCMD(Q_XGETQUOTA
,GRPQUOTA
), bdev
, id
.gid
, (caddr_t
)&D
)))
107 #endif /* HAVE_GROUP_QUOTA */
108 case SMB_USER_FS_QUOTA_TYPE
:
109 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
110 path
, bdev
, (unsigned)id
.uid
));
112 quotactl(QCMD(Q_XGETQSTAT
,USRQUOTA
), bdev
, -1, (caddr_t
)&F
);
114 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
) {
115 qflags
|= QUOTAS_DENY_DISK
;
117 else if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
) {
118 qflags
|= QUOTAS_ENABLED
;
124 #ifdef HAVE_GROUP_QUOTA
125 case SMB_GROUP_FS_QUOTA_TYPE
:
126 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
127 path
, bdev
, (unsigned)id
.gid
));
129 quotactl(QCMD(Q_XGETQSTAT
,GRPQUOTA
), bdev
, -1, (caddr_t
)&F
);
131 if (F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
) {
132 qflags
|= QUOTAS_DENY_DISK
;
134 else if (F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
) {
135 qflags
|= QUOTAS_ENABLED
;
141 #endif /* HAVE_GROUP_QUOTA */
148 dp
->softlimit
= (SMB_BIG_UINT
)D
.d_blk_softlimit
;
149 dp
->hardlimit
= (SMB_BIG_UINT
)D
.d_blk_hardlimit
;
150 dp
->ihardlimit
= (SMB_BIG_UINT
)D
.d_ino_hardlimit
;
151 dp
->isoftlimit
= (SMB_BIG_UINT
)D
.d_ino_softlimit
;
152 dp
->curinodes
= (SMB_BIG_UINT
)D
.d_icount
;
153 dp
->curblocks
= (SMB_BIG_UINT
)D
.d_bcount
;
159 /****************************************************************************
160 Abstract out the XFS Quota Manager quota set call.
161 ****************************************************************************/
162 int sys_set_xfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
166 SMB_BIG_UINT bsize
= (SMB_BIG_UINT
)BBSIZE
;
167 struct fs_disk_quota D
;
168 struct fs_quota_stat F
;
175 smb_panic("sys_set_xfs_quota: called with NULL pointer");
177 if (bsize
== dp
->bsize
) {
178 D
.d_blk_softlimit
= dp
->softlimit
;
179 D
.d_blk_hardlimit
= dp
->hardlimit
;
180 D
.d_ino_hardlimit
= dp
->ihardlimit
;
181 D
.d_ino_softlimit
= dp
->isoftlimit
;
183 D
.d_blk_softlimit
= (dp
->softlimit
*dp
->bsize
)/bsize
;
184 D
.d_blk_hardlimit
= (dp
->hardlimit
*dp
->bsize
)/bsize
;
185 D
.d_ino_hardlimit
= (dp
->ihardlimit
*dp
->bsize
)/bsize
;
186 D
.d_ino_softlimit
= (dp
->isoftlimit
*dp
->bsize
)/bsize
;
192 case SMB_USER_QUOTA_TYPE
:
193 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
194 path
, bdev
, (unsigned)id
.uid
));
196 D
.d_fieldmask
|= FS_DQ_LIMIT_MASK
;
197 ret
= quotactl(QCMD(Q_XSETQLIM
,USRQUOTA
), bdev
, id
.uid
, (caddr_t
)&D
);
199 #ifdef HAVE_GROUP_QUOTA
200 case SMB_GROUP_QUOTA_TYPE
:
201 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
202 path
, bdev
, (unsigned)id
.gid
));
204 D
.d_fieldmask
|= FS_DQ_LIMIT_MASK
;
205 ret
= quotactl(QCMD(Q_XSETQLIM
,GRPQUOTA
), bdev
, id
.gid
, (caddr_t
)&D
);
207 #endif /* HAVE_GROUP_QUOTA */
208 case SMB_USER_FS_QUOTA_TYPE
:
209 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
210 path
, bdev
, (unsigned)id
.uid
));
212 quotactl(QCMD(Q_XGETQSTAT
,USRQUOTA
), bdev
, -1, (caddr_t
)&F
);
214 if (qflags
& QUOTAS_DENY_DISK
) {
215 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
))
216 q_on
|= XFS_QUOTA_UDQ_ENFD
;
217 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
218 q_on
|= XFS_QUOTA_UDQ_ACCT
;
221 ret
= quotactl(QCMD(Q_XQUOTAON
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
226 } else if (qflags
& QUOTAS_ENABLED
) {
227 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
228 q_off
|= XFS_QUOTA_UDQ_ENFD
;
231 ret
= quotactl(QCMD(Q_XQUOTAOFF
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
236 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
237 q_on
|= XFS_QUOTA_UDQ_ACCT
;
240 ret
= quotactl(QCMD(Q_XQUOTAON
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
246 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
247 * only swittching off XFS_QUOTA_UDQ_ACCT work
249 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
250 q_off
|= XFS_QUOTA_UDQ_ENFD
;
251 if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
)
252 q_off
|= XFS_QUOTA_UDQ_ACCT
;
255 ret
= quotactl(QCMD(Q_XQUOTAOFF
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
265 #ifdef HAVE_GROUP_QUOTA
266 case SMB_GROUP_FS_QUOTA_TYPE
:
267 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
268 path
, bdev
, (unsigned)id
.gid
));
270 quotactl(QCMD(Q_XGETQSTAT
,GRPQUOTA
), bdev
, -1, (caddr_t
)&F
);
272 if (qflags
& QUOTAS_DENY_DISK
) {
273 if (!(F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
))
274 q_on
|= XFS_QUOTA_GDQ_ENFD
;
275 if (!(F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
))
276 q_on
|= XFS_QUOTA_GDQ_ACCT
;
279 ret
= quotactl(QCMD(Q_XQUOTAON
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
284 } else if (qflags
& QUOTAS_ENABLED
) {
285 if (F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
)
286 q_off
|= XFS_QUOTA_GDQ_ENFD
;
289 ret
= quotactl(QCMD(Q_XQUOTAOFF
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
294 if (!(F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
))
295 q_on
|= XFS_QUOTA_GDQ_ACCT
;
298 ret
= quotactl(QCMD(Q_XQUOTAON
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
304 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
305 * only swittching off XFS_QUOTA_UDQ_ACCT work
307 if (F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
)
308 q_off
|= XFS_QUOTA_GDQ_ENFD
;
309 if (F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
)
310 q_off
|= XFS_QUOTA_GDQ_ACCT
;
313 ret
= quotactl(QCMD(Q_XQUOTAOFF
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
323 #endif /* HAVE_GROUP_QUOTA */
332 #else /* HAVE_XFS_QUOTAS */
333 void dummy_sysquotas_xfs(void);
335 void dummy_sysquotas_xfs(void){}
336 #endif /* HAVE_XFS_QUOTAS */