1 // SPDX-License-Identifier: GPL-2.0 1 // SPDX-License-Identifier: GPL-2.0 2 /* 2 /* 3 * Copyright (c) 2000-2005 Silicon Graphics, I 3 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 4 * All Rights Reserved. 4 * All Rights Reserved. 5 */ 5 */ 6 #ifndef __XFS_DQUOT_H__ 6 #ifndef __XFS_DQUOT_H__ 7 #define __XFS_DQUOT_H__ 7 #define __XFS_DQUOT_H__ 8 8 9 /* 9 /* 10 * Dquots are structures that hold quota infor 10 * Dquots are structures that hold quota information about a user or a group, 11 * much like inodes are for files. In fact, dq 11 * much like inodes are for files. In fact, dquots share many characteristics 12 * with inodes. However, dquots can also be a 12 * with inodes. However, dquots can also be a centralized resource, relative 13 * to a collection of inodes. In this respect, 13 * to a collection of inodes. In this respect, dquots share some characteristics 14 * of the superblock. 14 * of the superblock. 15 * XFS dquots exploit both those in its algori 15 * XFS dquots exploit both those in its algorithms. They make every attempt 16 * to not be a bottleneck when quotas are on a 16 * to not be a bottleneck when quotas are on and have minimal impact, if any, 17 * when quotas are off. 17 * when quotas are off. 18 */ 18 */ 19 19 20 struct xfs_mount; 20 struct xfs_mount; 21 struct xfs_trans; 21 struct xfs_trans; 22 22 23 enum { 23 enum { 24 XFS_QLOWSP_1_PCNT = 0, 24 XFS_QLOWSP_1_PCNT = 0, 25 XFS_QLOWSP_3_PCNT, 25 XFS_QLOWSP_3_PCNT, 26 XFS_QLOWSP_5_PCNT, 26 XFS_QLOWSP_5_PCNT, 27 XFS_QLOWSP_MAX 27 XFS_QLOWSP_MAX 28 }; 28 }; 29 29 30 struct xfs_dquot_res { << 31 /* Total resources allocated and reser << 32 xfs_qcnt_t reserved; << 33 << 34 /* Total resources allocated. */ << 35 xfs_qcnt_t count; << 36 << 37 /* Absolute and preferred limits. */ << 38 xfs_qcnt_t hardlimit; << 39 xfs_qcnt_t softlimit; << 40 << 41 /* << 42 * For root dquots, this is the defaul << 43 * Otherwise, this is when the quota g << 44 * in seconds since the Unix epoch. << 45 */ << 46 time64_t timer; << 47 }; << 48 << 49 static inline bool << 50 xfs_dquot_res_over_limits( << 51 const struct xfs_dquot_res *qres) << 52 { << 53 if ((qres->softlimit && qres->softlimi << 54 (qres->hardlimit && qres->hardlimi << 55 return true; << 56 return false; << 57 } << 58 << 59 /* 30 /* 60 * The incore dquot structure 31 * The incore dquot structure 61 */ 32 */ 62 struct xfs_dquot { !! 33 typedef struct xfs_dquot { 63 struct list_head q_lru; !! 34 uint dq_flags; /* various flags (XFS_DQ_*) */ 64 struct xfs_mount *q_mount; !! 35 struct list_head q_lru; /* global free list of dquots */ 65 xfs_dqtype_t q_type; !! 36 struct xfs_mount*q_mount; /* filesystem this relates to */ 66 uint16_t q_flags; !! 37 struct xfs_trans*q_transp; /* trans this belongs to currently */ 67 xfs_dqid_t q_id; !! 38 uint q_nrefs; /* # active refs from inodes */ 68 uint q_nrefs; !! 39 xfs_daddr_t q_blkno; /* blkno of dquot buffer */ 69 int q_bufoffset; !! 40 int q_bufoffset; /* off of dq in buffer (# dquots) */ 70 xfs_daddr_t q_blkno; !! 41 xfs_fileoff_t q_fileoffset; /* offset in quotas file */ 71 xfs_fileoff_t q_fileoffset; !! 42 72 !! 43 xfs_disk_dquot_t q_core; /* actual usage & quotas */ 73 struct xfs_dquot_res q_blk; /* reg !! 44 xfs_dq_logitem_t q_logitem; /* dquot log item */ 74 struct xfs_dquot_res q_ino; /* ino !! 45 xfs_qcnt_t q_res_bcount; /* total regular nblks used+reserved */ 75 struct xfs_dquot_res q_rtb; /* rea !! 46 xfs_qcnt_t q_res_icount; /* total inos allocd+reserved */ 76 !! 47 xfs_qcnt_t q_res_rtbcount;/* total realtime blks used+reserved */ 77 struct xfs_dq_logitem q_logitem; !! 48 xfs_qcnt_t q_prealloc_lo_wmark;/* prealloc throttle wmark */ 78 !! 49 xfs_qcnt_t q_prealloc_hi_wmark;/* prealloc disabled wmark */ 79 xfs_qcnt_t q_prealloc_lo_ !! 50 int64_t q_low_space[XFS_QLOWSP_MAX]; 80 xfs_qcnt_t q_prealloc_hi_ !! 51 struct mutex q_qlock; /* quota lock */ 81 int64_t q_low_space[XF !! 52 struct completion q_flush; /* flush completion queue */ 82 struct mutex q_qlock; !! 53 atomic_t q_pincount; /* dquot pin count */ 83 struct completion q_flush; !! 54 wait_queue_head_t q_pinwait; /* dquot pinning wait queue */ 84 atomic_t q_pincount; !! 55 } xfs_dquot_t; 85 struct wait_queue_head q_pinwait; << 86 }; << 87 56 88 /* 57 /* 89 * Lock hierarchy for q_qlock: 58 * Lock hierarchy for q_qlock: 90 * XFS_QLOCK_NORMAL is the implicit defau 59 * XFS_QLOCK_NORMAL is the implicit default, 91 * XFS_QLOCK_NESTED is the dquot with the !! 60 * XFS_QLOCK_NESTED is the dquot with the higher id in xfs_dqlock2 92 */ 61 */ 93 enum { 62 enum { 94 XFS_QLOCK_NORMAL = 0, 63 XFS_QLOCK_NORMAL = 0, 95 XFS_QLOCK_NESTED, 64 XFS_QLOCK_NESTED, 96 }; 65 }; 97 66 98 /* 67 /* 99 * Manage the q_flush completion queue embedde !! 68 * Manage the q_flush completion queue embedded in the dquot. This completion 100 * queue synchronizes processes attempting to 69 * queue synchronizes processes attempting to flush the in-core dquot back to 101 * disk. 70 * disk. 102 */ 71 */ 103 static inline void xfs_dqflock(struct xfs_dquo !! 72 static inline void xfs_dqflock(xfs_dquot_t *dqp) 104 { 73 { 105 wait_for_completion(&dqp->q_flush); 74 wait_for_completion(&dqp->q_flush); 106 } 75 } 107 76 108 static inline bool xfs_dqflock_nowait(struct x !! 77 static inline bool xfs_dqflock_nowait(xfs_dquot_t *dqp) 109 { 78 { 110 return try_wait_for_completion(&dqp->q 79 return try_wait_for_completion(&dqp->q_flush); 111 } 80 } 112 81 113 static inline void xfs_dqfunlock(struct xfs_dq !! 82 static inline void xfs_dqfunlock(xfs_dquot_t *dqp) 114 { 83 { 115 complete(&dqp->q_flush); 84 complete(&dqp->q_flush); 116 } 85 } 117 86 118 static inline int xfs_dqlock_nowait(struct xfs 87 static inline int xfs_dqlock_nowait(struct xfs_dquot *dqp) 119 { 88 { 120 return mutex_trylock(&dqp->q_qlock); 89 return mutex_trylock(&dqp->q_qlock); 121 } 90 } 122 91 123 static inline void xfs_dqlock(struct xfs_dquot 92 static inline void xfs_dqlock(struct xfs_dquot *dqp) 124 { 93 { 125 mutex_lock(&dqp->q_qlock); 94 mutex_lock(&dqp->q_qlock); 126 } 95 } 127 96 128 static inline void xfs_dqunlock(struct xfs_dqu 97 static inline void xfs_dqunlock(struct xfs_dquot *dqp) 129 { 98 { 130 mutex_unlock(&dqp->q_qlock); 99 mutex_unlock(&dqp->q_qlock); 131 } 100 } 132 101 133 static inline int !! 102 static inline int xfs_this_quota_on(struct xfs_mount *mp, int type) 134 xfs_dquot_type(const struct xfs_dquot *dqp) << 135 { << 136 return dqp->q_type & XFS_DQTYPE_REC_MA << 137 } << 138 << 139 static inline int xfs_this_quota_on(struct xfs << 140 { 103 { 141 switch (type) { !! 104 switch (type & XFS_DQ_ALLTYPES) { 142 case XFS_DQTYPE_USER: !! 105 case XFS_DQ_USER: 143 return XFS_IS_UQUOTA_ON(mp); 106 return XFS_IS_UQUOTA_ON(mp); 144 case XFS_DQTYPE_GROUP: !! 107 case XFS_DQ_GROUP: 145 return XFS_IS_GQUOTA_ON(mp); 108 return XFS_IS_GQUOTA_ON(mp); 146 case XFS_DQTYPE_PROJ: !! 109 case XFS_DQ_PROJ: 147 return XFS_IS_PQUOTA_ON(mp); 110 return XFS_IS_PQUOTA_ON(mp); 148 default: 111 default: 149 return 0; 112 return 0; 150 } 113 } 151 } 114 } 152 115 153 static inline struct xfs_dquot *xfs_inode_dquo !! 116 static inline xfs_dquot_t *xfs_inode_dquot(struct xfs_inode *ip, int type) 154 struct xfs_inode *ip, << 155 xfs_dqtype_t type) << 156 { 117 { 157 switch (type) { !! 118 switch (type & XFS_DQ_ALLTYPES) { 158 case XFS_DQTYPE_USER: !! 119 case XFS_DQ_USER: 159 return ip->i_udquot; 120 return ip->i_udquot; 160 case XFS_DQTYPE_GROUP: !! 121 case XFS_DQ_GROUP: 161 return ip->i_gdquot; 122 return ip->i_gdquot; 162 case XFS_DQTYPE_PROJ: !! 123 case XFS_DQ_PROJ: 163 return ip->i_pdquot; 124 return ip->i_pdquot; 164 default: 125 default: 165 return NULL; 126 return NULL; 166 } 127 } 167 } 128 } 168 129 169 /* Decide if the dquot's limits are actually b << 170 static inline bool << 171 xfs_dquot_is_enforced( << 172 const struct xfs_dquot *dqp) << 173 { << 174 switch (xfs_dquot_type(dqp)) { << 175 case XFS_DQTYPE_USER: << 176 return XFS_IS_UQUOTA_ENFORCED( << 177 case XFS_DQTYPE_GROUP: << 178 return XFS_IS_GQUOTA_ENFORCED( << 179 case XFS_DQTYPE_PROJ: << 180 return XFS_IS_PQUOTA_ENFORCED( << 181 } << 182 ASSERT(0); << 183 return false; << 184 } << 185 << 186 /* 130 /* 187 * Check whether a dquot is under low free spa 131 * Check whether a dquot is under low free space conditions. We assume the quota 188 * is enabled and enforced. 132 * is enabled and enforced. 189 */ 133 */ 190 static inline bool xfs_dquot_lowsp(struct xfs_ 134 static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp) 191 { 135 { 192 int64_t freesp; 136 int64_t freesp; 193 137 194 freesp = dqp->q_blk.hardlimit - dqp->q !! 138 freesp = be64_to_cpu(dqp->q_core.d_blk_hardlimit) - dqp->q_res_bcount; 195 if (freesp < dqp->q_low_space[XFS_QLOW 139 if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT]) 196 return true; 140 return true; 197 141 198 return false; 142 return false; 199 } 143 } 200 144 201 void xfs_dquot_to_disk(struct xfs_disk_dquot * << 202 << 203 #define XFS_DQ_IS_LOCKED(dqp) (mutex_is_lock 145 #define XFS_DQ_IS_LOCKED(dqp) (mutex_is_locked(&((dqp)->q_qlock))) 204 #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->q_flag !! 146 #define XFS_DQ_IS_DIRTY(dqp) ((dqp)->dq_flags & XFS_DQ_DIRTY) >> 147 #define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQ_USER) >> 148 #define XFS_QM_ISPDQ(dqp) ((dqp)->dq_flags & XFS_DQ_PROJ) >> 149 #define XFS_QM_ISGDQ(dqp) ((dqp)->dq_flags & XFS_DQ_GROUP) >> 150 >> 151 extern void xfs_qm_dqdestroy(xfs_dquot_t *); >> 152 extern int xfs_qm_dqflush(struct xfs_dquot *, struct xfs_buf **); >> 153 extern void xfs_qm_dqunpin_wait(xfs_dquot_t *); >> 154 extern void xfs_qm_adjust_dqtimers(xfs_mount_t *, >> 155 xfs_disk_dquot_t *); >> 156 extern void xfs_qm_adjust_dqlimits(struct xfs_mount *, >> 157 struct xfs_dquot *); >> 158 extern xfs_dqid_t xfs_qm_id_for_quotatype(struct xfs_inode *ip, >> 159 uint type); >> 160 extern int xfs_qm_dqget(struct xfs_mount *mp, xfs_dqid_t id, >> 161 uint type, bool can_alloc, >> 162 struct xfs_dquot **dqpp); >> 163 extern int xfs_qm_dqget_inode(struct xfs_inode *ip, uint type, >> 164 bool can_alloc, >> 165 struct xfs_dquot **dqpp); >> 166 extern int xfs_qm_dqget_next(struct xfs_mount *mp, xfs_dqid_t id, >> 167 uint type, struct xfs_dquot **dqpp); >> 168 extern int xfs_qm_dqget_uncached(struct xfs_mount *mp, >> 169 xfs_dqid_t id, uint type, >> 170 struct xfs_dquot **dqpp); >> 171 extern void xfs_qm_dqput(xfs_dquot_t *); 205 172 206 void xfs_qm_dqdestroy(struct xfs_dq !! 173 extern void xfs_dqlock2(struct xfs_dquot *, struct xfs_dquot *); 207 int xfs_qm_dqflush(struct xfs_dquo << 208 void xfs_qm_dqunpin_wait(struct xfs << 209 void xfs_qm_adjust_dqtimers(struct << 210 void xfs_qm_adjust_dqlimits(struct << 211 xfs_dqid_t xfs_qm_id_for_quotatype(struct << 212 xfs_dqtype_t t << 213 int xfs_qm_dqget(struct xfs_mount << 214 xfs_dqtype_t t << 215 struct xfs_dqu << 216 int xfs_qm_dqget_inode(struct xfs_ << 217 bool can_alloc << 218 int xfs_qm_dqget_next(struct xfs_m << 219 xfs_dqtype_t t << 220 int xfs_qm_dqget_uncached(struct x << 221 xfs_dqid_t id, << 222 struct xfs_dqu << 223 void xfs_qm_dqput(struct xfs_dquot << 224 174 225 void xfs_dqlock2(struct xfs_dquot * !! 175 extern void xfs_dquot_set_prealloc_limits(struct xfs_dquot *); 226 void xfs_dqlockn(struct xfs_dqtrx * << 227 << 228 void xfs_dquot_set_prealloc_limits( << 229 176 230 static inline struct xfs_dquot *xfs_qm_dqhold( 177 static inline struct xfs_dquot *xfs_qm_dqhold(struct xfs_dquot *dqp) 231 { 178 { 232 xfs_dqlock(dqp); 179 xfs_dqlock(dqp); 233 dqp->q_nrefs++; 180 dqp->q_nrefs++; 234 xfs_dqunlock(dqp); 181 xfs_dqunlock(dqp); 235 return dqp; 182 return dqp; 236 } 183 } 237 184 238 time64_t xfs_dquot_set_timeout(struct xfs_moun !! 185 typedef int (*xfs_qm_dqiterate_fn)(struct xfs_dquot *dq, uint dqtype, 239 time64_t xfs_dquot_set_grace_period(time64_t g !! 186 void *priv); 240 !! 187 int xfs_qm_dqiterate(struct xfs_mount *mp, uint dqtype, 241 void xfs_qm_init_dquot_blk(struct xfs_trans *t !! 188 xfs_qm_dqiterate_fn iter_fn, void *priv); 242 type, struct xfs_buf *bp); << 243 189 244 #endif /* __XFS_DQUOT_H__ */ 190 #endif /* __XFS_DQUOT_H__ */ 245 191
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.