LCOV - code coverage report
Current view: top level - fs/xfs - xfs_quotaops.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc3-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 120 120 100.0 %
Date: 2023-07-31 20:08:12 Functions: 11 11 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (c) 2008, Christoph Hellwig
       4             :  * All Rights Reserved.
       5             :  */
       6             : #include "xfs.h"
       7             : #include "xfs_shared.h"
       8             : #include "xfs_format.h"
       9             : #include "xfs_log_format.h"
      10             : #include "xfs_trans_resv.h"
      11             : #include "xfs_mount.h"
      12             : #include "xfs_inode.h"
      13             : #include "xfs_quota.h"
      14             : #include "xfs_trans.h"
      15             : #include "xfs_icache.h"
      16             : #include "xfs_qm.h"
      17             : 
      18             : 
      19             : static void
      20     1235085 : xfs_qm_fill_state(
      21             :         struct qc_type_state    *tstate,
      22             :         struct xfs_mount        *mp,
      23             :         struct xfs_inode        *ip,
      24             :         xfs_ino_t               ino,
      25             :         struct xfs_def_quota    *defq)
      26             : {
      27     1235085 :         bool                    tempqip = false;
      28             : 
      29     1235085 :         tstate->ino = ino;
      30     1235085 :         if (!ip && ino == NULLFSINO)
      31             :                 return;
      32     1186439 :         if (!ip) {
      33         916 :                 if (xfs_iget(mp, NULL, ino, 0, 0, &ip))
      34             :                         return;
      35             :                 tempqip = true;
      36             :         }
      37     1186439 :         tstate->flags |= QCI_SYSFILE;
      38     1186439 :         tstate->blocks = ip->i_nblocks;
      39     1186439 :         tstate->nextents = ip->i_df.if_nextents;
      40     1186439 :         tstate->spc_timelimit = (u32)defq->blk.time;
      41     1186439 :         tstate->ino_timelimit = (u32)defq->ino.time;
      42     1186439 :         tstate->rt_spc_timelimit = (u32)defq->rtb.time;
      43     1186439 :         tstate->spc_warnlimit = 0;
      44     1186439 :         tstate->ino_warnlimit = 0;
      45     1186439 :         tstate->rt_spc_warnlimit = 0;
      46     1186439 :         if (tempqip)
      47         916 :                 xfs_irele(ip);
      48             : }
      49             : 
      50             : /*
      51             :  * Return quota status information, such as enforcements, quota file inode
      52             :  * numbers etc.
      53             :  */
      54             : static int
      55      423059 : xfs_fs_get_quota_state(
      56             :         struct super_block      *sb,
      57             :         struct qc_state         *state)
      58             : {
      59      423059 :         struct xfs_mount *mp = XFS_M(sb);
      60      423059 :         struct xfs_quotainfo *q = mp->m_quotainfo;
      61             : 
      62      423059 :         memset(state, 0, sizeof(*state));
      63      423059 :         if (!XFS_IS_QUOTA_ON(mp))
      64             :                 return 0;
      65      411726 :         state->s_incoredqs = q->qi_dquots;
      66      411726 :         if (XFS_IS_UQUOTA_ON(mp))
      67      410873 :                 state->s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED;
      68      411726 :         if (XFS_IS_UQUOTA_ENFORCED(mp))
      69      410837 :                 state->s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED;
      70      411726 :         if (XFS_IS_GQUOTA_ON(mp))
      71      410303 :                 state->s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED;
      72      411726 :         if (XFS_IS_GQUOTA_ENFORCED(mp))
      73      410274 :                 state->s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED;
      74      411726 :         if (XFS_IS_PQUOTA_ON(mp))
      75      364437 :                 state->s_state[PRJQUOTA].flags |= QCI_ACCT_ENABLED;
      76      411726 :         if (XFS_IS_PQUOTA_ENFORCED(mp))
      77      364418 :                 state->s_state[PRJQUOTA].flags |= QCI_LIMITS_ENFORCED;
      78             : 
      79      411726 :         xfs_qm_fill_state(&state->s_state[USRQUOTA], mp, q->qi_uquotaip,
      80             :                           mp->m_sb.sb_uquotino, &q->qi_usr_default);
      81      411722 :         xfs_qm_fill_state(&state->s_state[GRPQUOTA], mp, q->qi_gquotaip,
      82             :                           mp->m_sb.sb_gquotino, &q->qi_grp_default);
      83      411720 :         xfs_qm_fill_state(&state->s_state[PRJQUOTA], mp, q->qi_pquotaip,
      84             :                           mp->m_sb.sb_pquotino, &q->qi_prj_default);
      85      411720 :         return 0;
      86             : }
      87             : 
      88             : STATIC xfs_dqtype_t
      89      398255 : xfs_quota_type(int type)
      90             : {
      91      398255 :         switch (type) {
      92             :         case USRQUOTA:
      93             :                 return XFS_DQTYPE_USER;
      94      193442 :         case GRPQUOTA:
      95      193442 :                 return XFS_DQTYPE_GROUP;
      96        9664 :         default:
      97        9664 :                 return XFS_DQTYPE_PROJ;
      98             :         }
      99             : }
     100             : 
     101             : #define XFS_QC_SETINFO_MASK (QC_TIMER_MASK)
     102             : 
     103             : /*
     104             :  * Adjust quota timers & warnings
     105             :  */
     106             : static int
     107        5649 : xfs_fs_set_info(
     108             :         struct super_block      *sb,
     109             :         int                     type,
     110             :         struct qc_info          *info)
     111             : {
     112        5649 :         struct xfs_mount        *mp = XFS_M(sb);
     113        5649 :         struct qc_dqblk         newlim;
     114             : 
     115        5649 :         if (sb_rdonly(sb))
     116             :                 return -EROFS;
     117        5649 :         if (!XFS_IS_QUOTA_ON(mp))
     118             :                 return -ENOSYS;
     119        5649 :         if (info->i_fieldmask & ~XFS_QC_SETINFO_MASK)
     120             :                 return -EINVAL;
     121        5649 :         if ((info->i_fieldmask & XFS_QC_SETINFO_MASK) == 0)
     122             :                 return 0;
     123             : 
     124        5647 :         newlim.d_fieldmask = info->i_fieldmask;
     125        5647 :         newlim.d_spc_timer = info->i_spc_timelimit;
     126        5647 :         newlim.d_ino_timer = info->i_ino_timelimit;
     127        5647 :         newlim.d_rt_spc_timer = info->i_rt_spc_timelimit;
     128        5647 :         newlim.d_ino_warns = info->i_ino_warnlimit;
     129        5647 :         newlim.d_spc_warns = info->i_spc_warnlimit;
     130        5647 :         newlim.d_rt_spc_warns = info->i_rt_spc_warnlimit;
     131             : 
     132        5647 :         return xfs_qm_scall_setqlim(mp, 0, xfs_quota_type(type), &newlim);
     133             : }
     134             : 
     135             : static unsigned int
     136         222 : xfs_quota_flags(unsigned int uflags)
     137             : {
     138         222 :         unsigned int flags = 0;
     139             : 
     140         222 :         if (uflags & FS_QUOTA_UDQ_ACCT)
     141         102 :                 flags |= XFS_UQUOTA_ACCT;
     142         222 :         if (uflags & FS_QUOTA_PDQ_ACCT)
     143          12 :                 flags |= XFS_PQUOTA_ACCT;
     144         222 :         if (uflags & FS_QUOTA_GDQ_ACCT)
     145          84 :                 flags |= XFS_GQUOTA_ACCT;
     146         222 :         if (uflags & FS_QUOTA_UDQ_ENFD)
     147         126 :                 flags |= XFS_UQUOTA_ENFD;
     148         222 :         if (uflags & FS_QUOTA_GDQ_ENFD)
     149         132 :                 flags |= XFS_GQUOTA_ENFD;
     150         222 :         if (uflags & FS_QUOTA_PDQ_ENFD)
     151          48 :                 flags |= XFS_PQUOTA_ENFD;
     152             : 
     153         222 :         return flags;
     154             : }
     155             : 
     156             : STATIC int
     157          42 : xfs_quota_enable(
     158             :         struct super_block      *sb,
     159             :         unsigned int            uflags)
     160             : {
     161          42 :         struct xfs_mount        *mp = XFS_M(sb);
     162             : 
     163          42 :         if (sb_rdonly(sb))
     164             :                 return -EROFS;
     165          42 :         if (!XFS_IS_QUOTA_ON(mp))
     166             :                 return -ENOSYS;
     167             : 
     168          42 :         return xfs_qm_scall_quotaon(mp, xfs_quota_flags(uflags));
     169             : }
     170             : 
     171             : STATIC int
     172         180 : xfs_quota_disable(
     173             :         struct super_block      *sb,
     174             :         unsigned int            uflags)
     175             : {
     176         180 :         struct xfs_mount        *mp = XFS_M(sb);
     177             : 
     178         180 :         if (sb_rdonly(sb))
     179             :                 return -EROFS;
     180         180 :         if (!XFS_IS_QUOTA_ON(mp))
     181             :                 return -ENOSYS;
     182             : 
     183         180 :         return xfs_qm_scall_quotaoff(mp, xfs_quota_flags(uflags));
     184             : }
     185             : 
     186             : STATIC int
     187         125 : xfs_fs_rm_xquota(
     188             :         struct super_block      *sb,
     189             :         unsigned int            uflags)
     190             : {
     191         125 :         struct xfs_mount        *mp = XFS_M(sb);
     192         125 :         unsigned int            flags = 0;
     193             : 
     194         125 :         if (sb_rdonly(sb))
     195             :                 return -EROFS;
     196             : 
     197         125 :         if (XFS_IS_QUOTA_ON(mp))
     198             :                 return -EINVAL;
     199             : 
     200          78 :         if (uflags & ~(FS_USER_QUOTA | FS_GROUP_QUOTA | FS_PROJ_QUOTA))
     201             :                 return -EINVAL;
     202             : 
     203          78 :         if (uflags & FS_USER_QUOTA)
     204          42 :                 flags |= XFS_QMOPT_UQUOTA;
     205          78 :         if (uflags & FS_GROUP_QUOTA)
     206          24 :                 flags |= XFS_QMOPT_GQUOTA;
     207          78 :         if (uflags & FS_PROJ_QUOTA)
     208          12 :                 flags |= XFS_QMOPT_PQUOTA;
     209             : 
     210          78 :         return xfs_qm_scall_trunc_qfiles(mp, flags);
     211             : }
     212             : 
     213             : STATIC int
     214       60501 : xfs_fs_get_dqblk(
     215             :         struct super_block      *sb,
     216             :         struct kqid             qid,
     217             :         struct qc_dqblk         *qdq)
     218             : {
     219       60501 :         struct xfs_mount        *mp = XFS_M(sb);
     220       60501 :         xfs_dqid_t              id;
     221             : 
     222       60501 :         if (!XFS_IS_QUOTA_ON(mp))
     223             :                 return -ENOSYS;
     224             : 
     225       58617 :         id = from_kqid(&init_user_ns, qid);
     226       58579 :         return xfs_qm_scall_getquota(mp, id, xfs_quota_type(qid.type), qdq);
     227             : }
     228             : 
     229             : /* Return quota info for active quota >= this qid */
     230             : STATIC int
     231      272055 : xfs_fs_get_nextdqblk(
     232             :         struct super_block      *sb,
     233             :         struct kqid             *qid,
     234             :         struct qc_dqblk         *qdq)
     235             : {
     236      272055 :         int                     ret;
     237      272055 :         struct xfs_mount        *mp = XFS_M(sb);
     238      272055 :         xfs_dqid_t              id;
     239             : 
     240      272055 :         if (!XFS_IS_QUOTA_ON(mp))
     241             :                 return -ENOSYS;
     242             : 
     243      272013 :         id = from_kqid(&init_user_ns, *qid);
     244      272013 :         ret = xfs_qm_scall_getquota_next(mp, &id, xfs_quota_type(qid->type),
     245             :                         qdq);
     246      272013 :         if (ret)
     247             :                 return ret;
     248             : 
     249             :         /* ID may be different, so convert back what we got */
     250      268936 :         *qid = make_kqid(current_user_ns(), qid->type, id);
     251      268936 :         return 0;
     252             : }
     253             : 
     254             : STATIC int
     255       61924 : xfs_fs_set_dqblk(
     256             :         struct super_block      *sb,
     257             :         struct kqid             qid,
     258             :         struct qc_dqblk         *qdq)
     259             : {
     260       61924 :         struct xfs_mount        *mp = XFS_M(sb);
     261             : 
     262       61924 :         if (sb_rdonly(sb))
     263             :                 return -EROFS;
     264       61924 :         if (!XFS_IS_QUOTA_ON(mp))
     265             :                 return -ENOSYS;
     266             : 
     267       61849 :         return xfs_qm_scall_setqlim(mp, from_kqid(&init_user_ns, qid),
     268       61924 :                                      xfs_quota_type(qid.type), qdq);
     269             : }
     270             : 
     271             : const struct quotactl_ops xfs_quotactl_operations = {
     272             :         .get_state              = xfs_fs_get_quota_state,
     273             :         .set_info               = xfs_fs_set_info,
     274             :         .quota_enable           = xfs_quota_enable,
     275             :         .quota_disable          = xfs_quota_disable,
     276             :         .rm_xquota              = xfs_fs_rm_xquota,
     277             :         .get_dqblk              = xfs_fs_get_dqblk,
     278             :         .get_nextdqblk          = xfs_fs_get_nextdqblk,
     279             :         .set_dqblk              = xfs_fs_set_dqblk,
     280             : };

Generated by: LCOV version 1.14