summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_qm.h
blob: 57bddadbc051d73192d7818d0a80a863362eb8e5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
 * All Rights Reserved.
 */
#ifndef __XFS_QM_H__
#define __XFS_QM_H__

#include "xfs_dquot_item.h"
#include "xfs_dquot.h"

struct xfs_inode;

extern struct kmem_zone	*xfs_qm_dqtrxzone;

/*
 * Number of bmaps that we ask from bmapi when doing a quotacheck.
 * We make this restriction to keep the memory usage to a minimum.
 */
#define XFS_DQITER_MAP_SIZE	10

#define XFS_IS_DQUOT_UNINITIALIZED(dqp) ( \
	!dqp->q_blk.hardlimit && \
	!dqp->q_blk.softlimit && \
	!dqp->q_rtb.hardlimit && \
	!dqp->q_rtb.softlimit && \
	!dqp->q_ino.hardlimit && \
	!dqp->q_ino.softlimit && \
	!dqp->q_blk.count && \
	!dqp->q_rtb.count && \
	!dqp->q_ino.count)

/* Defaults for each quota type: time limits, warn limits, usage limits */
struct xfs_def_quota {
	time64_t	btimelimit;	/* limit for blks timer */
	time64_t	itimelimit;	/* limit for inodes timer */
	time64_t	rtbtimelimit;	/* limit for rt blks timer */
	xfs_qwarncnt_t	bwarnlimit;	/* limit for blks warnings */
	xfs_qwarncnt_t	iwarnlimit;	/* limit for inodes warnings */
	xfs_qwarncnt_t	rtbwarnlimit;	/* limit for rt blks warnings */
	xfs_qcnt_t	bhardlimit;	/* default data blk hard limit */
	xfs_qcnt_t	bsoftlimit;	/* default data blk soft limit */
	xfs_qcnt_t	ihardlimit;	/* default inode count hard limit */
	xfs_qcnt_t	isoftlimit;	/* default inode count soft limit */
	xfs_qcnt_t	rtbhardlimit;	/* default realtime blk hard limit */
	xfs_qcnt_t	rtbsoftlimit;	/* default realtime blk soft limit */
};

/*
 * Various quota information for individual filesystems.
 * The mount structure keeps a pointer to this.
 */
struct xfs_quotainfo {
	struct radix_tree_root	qi_uquota_tree;
	struct radix_tree_root	qi_gquota_tree;
	struct radix_tree_root	qi_pquota_tree;
	struct mutex		qi_tree_lock;
	struct xfs_inode	*qi_uquotaip;	/* user quota inode */
	struct xfs_inode	*qi_gquotaip;	/* group quota inode */
	struct xfs_inode	*qi_pquotaip;	/* project quota inode */
	struct list_lru		qi_lru;
	int			qi_dquots;
	struct mutex		qi_quotaofflock;/* to serialize quotaoff */
	xfs_filblks_t		qi_dqchunklen;	/* # BBs in a chunk of dqs */
	uint			qi_dqperchunk;	/* # ondisk dq in above chunk */
	struct xfs_def_quota	qi_usr_default;
	struct xfs_def_quota	qi_grp_default;
	struct xfs_def_quota	qi_prj_default;
	struct shrinker		qi_shrinker;
};

static inline struct radix_tree_root *
xfs_dquot_tree(
	struct xfs_quotainfo	*qi,
	int			type)
{
	switch (type) {
	case XFS_DQ_USER:
		return &qi->qi_uquota_tree;
	case XFS_DQ_GROUP:
		return &qi->qi_gquota_tree;
	case XFS_DQ_PROJ:
		return &qi->qi_pquota_tree;
	default:
		ASSERT(0);
	}
	return NULL;
}

static inline struct xfs_inode *
xfs_quota_inode(xfs_mount_t *mp, uint dq_flags)
{
	switch (dq_flags & XFS_DQ_ALLTYPES) {
	case XFS_DQ_USER:
		return mp->m_quotainfo->qi_uquotaip;
	case XFS_DQ_GROUP:
		return mp->m_quotainfo->qi_gquotaip;
	case XFS_DQ_PROJ:
		return mp->m_quotainfo->qi_pquotaip;
	default:
		ASSERT(0);
	}
	return NULL;
}

static inline int
xfs_dquot_type(struct xfs_dquot *dqp)
{
	if (XFS_QM_ISUDQ(dqp))
		return XFS_DQ_USER;
	if (XFS_QM_ISGDQ(dqp))
		return XFS_DQ_GROUP;
	ASSERT(XFS_QM_ISPDQ(dqp));
	return XFS_DQ_PROJ;
}

extern void	xfs_trans_mod_dquot(struct xfs_trans *tp, struct xfs_dquot *dqp,
				    uint field, int64_t delta);
extern void	xfs_trans_dqjoin(struct xfs_trans *, struct xfs_dquot *);
extern void	xfs_trans_log_dquot(struct xfs_trans *, struct xfs_dquot *);

/*
 * We keep the usr, grp, and prj dquots separately so that locking will be
 * easier to do at commit time. All transactions that we know of at this point
 * affect no more than two dquots of one type. Hence, the TRANS_MAXDQS value.
 */
enum {
	XFS_QM_TRANS_USR = 0,
	XFS_QM_TRANS_GRP,
	XFS_QM_TRANS_PRJ,
	XFS_QM_TRANS_DQTYPES
};
#define XFS_QM_TRANS_MAXDQS		2
struct xfs_dquot_acct {
	struct xfs_dqtrx	dqs[XFS_QM_TRANS_DQTYPES][XFS_QM_TRANS_MAXDQS];
};

/*
 * Users are allowed to have a usage exceeding their softlimit for
 * a period this long.
 */
#define XFS_QM_BTIMELIMIT	(7 * 24*60*60)          /* 1 week */
#define XFS_QM_RTBTIMELIMIT	(7 * 24*60*60)          /* 1 week */
#define XFS_QM_ITIMELIMIT	(7 * 24*60*60)          /* 1 week */

#define XFS_QM_BWARNLIMIT	5
#define XFS_QM_IWARNLIMIT	5
#define XFS_QM_RTBWARNLIMIT	5

extern void		xfs_qm_destroy_quotainfo(struct xfs_mount *);

/* dquot stuff */
extern void		xfs_qm_dqpurge_all(struct xfs_mount *, uint);
extern void		xfs_qm_dqrele_all_inodes(struct xfs_mount *, uint);

/* quota ops */
extern int		xfs_qm_scall_trunc_qfiles(struct xfs_mount *, uint);
extern int		xfs_qm_scall_getquota(struct xfs_mount *, xfs_dqid_t,
					uint, struct qc_dqblk *);
extern int		xfs_qm_scall_getquota_next(struct xfs_mount *,
					xfs_dqid_t *, uint, struct qc_dqblk *);
extern int		xfs_qm_scall_setqlim(struct xfs_mount *, xfs_dqid_t, uint,
					struct qc_dqblk *);
extern int		xfs_qm_scall_quotaon(struct xfs_mount *, uint);
extern int		xfs_qm_scall_quotaoff(struct xfs_mount *, uint);

static inline struct xfs_def_quota *
xfs_get_defquota(struct xfs_quotainfo *qi, int type)
{
	switch (type) {
	case XFS_DQ_USER:
		return &qi->qi_usr_default;
	case XFS_DQ_GROUP:
		return &qi->qi_grp_default;
	case XFS_DQ_PROJ:
		return &qi->qi_prj_default;
	default:
		ASSERT(0);
		return NULL;
	}
}

#endif /* __XFS_QM_H__ */