Merge tag 'backlight-next-6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/lee...
[linux-block.git] / fs / xfs / xfs_dquot.h
CommitLineData
0b61f8a4 1// SPDX-License-Identifier: GPL-2.0
1da177e4 2/*
4ce3121f
NS
3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
1da177e4
LT
5 */
6#ifndef __XFS_DQUOT_H__
7#define __XFS_DQUOT_H__
8
9/*
10 * Dquots are structures that hold quota information about a user or a group,
11 * much like inodes are for files. In fact, dquots share many characteristics
12 * with inodes. However, dquots can also be a centralized resource, relative
13 * to a collection of inodes. In this respect, dquots share some characteristics
14 * of the superblock.
15 * XFS dquots exploit both those in its algorithms. They make every attempt
16 * to not be a bottleneck when quotas are on and have minimal impact, if any,
17 * when quotas are off.
18 */
19
1da177e4
LT
20struct xfs_mount;
21struct xfs_trans;
22
b1366451
BF
23enum {
24 XFS_QLOWSP_1_PCNT = 0,
25 XFS_QLOWSP_3_PCNT,
26 XFS_QLOWSP_5_PCNT,
27 XFS_QLOWSP_MAX
28};
29
784e80f5
DW
30struct xfs_dquot_res {
31 /* Total resources allocated and reserved. */
32 xfs_qcnt_t reserved;
d3537cf9 33
be37d40c
DW
34 /* Total resources allocated. */
35 xfs_qcnt_t count;
36
d3537cf9
DW
37 /* Absolute and preferred limits. */
38 xfs_qcnt_t hardlimit;
39 xfs_qcnt_t softlimit;
c8c45fb2 40
19dce7ea
DW
41 /*
42 * For root dquots, this is the default grace period, in seconds.
43 * Otherwise, this is when the quota grace period expires,
44 * in seconds since the Unix epoch.
45 */
46 time64_t timer;
784e80f5
DW
47};
48
108523b8
DW
49static inline bool
50xfs_dquot_res_over_limits(
51 const struct xfs_dquot_res *qres)
52{
53 if ((qres->softlimit && qres->softlimit < qres->reserved) ||
54 (qres->hardlimit && qres->hardlimit < qres->reserved))
55 return true;
56 return false;
57}
58
1da177e4
LT
59/*
60 * The incore dquot structure
61 */
aefe69a4 62struct xfs_dquot {
aefe69a4
PR
63 struct list_head q_lru;
64 struct xfs_mount *q_mount;
1a7ed271 65 xfs_dqtype_t q_type;
985a78fd 66 uint16_t q_flags;
c51df733 67 xfs_dqid_t q_id;
aefe69a4 68 uint q_nrefs;
aefe69a4 69 int q_bufoffset;
c51df733 70 xfs_daddr_t q_blkno;
aefe69a4
PR
71 xfs_fileoff_t q_fileoffset;
72
784e80f5
DW
73 struct xfs_dquot_res q_blk; /* regular blocks */
74 struct xfs_dquot_res q_ino; /* inodes */
75 struct xfs_dquot_res q_rtb; /* realtime blocks */
76
fd8b81db 77 struct xfs_dq_logitem q_logitem;
784e80f5 78
aefe69a4
PR
79 xfs_qcnt_t q_prealloc_lo_wmark;
80 xfs_qcnt_t q_prealloc_hi_wmark;
81 int64_t q_low_space[XFS_QLOWSP_MAX];
82 struct mutex q_qlock;
83 struct completion q_flush;
84 atomic_t q_pincount;
85 struct wait_queue_head q_pinwait;
86};
1da177e4 87
5bb87a33 88/*
af901ca1 89 * Lock hierarchy for q_qlock:
5bb87a33 90 * XFS_QLOCK_NORMAL is the implicit default,
aefe69a4 91 * XFS_QLOCK_NESTED is the dquot with the higher id in xfs_dqlock2
5bb87a33
CH
92 */
93enum {
94 XFS_QLOCK_NORMAL = 0,
95 XFS_QLOCK_NESTED,
96};
97
1da177e4 98/*
aefe69a4 99 * Manage the q_flush completion queue embedded in the dquot. This completion
e1f49cf2
DC
100 * queue synchronizes processes attempting to flush the in-core dquot back to
101 * disk.
1da177e4 102 */
aefe69a4 103static inline void xfs_dqflock(struct xfs_dquot *dqp)
e1f49cf2
DC
104{
105 wait_for_completion(&dqp->q_flush);
106}
107
aefe69a4 108static inline bool xfs_dqflock_nowait(struct xfs_dquot *dqp)
e1f49cf2
DC
109{
110 return try_wait_for_completion(&dqp->q_flush);
111}
112
aefe69a4 113static inline void xfs_dqfunlock(struct xfs_dquot *dqp)
e1f49cf2
DC
114{
115 complete(&dqp->q_flush);
116}
1da177e4 117
800b484e
CH
118static inline int xfs_dqlock_nowait(struct xfs_dquot *dqp)
119{
120 return mutex_trylock(&dqp->q_qlock);
121}
122
123static inline void xfs_dqlock(struct xfs_dquot *dqp)
124{
125 mutex_lock(&dqp->q_qlock);
126}
127
5b03ff1b 128static inline void xfs_dqunlock(struct xfs_dquot *dqp)
800b484e
CH
129{
130 mutex_unlock(&dqp->q_qlock);
131}
132
00a342e4
DW
133static inline int
134xfs_dquot_type(const struct xfs_dquot *dqp)
135{
1a7ed271 136 return dqp->q_type & XFS_DQTYPE_REC_MASK;
00a342e4
DW
137}
138
1a7ed271 139static inline int xfs_this_quota_on(struct xfs_mount *mp, xfs_dqtype_t type)
6967b964 140{
af1db8f1 141 switch (type) {
8cd4901d 142 case XFS_DQTYPE_USER:
6967b964 143 return XFS_IS_UQUOTA_ON(mp);
8cd4901d 144 case XFS_DQTYPE_GROUP:
92f8ff73 145 return XFS_IS_GQUOTA_ON(mp);
8cd4901d 146 case XFS_DQTYPE_PROJ:
92f8ff73 147 return XFS_IS_PQUOTA_ON(mp);
6967b964
CS
148 default:
149 return 0;
150 }
151}
152
1a7ed271
DW
153static inline struct xfs_dquot *xfs_inode_dquot(
154 struct xfs_inode *ip,
155 xfs_dqtype_t type)
36731410 156{
af1db8f1 157 switch (type) {
8cd4901d 158 case XFS_DQTYPE_USER:
36731410 159 return ip->i_udquot;
8cd4901d 160 case XFS_DQTYPE_GROUP:
36731410 161 return ip->i_gdquot;
8cd4901d 162 case XFS_DQTYPE_PROJ:
92f8ff73 163 return ip->i_pdquot;
36731410
CS
164 default:
165 return NULL;
166 }
167}
168
dbcbc7b9
DW
169/* Decide if the dquot's limits are actually being enforced. */
170static inline bool
171xfs_dquot_is_enforced(
172 const struct xfs_dquot *dqp)
173{
0b04dd5d 174 switch (xfs_dquot_type(dqp)) {
dbcbc7b9
DW
175 case XFS_DQTYPE_USER:
176 return XFS_IS_UQUOTA_ENFORCED(dqp->q_mount);
177 case XFS_DQTYPE_GROUP:
178 return XFS_IS_GQUOTA_ENFORCED(dqp->q_mount);
179 case XFS_DQTYPE_PROJ:
180 return XFS_IS_PQUOTA_ENFORCED(dqp->q_mount);
181 }
182 ASSERT(0);
183 return false;
184}
185
dc06f398
BF
186/*
187 * Check whether a dquot is under low free space conditions. We assume the quota
188 * is enabled and enforced.
189 */
190static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
191{
192 int64_t freesp;
193
d3537cf9 194 freesp = dqp->q_blk.hardlimit - dqp->q_blk.reserved;
dc06f398
BF
195 if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT])
196 return true;
197
198 return false;
199}
200
0b0fa1d1
DW
201void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp);
202
7201813b 203#define XFS_DQ_IS_LOCKED(dqp) (mutex_is_locked(&((dqp)->q_qlock)))
985a78fd 204#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->q_flags & XFS_DQFLAG_DIRTY)
1da177e4 205
aefe69a4
PR
206void xfs_qm_dqdestroy(struct xfs_dquot *dqp);
207int xfs_qm_dqflush(struct xfs_dquot *dqp, struct xfs_buf **bpp);
208void xfs_qm_dqunpin_wait(struct xfs_dquot *dqp);
c8c753e1
DW
209void xfs_qm_adjust_dqtimers(struct xfs_dquot *d);
210void xfs_qm_adjust_dqlimits(struct xfs_dquot *d);
211xfs_dqid_t xfs_qm_id_for_quotatype(struct xfs_inode *ip,
1a7ed271 212 xfs_dqtype_t type);
aefe69a4 213int xfs_qm_dqget(struct xfs_mount *mp, xfs_dqid_t id,
1a7ed271
DW
214 xfs_dqtype_t type, bool can_alloc,
215 struct xfs_dquot **dqpp);
216int xfs_qm_dqget_inode(struct xfs_inode *ip, xfs_dqtype_t type,
217 bool can_alloc, struct xfs_dquot **dqpp);
aefe69a4 218int xfs_qm_dqget_next(struct xfs_mount *mp, xfs_dqid_t id,
1a7ed271 219 xfs_dqtype_t type, struct xfs_dquot **dqpp);
aefe69a4 220int xfs_qm_dqget_uncached(struct xfs_mount *mp,
1a7ed271
DW
221 xfs_dqid_t id, xfs_dqtype_t type,
222 struct xfs_dquot **dqpp);
aefe69a4 223void xfs_qm_dqput(struct xfs_dquot *dqp);
800b484e 224
aefe69a4 225void xfs_dqlock2(struct xfs_dquot *, struct xfs_dquot *);
1da177e4 226
aefe69a4 227void xfs_dquot_set_prealloc_limits(struct xfs_dquot *);
b1366451 228
78e55892
CH
229static inline struct xfs_dquot *xfs_qm_dqhold(struct xfs_dquot *dqp)
230{
231 xfs_dqlock(dqp);
232 dqp->q_nrefs++;
233 xfs_dqunlock(dqp);
234 return dqp;
235}
236
1a7ed271
DW
237typedef int (*xfs_qm_dqiterate_fn)(struct xfs_dquot *dq,
238 xfs_dqtype_t type, void *priv);
239int xfs_qm_dqiterate(struct xfs_mount *mp, xfs_dqtype_t type,
554ba965
DW
240 xfs_qm_dqiterate_fn iter_fn, void *priv);
241
11d8a919 242time64_t xfs_dquot_set_timeout(struct xfs_mount *mp, time64_t timeout);
ccc8e771 243time64_t xfs_dquot_set_grace_period(time64_t grace);
11d8a919 244
1da177e4 245#endif /* __XFS_DQUOT_H__ */