blob: 17a21677723f67a149fd3a4a179376abf126dbdb [file] [log] [blame]
Dave Chinner0b61f8a2018-06-05 19:42:14 -07001// SPDX-License-Identifier: GPL-2.0
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
Nathan Scott4ce31212005-11-02 14:59:41 +11003 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
4 * All Rights Reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07005 */
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
Linus Torvalds1da177e2005-04-16 15:20:36 -070020struct xfs_mount;
21struct xfs_trans;
22
Brian Fosterb1366452013-03-18 10:51:46 -040023enum {
24 XFS_QLOWSP_1_PCNT = 0,
25 XFS_QLOWSP_3_PCNT,
26 XFS_QLOWSP_5_PCNT,
27 XFS_QLOWSP_MAX
28};
29
Darrick J. Wong784e80f2020-07-14 10:37:30 -070030struct xfs_dquot_res {
31 /* Total resources allocated and reserved. */
32 xfs_qcnt_t reserved;
Darrick J. Wongd3537cf2020-07-14 10:37:31 -070033
Darrick J. Wongbe37d402020-07-14 10:37:31 -070034 /* Total resources allocated. */
35 xfs_qcnt_t count;
36
Darrick J. Wongd3537cf2020-07-14 10:37:31 -070037 /* Absolute and preferred limits. */
38 xfs_qcnt_t hardlimit;
39 xfs_qcnt_t softlimit;
Darrick J. Wongc8c45fb2020-07-14 10:37:31 -070040
41 /*
Darrick J. Wong19dce7e2020-07-14 10:37:32 -070042 * 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;
47
48 /*
Darrick J. Wongc8c45fb2020-07-14 10:37:31 -070049 * For root dquots, this is the maximum number of warnings that will
50 * be issued for this quota type. Otherwise, this is the number of
51 * warnings issued against this quota. Note that none of this is
52 * implemented.
53 */
54 xfs_qwarncnt_t warnings;
Darrick J. Wong784e80f2020-07-14 10:37:30 -070055};
56
Linus Torvalds1da177e2005-04-16 15:20:36 -070057/*
Linus Torvalds1da177e2005-04-16 15:20:36 -070058 * The incore dquot structure
59 */
Pavel Reichlaefe69a2019-11-12 17:04:02 -080060struct xfs_dquot {
Pavel Reichlaefe69a2019-11-12 17:04:02 -080061 struct list_head q_lru;
62 struct xfs_mount *q_mount;
Darrick J. Wong985a78f2020-07-14 10:37:13 -070063 uint8_t dq_flags;
64 uint16_t q_flags;
Darrick J. Wongc51df732020-07-14 10:37:30 -070065 xfs_dqid_t q_id;
Pavel Reichlaefe69a2019-11-12 17:04:02 -080066 uint q_nrefs;
Pavel Reichlaefe69a2019-11-12 17:04:02 -080067 int q_bufoffset;
Darrick J. Wongc51df732020-07-14 10:37:30 -070068 xfs_daddr_t q_blkno;
Pavel Reichlaefe69a2019-11-12 17:04:02 -080069 xfs_fileoff_t q_fileoffset;
Linus Torvalds1da177e2005-04-16 15:20:36 -070070
Darrick J. Wong784e80f2020-07-14 10:37:30 -070071 struct xfs_dquot_res q_blk; /* regular blocks */
72 struct xfs_dquot_res q_ino; /* inodes */
73 struct xfs_dquot_res q_rtb; /* realtime blocks */
74
Pavel Reichlfd8b81d2019-11-12 17:04:26 -080075 struct xfs_dq_logitem q_logitem;
Darrick J. Wong784e80f2020-07-14 10:37:30 -070076
Pavel Reichlaefe69a2019-11-12 17:04:02 -080077 xfs_qcnt_t q_prealloc_lo_wmark;
78 xfs_qcnt_t q_prealloc_hi_wmark;
79 int64_t q_low_space[XFS_QLOWSP_MAX];
80 struct mutex q_qlock;
81 struct completion q_flush;
82 atomic_t q_pincount;
83 struct wait_queue_head q_pinwait;
84};
Linus Torvalds1da177e2005-04-16 15:20:36 -070085
Christoph Hellwig5bb87a32009-01-19 02:03:19 +010086/*
André Goddard Rosaaf901ca2009-11-14 13:09:05 -020087 * Lock hierarchy for q_qlock:
Christoph Hellwig5bb87a32009-01-19 02:03:19 +010088 * XFS_QLOCK_NORMAL is the implicit default,
Pavel Reichlaefe69a2019-11-12 17:04:02 -080089 * XFS_QLOCK_NESTED is the dquot with the higher id in xfs_dqlock2
Christoph Hellwig5bb87a32009-01-19 02:03:19 +010090 */
91enum {
92 XFS_QLOCK_NORMAL = 0,
93 XFS_QLOCK_NESTED,
94};
95
Linus Torvalds1da177e2005-04-16 15:20:36 -070096/*
Pavel Reichlaefe69a2019-11-12 17:04:02 -080097 * Manage the q_flush completion queue embedded in the dquot. This completion
David Chinnere1f49cf2008-08-13 16:41:43 +100098 * queue synchronizes processes attempting to flush the in-core dquot back to
99 * disk.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100 */
Pavel Reichlaefe69a2019-11-12 17:04:02 -0800101static inline void xfs_dqflock(struct xfs_dquot *dqp)
David Chinnere1f49cf2008-08-13 16:41:43 +1000102{
103 wait_for_completion(&dqp->q_flush);
104}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105
Pavel Reichlaefe69a2019-11-12 17:04:02 -0800106static inline bool xfs_dqflock_nowait(struct xfs_dquot *dqp)
David Chinnere1f49cf2008-08-13 16:41:43 +1000107{
108 return try_wait_for_completion(&dqp->q_flush);
109}
110
Pavel Reichlaefe69a2019-11-12 17:04:02 -0800111static inline void xfs_dqfunlock(struct xfs_dquot *dqp)
David Chinnere1f49cf2008-08-13 16:41:43 +1000112{
113 complete(&dqp->q_flush);
114}
115
Christoph Hellwig800b4842011-12-06 21:58:14 +0000116static inline int xfs_dqlock_nowait(struct xfs_dquot *dqp)
117{
118 return mutex_trylock(&dqp->q_qlock);
119}
120
121static inline void xfs_dqlock(struct xfs_dquot *dqp)
122{
123 mutex_lock(&dqp->q_qlock);
124}
125
Christoph Hellwig5b03ff12012-02-20 02:31:22 +0000126static inline void xfs_dqunlock(struct xfs_dquot *dqp)
Christoph Hellwig800b4842011-12-06 21:58:14 +0000127{
128 mutex_unlock(&dqp->q_qlock);
129}
130
Chandra Seetharaman6967b962012-01-23 17:31:25 +0000131static inline int xfs_this_quota_on(struct xfs_mount *mp, int type)
132{
Darrick J. Wong8cd49012020-07-15 17:42:36 -0700133 switch (type & XFS_DQTYPE_REC_MASK) {
134 case XFS_DQTYPE_USER:
Chandra Seetharaman6967b962012-01-23 17:31:25 +0000135 return XFS_IS_UQUOTA_ON(mp);
Darrick J. Wong8cd49012020-07-15 17:42:36 -0700136 case XFS_DQTYPE_GROUP:
Chandra Seetharaman92f8ff72013-07-11 00:00:40 -0500137 return XFS_IS_GQUOTA_ON(mp);
Darrick J. Wong8cd49012020-07-15 17:42:36 -0700138 case XFS_DQTYPE_PROJ:
Chandra Seetharaman92f8ff72013-07-11 00:00:40 -0500139 return XFS_IS_PQUOTA_ON(mp);
Chandra Seetharaman6967b962012-01-23 17:31:25 +0000140 default:
141 return 0;
142 }
143}
144
Pavel Reichlaefe69a2019-11-12 17:04:02 -0800145static inline struct xfs_dquot *xfs_inode_dquot(struct xfs_inode *ip, int type)
Chandra Seetharaman36731412012-01-23 17:31:30 +0000146{
Darrick J. Wong8cd49012020-07-15 17:42:36 -0700147 switch (type & XFS_DQTYPE_REC_MASK) {
148 case XFS_DQTYPE_USER:
Chandra Seetharaman36731412012-01-23 17:31:30 +0000149 return ip->i_udquot;
Darrick J. Wong8cd49012020-07-15 17:42:36 -0700150 case XFS_DQTYPE_GROUP:
Chandra Seetharaman36731412012-01-23 17:31:30 +0000151 return ip->i_gdquot;
Darrick J. Wong8cd49012020-07-15 17:42:36 -0700152 case XFS_DQTYPE_PROJ:
Chandra Seetharaman92f8ff72013-07-11 00:00:40 -0500153 return ip->i_pdquot;
Chandra Seetharaman36731412012-01-23 17:31:30 +0000154 default:
155 return NULL;
156 }
157}
158
Brian Fosterdc06f3982014-07-24 19:49:28 +1000159/*
160 * Check whether a dquot is under low free space conditions. We assume the quota
161 * is enabled and enforced.
162 */
163static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
164{
165 int64_t freesp;
166
Darrick J. Wongd3537cf2020-07-14 10:37:31 -0700167 freesp = dqp->q_blk.hardlimit - dqp->q_blk.reserved;
Brian Fosterdc06f3982014-07-24 19:49:28 +1000168 if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT])
169 return true;
170
171 return false;
172}
173
Darrick J. Wong0b0fa1d2020-07-14 10:37:22 -0700174void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp);
175
Christoph Hellwig72018132009-02-09 08:39:24 +0100176#define XFS_DQ_IS_LOCKED(dqp) (mutex_is_locked(&((dqp)->q_qlock)))
Darrick J. Wong985a78f2020-07-14 10:37:13 -0700177#define XFS_DQ_IS_DIRTY(dqp) ((dqp)->q_flags & XFS_DQFLAG_DIRTY)
Darrick J. Wong8cd49012020-07-15 17:42:36 -0700178#define XFS_QM_ISUDQ(dqp) ((dqp)->dq_flags & XFS_DQTYPE_USER)
179#define XFS_QM_ISPDQ(dqp) ((dqp)->dq_flags & XFS_DQTYPE_PROJ)
180#define XFS_QM_ISGDQ(dqp) ((dqp)->dq_flags & XFS_DQTYPE_GROUP)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181
Pavel Reichlaefe69a2019-11-12 17:04:02 -0800182void xfs_qm_dqdestroy(struct xfs_dquot *dqp);
183int xfs_qm_dqflush(struct xfs_dquot *dqp, struct xfs_buf **bpp);
184void xfs_qm_dqunpin_wait(struct xfs_dquot *dqp);
Darrick J. Wongc8c753e2020-07-14 10:37:33 -0700185void xfs_qm_adjust_dqtimers(struct xfs_dquot *d);
186void xfs_qm_adjust_dqlimits(struct xfs_dquot *d);
187xfs_dqid_t xfs_qm_id_for_quotatype(struct xfs_inode *ip,
188 uint type);
Pavel Reichlaefe69a2019-11-12 17:04:02 -0800189int xfs_qm_dqget(struct xfs_mount *mp, xfs_dqid_t id,
Darrick J. Wong30ab2dc2018-05-04 15:30:24 -0700190 uint type, bool can_alloc,
Darrick J. Wong4882c192018-05-04 15:30:22 -0700191 struct xfs_dquot **dqpp);
Pavel Reichlaefe69a2019-11-12 17:04:02 -0800192int xfs_qm_dqget_inode(struct xfs_inode *ip, uint type,
193 bool can_alloc,
194 struct xfs_dquot **dqpp);
195int xfs_qm_dqget_next(struct xfs_mount *mp, xfs_dqid_t id,
Darrick J. Wong2e330e72018-05-04 15:30:20 -0700196 uint type, struct xfs_dquot **dqpp);
Pavel Reichlaefe69a2019-11-12 17:04:02 -0800197int xfs_qm_dqget_uncached(struct xfs_mount *mp,
198 xfs_dqid_t id, uint type,
199 struct xfs_dquot **dqpp);
200void xfs_qm_dqput(struct xfs_dquot *dqp);
Christoph Hellwig800b4842011-12-06 21:58:14 +0000201
Pavel Reichlaefe69a2019-11-12 17:04:02 -0800202void xfs_dqlock2(struct xfs_dquot *, struct xfs_dquot *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700203
Pavel Reichlaefe69a2019-11-12 17:04:02 -0800204void xfs_dquot_set_prealloc_limits(struct xfs_dquot *);
Brian Fosterb1366452013-03-18 10:51:46 -0400205
Christoph Hellwig78e55892011-12-06 21:58:22 +0000206static inline struct xfs_dquot *xfs_qm_dqhold(struct xfs_dquot *dqp)
207{
208 xfs_dqlock(dqp);
209 dqp->q_nrefs++;
210 xfs_dqunlock(dqp);
211 return dqp;
212}
213
Darrick J. Wong554ba962018-05-04 15:31:21 -0700214typedef int (*xfs_qm_dqiterate_fn)(struct xfs_dquot *dq, uint dqtype,
215 void *priv);
216int xfs_qm_dqiterate(struct xfs_mount *mp, uint dqtype,
217 xfs_qm_dqiterate_fn iter_fn, void *priv);
218
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219#endif /* __XFS_DQUOT_H__ */