1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
10 #include "xfs_shared.h"
11 #include "xfs_format.h"
12 #include "xfs_log_format.h"
13 #include "xfs_trans_resv.h"
15 #include "xfs_mount.h"
16 #include "xfs_inode.h"
17 #include "xfs_trans.h"
18 #include "xfs_quota.h"
20 #include "xfs_icache.h"
23 xfs_qm_scall_quotaoff(
28 * No file system can have quotas enabled on disk but not in core.
29 * Note that quota utilities (like quotaoff) _expect_
30 * errno == -EEXIST here.
32 if ((mp
->m_qflags
& flags
) == 0)
36 * We do not support actually turning off quota accounting any more.
37 * Just log a warning and ignore the accounting related flags.
39 if (flags
& XFS_ALL_QUOTA_ACCT
)
40 xfs_info(mp
, "disabling of quota accounting not supported.");
42 mutex_lock(&mp
->m_quotainfo
->qi_quotaofflock
);
43 mp
->m_qflags
&= ~(flags
& XFS_ALL_QUOTA_ENFD
);
44 spin_lock(&mp
->m_sb_lock
);
45 mp
->m_sb
.sb_qflags
= mp
->m_qflags
;
46 spin_unlock(&mp
->m_sb_lock
);
47 mutex_unlock(&mp
->m_quotainfo
->qi_quotaofflock
);
49 /* XXX what to do if error ? Revert back to old vals incore ? */
50 return xfs_sync_sb(mp
, false);
54 xfs_qm_scall_trunc_qfile(
62 error
= xfs_qm_qino_load(mp
, type
, &ip
);
68 xfs_ilock(ip
, XFS_IOLOCK_EXCL
);
70 error
= xfs_trans_alloc(mp
, &M_RES(mp
)->tr_itruncate
, 0, 0, 0, &tp
);
72 xfs_iunlock(ip
, XFS_IOLOCK_EXCL
);
76 xfs_ilock(ip
, XFS_ILOCK_EXCL
);
77 xfs_trans_ijoin(tp
, ip
, 0);
80 xfs_trans_log_inode(tp
, ip
, XFS_ILOG_CORE
);
82 error
= xfs_itruncate_extents(&tp
, ip
, XFS_DATA_FORK
, 0);
88 ASSERT(ip
->i_df
.if_nextents
== 0);
90 xfs_trans_ichgtime(tp
, ip
, XFS_ICHGTIME_MOD
| XFS_ICHGTIME_CHG
);
91 error
= xfs_trans_commit(tp
);
94 xfs_iunlock(ip
, XFS_ILOCK_EXCL
| XFS_IOLOCK_EXCL
);
101 xfs_qm_scall_trunc_qfiles(
107 if (!xfs_has_quota(mp
) || flags
== 0 ||
108 (flags
& ~XFS_QMOPT_QUOTALL
)) {
109 xfs_debug(mp
, "%s: flags=%x m_qflags=%x",
110 __func__
, flags
, mp
->m_qflags
);
114 if (flags
& XFS_QMOPT_UQUOTA
) {
115 error
= xfs_qm_scall_trunc_qfile(mp
, XFS_DQTYPE_USER
);
119 if (flags
& XFS_QMOPT_GQUOTA
) {
120 error
= xfs_qm_scall_trunc_qfile(mp
, XFS_DQTYPE_GROUP
);
124 if (flags
& XFS_QMOPT_PQUOTA
)
125 error
= xfs_qm_scall_trunc_qfile(mp
, XFS_DQTYPE_PROJ
);
131 * Switch on (a given) quota enforcement for a filesystem. This takes
132 * effect immediately.
133 * (Switching on quota accounting must be done at mount time.)
136 xfs_qm_scall_quotaon(
144 * Switching on quota accounting must be done at mount time,
145 * only consider quota enforcement stuff here.
147 flags
&= XFS_ALL_QUOTA_ENFD
;
150 xfs_debug(mp
, "%s: zero flags, m_qflags=%x",
151 __func__
, mp
->m_qflags
);
156 * Can't enforce without accounting. We check the superblock
157 * qflags here instead of m_qflags because rootfs can have
158 * quota acct on ondisk without m_qflags' knowing.
160 if (((mp
->m_sb
.sb_qflags
& XFS_UQUOTA_ACCT
) == 0 &&
161 (flags
& XFS_UQUOTA_ENFD
)) ||
162 ((mp
->m_sb
.sb_qflags
& XFS_GQUOTA_ACCT
) == 0 &&
163 (flags
& XFS_GQUOTA_ENFD
)) ||
164 ((mp
->m_sb
.sb_qflags
& XFS_PQUOTA_ACCT
) == 0 &&
165 (flags
& XFS_PQUOTA_ENFD
))) {
167 "%s: Can't enforce without acct, flags=%x sbflags=%x",
168 __func__
, flags
, mp
->m_sb
.sb_qflags
);
172 * If everything's up to-date incore, then don't waste time.
174 if ((mp
->m_qflags
& flags
) == flags
)
178 * Change sb_qflags on disk but not incore mp->qflags
179 * if this is the root filesystem.
181 spin_lock(&mp
->m_sb_lock
);
182 qf
= mp
->m_sb
.sb_qflags
;
183 mp
->m_sb
.sb_qflags
= qf
| flags
;
184 spin_unlock(&mp
->m_sb_lock
);
187 * There's nothing to change if it's the same.
189 if ((qf
& flags
) == flags
)
192 error
= xfs_sync_sb(mp
, false);
196 * If we aren't trying to switch on quota enforcement, we are done.
198 if (((mp
->m_sb
.sb_qflags
& XFS_UQUOTA_ACCT
) !=
199 (mp
->m_qflags
& XFS_UQUOTA_ACCT
)) ||
200 ((mp
->m_sb
.sb_qflags
& XFS_PQUOTA_ACCT
) !=
201 (mp
->m_qflags
& XFS_PQUOTA_ACCT
)) ||
202 ((mp
->m_sb
.sb_qflags
& XFS_GQUOTA_ACCT
) !=
203 (mp
->m_qflags
& XFS_GQUOTA_ACCT
)))
206 if (!XFS_IS_QUOTA_ON(mp
))
210 * Switch on quota enforcement in core.
212 mutex_lock(&mp
->m_quotainfo
->qi_quotaofflock
);
213 mp
->m_qflags
|= (flags
& XFS_ALL_QUOTA_ENFD
);
214 mutex_unlock(&mp
->m_quotainfo
->qi_quotaofflock
);
219 #define XFS_QC_MASK (QC_LIMIT_MASK | QC_TIMER_MASK)
222 * Adjust limits of this quota, and the defaults if passed in. Returns true
223 * if the new limits made sense and were applied, false otherwise.
227 struct xfs_mount
*mp
,
228 struct xfs_dquot_res
*res
,
229 struct xfs_quota_limits
*qlim
,
234 /* The hard limit can't be less than the soft limit. */
235 if (hard
!= 0 && hard
< soft
) {
236 xfs_debug(mp
, "%shard %lld < %ssoft %lld", tag
, hard
, tag
,
241 res
->hardlimit
= hard
;
242 res
->softlimit
= soft
;
253 struct xfs_mount
*mp
,
254 struct xfs_dquot_res
*res
,
255 struct xfs_quota_limits
*qlim
,
259 /* Set the length of the default grace period. */
260 res
->timer
= xfs_dquot_set_grace_period(timer
);
261 qlim
->time
= res
->timer
;
263 /* Set the grace period expiration on a quota. */
264 res
->timer
= xfs_dquot_set_timeout(mp
, timer
);
269 * Adjust quota limits, and start/stop timers accordingly.
272 xfs_qm_scall_setqlim(
273 struct xfs_mount
*mp
,
276 struct qc_dqblk
*newlim
)
278 struct xfs_quotainfo
*q
= mp
->m_quotainfo
;
279 struct xfs_dquot
*dqp
;
280 struct xfs_trans
*tp
;
281 struct xfs_def_quota
*defq
;
282 struct xfs_dquot_res
*res
;
283 struct xfs_quota_limits
*qlim
;
285 xfs_qcnt_t hard
, soft
;
287 if (newlim
->d_fieldmask
& ~XFS_QC_MASK
)
289 if ((newlim
->d_fieldmask
& XFS_QC_MASK
) == 0)
293 * Get the dquot (locked) before we start, as we need to do a
294 * transaction to allocate it if it doesn't exist. Once we have the
295 * dquot, unlock it so we can start the next transaction safely. We hold
296 * a reference to the dquot, so it's safe to do this unlock/lock without
297 * it being reclaimed in the mean time.
299 error
= xfs_qm_dqget(mp
, id
, type
, true, &dqp
);
301 ASSERT(error
!= -ENOENT
);
305 defq
= xfs_get_defquota(q
, xfs_dquot_type(dqp
));
308 error
= xfs_trans_alloc(mp
, &M_RES(mp
)->tr_qm_setqlim
, 0, 0, 0, &tp
);
313 xfs_trans_dqjoin(tp
, dqp
);
316 * Update quota limits, warnings, and timers, and the defaults
317 * if we're touching id == 0.
319 * Make sure that hardlimits are >= soft limits before changing.
321 * Update warnings counter(s) if requested.
323 * Timelimits for the super user set the relative time the other users
324 * can be over quota for this file system. If it is zero a default is
325 * used. Ditto for the default soft and hard limit values (already
326 * done, above), and for warnings.
328 * For other IDs, userspace can bump out the grace period if over
332 /* Blocks on the data device. */
333 hard
= (newlim
->d_fieldmask
& QC_SPC_HARD
) ?
334 (xfs_qcnt_t
) XFS_B_TO_FSB(mp
, newlim
->d_spc_hardlimit
) :
335 dqp
->q_blk
.hardlimit
;
336 soft
= (newlim
->d_fieldmask
& QC_SPC_SOFT
) ?
337 (xfs_qcnt_t
) XFS_B_TO_FSB(mp
, newlim
->d_spc_softlimit
) :
338 dqp
->q_blk
.softlimit
;
340 qlim
= id
== 0 ? &defq
->blk
: NULL
;
342 if (xfs_setqlim_limits(mp
, res
, qlim
, hard
, soft
, "blk"))
343 xfs_dquot_set_prealloc_limits(dqp
);
344 if (newlim
->d_fieldmask
& QC_SPC_TIMER
)
345 xfs_setqlim_timer(mp
, res
, qlim
, newlim
->d_spc_timer
);
347 /* Blocks on the realtime device. */
348 hard
= (newlim
->d_fieldmask
& QC_RT_SPC_HARD
) ?
349 (xfs_qcnt_t
) XFS_B_TO_FSB(mp
, newlim
->d_rt_spc_hardlimit
) :
350 dqp
->q_rtb
.hardlimit
;
351 soft
= (newlim
->d_fieldmask
& QC_RT_SPC_SOFT
) ?
352 (xfs_qcnt_t
) XFS_B_TO_FSB(mp
, newlim
->d_rt_spc_softlimit
) :
353 dqp
->q_rtb
.softlimit
;
355 qlim
= id
== 0 ? &defq
->rtb
: NULL
;
357 xfs_setqlim_limits(mp
, res
, qlim
, hard
, soft
, "rtb");
358 if (newlim
->d_fieldmask
& QC_RT_SPC_TIMER
)
359 xfs_setqlim_timer(mp
, res
, qlim
, newlim
->d_rt_spc_timer
);
362 hard
= (newlim
->d_fieldmask
& QC_INO_HARD
) ?
363 (xfs_qcnt_t
) newlim
->d_ino_hardlimit
:
364 dqp
->q_ino
.hardlimit
;
365 soft
= (newlim
->d_fieldmask
& QC_INO_SOFT
) ?
366 (xfs_qcnt_t
) newlim
->d_ino_softlimit
:
367 dqp
->q_ino
.softlimit
;
369 qlim
= id
== 0 ? &defq
->ino
: NULL
;
371 xfs_setqlim_limits(mp
, res
, qlim
, hard
, soft
, "ino");
372 if (newlim
->d_fieldmask
& QC_INO_TIMER
)
373 xfs_setqlim_timer(mp
, res
, qlim
, newlim
->d_ino_timer
);
377 * If the user is now over quota, start the timelimit.
378 * The user will not be 'warned'.
379 * Note that we keep the timers ticking, whether enforcement
380 * is on or off. We don't really want to bother with iterating
381 * over all ondisk dquots and turning the timers on/off.
383 xfs_qm_adjust_dqtimers(dqp
);
385 dqp
->q_flags
|= XFS_DQFLAG_DIRTY
;
386 xfs_trans_log_dquot(tp
, dqp
);
388 error
= xfs_trans_commit(tp
);
395 /* Fill out the quota context. */
397 xfs_qm_scall_getquota_fill_qc(
398 struct xfs_mount
*mp
,
400 const struct xfs_dquot
*dqp
,
401 struct qc_dqblk
*dst
)
403 memset(dst
, 0, sizeof(*dst
));
404 dst
->d_spc_hardlimit
= XFS_FSB_TO_B(mp
, dqp
->q_blk
.hardlimit
);
405 dst
->d_spc_softlimit
= XFS_FSB_TO_B(mp
, dqp
->q_blk
.softlimit
);
406 dst
->d_ino_hardlimit
= dqp
->q_ino
.hardlimit
;
407 dst
->d_ino_softlimit
= dqp
->q_ino
.softlimit
;
408 dst
->d_space
= XFS_FSB_TO_B(mp
, dqp
->q_blk
.reserved
);
409 dst
->d_ino_count
= dqp
->q_ino
.reserved
;
410 dst
->d_spc_timer
= dqp
->q_blk
.timer
;
411 dst
->d_ino_timer
= dqp
->q_ino
.timer
;
412 dst
->d_ino_warns
= 0;
413 dst
->d_spc_warns
= 0;
414 dst
->d_rt_spc_hardlimit
= XFS_FSB_TO_B(mp
, dqp
->q_rtb
.hardlimit
);
415 dst
->d_rt_spc_softlimit
= XFS_FSB_TO_B(mp
, dqp
->q_rtb
.softlimit
);
416 dst
->d_rt_space
= XFS_FSB_TO_B(mp
, dqp
->q_rtb
.reserved
);
417 dst
->d_rt_spc_timer
= dqp
->q_rtb
.timer
;
418 dst
->d_rt_spc_warns
= 0;
421 * Internally, we don't reset all the timers when quota enforcement
422 * gets turned off. No need to confuse the user level code,
423 * so return zeroes in that case.
425 if (!xfs_dquot_is_enforced(dqp
)) {
426 dst
->d_spc_timer
= 0;
427 dst
->d_ino_timer
= 0;
428 dst
->d_rt_spc_timer
= 0;
432 /* Return the quota information for the dquot matching id. */
434 xfs_qm_scall_getquota(
435 struct xfs_mount
*mp
,
438 struct qc_dqblk
*dst
)
440 struct xfs_dquot
*dqp
;
444 * Expedite pending inodegc work at the start of a quota reporting
445 * scan but don't block waiting for it to complete.
448 xfs_inodegc_push(mp
);
451 * Try to get the dquot. We don't want it allocated on disk, so don't
452 * set doalloc. If it doesn't exist, we'll get ENOENT back.
454 error
= xfs_qm_dqget(mp
, id
, type
, false, &dqp
);
459 * If everything's NULL, this dquot doesn't quite exist as far as
460 * our utility programs are concerned.
462 if (XFS_IS_DQUOT_UNINITIALIZED(dqp
)) {
467 xfs_qm_scall_getquota_fill_qc(mp
, type
, dqp
, dst
);
475 * Return the quota information for the first initialized dquot whose id
476 * is at least as high as id.
479 xfs_qm_scall_getquota_next(
480 struct xfs_mount
*mp
,
483 struct qc_dqblk
*dst
)
485 struct xfs_dquot
*dqp
;
488 /* Flush inodegc work at the start of a quota reporting scan. */
490 xfs_inodegc_push(mp
);
492 error
= xfs_qm_dqget_next(mp
, *id
, type
, &dqp
);
496 /* Fill in the ID we actually read from disk */
499 xfs_qm_scall_getquota_fill_qc(mp
, type
, dqp
, dst
);