root/fs/xfs/xfs_quotaops.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. xfs_qm_fill_state
  2. xfs_fs_get_quota_state
  3. xfs_quota_type
  4. xfs_fs_set_info
  5. xfs_quota_flags
  6. xfs_quota_enable
  7. xfs_quota_disable
  8. xfs_fs_rm_xquota
  9. xfs_fs_get_dqblk
  10. xfs_fs_get_nextdqblk
  11. xfs_fs_set_dqblk

   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 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 {
  26         struct xfs_quotainfo *q = mp->m_quotainfo;
  27         bool tempqip = false;
  28 
  29         tstate->ino = ino;
  30         if (!ip && ino == NULLFSINO)
  31                 return;
  32         if (!ip) {
  33                 if (xfs_iget(mp, NULL, ino, 0, 0, &ip))
  34                         return;
  35                 tempqip = true;
  36         }
  37         tstate->flags |= QCI_SYSFILE;
  38         tstate->blocks = ip->i_d.di_nblocks;
  39         tstate->nextents = ip->i_d.di_nextents;
  40         tstate->spc_timelimit = q->qi_btimelimit;
  41         tstate->ino_timelimit = q->qi_itimelimit;
  42         tstate->rt_spc_timelimit = q->qi_rtbtimelimit;
  43         tstate->spc_warnlimit = q->qi_bwarnlimit;
  44         tstate->ino_warnlimit = q->qi_iwarnlimit;
  45         tstate->rt_spc_warnlimit = q->qi_rtbwarnlimit;
  46         if (tempqip)
  47                 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 xfs_fs_get_quota_state(
  56         struct super_block      *sb,
  57         struct qc_state         *state)
  58 {
  59         struct xfs_mount *mp = XFS_M(sb);
  60         struct xfs_quotainfo *q = mp->m_quotainfo;
  61 
  62         memset(state, 0, sizeof(*state));
  63         if (!XFS_IS_QUOTA_RUNNING(mp))
  64                 return 0;
  65         state->s_incoredqs = q->qi_dquots;
  66         if (XFS_IS_UQUOTA_RUNNING(mp))
  67                 state->s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED;
  68         if (XFS_IS_UQUOTA_ENFORCED(mp))
  69                 state->s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED;
  70         if (XFS_IS_GQUOTA_RUNNING(mp))
  71                 state->s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED;
  72         if (XFS_IS_GQUOTA_ENFORCED(mp))
  73                 state->s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED;
  74         if (XFS_IS_PQUOTA_RUNNING(mp))
  75                 state->s_state[PRJQUOTA].flags |= QCI_ACCT_ENABLED;
  76         if (XFS_IS_PQUOTA_ENFORCED(mp))
  77                 state->s_state[PRJQUOTA].flags |= QCI_LIMITS_ENFORCED;
  78 
  79         xfs_qm_fill_state(&state->s_state[USRQUOTA], mp, q->qi_uquotaip,
  80                           mp->m_sb.sb_uquotino);
  81         xfs_qm_fill_state(&state->s_state[GRPQUOTA], mp, q->qi_gquotaip,
  82                           mp->m_sb.sb_gquotino);
  83         xfs_qm_fill_state(&state->s_state[PRJQUOTA], mp, q->qi_pquotaip,
  84                           mp->m_sb.sb_pquotino);
  85         return 0;
  86 }
  87 
  88 STATIC int
  89 xfs_quota_type(int type)
  90 {
  91         switch (type) {
  92         case USRQUOTA:
  93                 return XFS_DQ_USER;
  94         case GRPQUOTA:
  95                 return XFS_DQ_GROUP;
  96         default:
  97                 return XFS_DQ_PROJ;
  98         }
  99 }
 100 
 101 #define XFS_QC_SETINFO_MASK (QC_TIMER_MASK | QC_WARNS_MASK)
 102 
 103 /*
 104  * Adjust quota timers & warnings
 105  */
 106 static int
 107 xfs_fs_set_info(
 108         struct super_block      *sb,
 109         int                     type,
 110         struct qc_info          *info)
 111 {
 112         struct xfs_mount *mp = XFS_M(sb);
 113         struct qc_dqblk newlim;
 114 
 115         if (sb_rdonly(sb))
 116                 return -EROFS;
 117         if (!XFS_IS_QUOTA_RUNNING(mp))
 118                 return -ENOSYS;
 119         if (!XFS_IS_QUOTA_ON(mp))
 120                 return -ESRCH;
 121         if (info->i_fieldmask & ~XFS_QC_SETINFO_MASK)
 122                 return -EINVAL;
 123         if ((info->i_fieldmask & XFS_QC_SETINFO_MASK) == 0)
 124                 return 0;
 125 
 126         newlim.d_fieldmask = info->i_fieldmask;
 127         newlim.d_spc_timer = info->i_spc_timelimit;
 128         newlim.d_ino_timer = info->i_ino_timelimit;
 129         newlim.d_rt_spc_timer = info->i_rt_spc_timelimit;
 130         newlim.d_ino_warns = info->i_ino_warnlimit;
 131         newlim.d_spc_warns = info->i_spc_warnlimit;
 132         newlim.d_rt_spc_warns = info->i_rt_spc_warnlimit;
 133 
 134         return xfs_qm_scall_setqlim(mp, 0, xfs_quota_type(type), &newlim);
 135 }
 136 
 137 static unsigned int
 138 xfs_quota_flags(unsigned int uflags)
 139 {
 140         unsigned int flags = 0;
 141 
 142         if (uflags & FS_QUOTA_UDQ_ACCT)
 143                 flags |= XFS_UQUOTA_ACCT;
 144         if (uflags & FS_QUOTA_PDQ_ACCT)
 145                 flags |= XFS_PQUOTA_ACCT;
 146         if (uflags & FS_QUOTA_GDQ_ACCT)
 147                 flags |= XFS_GQUOTA_ACCT;
 148         if (uflags & FS_QUOTA_UDQ_ENFD)
 149                 flags |= XFS_UQUOTA_ENFD;
 150         if (uflags & FS_QUOTA_GDQ_ENFD)
 151                 flags |= XFS_GQUOTA_ENFD;
 152         if (uflags & FS_QUOTA_PDQ_ENFD)
 153                 flags |= XFS_PQUOTA_ENFD;
 154 
 155         return flags;
 156 }
 157 
 158 STATIC int
 159 xfs_quota_enable(
 160         struct super_block      *sb,
 161         unsigned int            uflags)
 162 {
 163         struct xfs_mount        *mp = XFS_M(sb);
 164 
 165         if (sb_rdonly(sb))
 166                 return -EROFS;
 167         if (!XFS_IS_QUOTA_RUNNING(mp))
 168                 return -ENOSYS;
 169 
 170         return xfs_qm_scall_quotaon(mp, xfs_quota_flags(uflags));
 171 }
 172 
 173 STATIC int
 174 xfs_quota_disable(
 175         struct super_block      *sb,
 176         unsigned int            uflags)
 177 {
 178         struct xfs_mount        *mp = XFS_M(sb);
 179 
 180         if (sb_rdonly(sb))
 181                 return -EROFS;
 182         if (!XFS_IS_QUOTA_RUNNING(mp))
 183                 return -ENOSYS;
 184         if (!XFS_IS_QUOTA_ON(mp))
 185                 return -EINVAL;
 186 
 187         return xfs_qm_scall_quotaoff(mp, xfs_quota_flags(uflags));
 188 }
 189 
 190 STATIC int
 191 xfs_fs_rm_xquota(
 192         struct super_block      *sb,
 193         unsigned int            uflags)
 194 {
 195         struct xfs_mount        *mp = XFS_M(sb);
 196         unsigned int            flags = 0;
 197 
 198         if (sb_rdonly(sb))
 199                 return -EROFS;
 200 
 201         if (XFS_IS_QUOTA_ON(mp))
 202                 return -EINVAL;
 203 
 204         if (uflags & ~(FS_USER_QUOTA | FS_GROUP_QUOTA | FS_PROJ_QUOTA))
 205                 return -EINVAL;
 206 
 207         if (uflags & FS_USER_QUOTA)
 208                 flags |= XFS_DQ_USER;
 209         if (uflags & FS_GROUP_QUOTA)
 210                 flags |= XFS_DQ_GROUP;
 211         if (uflags & FS_PROJ_QUOTA)
 212                 flags |= XFS_DQ_PROJ;
 213 
 214         return xfs_qm_scall_trunc_qfiles(mp, flags);
 215 }
 216 
 217 STATIC int
 218 xfs_fs_get_dqblk(
 219         struct super_block      *sb,
 220         struct kqid             qid,
 221         struct qc_dqblk         *qdq)
 222 {
 223         struct xfs_mount        *mp = XFS_M(sb);
 224         xfs_dqid_t              id;
 225 
 226         if (!XFS_IS_QUOTA_RUNNING(mp))
 227                 return -ENOSYS;
 228         if (!XFS_IS_QUOTA_ON(mp))
 229                 return -ESRCH;
 230 
 231         id = from_kqid(&init_user_ns, qid);
 232         return xfs_qm_scall_getquota(mp, id, xfs_quota_type(qid.type), qdq);
 233 }
 234 
 235 /* Return quota info for active quota >= this qid */
 236 STATIC int
 237 xfs_fs_get_nextdqblk(
 238         struct super_block      *sb,
 239         struct kqid             *qid,
 240         struct qc_dqblk         *qdq)
 241 {
 242         int                     ret;
 243         struct xfs_mount        *mp = XFS_M(sb);
 244         xfs_dqid_t              id;
 245 
 246         if (!XFS_IS_QUOTA_RUNNING(mp))
 247                 return -ENOSYS;
 248         if (!XFS_IS_QUOTA_ON(mp))
 249                 return -ESRCH;
 250 
 251         id = from_kqid(&init_user_ns, *qid);
 252         ret = xfs_qm_scall_getquota_next(mp, &id, xfs_quota_type(qid->type),
 253                         qdq);
 254         if (ret)
 255                 return ret;
 256 
 257         /* ID may be different, so convert back what we got */
 258         *qid = make_kqid(current_user_ns(), qid->type, id);
 259         return 0;
 260 }
 261 
 262 STATIC int
 263 xfs_fs_set_dqblk(
 264         struct super_block      *sb,
 265         struct kqid             qid,
 266         struct qc_dqblk         *qdq)
 267 {
 268         struct xfs_mount        *mp = XFS_M(sb);
 269 
 270         if (sb_rdonly(sb))
 271                 return -EROFS;
 272         if (!XFS_IS_QUOTA_RUNNING(mp))
 273                 return -ENOSYS;
 274         if (!XFS_IS_QUOTA_ON(mp))
 275                 return -ESRCH;
 276 
 277         return xfs_qm_scall_setqlim(mp, from_kqid(&init_user_ns, qid),
 278                                      xfs_quota_type(qid.type), qdq);
 279 }
 280 
 281 const struct quotactl_ops xfs_quotactl_operations = {
 282         .get_state              = xfs_fs_get_quota_state,
 283         .set_info               = xfs_fs_set_info,
 284         .quota_enable           = xfs_quota_enable,
 285         .quota_disable          = xfs_quota_disable,
 286         .rm_xquota              = xfs_fs_rm_xquota,
 287         .get_dqblk              = xfs_fs_get_dqblk,
 288         .get_nextdqblk          = xfs_fs_get_nextdqblk,
 289         .set_dqblk              = xfs_fs_set_dqblk,
 290 };

/* [<][>][^][v][top][bottom][index][help] */