00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "includes.h"
00023
00024 #undef DBGC_CLASS
00025 #define DBGC_CLASS DBGC_QUOTA
00026
00027 #ifndef HAVE_SYS_QUOTAS
00028 #ifdef HAVE_XFS_QUOTAS
00029 #undef HAVE_XFS_QUOTAS
00030 #endif
00031 #endif
00032
00033 #ifdef HAVE_XFS_QUOTAS
00034
00035 #ifdef HAVE_LINUX_XFS_QUOTAS
00036 #include "samba_linux_quota.h"
00037 #include "samba_xfs_quota.h"
00038 #define HAVE_GROUP_QUOTA
00039 #else
00040 #include <sys/quota.h>
00041 #endif
00042
00043
00044 #ifndef Q_XQUOTAON
00045 #define Q_XQUOTAON Q_QUOTAON
00046 #endif
00047 #ifndef Q_XQUOTAOFF
00048 #define Q_XQUOTAOFF Q_QUOTAOFF
00049 #endif
00050 #ifndef Q_XGETQSTAT
00051 #define Q_XGETQSTAT Q_GETQSTAT
00052 #endif
00053
00054
00055
00056
00057 #ifndef QCMD
00058 #define QCMD(x,y) x
00059 #endif
00060
00061
00062
00063
00064 #ifndef BBSHIFT
00065 #define BBSHIFT 9
00066 #endif
00067 #ifndef BBSIZE
00068 #define BBSIZE (1<<BBSHIFT)
00069 #endif
00070
00071
00072
00073
00074 int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
00075 {
00076 int ret = -1;
00077 uint32 qflags = 0;
00078 SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE;
00079 struct fs_disk_quota D;
00080 struct fs_quota_stat F;
00081 ZERO_STRUCT(D);
00082 ZERO_STRUCT(F);
00083
00084 if (!bdev||!dp)
00085 smb_panic("sys_get_xfs_quota: called with NULL pointer");
00086
00087 ZERO_STRUCT(*dp);
00088 dp->qtype = qtype;
00089
00090 switch (qtype) {
00091 case SMB_USER_QUOTA_TYPE:
00092 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
00093 path, bdev, (unsigned)id.uid));
00094
00095 if ((ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D)))
00096 return ret;
00097 break;
00098 #ifdef HAVE_GROUP_QUOTA
00099 case SMB_GROUP_QUOTA_TYPE:
00100 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
00101 path, bdev, (unsigned)id.gid));
00102
00103 if ((ret=quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D)))
00104 return ret;
00105 break;
00106 #endif
00107 case SMB_USER_FS_QUOTA_TYPE:
00108 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
00109 path, bdev, (unsigned)id.uid));
00110
00111 quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F);
00112
00113 if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) {
00114 qflags |= QUOTAS_DENY_DISK;
00115 }
00116 else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) {
00117 qflags |= QUOTAS_ENABLED;
00118 }
00119
00120 ret = 0;
00121
00122 break;
00123 #ifdef HAVE_GROUP_QUOTA
00124 case SMB_GROUP_FS_QUOTA_TYPE:
00125 DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
00126 path, bdev, (unsigned)id.gid));
00127
00128 quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F);
00129
00130 if (F.qs_flags & XFS_QUOTA_GDQ_ENFD) {
00131 qflags |= QUOTAS_DENY_DISK;
00132 }
00133 else if (F.qs_flags & XFS_QUOTA_GDQ_ACCT) {
00134 qflags |= QUOTAS_ENABLED;
00135 }
00136
00137 ret = 0;
00138
00139 break;
00140 #endif
00141 default:
00142 errno = ENOSYS;
00143 return -1;
00144 }
00145
00146 dp->bsize = bsize;
00147 dp->softlimit = (SMB_BIG_UINT)D.d_blk_softlimit;
00148 dp->hardlimit = (SMB_BIG_UINT)D.d_blk_hardlimit;
00149 dp->ihardlimit = (SMB_BIG_UINT)D.d_ino_hardlimit;
00150 dp->isoftlimit = (SMB_BIG_UINT)D.d_ino_softlimit;
00151 dp->curinodes = (SMB_BIG_UINT)D.d_icount;
00152 dp->curblocks = (SMB_BIG_UINT)D.d_bcount;
00153 dp->qflags = qflags;
00154
00155 return ret;
00156 }
00157
00158
00159
00160
00161 int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
00162 {
00163 int ret = -1;
00164 uint32 qflags = 0;
00165 SMB_BIG_UINT bsize = (SMB_BIG_UINT)BBSIZE;
00166 struct fs_disk_quota D;
00167 struct fs_quota_stat F;
00168 int q_on = 0;
00169 int q_off = 0;
00170 ZERO_STRUCT(D);
00171 ZERO_STRUCT(F);
00172
00173 if (!bdev||!dp)
00174 smb_panic("sys_set_xfs_quota: called with NULL pointer");
00175
00176 if (bsize == dp->bsize) {
00177 D.d_blk_softlimit = dp->softlimit;
00178 D.d_blk_hardlimit = dp->hardlimit;
00179 D.d_ino_hardlimit = dp->ihardlimit;
00180 D.d_ino_softlimit = dp->isoftlimit;
00181 } else {
00182 D.d_blk_softlimit = (dp->softlimit*dp->bsize)/bsize;
00183 D.d_blk_hardlimit = (dp->hardlimit*dp->bsize)/bsize;
00184 D.d_ino_hardlimit = (dp->ihardlimit*dp->bsize)/bsize;
00185 D.d_ino_softlimit = (dp->isoftlimit*dp->bsize)/bsize;
00186 }
00187
00188 qflags = dp->qflags;
00189
00190 switch (qtype) {
00191 case SMB_USER_QUOTA_TYPE:
00192 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
00193 path, bdev, (unsigned)id.uid));
00194
00195 D.d_fieldmask |= FS_DQ_LIMIT_MASK;
00196 ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (caddr_t)&D);
00197 break;
00198 #ifdef HAVE_GROUP_QUOTA
00199 case SMB_GROUP_QUOTA_TYPE:
00200 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
00201 path, bdev, (unsigned)id.gid));
00202
00203 D.d_fieldmask |= FS_DQ_LIMIT_MASK;
00204 ret = quotactl(QCMD(Q_XSETQLIM,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
00205 break;
00206 #endif
00207 case SMB_USER_FS_QUOTA_TYPE:
00208 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
00209 path, bdev, (unsigned)id.uid));
00210
00211 quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F);
00212
00213 if (qflags & QUOTAS_DENY_DISK) {
00214 if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD))
00215 q_on |= XFS_QUOTA_UDQ_ENFD;
00216 if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
00217 q_on |= XFS_QUOTA_UDQ_ACCT;
00218
00219 if (q_on != 0) {
00220 ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on);
00221 } else {
00222 ret = 0;
00223 }
00224
00225 } else if (qflags & QUOTAS_ENABLED) {
00226 if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
00227 q_off |= XFS_QUOTA_UDQ_ENFD;
00228
00229 if (q_off != 0) {
00230 ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off);
00231 } else {
00232 ret = 0;
00233 }
00234
00235 if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
00236 q_on |= XFS_QUOTA_UDQ_ACCT;
00237
00238 if (q_on != 0) {
00239 ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on);
00240 } else {
00241 ret = 0;
00242 }
00243 } else {
00244 #if 0
00245
00246
00247
00248 if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
00249 q_off |= XFS_QUOTA_UDQ_ENFD;
00250 if (F.qs_flags & XFS_QUOTA_UDQ_ACCT)
00251 q_off |= XFS_QUOTA_UDQ_ACCT;
00252
00253 if (q_off !=0) {
00254 ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off);
00255 } else {
00256 ret = 0;
00257 }
00258 #else
00259 ret = -1;
00260 #endif
00261 }
00262
00263 break;
00264 #ifdef HAVE_GROUP_QUOTA
00265 case SMB_GROUP_FS_QUOTA_TYPE:
00266 DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
00267 path, bdev, (unsigned)id.gid));
00268
00269 quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F);
00270
00271 if (qflags & QUOTAS_DENY_DISK) {
00272 if (!(F.qs_flags & XFS_QUOTA_GDQ_ENFD))
00273 q_on |= XFS_QUOTA_GDQ_ENFD;
00274 if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
00275 q_on |= XFS_QUOTA_GDQ_ACCT;
00276
00277 if (q_on != 0) {
00278 ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on);
00279 } else {
00280 ret = 0;
00281 }
00282
00283 } else if (qflags & QUOTAS_ENABLED) {
00284 if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
00285 q_off |= XFS_QUOTA_GDQ_ENFD;
00286
00287 if (q_off != 0) {
00288 ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off);
00289 } else {
00290 ret = 0;
00291 }
00292
00293 if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
00294 q_on |= XFS_QUOTA_GDQ_ACCT;
00295
00296 if (q_on != 0) {
00297 ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on);
00298 } else {
00299 ret = 0;
00300 }
00301 } else {
00302 #if 0
00303
00304
00305
00306 if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
00307 q_off |= XFS_QUOTA_GDQ_ENFD;
00308 if (F.qs_flags & XFS_QUOTA_GDQ_ACCT)
00309 q_off |= XFS_QUOTA_GDQ_ACCT;
00310
00311 if (q_off !=0) {
00312 ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off);
00313 } else {
00314 ret = 0;
00315 }
00316 #else
00317 ret = -1;
00318 #endif
00319 }
00320
00321 break;
00322 #endif
00323 default:
00324 errno = ENOSYS;
00325 return -1;
00326 }
00327
00328 return ret;
00329 }
00330
00331 #else
00332 void dummy_sysquotas_xfs(void);
00333
00334 void dummy_sysquotas_xfs(void){}
00335 #endif