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"
40 #define HAVE_GROUP_QUOTA
42 #include <sys/quota.h>
47 #define Q_XQUOTAON Q_QUOTAON
48 #endif /* Q_XQUOTAON */
50 #define Q_XQUOTAOFF Q_QUOTAOFF
51 #endif /* Q_XQUOTAOFF */
53 #define Q_XGETQSTAT Q_GETQSTAT
54 #endif /* Q_XGETQSTAT */
56 /* currently doesn't support Group and Project quotas on IRIX
64 * IRIX has BBSIZE in <sys/param.h>
70 #define BBSIZE (1<<BBSHIFT)
73 /****************************************************************************
74 Abstract out the XFS Quota Manager quota get call.
75 ****************************************************************************/
76 int sys_get_xfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
80 uint64_t bsize
= (uint64_t)BBSIZE
;
81 struct fs_disk_quota D
;
82 struct fs_quota_stat F
;
87 smb_panic("sys_get_xfs_quota: called with NULL pointer");
93 case SMB_USER_QUOTA_TYPE
:
94 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
95 path
, bdev
, (unsigned)id
.uid
));
97 if ((ret
=quotactl(QCMD(Q_XGETQUOTA
,USRQUOTA
), bdev
, id
.uid
, (caddr_t
)&D
)))
100 #ifdef HAVE_GROUP_QUOTA
101 case SMB_GROUP_QUOTA_TYPE
:
102 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
103 path
, bdev
, (unsigned)id
.gid
));
105 if ((ret
=quotactl(QCMD(Q_XGETQUOTA
,GRPQUOTA
), bdev
, id
.gid
, (caddr_t
)&D
)))
108 #endif /* HAVE_GROUP_QUOTA */
109 case SMB_USER_FS_QUOTA_TYPE
:
110 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
111 path
, bdev
, (unsigned)id
.uid
));
113 quotactl(QCMD(Q_XGETQSTAT
,USRQUOTA
), bdev
, -1, (caddr_t
)&F
);
115 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
) {
116 qflags
|= QUOTAS_DENY_DISK
;
118 else if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
) {
119 qflags
|= QUOTAS_ENABLED
;
125 #ifdef HAVE_GROUP_QUOTA
126 case SMB_GROUP_FS_QUOTA_TYPE
:
127 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
128 path
, bdev
, (unsigned)id
.gid
));
130 quotactl(QCMD(Q_XGETQSTAT
,GRPQUOTA
), bdev
, -1, (caddr_t
)&F
);
132 if (F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
) {
133 qflags
|= QUOTAS_DENY_DISK
;
135 else if (F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
) {
136 qflags
|= QUOTAS_ENABLED
;
142 #endif /* HAVE_GROUP_QUOTA */
149 dp
->softlimit
= (uint64_t)D
.d_blk_softlimit
;
150 dp
->hardlimit
= (uint64_t)D
.d_blk_hardlimit
;
151 dp
->ihardlimit
= (uint64_t)D
.d_ino_hardlimit
;
152 dp
->isoftlimit
= (uint64_t)D
.d_ino_softlimit
;
153 dp
->curinodes
= (uint64_t)D
.d_icount
;
154 dp
->curblocks
= (uint64_t)D
.d_bcount
;
160 /****************************************************************************
161 Abstract out the XFS Quota Manager quota set call.
162 ****************************************************************************/
163 int sys_set_xfs_quota(const char *path
, const char *bdev
, enum SMB_QUOTA_TYPE qtype
, unid_t id
, SMB_DISK_QUOTA
*dp
)
167 uint64_t bsize
= (uint64_t)BBSIZE
;
168 struct fs_disk_quota D
;
169 struct fs_quota_stat F
;
176 smb_panic("sys_set_xfs_quota: called with NULL pointer");
178 if (bsize
== dp
->bsize
) {
179 D
.d_blk_softlimit
= dp
->softlimit
;
180 D
.d_blk_hardlimit
= dp
->hardlimit
;
181 D
.d_ino_hardlimit
= dp
->ihardlimit
;
182 D
.d_ino_softlimit
= dp
->isoftlimit
;
184 D
.d_blk_softlimit
= (dp
->softlimit
*dp
->bsize
)/bsize
;
185 D
.d_blk_hardlimit
= (dp
->hardlimit
*dp
->bsize
)/bsize
;
186 D
.d_ino_hardlimit
= (dp
->ihardlimit
*dp
->bsize
)/bsize
;
187 D
.d_ino_softlimit
= (dp
->isoftlimit
*dp
->bsize
)/bsize
;
193 case SMB_USER_QUOTA_TYPE
:
194 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
195 path
, bdev
, (unsigned)id
.uid
));
197 D
.d_fieldmask
|= FS_DQ_LIMIT_MASK
;
198 ret
= quotactl(QCMD(Q_XSETQLIM
,USRQUOTA
), bdev
, id
.uid
, (caddr_t
)&D
);
200 #ifdef HAVE_GROUP_QUOTA
201 case SMB_GROUP_QUOTA_TYPE
:
202 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
203 path
, bdev
, (unsigned)id
.gid
));
205 D
.d_fieldmask
|= FS_DQ_LIMIT_MASK
;
206 ret
= quotactl(QCMD(Q_XSETQLIM
,GRPQUOTA
), bdev
, id
.gid
, (caddr_t
)&D
);
208 #endif /* HAVE_GROUP_QUOTA */
209 case SMB_USER_FS_QUOTA_TYPE
:
210 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
211 path
, bdev
, (unsigned)id
.uid
));
213 quotactl(QCMD(Q_XGETQSTAT
,USRQUOTA
), bdev
, -1, (caddr_t
)&F
);
215 if (qflags
& QUOTAS_DENY_DISK
) {
216 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
))
217 q_on
|= XFS_QUOTA_UDQ_ENFD
;
218 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
219 q_on
|= XFS_QUOTA_UDQ_ACCT
;
222 ret
= quotactl(QCMD(Q_XQUOTAON
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
227 } else if (qflags
& QUOTAS_ENABLED
) {
228 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
229 q_off
|= XFS_QUOTA_UDQ_ENFD
;
232 ret
= quotactl(QCMD(Q_XQUOTAOFF
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
237 if (!(F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
))
238 q_on
|= XFS_QUOTA_UDQ_ACCT
;
241 ret
= quotactl(QCMD(Q_XQUOTAON
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
247 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
248 * only swittching off XFS_QUOTA_UDQ_ACCT work
250 if (F
.qs_flags
& XFS_QUOTA_UDQ_ENFD
)
251 q_off
|= XFS_QUOTA_UDQ_ENFD
;
252 if (F
.qs_flags
& XFS_QUOTA_UDQ_ACCT
)
253 q_off
|= XFS_QUOTA_UDQ_ACCT
;
256 ret
= quotactl(QCMD(Q_XQUOTAOFF
,USRQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
266 #ifdef HAVE_GROUP_QUOTA
267 case SMB_GROUP_FS_QUOTA_TYPE
:
268 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
269 path
, bdev
, (unsigned)id
.gid
));
271 quotactl(QCMD(Q_XGETQSTAT
,GRPQUOTA
), bdev
, -1, (caddr_t
)&F
);
273 if (qflags
& QUOTAS_DENY_DISK
) {
274 if (!(F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
))
275 q_on
|= XFS_QUOTA_GDQ_ENFD
;
276 if (!(F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
))
277 q_on
|= XFS_QUOTA_GDQ_ACCT
;
280 ret
= quotactl(QCMD(Q_XQUOTAON
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
285 } else if (qflags
& QUOTAS_ENABLED
) {
286 if (F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
)
287 q_off
|= XFS_QUOTA_GDQ_ENFD
;
290 ret
= quotactl(QCMD(Q_XQUOTAOFF
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
295 if (!(F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
))
296 q_on
|= XFS_QUOTA_GDQ_ACCT
;
299 ret
= quotactl(QCMD(Q_XQUOTAON
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_on
);
305 /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
306 * only swittching off XFS_QUOTA_UDQ_ACCT work
308 if (F
.qs_flags
& XFS_QUOTA_GDQ_ENFD
)
309 q_off
|= XFS_QUOTA_GDQ_ENFD
;
310 if (F
.qs_flags
& XFS_QUOTA_GDQ_ACCT
)
311 q_off
|= XFS_QUOTA_GDQ_ACCT
;
314 ret
= quotactl(QCMD(Q_XQUOTAOFF
,GRPQUOTA
),bdev
, -1, (caddr_t
)&q_off
);
324 #endif /* HAVE_GROUP_QUOTA */
333 #else /* HAVE_XFS_QUOTAS */
334 void dummy_sysquotas_xfs(void);
336 void dummy_sysquotas_xfs(void){}
337 #endif /* HAVE_XFS_QUOTAS */