LCOV - code coverage report
Current view: top level - fs/xfs - xfs_quotaops.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsa @ Mon Jul 31 20:08:27 PDT 2023 Lines: 120 120 100.0 %
Date: 2023-07-31 20:08:27 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      442864 : 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      442864 :         bool                    tempqip = false;
      28             : 
      29      442864 :         tstate->ino = ino;
      30      442864 :         if (!ip && ino == NULLFSINO)
      31             :                 return;
      32      440114 :         if (!ip) {
      33         310 :                 if (xfs_iget(mp, NULL, ino, 0, 0, &ip))
      34             :                         return;
      35             :                 tempqip = true;
      36             :         }
      37      440114 :         tstate->flags |= QCI_SYSFILE;
      38      440114 :         tstate->blocks = ip->i_nblocks;
      39      440114 :         tstate->nextents = ip->i_df.if_nextents;
      40      440114 :         tstate->spc_timelimit = (u32)defq->blk.time;
      41      440114 :         tstate->ino_timelimit = (u32)defq->ino.time;
      42      440114 :         tstate->rt_spc_timelimit = (u32)defq->rtb.time;
      43      440114 :         tstate->spc_warnlimit = 0;
      44      440114 :         tstate->ino_warnlimit = 0;
      45      440114 :         tstate->rt_spc_warnlimit = 0;
      46      440114 :         if (tempqip)
      47         310 :                 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      149052 : xfs_fs_get_quota_state(
      56             :         struct super_block      *sb,
      57             :         struct qc_state         *state)
      58             : {
      59      149052 :         struct xfs_mount *mp = XFS_M(sb);
      60      149052 :         struct xfs_quotainfo *q = mp->m_quotainfo;
      61             : 
      62      149052 :         memset(state, 0, sizeof(*state));
      63      149052 :         if (!XFS_IS_QUOTA_ON(mp))
      64             :                 return 0;
      65      148084 :         state->s_incoredqs = q->qi_dquots;
      66      148084 :         if (XFS_IS_UQUOTA_ON(mp))
      67      147800 :                 state->s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED;
      68      148084 :         if (XFS_IS_UQUOTA_ENFORCED(mp))
      69      147780 :                 state->s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED;
      70      148084 :         if (XFS_IS_GQUOTA_ON(mp))
      71      147598 :                 state->s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED;
      72      148084 :         if (XFS_IS_GQUOTA_ENFORCED(mp))
      73      147589 :                 state->s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED;
      74      148084 :         if (XFS_IS_PQUOTA_ON(mp))
      75      145801 :                 state->s_state[PRJQUOTA].flags |= QCI_ACCT_ENABLED;
      76      148084 :         if (XFS_IS_PQUOTA_ENFORCED(mp))
      77      145799 :                 state->s_state[PRJQUOTA].flags |= QCI_LIMITS_ENFORCED;
      78             : 
      79      148084 :         xfs_qm_fill_state(&state->s_state[USRQUOTA], mp, q->qi_uquotaip,
      80             :                           mp->m_sb.sb_uquotino, &q->qi_usr_default);
      81      147634 :         xfs_qm_fill_state(&state->s_state[GRPQUOTA], mp, q->qi_gquotaip,
      82             :                           mp->m_sb.sb_gquotino, &q->qi_grp_default);
      83      147587 :         xfs_qm_fill_state(&state->s_state[PRJQUOTA], mp, q->qi_pquotaip,
      84             :                           mp->m_sb.sb_pquotino, &q->qi_prj_default);
      85      147587 :         return 0;
      86             : }
      87             : 
      88             : STATIC xfs_dqtype_t
      89      104696 : xfs_quota_type(int type)
      90             : {
      91      104696 :         switch (type) {
      92             :         case USRQUOTA:
      93             :                 return XFS_DQTYPE_USER;
      94       50786 :         case GRPQUOTA:
      95       50786 :                 return XFS_DQTYPE_GROUP;
      96        2674 :         default:
      97        2674 :                 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        1869 : xfs_fs_set_info(
     108             :         struct super_block      *sb,
     109             :         int                     type,
     110             :         struct qc_info          *info)
     111             : {
     112        1869 :         struct xfs_mount        *mp = XFS_M(sb);
     113        1869 :         struct qc_dqblk         newlim;
     114             : 
     115        1869 :         if (sb_rdonly(sb))
     116             :                 return -EROFS;
     117        1869 :         if (!XFS_IS_QUOTA_ON(mp))
     118             :                 return -ENOSYS;
     119        1869 :         if (info->i_fieldmask & ~XFS_QC_SETINFO_MASK)
     120             :                 return -EINVAL;
     121        1869 :         if ((info->i_fieldmask & XFS_QC_SETINFO_MASK) == 0)
     122             :                 return 0;
     123             : 
     124        1869 :         newlim.d_fieldmask = info->i_fieldmask;
     125        1869 :         newlim.d_spc_timer = info->i_spc_timelimit;
     126        1869 :         newlim.d_ino_timer = info->i_ino_timelimit;
     127        1869 :         newlim.d_rt_spc_timer = info->i_rt_spc_timelimit;
     128        1869 :         newlim.d_ino_warns = info->i_ino_warnlimit;
     129        1869 :         newlim.d_spc_warns = info->i_spc_warnlimit;
     130        1869 :         newlim.d_rt_spc_warns = info->i_rt_spc_warnlimit;
     131             : 
     132        1869 :         return xfs_qm_scall_setqlim(mp, 0, xfs_quota_type(type), &newlim);
     133             : }
     134             : 
     135             : static unsigned int
     136          74 : xfs_quota_flags(unsigned int uflags)
     137             : {
     138          74 :         unsigned int flags = 0;
     139             : 
     140          74 :         if (uflags & FS_QUOTA_UDQ_ACCT)
     141          34 :                 flags |= XFS_UQUOTA_ACCT;
     142          74 :         if (uflags & FS_QUOTA_PDQ_ACCT)
     143           4 :                 flags |= XFS_PQUOTA_ACCT;
     144          74 :         if (uflags & FS_QUOTA_GDQ_ACCT)
     145          28 :                 flags |= XFS_GQUOTA_ACCT;
     146          74 :         if (uflags & FS_QUOTA_UDQ_ENFD)
     147          42 :                 flags |= XFS_UQUOTA_ENFD;
     148          74 :         if (uflags & FS_QUOTA_GDQ_ENFD)
     149          44 :                 flags |= XFS_GQUOTA_ENFD;
     150          74 :         if (uflags & FS_QUOTA_PDQ_ENFD)
     151          16 :                 flags |= XFS_PQUOTA_ENFD;
     152             : 
     153          74 :         return flags;
     154             : }
     155             : 
     156             : STATIC int
     157          14 : xfs_quota_enable(
     158             :         struct super_block      *sb,
     159             :         unsigned int            uflags)
     160             : {
     161          14 :         struct xfs_mount        *mp = XFS_M(sb);
     162             : 
     163          14 :         if (sb_rdonly(sb))
     164             :                 return -EROFS;
     165          14 :         if (!XFS_IS_QUOTA_ON(mp))
     166             :                 return -ENOSYS;
     167             : 
     168          14 :         return xfs_qm_scall_quotaon(mp, xfs_quota_flags(uflags));
     169             : }
     170             : 
     171             : STATIC int
     172          60 : xfs_quota_disable(
     173             :         struct super_block      *sb,
     174             :         unsigned int            uflags)
     175             : {
     176          60 :         struct xfs_mount        *mp = XFS_M(sb);
     177             : 
     178          60 :         if (sb_rdonly(sb))
     179             :                 return -EROFS;
     180          60 :         if (!XFS_IS_QUOTA_ON(mp))
     181             :                 return -ENOSYS;
     182             : 
     183          60 :         return xfs_qm_scall_quotaoff(mp, xfs_quota_flags(uflags));
     184             : }
     185             : 
     186             : STATIC int
     187          40 : xfs_fs_rm_xquota(
     188             :         struct super_block      *sb,
     189             :         unsigned int            uflags)
     190             : {
     191          40 :         struct xfs_mount        *mp = XFS_M(sb);
     192          40 :         unsigned int            flags = 0;
     193             : 
     194          40 :         if (sb_rdonly(sb))
     195             :                 return -EROFS;
     196             : 
     197          40 :         if (XFS_IS_QUOTA_ON(mp))
     198             :                 return -EINVAL;
     199             : 
     200          24 :         if (uflags & ~(FS_USER_QUOTA | FS_GROUP_QUOTA | FS_PROJ_QUOTA))
     201             :                 return -EINVAL;
     202             : 
     203          24 :         if (uflags & FS_USER_QUOTA)
     204          12 :                 flags |= XFS_QMOPT_UQUOTA;
     205          24 :         if (uflags & FS_GROUP_QUOTA)
     206           8 :                 flags |= XFS_QMOPT_GQUOTA;
     207          24 :         if (uflags & FS_PROJ_QUOTA)
     208           4 :                 flags |= XFS_QMOPT_PQUOTA;
     209             : 
     210          24 :         return xfs_qm_scall_trunc_qfiles(mp, flags);
     211             : }
     212             : 
     213             : STATIC int
     214       20212 : xfs_fs_get_dqblk(
     215             :         struct super_block      *sb,
     216             :         struct kqid             qid,
     217             :         struct qc_dqblk         *qdq)
     218             : {
     219       20212 :         struct xfs_mount        *mp = XFS_M(sb);
     220       20212 :         xfs_dqid_t              id;
     221             : 
     222       20212 :         if (!XFS_IS_QUOTA_ON(mp))
     223             :                 return -ENOSYS;
     224             : 
     225       19584 :         id = from_kqid(&init_user_ns, qid);
     226       19439 :         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       62645 : xfs_fs_get_nextdqblk(
     232             :         struct super_block      *sb,
     233             :         struct kqid             *qid,
     234             :         struct qc_dqblk         *qdq)
     235             : {
     236       62645 :         int                     ret;
     237       62645 :         struct xfs_mount        *mp = XFS_M(sb);
     238       62645 :         xfs_dqid_t              id;
     239             : 
     240       62645 :         if (!XFS_IS_QUOTA_ON(mp))
     241             :                 return -ENOSYS;
     242             : 
     243       62631 :         id = from_kqid(&init_user_ns, *qid);
     244       62631 :         ret = xfs_qm_scall_getquota_next(mp, &id, xfs_quota_type(qid->type),
     245             :                         qdq);
     246       62631 :         if (ret)
     247             :                 return ret;
     248             : 
     249             :         /* ID may be different, so convert back what we got */
     250       61535 :         *qid = make_kqid(current_user_ns(), qid->type, id);
     251       61535 :         return 0;
     252             : }
     253             : 
     254             : STATIC int
     255       20697 : xfs_fs_set_dqblk(
     256             :         struct super_block      *sb,
     257             :         struct kqid             qid,
     258             :         struct qc_dqblk         *qdq)
     259             : {
     260       20697 :         struct xfs_mount        *mp = XFS_M(sb);
     261             : 
     262       20697 :         if (sb_rdonly(sb))
     263             :                 return -EROFS;
     264       20697 :         if (!XFS_IS_QUOTA_ON(mp))
     265             :                 return -ENOSYS;
     266             : 
     267       20697 :         return xfs_qm_scall_setqlim(mp, from_kqid(&init_user_ns, qid),
     268       20648 :                                      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