Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0 2 : /* 3 : * Copyright (c) 2000-2005 Silicon Graphics, Inc. 4 : * All Rights Reserved. 5 : */ 6 : #ifndef __XFS_QM_H__ 7 : #define __XFS_QM_H__ 8 : 9 : #include "xfs_dquot_item.h" 10 : #include "xfs_dquot.h" 11 : 12 : struct xfs_inode; 13 : 14 : extern struct kmem_cache *xfs_dqtrx_cache; 15 : 16 : /* 17 : * Number of bmaps that we ask from bmapi when doing a quotacheck. 18 : * We make this restriction to keep the memory usage to a minimum. 19 : */ 20 : #define XFS_DQITER_MAP_SIZE 10 21 : 22 : #define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \ 23 : !dqp->q_blk.hardlimit && \ 24 : !dqp->q_blk.softlimit && \ 25 : !dqp->q_rtb.hardlimit && \ 26 : !dqp->q_rtb.softlimit && \ 27 : !dqp->q_ino.hardlimit && \ 28 : !dqp->q_ino.softlimit && \ 29 : !dqp->q_blk.count && \ 30 : !dqp->q_rtb.count && \ 31 : !dqp->q_ino.count) 32 : 33 : struct xfs_quota_limits { 34 : xfs_qcnt_t hard; /* default hard limit */ 35 : xfs_qcnt_t soft; /* default soft limit */ 36 : time64_t time; /* limit for timers */ 37 : }; 38 : 39 : /* Defaults for each quota type: time limits, warn limits, usage limits */ 40 : struct xfs_def_quota { 41 : struct xfs_quota_limits blk; 42 : struct xfs_quota_limits ino; 43 : struct xfs_quota_limits rtb; 44 : }; 45 : 46 : /* 47 : * Various quota information for individual filesystems. 48 : * The mount structure keeps a pointer to this. 49 : */ 50 : struct xfs_quotainfo { 51 : struct radix_tree_root qi_uquota_tree; 52 : struct radix_tree_root qi_gquota_tree; 53 : struct radix_tree_root qi_pquota_tree; 54 : struct mutex qi_tree_lock; 55 : struct xfs_inode *qi_uquotaip; /* user quota inode */ 56 : struct xfs_inode *qi_gquotaip; /* group quota inode */ 57 : struct xfs_inode *qi_pquotaip; /* project quota inode */ 58 : struct list_lru qi_lru; 59 : int qi_dquots; 60 : struct mutex qi_quotaofflock;/* to serialize quotaoff */ 61 : xfs_filblks_t qi_dqchunklen; /* # BBs in a chunk of dqs */ 62 : uint qi_dqperchunk; /* # ondisk dq in above chunk */ 63 : struct xfs_def_quota qi_usr_default; 64 : struct xfs_def_quota qi_grp_default; 65 : struct xfs_def_quota qi_prj_default; 66 : struct shrinker qi_shrinker; 67 : 68 : /* Minimum and maximum quota expiration timestamp values. */ 69 : time64_t qi_expiry_min; 70 : time64_t qi_expiry_max; 71 : 72 : /* Hook to feed quota counter updates to an active online repair. */ 73 : struct xfs_hooks qi_mod_ino_dqtrx_hooks; 74 : struct xfs_hooks qi_apply_dqtrx_hooks; 75 : }; 76 : 77 : static inline struct radix_tree_root * 78 146875607 : xfs_dquot_tree( 79 : struct xfs_quotainfo *qi, 80 : xfs_dqtype_t type) 81 : { 82 146875607 : switch (type) { 83 58117626 : case XFS_DQTYPE_USER: 84 58117626 : return &qi->qi_uquota_tree; 85 57591645 : case XFS_DQTYPE_GROUP: 86 57591645 : return &qi->qi_gquota_tree; 87 31166336 : case XFS_DQTYPE_PROJ: 88 31166336 : return &qi->qi_pquota_tree; 89 0 : default: 90 0 : ASSERT(0); 91 : } 92 0 : return NULL; 93 : } 94 : 95 : static inline struct xfs_inode * 96 26771204 : xfs_quota_inode(struct xfs_mount *mp, xfs_dqtype_t type) 97 : { 98 26771204 : switch (type) { 99 13196293 : case XFS_DQTYPE_USER: 100 13196293 : return mp->m_quotainfo->qi_uquotaip; 101 12650060 : case XFS_DQTYPE_GROUP: 102 12650060 : return mp->m_quotainfo->qi_gquotaip; 103 924851 : case XFS_DQTYPE_PROJ: 104 924851 : return mp->m_quotainfo->qi_pquotaip; 105 0 : default: 106 0 : ASSERT(0); 107 : } 108 0 : return NULL; 109 : } 110 : 111 : /* 112 : * Parameters for tracking dqtrx changes on behalf of an inode. The hook 113 : * function arg parameter is the field being updated. 114 : */ 115 : struct xfs_mod_ino_dqtrx_params { 116 : uintptr_t tx_id; 117 : xfs_ino_t ino; 118 : xfs_dqtype_t q_type; 119 : xfs_dqid_t q_id; 120 : int64_t delta; 121 : }; 122 : 123 : extern void xfs_trans_mod_dquot(struct xfs_trans *tp, struct xfs_dquot *dqp, 124 : uint field, int64_t delta); 125 : extern void xfs_trans_dqjoin(struct xfs_trans *, struct xfs_dquot *); 126 : extern void xfs_trans_log_dquot(struct xfs_trans *, struct xfs_dquot *); 127 : 128 : /* 129 : * We keep the usr, grp, and prj dquots separately so that locking will be 130 : * easier to do at commit time. All transactions that we know of at this point 131 : * affect no more than two dquots of one type. Hence, the TRANS_MAXDQS value. 132 : */ 133 : enum { 134 : XFS_QM_TRANS_USR = 0, 135 : XFS_QM_TRANS_GRP, 136 : XFS_QM_TRANS_PRJ, 137 : XFS_QM_TRANS_DQTYPES 138 : }; 139 : #define XFS_QM_TRANS_MAXDQS 5 140 : struct xfs_dquot_acct { 141 : struct xfs_dqtrx dqs[XFS_QM_TRANS_DQTYPES][XFS_QM_TRANS_MAXDQS]; 142 : }; 143 : 144 : /* 145 : * Users are allowed to have a usage exceeding their softlimit for 146 : * a period this long. 147 : */ 148 : #define XFS_QM_BTIMELIMIT (7 * 24*60*60) /* 1 week */ 149 : #define XFS_QM_RTBTIMELIMIT (7 * 24*60*60) /* 1 week */ 150 : #define XFS_QM_ITIMELIMIT (7 * 24*60*60) /* 1 week */ 151 : 152 : extern void xfs_qm_destroy_quotainfo(struct xfs_mount *); 153 : 154 : /* quota ops */ 155 : extern int xfs_qm_scall_trunc_qfiles(struct xfs_mount *, uint); 156 : extern int xfs_qm_scall_getquota(struct xfs_mount *mp, 157 : xfs_dqid_t id, 158 : xfs_dqtype_t type, 159 : struct qc_dqblk *dst); 160 : extern int xfs_qm_scall_getquota_next(struct xfs_mount *mp, 161 : xfs_dqid_t *id, 162 : xfs_dqtype_t type, 163 : struct qc_dqblk *dst); 164 : extern int xfs_qm_scall_setqlim(struct xfs_mount *mp, 165 : xfs_dqid_t id, 166 : xfs_dqtype_t type, 167 : struct qc_dqblk *newlim); 168 : extern int xfs_qm_scall_quotaon(struct xfs_mount *, uint); 169 : extern int xfs_qm_scall_quotaoff(struct xfs_mount *, uint); 170 : 171 : static inline struct xfs_def_quota * 172 6418069974 : xfs_get_defquota(struct xfs_quotainfo *qi, xfs_dqtype_t type) 173 : { 174 6418069974 : switch (type) { 175 2206995344 : case XFS_DQTYPE_USER: 176 2206995344 : return &qi->qi_usr_default; 177 2206444584 : case XFS_DQTYPE_GROUP: 178 2206444584 : return &qi->qi_grp_default; 179 2004630046 : case XFS_DQTYPE_PROJ: 180 2004630046 : return &qi->qi_prj_default; 181 0 : default: 182 0 : ASSERT(0); 183 0 : return NULL; 184 : } 185 : } 186 : 187 : #endif /* __XFS_QM_H__ */