Blame view

fs/xfs/xfs_quotaops.c 7.09 KB
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  /*
   * Copyright (c) 2008, Christoph Hellwig
   * All Rights Reserved.
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public License as
   * published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it would be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program; if not, write the Free Software Foundation,
   * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
   */
  #include "xfs.h"
6ca1c9063   Dave Chinner   xfs: separate dqu...
19
  #include "xfs_format.h"
239880ef6   Dave Chinner   xfs: decouple log...
20
  #include "xfs_log_format.h"
7fd36c441   Dave Chinner   xfs: split out tr...
21
  #include "xfs_trans_resv.h"
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
22
  #include "xfs_mount.h"
a4fbe6ab1   Dave Chinner   xfs: decouple ino...
23
  #include "xfs_inode.h"
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
24
  #include "xfs_quota.h"
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
25
  #include "xfs_trans.h"
5d3684c28   Jan Kara   xfs: Convert to u...
26
27
  #include "xfs_trace.h"
  #include "xfs_icache.h"
06f8e2d67   Alex Elder   xfs: don't expect...
28
  #include "xfs_qm.h"
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
29
  #include <linux/quota.h>
5d3684c28   Jan Kara   xfs: Convert to u...
30
31
32
33
34
35
  static void
  xfs_qm_fill_state(
  	struct qc_type_state	*tstate,
  	struct xfs_mount	*mp,
  	struct xfs_inode	*ip,
  	xfs_ino_t		ino)
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
36
  {
5d3684c28   Jan Kara   xfs: Convert to u...
37
38
39
40
41
42
43
44
45
46
  	struct xfs_quotainfo *q = mp->m_quotainfo;
  	bool tempqip = false;
  
  	tstate->ino = ino;
  	if (!ip && ino == NULLFSINO)
  		return;
  	if (!ip) {
  		if (xfs_iget(mp, NULL, ino, 0, 0, &ip))
  			return;
  		tempqip = true;
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
47
  	}
5d3684c28   Jan Kara   xfs: Convert to u...
48
49
50
51
52
53
54
55
56
57
58
  	tstate->flags |= QCI_SYSFILE;
  	tstate->blocks = ip->i_d.di_nblocks;
  	tstate->nextents = ip->i_d.di_nextents;
  	tstate->spc_timelimit = q->qi_btimelimit;
  	tstate->ino_timelimit = q->qi_itimelimit;
  	tstate->rt_spc_timelimit = q->qi_rtbtimelimit;
  	tstate->spc_warnlimit = q->qi_bwarnlimit;
  	tstate->ino_warnlimit = q->qi_iwarnlimit;
  	tstate->rt_spc_warnlimit = q->qi_rtbwarnlimit;
  	if (tempqip)
  		IRELE(ip);
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
59
  }
5d3684c28   Jan Kara   xfs: Convert to u...
60
61
62
63
64
65
  /*
   * Return quota status information, such as enforcements, quota file inode
   * numbers etc.
   */
  static int
  xfs_fs_get_quota_state(
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
66
  	struct super_block	*sb,
5d3684c28   Jan Kara   xfs: Convert to u...
67
  	struct qc_state		*state)
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
68
  {
5d3684c28   Jan Kara   xfs: Convert to u...
69
70
  	struct xfs_mount *mp = XFS_M(sb);
  	struct xfs_quotainfo *q = mp->m_quotainfo;
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
71

5d3684c28   Jan Kara   xfs: Convert to u...
72
  	memset(state, 0, sizeof(*state));
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
73
  	if (!XFS_IS_QUOTA_RUNNING(mp))
5d3684c28   Jan Kara   xfs: Convert to u...
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  		return 0;
  	state->s_incoredqs = q->qi_dquots;
  	if (XFS_IS_UQUOTA_RUNNING(mp))
  		state->s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED;
  	if (XFS_IS_UQUOTA_ENFORCED(mp))
  		state->s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED;
  	if (XFS_IS_GQUOTA_RUNNING(mp))
  		state->s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED;
  	if (XFS_IS_GQUOTA_ENFORCED(mp))
  		state->s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED;
  	if (XFS_IS_PQUOTA_RUNNING(mp))
  		state->s_state[PRJQUOTA].flags |= QCI_ACCT_ENABLED;
  	if (XFS_IS_PQUOTA_ENFORCED(mp))
  		state->s_state[PRJQUOTA].flags |= QCI_LIMITS_ENFORCED;
  
  	xfs_qm_fill_state(&state->s_state[USRQUOTA], mp, q->qi_uquotaip,
  			  mp->m_sb.sb_uquotino);
  	xfs_qm_fill_state(&state->s_state[GRPQUOTA], mp, q->qi_gquotaip,
  			  mp->m_sb.sb_gquotino);
  	xfs_qm_fill_state(&state->s_state[PRJQUOTA], mp, q->qi_pquotaip,
  			  mp->m_sb.sb_pquotino);
  	return 0;
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
96
97
98
  }
  
  STATIC int
