LCOV - code coverage report
Current view: top level - source3/lib - sysquotas_xfs.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 33 135 24.4 %
Date: 2021-09-23 10:06:22 Functions: 1 2 50.0 %

          Line data    Source code
       1             : /* 
       2             :    Unix SMB/CIFS implementation.
       3             :    System QUOTA function wrappers for XFS
       4             :    Copyright (C) Stefan (metze) Metzmacher      2003
       5             :    
       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.
      10             :    
      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.
      15             :    
      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/>.
      18             : */
      19             : 
      20             : 
      21             : #include "includes.h"
      22             : 
      23             : #undef DBGC_CLASS
      24             : #define DBGC_CLASS DBGC_QUOTA
      25             : 
      26             : #if defined(HAVE_SYS_QUOTAS) && defined(HAVE_XFS_QUOTAS)
      27             : 
      28             : #ifdef HAVE_SYS_QUOTA_H
      29             : #include <sys/quota.h> 
      30             : #endif
      31             : 
      32             : /* this one should actually come from glibc: */
      33             : /* #include "samba_linux_quota.h" */
      34             : 
      35             : #ifdef HAVE_XFS_XQM_H
      36             : #include <xfs/xqm.h>
      37             : #endif
      38             : 
      39             : #define HAVE_GROUP_QUOTA
      40             : 
      41             : /* on IRIX */
      42             : #ifndef Q_XQUOTAON
      43             : #define Q_XQUOTAON Q_QUOTAON
      44             : #endif /* Q_XQUOTAON */
      45             : #ifndef Q_XQUOTAOFF
      46             : #define Q_XQUOTAOFF Q_QUOTAOFF
      47             : #endif /* Q_XQUOTAOFF */
      48             : #ifndef Q_XGETQSTAT
      49             : #define Q_XGETQSTAT Q_GETQSTAT
      50             : #endif /* Q_XGETQSTAT */
      51             : 
      52             : /* currently doesn't support Group and Project quotas on IRIX 
      53             :  */
      54             : 
      55             : #ifndef QCMD
      56             : #define QCMD(x,y) x
      57             : #endif
      58             : 
      59             : /*
      60             :  * IRIX has BBSIZE in <sys/param.h>
      61             :  */
      62             : #ifndef BBSHIFT
      63             : #define BBSHIFT         9
      64             : #endif /* BBSHIFT */
      65             : #ifndef BBSIZE
      66             : #define BBSIZE          (1<<BBSHIFT)
      67             : #endif /* BBSIZE */
      68             : 
      69             : /****************************************************************************
      70             :  Abstract out the XFS Quota Manager quota get call.
      71             : ****************************************************************************/
      72        1366 : int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
      73             : {
      74        1366 :         int ret = -1;
      75        1366 :         uint32_t qflags = 0;
      76        1366 :         uint64_t bsize = (uint64_t)BBSIZE;
      77             :         struct fs_disk_quota D;
      78             :         struct fs_quota_stat F;
      79        1366 :         ZERO_STRUCT(D);
      80        1366 :         ZERO_STRUCT(F);
      81             : 
      82        1366 :         if (!bdev||!dp)
      83           0 :                 smb_panic("sys_get_xfs_quota: called with NULL pointer");
      84             :                 
      85        1366 :         ZERO_STRUCT(*dp);
      86        1366 :         dp->qtype = qtype;
      87             :                 
      88        1366 :         switch (qtype) {
      89           0 :                 case SMB_USER_QUOTA_TYPE:
      90           0 :                         DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
      91             :                                 path, bdev, (unsigned)id.uid));
      92             : 
      93           0 :                         ret=quotactl(QCMD(Q_XGETQUOTA,USRQUOTA), bdev, id.uid, (caddr_t)&D);
      94             :                         /* XFS fails with ENOENT if the user has no
      95             :                          * quota. Our protocol in that case is to
      96             :                          * succeed and return 0 as quota.
      97             :                          */
      98           0 :                         if (ret != 0 && errno != ENOENT) {
      99           0 :                                 return ret;
     100             :                         }
     101             : 
     102           0 :                         ret = 0;
     103           0 :                         break;
     104             : #ifdef HAVE_GROUP_QUOTA
     105           0 :                 case SMB_GROUP_QUOTA_TYPE:
     106           0 :                         DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
     107             :                                 path, bdev, (unsigned)id.gid));
     108             : 
     109           0 :                         ret=quotactl(QCMD(Q_XGETQUOTA,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
     110             :                         /* XFS fails with ENOENT if the user has no
     111             :                          * quota. Our protocol in that case is to
     112             :                          * succeed and return 0 as quota.
     113             :                          */
     114           0 :                         if (ret != 0 && errno != ENOENT) {
     115           0 :                                 return ret;
     116             :                         }
     117           0 :                         break;
     118             : #endif /* HAVE_GROUP_QUOTA */
     119         683 :                 case SMB_USER_FS_QUOTA_TYPE:
     120         683 :                         DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
     121             :                                 path, bdev, (unsigned)id.uid));
     122             : 
     123         683 :                         quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F);
     124             : 
     125         683 :                         if (F.qs_flags & XFS_QUOTA_UDQ_ENFD) {
     126           0 :                                 qflags |= QUOTAS_DENY_DISK;
     127             :                         }
     128         683 :                         else if (F.qs_flags & XFS_QUOTA_UDQ_ACCT) {
     129           0 :                                 qflags |= QUOTAS_ENABLED;
     130             :                         }
     131             : 
     132         683 :                         ret = 0;
     133             : 
     134         683 :                         break;
     135             : #ifdef HAVE_GROUP_QUOTA
     136         683 :                 case SMB_GROUP_FS_QUOTA_TYPE:
     137         683 :                         DEBUG(10,("sys_get_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
     138             :                                 path, bdev, (unsigned)id.gid));
     139             : 
     140         683 :                         quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F);
     141             : 
     142         683 :                         if (F.qs_flags & XFS_QUOTA_GDQ_ENFD) {
     143           0 :                                 qflags |= QUOTAS_DENY_DISK;
     144             :                         }
     145         683 :                         else if (F.qs_flags & XFS_QUOTA_GDQ_ACCT) {
     146           0 :                                 qflags |= QUOTAS_ENABLED;
     147             :                         }
     148             : 
     149         683 :                         ret = 0;
     150             : 
     151         683 :                         break;
     152             : #endif /* HAVE_GROUP_QUOTA */
     153           0 :                 default:
     154           0 :                         errno = ENOSYS;
     155           0 :                         return -1;
     156             :         }
     157             : 
     158        1366 :         dp->bsize = bsize;
     159        1366 :         dp->softlimit = (uint64_t)D.d_blk_softlimit;
     160        1366 :         dp->hardlimit = (uint64_t)D.d_blk_hardlimit;
     161        1366 :         dp->ihardlimit = (uint64_t)D.d_ino_hardlimit;
     162        1366 :         dp->isoftlimit = (uint64_t)D.d_ino_softlimit;
     163        1366 :         dp->curinodes = (uint64_t)D.d_icount;
     164        1366 :         dp->curblocks = (uint64_t)D.d_bcount;
     165        1366 :         dp->qflags = qflags;
     166             : 
     167        1366 :         return ret;
     168             : }
     169             : 
     170             : /****************************************************************************
     171             :  Abstract out the XFS Quota Manager quota set call.
     172             : ****************************************************************************/
     173           0 : int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp)
     174             : {
     175           0 :         int ret = -1;
     176           0 :         uint32_t qflags = 0;
     177           0 :         uint64_t bsize = (uint64_t)BBSIZE;
     178             :         struct fs_disk_quota D;
     179             :         struct fs_quota_stat F;
     180           0 :         int q_on = 0;
     181           0 :         int q_off = 0;
     182           0 :         ZERO_STRUCT(D);
     183           0 :         ZERO_STRUCT(F);
     184             : 
     185           0 :         if (!bdev||!dp)
     186           0 :                 smb_panic("sys_set_xfs_quota: called with NULL pointer");
     187             :         
     188           0 :         if (bsize == dp->bsize) {
     189           0 :                 D.d_blk_softlimit = dp->softlimit;
     190           0 :                 D.d_blk_hardlimit = dp->hardlimit;
     191             :         } else {
     192           0 :                 D.d_blk_softlimit = (dp->softlimit*dp->bsize)/bsize;
     193           0 :                 D.d_blk_hardlimit = (dp->hardlimit*dp->bsize)/bsize;
     194             :         }
     195           0 :         D.d_ino_hardlimit = dp->ihardlimit;
     196           0 :         D.d_ino_softlimit = dp->isoftlimit;
     197             : 
     198           0 :         qflags = dp->qflags;
     199             : 
     200           0 :         switch (qtype) {
     201           0 :                 case SMB_USER_QUOTA_TYPE:
     202           0 :                         DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_QUOTA_TYPE uid[%u]\n",
     203             :                                 path, bdev, (unsigned)id.uid));
     204             : 
     205           0 :                         D.d_fieldmask |= FS_DQ_LIMIT_MASK;
     206           0 :                         ret = quotactl(QCMD(Q_XSETQLIM,USRQUOTA), bdev, id.uid, (caddr_t)&D);
     207           0 :                         break;
     208             : #ifdef HAVE_GROUP_QUOTA
     209           0 :                 case SMB_GROUP_QUOTA_TYPE:
     210           0 :                         DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_QUOTA_TYPE gid[%u]\n",
     211             :                                 path, bdev, (unsigned)id.gid));
     212             : 
     213           0 :                         D.d_fieldmask |= FS_DQ_LIMIT_MASK;
     214           0 :                         ret = quotactl(QCMD(Q_XSETQLIM,GRPQUOTA), bdev, id.gid, (caddr_t)&D);
     215           0 :                         break;
     216             : #endif /* HAVE_GROUP_QUOTA */
     217           0 :                 case SMB_USER_FS_QUOTA_TYPE:
     218           0 :                         DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_USER_FS_QUOTA_TYPE (uid[%u])\n",
     219             :                                 path, bdev, (unsigned)id.uid));
     220             : 
     221           0 :                         quotactl(QCMD(Q_XGETQSTAT,USRQUOTA), bdev, -1, (caddr_t)&F);
     222             :                         
     223           0 :                         if (qflags & QUOTAS_DENY_DISK) {
     224           0 :                                 if (!(F.qs_flags & XFS_QUOTA_UDQ_ENFD))
     225           0 :                                         q_on |= XFS_QUOTA_UDQ_ENFD;
     226           0 :                                 if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
     227           0 :                                         q_on |= XFS_QUOTA_UDQ_ACCT;
     228             :                                 
     229           0 :                                 if (q_on != 0) {
     230           0 :                                         ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on);
     231             :                                 } else {
     232           0 :                                         ret = 0;
     233             :                                 }
     234             : 
     235           0 :                         } else if (qflags & QUOTAS_ENABLED) {
     236           0 :                                 if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
     237           0 :                                         q_off |= XFS_QUOTA_UDQ_ENFD;
     238             : 
     239           0 :                                 if (q_off != 0) {
     240           0 :                                         ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off);
     241             :                                 } else {
     242           0 :                                         ret = 0;
     243             :                                 }
     244             : 
     245           0 :                                 if (!(F.qs_flags & XFS_QUOTA_UDQ_ACCT))
     246           0 :                                         q_on |= XFS_QUOTA_UDQ_ACCT;
     247             : 
     248           0 :                                 if (q_on != 0) {
     249           0 :                                         ret = quotactl(QCMD(Q_XQUOTAON,USRQUOTA),bdev, -1, (caddr_t)&q_on);
     250             :                                 } else {
     251           0 :                                         ret = 0;
     252             :                                 }
     253             :                         } else {
     254             : #if 0
     255             :                         /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
     256             :                          * only swittching off XFS_QUOTA_UDQ_ACCT work
     257             :                          */
     258             :                                 if (F.qs_flags & XFS_QUOTA_UDQ_ENFD)
     259             :                                         q_off |= XFS_QUOTA_UDQ_ENFD;
     260             :                                 if (F.qs_flags & XFS_QUOTA_UDQ_ACCT)
     261             :                                         q_off |= XFS_QUOTA_UDQ_ACCT;
     262             : 
     263             :                                 if (q_off !=0) {
     264             :                                         ret = quotactl(QCMD(Q_XQUOTAOFF,USRQUOTA),bdev, -1, (caddr_t)&q_off);
     265             :                                 } else {
     266             :                                         ret = 0;
     267             :                                 }
     268             : #else
     269           0 :                                 ret = -1;
     270             : #endif
     271             :                         }
     272             : 
     273           0 :                         break;
     274             : #ifdef HAVE_GROUP_QUOTA
     275           0 :                 case SMB_GROUP_FS_QUOTA_TYPE:
     276           0 :                         DEBUG(10,("sys_set_xfs_quota: path[%s] bdev[%s] SMB_GROUP_FS_QUOTA_TYPE (gid[%u])\n",
     277             :                                 path, bdev, (unsigned)id.gid));
     278             : 
     279           0 :                         quotactl(QCMD(Q_XGETQSTAT,GRPQUOTA), bdev, -1, (caddr_t)&F);
     280             :                         
     281           0 :                         if (qflags & QUOTAS_DENY_DISK) {
     282           0 :                                 if (!(F.qs_flags & XFS_QUOTA_GDQ_ENFD))
     283           0 :                                         q_on |= XFS_QUOTA_GDQ_ENFD;
     284           0 :                                 if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
     285           0 :                                         q_on |= XFS_QUOTA_GDQ_ACCT;
     286             :                                 
     287           0 :                                 if (q_on != 0) {
     288           0 :                                         ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on);
     289             :                                 } else {
     290           0 :                                         ret = 0;
     291             :                                 }
     292             : 
     293           0 :                         } else if (qflags & QUOTAS_ENABLED) {
     294           0 :                                 if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
     295           0 :                                         q_off |= XFS_QUOTA_GDQ_ENFD;
     296             : 
     297           0 :                                 if (q_off != 0) {
     298           0 :                                         ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off);
     299             :                                 } else {
     300           0 :                                         ret = 0;
     301             :                                 }
     302             : 
     303           0 :                                 if (!(F.qs_flags & XFS_QUOTA_GDQ_ACCT))
     304           0 :                                         q_on |= XFS_QUOTA_GDQ_ACCT;
     305             : 
     306           0 :                                 if (q_on != 0) {
     307           0 :                                         ret = quotactl(QCMD(Q_XQUOTAON,GRPQUOTA),bdev, -1, (caddr_t)&q_on);
     308             :                                 } else {
     309           0 :                                         ret = 0;
     310             :                                 }
     311             :                         } else {
     312             : #if 0
     313             :                         /* Switch on XFS_QUOTA_UDQ_ACCT didn't work!
     314             :                          * only swittching off XFS_QUOTA_UDQ_ACCT work
     315             :                          */
     316             :                                 if (F.qs_flags & XFS_QUOTA_GDQ_ENFD)
     317             :                                         q_off |= XFS_QUOTA_GDQ_ENFD;
     318             :                                 if (F.qs_flags & XFS_QUOTA_GDQ_ACCT)
     319             :                                         q_off |= XFS_QUOTA_GDQ_ACCT;
     320             : 
     321             :                                 if (q_off !=0) {
     322             :                                         ret = quotactl(QCMD(Q_XQUOTAOFF,GRPQUOTA),bdev, -1, (caddr_t)&q_off);
     323             :                                 } else {
     324             :                                         ret = 0;
     325             :                                 }
     326             : #else
     327           0 :                                 ret = -1;
     328             : #endif
     329             :                         }
     330             : 
     331           0 :                         break;
     332             : #endif /* HAVE_GROUP_QUOTA */
     333           0 :                 default:
     334           0 :                         errno = ENOSYS;
     335           0 :                         return -1;
     336             :         }
     337             : 
     338           0 :         return ret;
     339             : }
     340             : 
     341             : #else /* HAVE_XFS_QUOTAS */
     342             :  void dummy_sysquotas_xfs(void);
     343             : 
     344             :  void dummy_sysquotas_xfs(void){}
     345             : #endif /* HAVE_XFS_QUOTAS */

Generated by: LCOV version 1.13