1/*
2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19#include <linux/capability.h>
20
21#include "xfs.h"
22#include "xfs_fs.h"
23#include "xfs_shared.h"
24#include "xfs_format.h"
25#include "xfs_log_format.h"
26#include "xfs_trans_resv.h"
27#include "xfs_bit.h"
28#include "xfs_sb.h"
29#include "xfs_mount.h"
30#include "xfs_inode.h"
31#include "xfs_trans.h"
32#include "xfs_error.h"
33#include "xfs_quota.h"
34#include "xfs_qm.h"
35#include "xfs_trace.h"
36#include "xfs_icache.h"
37
38STATIC int	xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint);
39STATIC int	xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *,
40					uint);
41
42/*
43 * Turn off quota accounting and/or enforcement for all udquots and/or
44 * gdquots. Called only at unmount time.
45 *
46 * This assumes that there are no dquots of this file system cached
47 * incore, and modifies the ondisk dquot directly. Therefore, for example,
48 * it is an error to call this twice, without purging the cache.
49 */
50int
51xfs_qm_scall_quotaoff(
52	xfs_mount_t		*mp,
53	uint			flags)
54{
55	struct xfs_quotainfo	*q = mp->m_quotainfo;
56	uint			dqtype;
57	int			error;
58	uint			inactivate_flags;
59	xfs_qoff_logitem_t	*qoffstart;
60
61	/*
62	 * No file system can have quotas enabled on disk but not in core.
63	 * Note that quota utilities (like quotaoff) _expect_
64	 * errno == -EEXIST here.
65	 */
66	if ((mp->m_qflags & flags) == 0)
67		return -EEXIST;
68	error = 0;
69
70	flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
71
72	/*
73	 * We don't want to deal with two quotaoffs messing up each other,
74	 * so we're going to serialize it. quotaoff isn't exactly a performance
75	 * critical thing.
76	 * If quotaoff, then we must be dealing with the root filesystem.
77	 */
78	ASSERT(q);
79	mutex_lock(&q->qi_quotaofflock);
80
81	/*
82	 * If we're just turning off quota enforcement, change mp and go.
83	 */
84	if ((flags & XFS_ALL_QUOTA_ACCT) == 0) {
85		mp->m_qflags &= ~(flags);
86
87		spin_lock(&mp->m_sb_lock);
88		mp->m_sb.sb_qflags = mp->m_qflags;
89		spin_unlock(&mp->m_sb_lock);
90		mutex_unlock(&q->qi_quotaofflock);
91
92		/* XXX what to do if error ? Revert back to old vals incore ? */
93		return xfs_sync_sb(mp, false);
94	}
95
96	dqtype = 0;
97	inactivate_flags = 0;
98	/*
99	 * If accounting is off, we must turn enforcement off, clear the
100	 * quota 'CHKD' certificate to make it known that we have to
101	 * do a quotacheck the next time this quota is turned on.
102	 */
103	if (flags & XFS_UQUOTA_ACCT) {
104		dqtype |= XFS_QMOPT_UQUOTA;
105		flags |= (XFS_UQUOTA_CHKD | XFS_UQUOTA_ENFD);
106		inactivate_flags |= XFS_UQUOTA_ACTIVE;
107	}
108	if (flags & XFS_GQUOTA_ACCT) {
109		dqtype |= XFS_QMOPT_GQUOTA;
110		flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD);
111		inactivate_flags |= XFS_GQUOTA_ACTIVE;
112	}
113	if (flags & XFS_PQUOTA_ACCT) {
114		dqtype |= XFS_QMOPT_PQUOTA;
115		flags |= (XFS_PQUOTA_CHKD | XFS_PQUOTA_ENFD);
116		inactivate_flags |= XFS_PQUOTA_ACTIVE;
117	}
118
119	/*
120	 * Nothing to do?  Don't complain. This happens when we're just
121	 * turning off quota enforcement.
122	 */
123	if ((mp->m_qflags & flags) == 0)
124		goto out_unlock;
125
126	/*
127	 * Write the LI_QUOTAOFF log record, and do SB changes atomically,
128	 * and synchronously. If we fail to write, we should abort the
129	 * operation as it cannot be recovered safely if we crash.
130	 */
131	error = xfs_qm_log_quotaoff(mp, &qoffstart, flags);
132	if (error)
133		goto out_unlock;
134
135	/*
136	 * Next we clear the XFS_MOUNT_*DQ_ACTIVE bit(s) in the mount struct
137	 * to take care of the race between dqget and quotaoff. We don't take
138	 * any special locks to reset these bits. All processes need to check
139	 * these bits *after* taking inode lock(s) to see if the particular
140	 * quota type is in the process of being turned off. If *ACTIVE, it is
141	 * guaranteed that all dquot structures and all quotainode ptrs will all
142	 * stay valid as long as that inode is kept locked.
143	 *
144	 * There is no turning back after this.
145	 */
146	mp->m_qflags &= ~inactivate_flags;
147
148	/*
149	 * Give back all the dquot reference(s) held by inodes.
150	 * Here we go thru every single incore inode in this file system, and
151	 * do a dqrele on the i_udquot/i_gdquot that it may have.
152	 * Essentially, as long as somebody has an inode locked, this guarantees
153	 * that quotas will not be turned off. This is handy because in a
154	 * transaction once we lock the inode(s) and check for quotaon, we can
155	 * depend on the quota inodes (and other things) being valid as long as
156	 * we keep the lock(s).
157	 */
158	xfs_qm_dqrele_all_inodes(mp, flags);
159
160	/*
161	 * Next we make the changes in the quota flag in the mount struct.
162	 * This isn't protected by a particular lock directly, because we
163	 * don't want to take a mrlock every time we depend on quotas being on.
164	 */
165	mp->m_qflags &= ~flags;
166
167	/*
168	 * Go through all the dquots of this file system and purge them,
169	 * according to what was turned off.
170	 */
171	xfs_qm_dqpurge_all(mp, dqtype);
172
173	/*
174	 * Transactions that had started before ACTIVE state bit was cleared
175	 * could have logged many dquots, so they'd have higher LSNs than
176	 * the first QUOTAOFF log record does. If we happen to crash when
177	 * the tail of the log has gone past the QUOTAOFF record, but
178	 * before the last dquot modification, those dquots __will__
179	 * recover, and that's not good.
180	 *
181	 * So, we have QUOTAOFF start and end logitems; the start
182	 * logitem won't get overwritten until the end logitem appears...
183	 */
184	error = xfs_qm_log_quotaoff_end(mp, qoffstart, flags);
185	if (error) {
186		/* We're screwed now. Shutdown is the only option. */
187		xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
188		goto out_unlock;
189	}
190
191	/*
192	 * If all quotas are completely turned off, close shop.
193	 */
194	if (mp->m_qflags == 0) {
195		mutex_unlock(&q->qi_quotaofflock);
196		xfs_qm_destroy_quotainfo(mp);
197		return 0;
198	}
199
200	/*
201	 * Release our quotainode references if we don't need them anymore.
202	 */
203	if ((dqtype & XFS_QMOPT_UQUOTA) && q->qi_uquotaip) {
204		IRELE(q->qi_uquotaip);
205		q->qi_uquotaip = NULL;
206	}
207	if ((dqtype & XFS_QMOPT_GQUOTA) && q->qi_gquotaip) {
208		IRELE(q->qi_gquotaip);
209		q->qi_gquotaip = NULL;
210	}
211	if ((dqtype & XFS_QMOPT_PQUOTA) && q->qi_pquotaip) {
212		IRELE(q->qi_pquotaip);
213		q->qi_pquotaip = NULL;
214	}
215
216out_unlock:
217	mutex_unlock(&q->qi_quotaofflock);
218	return error;
219}
220
221STATIC int
222xfs_qm_scall_trunc_qfile(
223	struct xfs_mount	*mp,
224	xfs_ino_t		ino)
225{
226	struct xfs_inode	*ip;
227	struct xfs_trans	*tp;
228	int			error;
229
230	if (ino == NULLFSINO)
231		return 0;
232
233	error = xfs_iget(mp, NULL, ino, 0, 0, &ip);
234	if (error)
235		return error;
236
237	xfs_ilock(ip, XFS_IOLOCK_EXCL);
238
239	tp = xfs_trans_alloc(mp, XFS_TRANS_TRUNCATE_FILE);
240	error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
241	if (error) {
242		xfs_trans_cancel(tp, 0);
243		xfs_iunlock(ip, XFS_IOLOCK_EXCL);
244		goto out_put;
245	}
246
247	xfs_ilock(ip, XFS_ILOCK_EXCL);
248	xfs_trans_ijoin(tp, ip, 0);
249
250	ip->i_d.di_size = 0;
251	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
252
253	error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0);
254	if (error) {
255		xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES |
256				     XFS_TRANS_ABORT);
257		goto out_unlock;
258	}
259
260	ASSERT(ip->i_d.di_nextents == 0);
261
262	xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
263	error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
264
265out_unlock:
266	xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
267out_put:
268	IRELE(ip);
269	return error;
270}
271
272int
273xfs_qm_scall_trunc_qfiles(
274	xfs_mount_t	*mp,
275	uint		flags)
276{
277	int		error = -EINVAL;
278
279	if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0 ||
280	    (flags & ~XFS_DQ_ALLTYPES)) {
281		xfs_debug(mp, "%s: flags=%x m_qflags=%x",
282			__func__, flags, mp->m_qflags);
283		return -EINVAL;
284	}
285
286	if (flags & XFS_DQ_USER) {
287		error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_uquotino);
288		if (error)
289			return error;
290	}
291	if (flags & XFS_DQ_GROUP) {
292		error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_gquotino);
293		if (error)
294			return error;
295	}
296	if (flags & XFS_DQ_PROJ)
297		error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_pquotino);
298
299	return error;
300}
301
302/*
303 * Switch on (a given) quota enforcement for a filesystem.  This takes
304 * effect immediately.
305 * (Switching on quota accounting must be done at mount time.)
306 */
307int
308xfs_qm_scall_quotaon(
309	xfs_mount_t	*mp,
310	uint		flags)
311{
312	int		error;
313	uint		qf;
314
315	flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
316	/*
317	 * Switching on quota accounting must be done at mount time.
318	 */
319	flags &= ~(XFS_ALL_QUOTA_ACCT);
320
321	if (flags == 0) {
322		xfs_debug(mp, "%s: zero flags, m_qflags=%x",
323			__func__, mp->m_qflags);
324		return -EINVAL;
325	}
326
327	/*
328	 * Can't enforce without accounting. We check the superblock
329	 * qflags here instead of m_qflags because rootfs can have
330	 * quota acct on ondisk without m_qflags' knowing.
331	 */
332	if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
333	     (flags & XFS_UQUOTA_ENFD)) ||
334	    ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
335	     (flags & XFS_GQUOTA_ENFD)) ||
336	    ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
337	     (flags & XFS_PQUOTA_ENFD))) {
338		xfs_debug(mp,
339			"%s: Can't enforce without acct, flags=%x sbflags=%x",
340			__func__, flags, mp->m_sb.sb_qflags);
341		return -EINVAL;
342	}
343	/*
344	 * If everything's up to-date incore, then don't waste time.
345	 */
346	if ((mp->m_qflags & flags) == flags)
347		return -EEXIST;
348
349	/*
350	 * Change sb_qflags on disk but not incore mp->qflags
351	 * if this is the root filesystem.
352	 */
353	spin_lock(&mp->m_sb_lock);
354	qf = mp->m_sb.sb_qflags;
355	mp->m_sb.sb_qflags = qf | flags;
356	spin_unlock(&mp->m_sb_lock);
357
358	/*
359	 * There's nothing to change if it's the same.
360	 */
361	if ((qf & flags) == flags)
362		return -EEXIST;
363
364	error = xfs_sync_sb(mp, false);
365	if (error)
366		return error;
367	/*
368	 * If we aren't trying to switch on quota enforcement, we are done.
369	 */
370	if  (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) !=
371	     (mp->m_qflags & XFS_UQUOTA_ACCT)) ||
372	     ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) !=
373	     (mp->m_qflags & XFS_PQUOTA_ACCT)) ||
374	     ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) !=
375	     (mp->m_qflags & XFS_GQUOTA_ACCT)))
376		return 0;
377
378	if (! XFS_IS_QUOTA_RUNNING(mp))
379		return -ESRCH;
380
381	/*
382	 * Switch on quota enforcement in core.
383	 */
384	mutex_lock(&mp->m_quotainfo->qi_quotaofflock);
385	mp->m_qflags |= (flags & XFS_ALL_QUOTA_ENFD);
386	mutex_unlock(&mp->m_quotainfo->qi_quotaofflock);
387
388	return 0;
389}
390
391#define XFS_QC_MASK \
392	(QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK)
393
394/*
395 * Adjust quota limits, and start/stop timers accordingly.
396 */
397int
398xfs_qm_scall_setqlim(
399	struct xfs_mount	*mp,
400	xfs_dqid_t		id,
401	uint			type,
402	struct qc_dqblk		*newlim)
403{
404	struct xfs_quotainfo	*q = mp->m_quotainfo;
405	struct xfs_disk_dquot	*ddq;
406	struct xfs_dquot	*dqp;
407	struct xfs_trans	*tp;
408	int			error;
409	xfs_qcnt_t		hard, soft;
410
411	if (newlim->d_fieldmask & ~XFS_QC_MASK)
412		return -EINVAL;
413	if ((newlim->d_fieldmask & XFS_QC_MASK) == 0)
414		return 0;
415
416	/*
417	 * We don't want to race with a quotaoff so take the quotaoff lock.
418	 * We don't hold an inode lock, so there's nothing else to stop
419	 * a quotaoff from happening.
420	 */
421	mutex_lock(&q->qi_quotaofflock);
422
423	/*
424	 * Get the dquot (locked) before we start, as we need to do a
425	 * transaction to allocate it if it doesn't exist. Once we have the
426	 * dquot, unlock it so we can start the next transaction safely. We hold
427	 * a reference to the dquot, so it's safe to do this unlock/lock without
428	 * it being reclaimed in the mean time.
429	 */
430	error = xfs_qm_dqget(mp, NULL, id, type, XFS_QMOPT_DQALLOC, &dqp);
431	if (error) {
432		ASSERT(error != -ENOENT);
433		goto out_unlock;
434	}
435	xfs_dqunlock(dqp);
436
437	tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM);
438	error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_setqlim, 0, 0);
439	if (error) {
440		xfs_trans_cancel(tp, 0);
441		goto out_rele;
442	}
443
444	xfs_dqlock(dqp);
445	xfs_trans_dqjoin(tp, dqp);
446	ddq = &dqp->q_core;
447
448	/*
449	 * Make sure that hardlimits are >= soft limits before changing.
450	 */
451	hard = (newlim->d_fieldmask & QC_SPC_HARD) ?
452		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) :
453			be64_to_cpu(ddq->d_blk_hardlimit);
454	soft = (newlim->d_fieldmask & QC_SPC_SOFT) ?
455		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) :
456			be64_to_cpu(ddq->d_blk_softlimit);
457	if (hard == 0 || hard >= soft) {
458		ddq->d_blk_hardlimit = cpu_to_be64(hard);
459		ddq->d_blk_softlimit = cpu_to_be64(soft);
460		xfs_dquot_set_prealloc_limits(dqp);
461		if (id == 0) {
462			q->qi_bhardlimit = hard;
463			q->qi_bsoftlimit = soft;
464		}
465	} else {
466		xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft);
467	}
468	hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ?
469		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) :
470			be64_to_cpu(ddq->d_rtb_hardlimit);
471	soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ?
472		(xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) :
473			be64_to_cpu(ddq->d_rtb_softlimit);
474	if (hard == 0 || hard >= soft) {
475		ddq->d_rtb_hardlimit = cpu_to_be64(hard);
476		ddq->d_rtb_softlimit = cpu_to_be64(soft);
477		if (id == 0) {
478			q->qi_rtbhardlimit = hard;
479			q->qi_rtbsoftlimit = soft;
480		}
481	} else {
482		xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft);
483	}
484
485	hard = (newlim->d_fieldmask & QC_INO_HARD) ?
486		(xfs_qcnt_t) newlim->d_ino_hardlimit :
487			be64_to_cpu(ddq->d_ino_hardlimit);
488	soft = (newlim->d_fieldmask & QC_INO_SOFT) ?
489		(xfs_qcnt_t) newlim->d_ino_softlimit :
490			be64_to_cpu(ddq->d_ino_softlimit);
491	if (hard == 0 || hard >= soft) {
492		ddq->d_ino_hardlimit = cpu_to_be64(hard);
493		ddq->d_ino_softlimit = cpu_to_be64(soft);
494		if (id == 0) {
495			q->qi_ihardlimit = hard;
496			q->qi_isoftlimit = soft;
497		}
498	} else {
499		xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft);
500	}
501
502	/*
503	 * Update warnings counter(s) if requested
504	 */
505	if (newlim->d_fieldmask & QC_SPC_WARNS)
506		ddq->d_bwarns = cpu_to_be16(newlim->d_spc_warns);
507	if (newlim->d_fieldmask & QC_INO_WARNS)
508		ddq->d_iwarns = cpu_to_be16(newlim->d_ino_warns);
509	if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
510		ddq->d_rtbwarns = cpu_to_be16(newlim->d_rt_spc_warns);
511
512	if (id == 0) {
513		/*
514		 * Timelimits for the super user set the relative time
515		 * the other users can be over quota for this file system.
516		 * If it is zero a default is used.  Ditto for the default
517		 * soft and hard limit values (already done, above), and
518		 * for warnings.
519		 */
520		if (newlim->d_fieldmask & QC_SPC_TIMER) {
521			q->qi_btimelimit = newlim->d_spc_timer;
522			ddq->d_btimer = cpu_to_be32(newlim->d_spc_timer);
523		}
524		if (newlim->d_fieldmask & QC_INO_TIMER) {
525			q->qi_itimelimit = newlim->d_ino_timer;
526			ddq->d_itimer = cpu_to_be32(newlim->d_ino_timer);
527		}
528		if (newlim->d_fieldmask & QC_RT_SPC_TIMER) {
529			q->qi_rtbtimelimit = newlim->d_rt_spc_timer;
530			ddq->d_rtbtimer = cpu_to_be32(newlim->d_rt_spc_timer);
531		}
532		if (newlim->d_fieldmask & QC_SPC_WARNS)
533			q->qi_bwarnlimit = newlim->d_spc_warns;
534		if (newlim->d_fieldmask & QC_INO_WARNS)
535			q->qi_iwarnlimit = newlim->d_ino_warns;
536		if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
537			q->qi_rtbwarnlimit = newlim->d_rt_spc_warns;
538	} else {
539		/*
540		 * If the user is now over quota, start the timelimit.
541		 * The user will not be 'warned'.
542		 * Note that we keep the timers ticking, whether enforcement
543		 * is on or off. We don't really want to bother with iterating
544		 * over all ondisk dquots and turning the timers on/off.
545		 */
546		xfs_qm_adjust_dqtimers(mp, ddq);
547	}
548	dqp->dq_flags |= XFS_DQ_DIRTY;
549	xfs_trans_log_dquot(tp, dqp);
550
551	error = xfs_trans_commit(tp, 0);
552
553out_rele:
554	xfs_qm_dqrele(dqp);
555out_unlock:
556	mutex_unlock(&q->qi_quotaofflock);
557	return error;
558}
559
560STATIC int
561xfs_qm_log_quotaoff_end(
562	xfs_mount_t		*mp,
563	xfs_qoff_logitem_t	*startqoff,
564	uint			flags)
565{
566	xfs_trans_t		*tp;
567	int			error;
568	xfs_qoff_logitem_t	*qoffi;
569
570	tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END);
571
572	error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_equotaoff, 0, 0);
573	if (error) {
574		xfs_trans_cancel(tp, 0);
575		return error;
576	}
577
578	qoffi = xfs_trans_get_qoff_item(tp, startqoff,
579					flags & XFS_ALL_QUOTA_ACCT);
580	xfs_trans_log_quotaoff_item(tp, qoffi);
581
582	/*
583	 * We have to make sure that the transaction is secure on disk before we
584	 * return and actually stop quota accounting. So, make it synchronous.
585	 * We don't care about quotoff's performance.
586	 */
587	xfs_trans_set_sync(tp);
588	error = xfs_trans_commit(tp, 0);
589	return error;
590}
591
592
593STATIC int
594xfs_qm_log_quotaoff(
595	xfs_mount_t	       *mp,
596	xfs_qoff_logitem_t     **qoffstartp,
597	uint		       flags)
598{
599	xfs_trans_t	       *tp;
600	int			error;
601	xfs_qoff_logitem_t     *qoffi;
602
603	*qoffstartp = NULL;
604
605	tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF);
606	error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_quotaoff, 0, 0);
607	if (error) {
608		xfs_trans_cancel(tp, 0);
609		goto out;
610	}
611
612	qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT);
613	xfs_trans_log_quotaoff_item(tp, qoffi);
614
615	spin_lock(&mp->m_sb_lock);
616	mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL;
617	spin_unlock(&mp->m_sb_lock);
618
619	xfs_log_sb(tp);
620
621	/*
622	 * We have to make sure that the transaction is secure on disk before we
623	 * return and actually stop quota accounting. So, make it synchronous.
624	 * We don't care about quotoff's performance.
625	 */
626	xfs_trans_set_sync(tp);
627	error = xfs_trans_commit(tp, 0);
628	if (error)
629		goto out;
630
631	*qoffstartp = qoffi;
632out:
633	return error;
634}
635
636
637int
638xfs_qm_scall_getquota(
639	struct xfs_mount	*mp,
640	xfs_dqid_t		id,
641	uint			type,
642	struct qc_dqblk		*dst)
643{
644	struct xfs_dquot	*dqp;
645	int			error;
646
647	/*
648	 * Try to get the dquot. We don't want it allocated on disk, so
649	 * we aren't passing the XFS_QMOPT_DOALLOC flag. If it doesn't
650	 * exist, we'll get ENOENT back.
651	 */
652	error = xfs_qm_dqget(mp, NULL, id, type, 0, &dqp);
653	if (error)
654		return error;
655
656	/*
657	 * If everything's NULL, this dquot doesn't quite exist as far as
658	 * our utility programs are concerned.
659	 */
660	if (XFS_IS_DQUOT_UNINITIALIZED(dqp)) {
661		error = -ENOENT;
662		goto out_put;
663	}
664
665	memset(dst, 0, sizeof(*dst));
666	dst->d_spc_hardlimit =
667		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_hardlimit));
668	dst->d_spc_softlimit =
669		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit));
670	dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
671	dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
672	dst->d_space = XFS_FSB_TO_B(mp, dqp->q_res_bcount);
673	dst->d_ino_count = dqp->q_res_icount;
674	dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer);
675	dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer);
676	dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns);
677	dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns);
678	dst->d_rt_spc_hardlimit =
679		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit));
680	dst->d_rt_spc_softlimit =
681		XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit));
682	dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_res_rtbcount);
683	dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
684	dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
685
686	/*
687	 * Internally, we don't reset all the timers when quota enforcement
688	 * gets turned off. No need to confuse the user level code,
689	 * so return zeroes in that case.
690	 */
691	if ((!XFS_IS_UQUOTA_ENFORCED(mp) &&
692	     dqp->q_core.d_flags == XFS_DQ_USER) ||
693	    (!XFS_IS_GQUOTA_ENFORCED(mp) &&
694	     dqp->q_core.d_flags == XFS_DQ_GROUP) ||
695	    (!XFS_IS_PQUOTA_ENFORCED(mp) &&
696	     dqp->q_core.d_flags == XFS_DQ_PROJ)) {
697		dst->d_spc_timer = 0;
698		dst->d_ino_timer = 0;
699		dst->d_rt_spc_timer = 0;
700	}
701
702#ifdef DEBUG
703	if (((XFS_IS_UQUOTA_ENFORCED(mp) && type == XFS_DQ_USER) ||
704	     (XFS_IS_GQUOTA_ENFORCED(mp) && type == XFS_DQ_GROUP) ||
705	     (XFS_IS_PQUOTA_ENFORCED(mp) && type == XFS_DQ_PROJ)) &&
706	    id != 0) {
707		if ((dst->d_space > dst->d_spc_softlimit) &&
708		    (dst->d_spc_softlimit > 0)) {
709			ASSERT(dst->d_spc_timer != 0);
710		}
711		if ((dst->d_ino_count > dst->d_ino_softlimit) &&
712		    (dst->d_ino_softlimit > 0)) {
713			ASSERT(dst->d_ino_timer != 0);
714		}
715	}
716#endif
717out_put:
718	xfs_qm_dqput(dqp);
719	return error;
720}
721
722
723STATIC int
724xfs_dqrele_inode(
725	struct xfs_inode	*ip,
726	int			flags,
727	void			*args)
728{
729	/* skip quota inodes */
730	if (ip == ip->i_mount->m_quotainfo->qi_uquotaip ||
731	    ip == ip->i_mount->m_quotainfo->qi_gquotaip ||
732	    ip == ip->i_mount->m_quotainfo->qi_pquotaip) {
733		ASSERT(ip->i_udquot == NULL);
734		ASSERT(ip->i_gdquot == NULL);
735		ASSERT(ip->i_pdquot == NULL);
736		return 0;
737	}
738
739	xfs_ilock(ip, XFS_ILOCK_EXCL);
740	if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) {
741		xfs_qm_dqrele(ip->i_udquot);
742		ip->i_udquot = NULL;
743	}
744	if ((flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) {
745		xfs_qm_dqrele(ip->i_gdquot);
746		ip->i_gdquot = NULL;
747	}
748	if ((flags & XFS_PQUOTA_ACCT) && ip->i_pdquot) {
749		xfs_qm_dqrele(ip->i_pdquot);
750		ip->i_pdquot = NULL;
751	}
752	xfs_iunlock(ip, XFS_ILOCK_EXCL);
753	return 0;
754}
755
756
757/*
758 * Go thru all the inodes in the file system, releasing their dquots.
759 *
760 * Note that the mount structure gets modified to indicate that quotas are off
761 * AFTER this, in the case of quotaoff.
762 */
763void
764xfs_qm_dqrele_all_inodes(
765	struct xfs_mount *mp,
766	uint		 flags)
767{
768	ASSERT(mp->m_quotainfo);
769	xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, NULL);
770}
771