5d3684c28   Jan Kara   xfs: Convert to u...
99
  xfs_quota_type(int type)
5d5e3d576   Chandra Seetharaman   xfs: Add support ...
100
  {
5d3684c28   Jan Kara   xfs: Convert to u...
101
102
103
104
105
106
107
108
  	switch (type) {
  	case USRQUOTA:
  		return XFS_DQ_USER;
  	case GRPQUOTA:
  		return XFS_DQ_GROUP;
  	default:
  		return XFS_DQ_PROJ;
  	}
5d5e3d576   Chandra Seetharaman   xfs: Add support ...
109
  }
c14cad9ee   Jan Kara   xfs: Add support ...
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
  #define XFS_QC_SETINFO_MASK (QC_TIMER_MASK | QC_WARNS_MASK)
  
  /*
   * Adjust quota timers & warnings
   */
  static int
  xfs_fs_set_info(
  	struct super_block	*sb,
  	int			type,
  	struct qc_info		*info)
  {
  	struct xfs_mount *mp = XFS_M(sb);
  	struct qc_dqblk newlim;
  
  	if (sb->s_flags & MS_RDONLY)
  		return -EROFS;
  	if (!XFS_IS_QUOTA_RUNNING(mp))
  		return -ENOSYS;
  	if (!XFS_IS_QUOTA_ON(mp))
  		return -ESRCH;
  	if (info->i_fieldmask & ~XFS_QC_SETINFO_MASK)
  		return -EINVAL;
  	if ((info->i_fieldmask & XFS_QC_SETINFO_MASK) == 0)
  		return 0;
  
  	newlim.d_fieldmask = info->i_fieldmask;
  	newlim.d_spc_timer = info->i_spc_timelimit;
  	newlim.d_ino_timer = info->i_ino_timelimit;
  	newlim.d_rt_spc_timer = info->i_rt_spc_timelimit;
  	newlim.d_ino_warns = info->i_ino_warnlimit;
  	newlim.d_spc_warns = info->i_spc_warnlimit;
  	newlim.d_rt_spc_warns = info->i_rt_spc_warnlimit;
  
  	return xfs_qm_scall_setqlim(mp, 0, xfs_quota_type(type), &newlim);
  }
38e478c44   Jan Kara   quota: Split ->se...
145
146
  static unsigned int
  xfs_quota_flags(unsigned int uflags)
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
147
  {
38e478c44   Jan Kara   quota: Split ->se...
148
  	unsigned int flags = 0;
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
149

ade7ce31c   Christoph Hellwig   quota: Clean up t...
150
  	if (uflags & FS_QUOTA_UDQ_ACCT)
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
151
  		flags |= XFS_UQUOTA_ACCT;
ade7ce31c   Christoph Hellwig   quota: Clean up t...
152
  	if (uflags & FS_QUOTA_PDQ_ACCT)
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
153
  		flags |= XFS_PQUOTA_ACCT;
ade7ce31c   Christoph Hellwig   quota: Clean up t...
154
  	if (uflags & FS_QUOTA_GDQ_ACCT)
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
155
  		flags |= XFS_GQUOTA_ACCT;
ade7ce31c   Christoph Hellwig   quota: Clean up t...
156
  	if (uflags & FS_QUOTA_UDQ_ENFD)
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
157
  		flags |= XFS_UQUOTA_ENFD;
83e782e1a   Chandra Seetharaman   xfs: Remove incor...
158
159
160
161
  	if (uflags & FS_QUOTA_GDQ_ENFD)
  		flags |= XFS_GQUOTA_ENFD;
  	if (uflags & FS_QUOTA_PDQ_ENFD)
  		flags |= XFS_PQUOTA_ENFD;
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
162

38e478c44   Jan Kara   quota: Split ->se...
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
  	return flags;
  }
  
  STATIC int
  xfs_quota_enable(
  	struct super_block	*sb,
  	unsigned int		uflags)
  {
  	struct xfs_mount	*mp = XFS_M(sb);
  
  	if (sb->s_flags & MS_RDONLY)
  		return -EROFS;
  	if (!XFS_IS_QUOTA_RUNNING(mp))
  		return -ENOSYS;
  
  	return xfs_qm_scall_quotaon(mp, xfs_quota_flags(uflags));
  }
  
  STATIC int
  xfs_quota_disable(
  	struct super_block	*sb,
  	unsigned int		uflags)
  {
  	struct xfs_mount	*mp = XFS_M(sb);
  
  	if (sb->s_flags & MS_RDONLY)
  		return -EROFS;
  	if (!XFS_IS_QUOTA_RUNNING(mp))
  		return -ENOSYS;
  	if (!XFS_IS_QUOTA_ON(mp))
  		return -EINVAL;
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
194

38e478c44   Jan Kara   quota: Split ->se...
195
  	return xfs_qm_scall_quotaoff(mp, xfs_quota_flags(uflags));
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
196
197
198
  }
  
  STATIC int
9da93f9b7   Eric Sandeen   xfs: fix Q_XQUOTA...
199
200
201
202
203
204
  xfs_fs_rm_xquota(
  	struct super_block	*sb,
  	unsigned int		uflags)
  {
  	struct xfs_mount	*mp = XFS_M(sb);
  	unsigned int		flags = 0;
2451337dd   Dave Chinner   xfs: global error...
205

9da93f9b7   Eric Sandeen   xfs: fix Q_XQUOTA...
206
207
208
209
210
211
212
213
214
215
  	if (sb->s_flags & MS_RDONLY)
  		return -EROFS;
  
  	if (XFS_IS_QUOTA_ON(mp))
  		return -EINVAL;
  
  	if (uflags & FS_USER_QUOTA)
  		flags |= XFS_DQ_USER;
  	if (uflags & FS_GROUP_QUOTA)
  		flags |= XFS_DQ_GROUP;
74dc93a90   Jie Liu   xfs: fix uflags d...
216
  	if (uflags & FS_PROJ_QUOTA)
9da93f9b7   Eric Sandeen   xfs: fix Q_XQUOTA...
217
  		flags |= XFS_DQ_PROJ;
2451337dd   Dave Chinner   xfs: global error...
218
219
  	return xfs_qm_scall_trunc_qfiles(mp, flags);
  }
9da93f9b7   Eric Sandeen   xfs: fix Q_XQUOTA...
220
221
  
  STATIC int
b9b2dd36c   Christoph Hellwig   quota: unify ->ge...
222
  xfs_fs_get_dqblk(
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
223
  	struct super_block	*sb,
74a8a1037   Eric W. Biederman   userns: Convert q...
224
  	struct kqid		qid,
14bf61ffe   Jan Kara   quota: Switch ->g...
225
  	struct qc_dqblk		*qdq)
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
226
227
  {
  	struct xfs_mount	*mp = XFS_M(sb);
296c24e26   Eric Sandeen   xfs: wire up Q_XG...
228
  	xfs_dqid_t		id;
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
229
230
231
232
233
  
  	if (!XFS_IS_QUOTA_RUNNING(mp))
  		return -ENOSYS;
  	if (!XFS_IS_QUOTA_ON(mp))
  		return -ESRCH;
296c24e26   Eric Sandeen   xfs: wire up Q_XG...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
  	id = from_kqid(&init_user_ns, qid);
  	return xfs_qm_scall_getquota(mp, &id,
  				      xfs_quota_type(qid.type), qdq, 0);
  }
  
  /* Return quota info for active quota >= this qid */
  STATIC int
  xfs_fs_get_nextdqblk(
  	struct super_block	*sb,
  	struct kqid		*qid,
  	struct qc_dqblk		*qdq)
  {
  	int			ret;
  	struct xfs_mount	*mp = XFS_M(sb);
  	xfs_dqid_t		id;
  
  	if (!XFS_IS_QUOTA_RUNNING(mp))
  		return -ENOSYS;
  	if (!XFS_IS_QUOTA_ON(mp))
  		return -ESRCH;
  
  	id = from_kqid(&init_user_ns, *qid);
  	ret = xfs_qm_scall_getquota(mp, &id,
  				    xfs_quota_type(qid->type), qdq,
  				    XFS_QMOPT_DQNEXT);
  	if (ret)
  		return ret;
  
  	/* ID may be different, so convert back what we got */
  	*qid = make_kqid(current_user_ns(), qid->type, id);
  	return 0;
  	
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
266
267
268
  }
  
  STATIC int
c472b4327   Christoph Hellwig   quota: unify ->se...
269
  xfs_fs_set_dqblk(
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
270
  	struct super_block	*sb,
74a8a1037   Eric W. Biederman   userns: Convert q...
271
  	struct kqid		qid,
14bf61ffe   Jan Kara   quota: Switch ->g...
272
  	struct qc_dqblk		*qdq)
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
273
274
275
276
277
278
279
280
281
  {
  	struct xfs_mount	*mp = XFS_M(sb);
  
  	if (sb->s_flags & MS_RDONLY)
  		return -EROFS;
  	if (!XFS_IS_QUOTA_RUNNING(mp))
  		return -ENOSYS;
  	if (!XFS_IS_QUOTA_ON(mp))
  		return -ESRCH;
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
282

2451337dd   Dave Chinner   xfs: global error...
283
  	return xfs_qm_scall_setqlim(mp, from_kqid(&init_user_ns, qid),
14bf61ffe   Jan Kara   quota: Switch ->g...
284
  				     xfs_quota_type(qid.type), qdq);
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
285
  }
0d54b217a   Alexey Dobriyan   const: make struc...
286
  const struct quotactl_ops xfs_quotactl_operations = {
5d3684c28   Jan Kara   xfs: Convert to u...
287
  	.get_state		= xfs_fs_get_quota_state,
c14cad9ee   Jan Kara   xfs: Add support ...
288
  	.set_info		= xfs_fs_set_info,
38e478c44   Jan Kara   quota: Split ->se...
289
290
  	.quota_enable		= xfs_quota_enable,
  	.quota_disable		= xfs_quota_disable,
9da93f9b7   Eric Sandeen   xfs: fix Q_XQUOTA...
291
  	.rm_xquota		= xfs_fs_rm_xquota,
b9b2dd36c   Christoph Hellwig   quota: unify ->ge...
292
  	.get_dqblk		= xfs_fs_get_dqblk,
296c24e26   Eric Sandeen   xfs: wire up Q_XG...
293
  	.get_nextdqblk		= xfs_fs_get_nextdqblk,
c472b4327   Christoph Hellwig   quota: unify ->se...
294
  	.set_dqblk		= xfs_fs_set_dqblk,
fcafb71b5   Christoph Hellwig   xfs: get rid of i...
295
  };