blob: 565efb73c233e79e9b2d8a459e91d90a56281f19 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Copyright (c) 2000-2002 Silicon Graphics, Inc. All Rights Reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of version 2 of the GNU General Public License as
6 * published by the Free Software Foundation.
7 *
8 * This program is distributed in the hope that it would be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 *
12 * Further, this software is distributed without any warranty that it is
13 * free of the rightful claim of any third person regarding infringement
14 * or the like. Any license provided herein, whether implied or
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */
32
33#include "xfs.h"
34#include "xfs_fs.h"
35#include "xfs_inum.h"
36#include "xfs_log.h"
37#include "xfs_trans.h"
38#include "xfs_sb.h"
39#include "xfs_ag.h"
40#include "xfs_dir.h"
41#include "xfs_dir2.h"
42#include "xfs_alloc.h"
43#include "xfs_dmapi.h"
44#include "xfs_quota.h"
45#include "xfs_mount.h"
46#include "xfs_alloc_btree.h"
47#include "xfs_bmap_btree.h"
48#include "xfs_ialloc_btree.h"
49#include "xfs_btree.h"
50#include "xfs_ialloc.h"
51#include "xfs_attr_sf.h"
52#include "xfs_dir_sf.h"
53#include "xfs_dir2_sf.h"
54#include "xfs_dinode.h"
55#include "xfs_inode.h"
56#include "xfs_bmap.h"
57#include "xfs_bit.h"
58#include "xfs_rtalloc.h"
59#include "xfs_error.h"
60#include "xfs_itable.h"
61#include "xfs_rw.h"
62#include "xfs_acl.h"
63#include "xfs_cap.h"
64#include "xfs_mac.h"
65#include "xfs_attr.h"
66#include "xfs_buf_item.h"
67#include "xfs_trans_priv.h"
68
69#include "xfs_qm.h"
70
71STATIC void xfs_trans_alloc_dqinfo(xfs_trans_t *);
72
73/*
74 * Add the locked dquot to the transaction.
75 * The dquot must be locked, and it cannot be associated with any
76 * transaction.
77 */
78void
79xfs_trans_dqjoin(
80 xfs_trans_t *tp,
81 xfs_dquot_t *dqp)
82{
83 xfs_dq_logitem_t *lp;
84
85 ASSERT(! XFS_DQ_IS_ADDEDTO_TRX(tp, dqp));
86 ASSERT(XFS_DQ_IS_LOCKED(dqp));
87 ASSERT(XFS_DQ_IS_LOGITEM_INITD(dqp));
88 lp = &dqp->q_logitem;
89
90 /*
91 * Get a log_item_desc to point at the new item.
92 */
93 (void) xfs_trans_add_item(tp, (xfs_log_item_t*)(lp));
94
95 /*
96 * Initialize i_transp so we can later determine if this dquot is
97 * associated with this transaction.
98 */
99 dqp->q_transp = tp;
100}
101
102
103/*
104 * This is called to mark the dquot as needing
105 * to be logged when the transaction is committed. The dquot must
106 * already be associated with the given transaction.
107 * Note that it marks the entire transaction as dirty. In the ordinary
108 * case, this gets called via xfs_trans_commit, after the transaction
109 * is already dirty. However, there's nothing stop this from getting
110 * called directly, as done by xfs_qm_scall_setqlim. Hence, the TRANS_DIRTY
111 * flag.
112 */
113void
114xfs_trans_log_dquot(
115 xfs_trans_t *tp,
116 xfs_dquot_t *dqp)
117{
118 xfs_log_item_desc_t *lidp;
119
120 ASSERT(XFS_DQ_IS_ADDEDTO_TRX(tp, dqp));
121 ASSERT(XFS_DQ_IS_LOCKED(dqp));
122
123 lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)(&dqp->q_logitem));
124 ASSERT(lidp != NULL);
125
126 tp->t_flags |= XFS_TRANS_DIRTY;
127 lidp->lid_flags |= XFS_LID_DIRTY;
128}
129
130/*
131 * Carry forward whatever is left of the quota blk reservation to
132 * the spanky new transaction
133 */
134STATIC void
135xfs_trans_dup_dqinfo(
136 xfs_trans_t *otp,
137 xfs_trans_t *ntp)
138{
139 xfs_dqtrx_t *oq, *nq;
140 int i,j;
141 xfs_dqtrx_t *oqa, *nqa;
142
143 if (!otp->t_dqinfo)
144 return;
145
146 xfs_trans_alloc_dqinfo(ntp);
147 oqa = otp->t_dqinfo->dqa_usrdquots;
148 nqa = ntp->t_dqinfo->dqa_usrdquots;
149
150 /*
151 * Because the quota blk reservation is carried forward,
152 * it is also necessary to carry forward the DQ_DIRTY flag.
153 */
154 if(otp->t_flags & XFS_TRANS_DQ_DIRTY)
155 ntp->t_flags |= XFS_TRANS_DQ_DIRTY;
156
157 for (j = 0; j < 2; j++) {
158 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
159 if (oqa[i].qt_dquot == NULL)
160 break;
161 oq = &oqa[i];
162 nq = &nqa[i];
163
164 nq->qt_dquot = oq->qt_dquot;
165 nq->qt_bcount_delta = nq->qt_icount_delta = 0;
166 nq->qt_rtbcount_delta = 0;
167
168 /*
169 * Transfer whatever is left of the reservations.
170 */
171 nq->qt_blk_res = oq->qt_blk_res - oq->qt_blk_res_used;
172 oq->qt_blk_res = oq->qt_blk_res_used;
173
174 nq->qt_rtblk_res = oq->qt_rtblk_res -
175 oq->qt_rtblk_res_used;
176 oq->qt_rtblk_res = oq->qt_rtblk_res_used;
177
178 nq->qt_ino_res = oq->qt_ino_res - oq->qt_ino_res_used;
179 oq->qt_ino_res = oq->qt_ino_res_used;
180
181 }
182 oqa = otp->t_dqinfo->dqa_grpdquots;
183 nqa = ntp->t_dqinfo->dqa_grpdquots;
184 }
185}
186
187/*
188 * Wrap around mod_dquot to account for both user and group quotas.
189 */
Christoph Hellwigba0f32d2005-06-21 15:36:52 +1000190STATIC void
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191xfs_trans_mod_dquot_byino(
192 xfs_trans_t *tp,
193 xfs_inode_t *ip,
194 uint field,
195 long delta)
196{
197 xfs_mount_t *mp;
198
199 ASSERT(tp);
200 mp = tp->t_mountp;
201
202 if (!XFS_IS_QUOTA_ON(mp) ||
203 ip->i_ino == mp->m_sb.sb_uquotino ||
204 ip->i_ino == mp->m_sb.sb_gquotino)
205 return;
206
207 if (tp->t_dqinfo == NULL)
208 xfs_trans_alloc_dqinfo(tp);
209
Nathan Scottc8ad20f2005-06-21 15:38:48 +1000210 if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700211 (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta);
Nathan Scottc8ad20f2005-06-21 15:38:48 +1000212 if (XFS_IS_OQUOTA_ON(mp) && ip->i_gdquot)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213 (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700214}
215
216STATIC xfs_dqtrx_t *
217xfs_trans_get_dqtrx(
218 xfs_trans_t *tp,
219 xfs_dquot_t *dqp)
220{
221 int i;
222 xfs_dqtrx_t *qa;
223
224 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
225 qa = XFS_QM_DQP_TO_DQACCT(tp, dqp);
226
227 if (qa[i].qt_dquot == NULL ||
228 qa[i].qt_dquot == dqp) {
229 return (&qa[i]);
230 }
231 }
232
233 return (NULL);
234}
235
236/*
237 * Make the changes in the transaction structure.
238 * The moral equivalent to xfs_trans_mod_sb().
239 * We don't touch any fields in the dquot, so we don't care
240 * if it's locked or not (most of the time it won't be).
241 */
242void
243xfs_trans_mod_dquot(
244 xfs_trans_t *tp,
245 xfs_dquot_t *dqp,
246 uint field,
247 long delta)
248{
249 xfs_dqtrx_t *qtrx;
250
251 ASSERT(tp);
252 qtrx = NULL;
253
254 if (tp->t_dqinfo == NULL)
255 xfs_trans_alloc_dqinfo(tp);
256 /*
257 * Find either the first free slot or the slot that belongs
258 * to this dquot.
259 */
260 qtrx = xfs_trans_get_dqtrx(tp, dqp);
261 ASSERT(qtrx);
262 if (qtrx->qt_dquot == NULL)
263 qtrx->qt_dquot = dqp;
264
265 switch (field) {
266
267 /*
268 * regular disk blk reservation
269 */
270 case XFS_TRANS_DQ_RES_BLKS:
271 qtrx->qt_blk_res += (ulong)delta;
272 break;
273
274 /*
275 * inode reservation
276 */
277 case XFS_TRANS_DQ_RES_INOS:
278 qtrx->qt_ino_res += (ulong)delta;
279 break;
280
281 /*
282 * disk blocks used.
283 */
284 case XFS_TRANS_DQ_BCOUNT:
285 if (qtrx->qt_blk_res && delta > 0) {
286 qtrx->qt_blk_res_used += (ulong)delta;
287 ASSERT(qtrx->qt_blk_res >= qtrx->qt_blk_res_used);
288 }
289 qtrx->qt_bcount_delta += delta;
290 break;
291
292 case XFS_TRANS_DQ_DELBCOUNT:
293 qtrx->qt_delbcnt_delta += delta;
294 break;
295
296 /*
297 * Inode Count
298 */
299 case XFS_TRANS_DQ_ICOUNT:
300 if (qtrx->qt_ino_res && delta > 0) {
301 qtrx->qt_ino_res_used += (ulong)delta;
302 ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used);
303 }
304 qtrx->qt_icount_delta += delta;
305 break;
306
307 /*
308 * rtblk reservation
309 */
310 case XFS_TRANS_DQ_RES_RTBLKS:
311 qtrx->qt_rtblk_res += (ulong)delta;
312 break;
313
314 /*
315 * rtblk count
316 */
317 case XFS_TRANS_DQ_RTBCOUNT:
318 if (qtrx->qt_rtblk_res && delta > 0) {
319 qtrx->qt_rtblk_res_used += (ulong)delta;
320 ASSERT(qtrx->qt_rtblk_res >= qtrx->qt_rtblk_res_used);
321 }
322 qtrx->qt_rtbcount_delta += delta;
323 break;
324
325 case XFS_TRANS_DQ_DELRTBCOUNT:
326 qtrx->qt_delrtb_delta += delta;
327 break;
328
329 default:
330 ASSERT(0);
331 }
332 tp->t_flags |= XFS_TRANS_DQ_DIRTY;
333}
334
335
336/*
337 * Given an array of dqtrx structures, lock all the dquots associated
338 * and join them to the transaction, provided they have been modified.
339 * We know that the highest number of dquots (of one type - usr OR grp),
340 * involved in a transaction is 2 and that both usr and grp combined - 3.
341 * So, we don't attempt to make this very generic.
342 */
343STATIC void
344xfs_trans_dqlockedjoin(
345 xfs_trans_t *tp,
346 xfs_dqtrx_t *q)
347{
348 ASSERT(q[0].qt_dquot != NULL);
349 if (q[1].qt_dquot == NULL) {
350 xfs_dqlock(q[0].qt_dquot);
351 xfs_trans_dqjoin(tp, q[0].qt_dquot);
352 } else {
353 ASSERT(XFS_QM_TRANS_MAXDQS == 2);
354 xfs_dqlock2(q[0].qt_dquot, q[1].qt_dquot);
355 xfs_trans_dqjoin(tp, q[0].qt_dquot);
356 xfs_trans_dqjoin(tp, q[1].qt_dquot);
357 }
358}
359
360
361/*
362 * Called by xfs_trans_commit() and similar in spirit to
363 * xfs_trans_apply_sb_deltas().
364 * Go thru all the dquots belonging to this transaction and modify the
365 * INCORE dquot to reflect the actual usages.
366 * Unreserve just the reservations done by this transaction.
367 * dquot is still left locked at exit.
368 */
Christoph Hellwigba0f32d2005-06-21 15:36:52 +1000369STATIC void
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370xfs_trans_apply_dquot_deltas(
371 xfs_trans_t *tp)
372{
373 int i, j;
374 xfs_dquot_t *dqp;
375 xfs_dqtrx_t *qtrx, *qa;
376 xfs_disk_dquot_t *d;
377 long totalbdelta;
378 long totalrtbdelta;
379
380 if (! (tp->t_flags & XFS_TRANS_DQ_DIRTY))
381 return;
382
383 ASSERT(tp->t_dqinfo);
384 qa = tp->t_dqinfo->dqa_usrdquots;
385 for (j = 0; j < 2; j++) {
386 if (qa[0].qt_dquot == NULL) {
387 qa = tp->t_dqinfo->dqa_grpdquots;
388 continue;
389 }
390
391 /*
392 * Lock all of the dquots and join them to the transaction.
393 */
394 xfs_trans_dqlockedjoin(tp, qa);
395
396 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
397 qtrx = &qa[i];
398 /*
399 * The array of dquots is filled
400 * sequentially, not sparsely.
401 */
402 if ((dqp = qtrx->qt_dquot) == NULL)
403 break;
404
405 ASSERT(XFS_DQ_IS_LOCKED(dqp));
406 ASSERT(XFS_DQ_IS_ADDEDTO_TRX(tp, dqp));
407
408 /*
409 * adjust the actual number of blocks used
410 */
411 d = &dqp->q_core;
412
413 /*
414 * The issue here is - sometimes we don't make a blkquota
415 * reservation intentionally to be fair to users
416 * (when the amount is small). On the other hand,
417 * delayed allocs do make reservations, but that's
418 * outside of a transaction, so we have no
419 * idea how much was really reserved.
420 * So, here we've accumulated delayed allocation blks and
421 * non-delay blks. The assumption is that the
422 * delayed ones are always reserved (outside of a
423 * transaction), and the others may or may not have
424 * quota reservations.
425 */
426 totalbdelta = qtrx->qt_bcount_delta +
427 qtrx->qt_delbcnt_delta;
428 totalrtbdelta = qtrx->qt_rtbcount_delta +
429 qtrx->qt_delrtb_delta;
430#ifdef QUOTADEBUG
431 if (totalbdelta < 0)
432 ASSERT(INT_GET(d->d_bcount, ARCH_CONVERT) >=
433 (xfs_qcnt_t) -totalbdelta);
434
435 if (totalrtbdelta < 0)
436 ASSERT(INT_GET(d->d_rtbcount, ARCH_CONVERT) >=
437 (xfs_qcnt_t) -totalrtbdelta);
438
439 if (qtrx->qt_icount_delta < 0)
440 ASSERT(INT_GET(d->d_icount, ARCH_CONVERT) >=
441 (xfs_qcnt_t) -qtrx->qt_icount_delta);
442#endif
443 if (totalbdelta)
444 INT_MOD(d->d_bcount, ARCH_CONVERT, (xfs_qcnt_t)totalbdelta);
445
446 if (qtrx->qt_icount_delta)
447 INT_MOD(d->d_icount, ARCH_CONVERT, (xfs_qcnt_t)qtrx->qt_icount_delta);
448
449 if (totalrtbdelta)
450 INT_MOD(d->d_rtbcount, ARCH_CONVERT, (xfs_qcnt_t)totalrtbdelta);
451
452 /*
453 * Get any default limits in use.
454 * Start/reset the timer(s) if needed.
455 */
456 if (d->d_id) {
457 xfs_qm_adjust_dqlimits(tp->t_mountp, d);
458 xfs_qm_adjust_dqtimers(tp->t_mountp, d);
459 }
460
461 dqp->dq_flags |= XFS_DQ_DIRTY;
462 /*
463 * add this to the list of items to get logged
464 */
465 xfs_trans_log_dquot(tp, dqp);
466 /*
467 * Take off what's left of the original reservation.
468 * In case of delayed allocations, there's no
469 * reservation that a transaction structure knows of.
470 */
471 if (qtrx->qt_blk_res != 0) {
472 if (qtrx->qt_blk_res != qtrx->qt_blk_res_used) {
473 if (qtrx->qt_blk_res >
474 qtrx->qt_blk_res_used)
475 dqp->q_res_bcount -= (xfs_qcnt_t)
476 (qtrx->qt_blk_res -
477 qtrx->qt_blk_res_used);
478 else
479 dqp->q_res_bcount -= (xfs_qcnt_t)
480 (qtrx->qt_blk_res_used -
481 qtrx->qt_blk_res);
482 }
483 } else {
484 /*
485 * These blks were never reserved, either inside
486 * a transaction or outside one (in a delayed
487 * allocation). Also, this isn't always a
488 * negative number since we sometimes
489 * deliberately skip quota reservations.
490 */
491 if (qtrx->qt_bcount_delta) {
492 dqp->q_res_bcount +=
493 (xfs_qcnt_t)qtrx->qt_bcount_delta;
494 }
495 }
496 /*
497 * Adjust the RT reservation.
498 */
499 if (qtrx->qt_rtblk_res != 0) {
500 if (qtrx->qt_blk_res != qtrx->qt_blk_res_used) {
501 if (qtrx->qt_rtblk_res >
502 qtrx->qt_rtblk_res_used)
503 dqp->q_res_rtbcount -= (xfs_qcnt_t)
504 (qtrx->qt_rtblk_res -
505 qtrx->qt_rtblk_res_used);
506 else
507 dqp->q_res_rtbcount -= (xfs_qcnt_t)
508 (qtrx->qt_rtblk_res_used -
509 qtrx->qt_rtblk_res);
510 }
511 } else {
512 if (qtrx->qt_rtbcount_delta)
513 dqp->q_res_rtbcount +=
514 (xfs_qcnt_t)qtrx->qt_rtbcount_delta;
515 }
516
517 /*
518 * Adjust the inode reservation.
519 */
520 if (qtrx->qt_ino_res != 0) {
521 ASSERT(qtrx->qt_ino_res >=
522 qtrx->qt_ino_res_used);
523 if (qtrx->qt_ino_res > qtrx->qt_ino_res_used)
524 dqp->q_res_icount -= (xfs_qcnt_t)
525 (qtrx->qt_ino_res -
526 qtrx->qt_ino_res_used);
527 } else {
528 if (qtrx->qt_icount_delta)
529 dqp->q_res_icount +=
530 (xfs_qcnt_t)qtrx->qt_icount_delta;
531 }
532
533
534#ifdef QUOTADEBUG
535 if (qtrx->qt_rtblk_res != 0)
536 cmn_err(CE_DEBUG, "RT res %d for 0x%p\n",
537 (int) qtrx->qt_rtblk_res, dqp);
538#endif
539 ASSERT(dqp->q_res_bcount >=
540 INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
541 ASSERT(dqp->q_res_icount >=
542 INT_GET(dqp->q_core.d_icount, ARCH_CONVERT));
543 ASSERT(dqp->q_res_rtbcount >=
544 INT_GET(dqp->q_core.d_rtbcount, ARCH_CONVERT));
545 }
546 /*
547 * Do the group quotas next
548 */
549 qa = tp->t_dqinfo->dqa_grpdquots;
550 }
551}
552
553/*
554 * Release the reservations, and adjust the dquots accordingly.
555 * This is called only when the transaction is being aborted. If by
556 * any chance we have done dquot modifications incore (ie. deltas) already,
557 * we simply throw those away, since that's the expected behavior
558 * when a transaction is curtailed without a commit.
559 */
560STATIC void
561xfs_trans_unreserve_and_mod_dquots(
562 xfs_trans_t *tp)
563{
564 int i, j;
565 xfs_dquot_t *dqp;
566 xfs_dqtrx_t *qtrx, *qa;
567 boolean_t locked;
568
569 if (!tp->t_dqinfo || !(tp->t_flags & XFS_TRANS_DQ_DIRTY))
570 return;
571
572 qa = tp->t_dqinfo->dqa_usrdquots;
573
574 for (j = 0; j < 2; j++) {
575 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
576 qtrx = &qa[i];
577 /*
578 * We assume that the array of dquots is filled
579 * sequentially, not sparsely.
580 */
581 if ((dqp = qtrx->qt_dquot) == NULL)
582 break;
583 /*
584 * Unreserve the original reservation. We don't care
585 * about the number of blocks used field, or deltas.
586 * Also we don't bother to zero the fields.
587 */
588 locked = B_FALSE;
589 if (qtrx->qt_blk_res) {
590 xfs_dqlock(dqp);
591 locked = B_TRUE;
592 dqp->q_res_bcount -=
593 (xfs_qcnt_t)qtrx->qt_blk_res;
594 }
595 if (qtrx->qt_ino_res) {
596 if (!locked) {
597 xfs_dqlock(dqp);
598 locked = B_TRUE;
599 }
600 dqp->q_res_icount -=
601 (xfs_qcnt_t)qtrx->qt_ino_res;
602 }
603
604 if (qtrx->qt_rtblk_res) {
605 if (!locked) {
606 xfs_dqlock(dqp);
607 locked = B_TRUE;
608 }
609 dqp->q_res_rtbcount -=
610 (xfs_qcnt_t)qtrx->qt_rtblk_res;
611 }
612 if (locked)
613 xfs_dqunlock(dqp);
614
615 }
616 qa = tp->t_dqinfo->dqa_grpdquots;
617 }
618}
619
620/*
621 * This reserves disk blocks and inodes against a dquot.
622 * Flags indicate if the dquot is to be locked here and also
623 * if the blk reservation is for RT or regular blocks.
624 * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check.
625 * Returns EDQUOT if quota is exceeded.
626 */
627STATIC int
628xfs_trans_dqresv(
629 xfs_trans_t *tp,
630 xfs_mount_t *mp,
631 xfs_dquot_t *dqp,
632 long nblks,
633 long ninos,
634 uint flags)
635{
636 int error;
637 xfs_qcnt_t hardlimit;
638 xfs_qcnt_t softlimit;
639 time_t btimer;
640 xfs_qcnt_t *resbcountp;
641 xfs_quotainfo_t *q = mp->m_quotainfo;
642
643 if (! (flags & XFS_QMOPT_DQLOCK)) {
644 xfs_dqlock(dqp);
645 }
646 ASSERT(XFS_DQ_IS_LOCKED(dqp));
647 if (flags & XFS_TRANS_DQ_RES_BLKS) {
648 hardlimit = INT_GET(dqp->q_core.d_blk_hardlimit, ARCH_CONVERT);
649 if (!hardlimit)
650 hardlimit = q->qi_bhardlimit;
651 softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT);
652 if (!softlimit)
653 softlimit = q->qi_bsoftlimit;
654 btimer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
655 resbcountp = &dqp->q_res_bcount;
656 } else {
657 ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
658 hardlimit = INT_GET(dqp->q_core.d_rtb_hardlimit, ARCH_CONVERT);
659 if (!hardlimit)
660 hardlimit = q->qi_rtbhardlimit;
661 softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT);
662 if (!softlimit)
663 softlimit = q->qi_rtbsoftlimit;
664 btimer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
665 resbcountp = &dqp->q_res_rtbcount;
666 }
667 error = 0;
668
669 if ((flags & XFS_QMOPT_FORCE_RES) == 0 &&
670 dqp->q_core.d_id &&
671 XFS_IS_QUOTA_ENFORCED(dqp->q_mount)) {
672#ifdef QUOTADEBUG
673 cmn_err(CE_DEBUG, "BLK Res: nblks=%ld + resbcount=%Ld"
674 " > hardlimit=%Ld?", nblks, *resbcountp, hardlimit);
675#endif
676 if (nblks > 0) {
677 /*
678 * dquot is locked already. See if we'd go over the
679 * hardlimit or exceed the timelimit if we allocate
680 * nblks.
681 */
682 if (hardlimit > 0ULL &&
683 (hardlimit <= nblks + *resbcountp)) {
684 error = EDQUOT;
685 goto error_return;
686 }
687
688 if (softlimit > 0ULL &&
689 (softlimit <= nblks + *resbcountp)) {
690 /*
691 * If timer or warnings has expired,
692 * return EDQUOT
693 */
694 if ((btimer != 0 && get_seconds() > btimer) ||
695 (dqp->q_core.d_bwarns &&
696 INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) >=
697 XFS_QI_BWARNLIMIT(dqp->q_mount))) {
698 error = EDQUOT;
699 goto error_return;
700 }
701 }
702 }
703 if (ninos > 0) {
704 hardlimit = INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT);
705 if (!hardlimit)
706 hardlimit = q->qi_ihardlimit;
707 softlimit = INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT);
708 if (!softlimit)
709 softlimit = q->qi_isoftlimit;
710 if (hardlimit > 0ULL &&
711 INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= hardlimit) {
712 error = EDQUOT;
713 goto error_return;
714 } else if (softlimit > 0ULL &&
715 INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >= softlimit) {
716 /*
717 * If timer or warnings has expired,
718 * return EDQUOT
719 */
720 if ((dqp->q_core.d_itimer &&
721 get_seconds() > INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT)) ||
722 (dqp->q_core.d_iwarns &&
723 INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) >=
724 XFS_QI_IWARNLIMIT(dqp->q_mount))) {
725 error = EDQUOT;
726 goto error_return;
727 }
728 }
729 }
730 }
731
732 /*
733 * Change the reservation, but not the actual usage.
734 * Note that q_res_bcount = q_core.d_bcount + resv
735 */
736 (*resbcountp) += (xfs_qcnt_t)nblks;
737 if (ninos != 0)
738 dqp->q_res_icount += (xfs_qcnt_t)ninos;
739
740 /*
741 * note the reservation amt in the trans struct too,
742 * so that the transaction knows how much was reserved by
743 * it against this particular dquot.
744 * We don't do this when we are reserving for a delayed allocation,
745 * because we don't have the luxury of a transaction envelope then.
746 */
747 if (tp) {
748 ASSERT(tp->t_dqinfo);
749 ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
750 if (nblks != 0)
751 xfs_trans_mod_dquot(tp, dqp,
752 flags & XFS_QMOPT_RESBLK_MASK,
753 nblks);
754 if (ninos != 0)
755 xfs_trans_mod_dquot(tp, dqp,
756 XFS_TRANS_DQ_RES_INOS,
757 ninos);
758 }
759 ASSERT(dqp->q_res_bcount >= INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
760 ASSERT(dqp->q_res_rtbcount >= INT_GET(dqp->q_core.d_rtbcount, ARCH_CONVERT));
761 ASSERT(dqp->q_res_icount >= INT_GET(dqp->q_core.d_icount, ARCH_CONVERT));
762
763error_return:
764 if (! (flags & XFS_QMOPT_DQLOCK)) {
765 xfs_dqunlock(dqp);
766 }
767 return (error);
768}
769
770
771/*
772 * Given a dquot(s), make disk block and/or inode reservations against them.
773 * The fact that this does the reservation against both the usr and
774 * grp quotas is important, because this follows a both-or-nothing
775 * approach.
776 *
777 * flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked.
778 * XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
779 * XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
780 * XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
781 * dquots are unlocked on return, if they were not locked by caller.
782 */
783int
784xfs_trans_reserve_quota_bydquots(
785 xfs_trans_t *tp,
786 xfs_mount_t *mp,
787 xfs_dquot_t *udqp,
788 xfs_dquot_t *gdqp,
789 long nblks,
790 long ninos,
791 uint flags)
792{
793 int resvd;
794
795 if (! XFS_IS_QUOTA_ON(mp))
796 return (0);
797
798 if (tp && tp->t_dqinfo == NULL)
799 xfs_trans_alloc_dqinfo(tp);
800
801 ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
802 resvd = 0;
803
804 if (udqp) {
805 if (xfs_trans_dqresv(tp, mp, udqp, nblks, ninos, flags))
806 return (EDQUOT);
807 resvd = 1;
808 }
809
810 if (gdqp) {
811 if (xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags)) {
812 /*
813 * can't do it, so backout previous reservation
814 */
815 if (resvd) {
816 flags |= XFS_QMOPT_FORCE_RES;
817 xfs_trans_dqresv(tp, mp, udqp,
818 -nblks, -ninos, flags);
819 }
820 return (EDQUOT);
821 }
822 }
823
824 /*
825 * Didnt change anything critical, so, no need to log
826 */
827 return (0);
828}
829
830
831/*
832 * Lock the dquot and change the reservation if we can.
833 * This doesn't change the actual usage, just the reservation.
834 * The inode sent in is locked.
835 *
836 * Returns 0 on success, EDQUOT or other errors otherwise
837 */
838STATIC int
839xfs_trans_reserve_quota_nblks(
840 xfs_trans_t *tp,
841 xfs_mount_t *mp,
842 xfs_inode_t *ip,
843 long nblks,
844 long ninos,
845 uint type)
846{
847 int error;
848
849 if (!XFS_IS_QUOTA_ON(mp))
850 return (0);
851
852 ASSERT(ip->i_ino != mp->m_sb.sb_uquotino);
853 ASSERT(ip->i_ino != mp->m_sb.sb_gquotino);
854
855 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
856 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));
857 ASSERT((type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_RTBLKS ||
858 (type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_BLKS);
859
860 /*
861 * Reserve nblks against these dquots, with trans as the mediator.
862 */
863 error = xfs_trans_reserve_quota_bydquots(tp, mp,
864 ip->i_udquot, ip->i_gdquot,
865 nblks, ninos,
866 type);
867 return (error);
868}
869
870/*
871 * This routine is called to allocate a quotaoff log item.
872 */
873xfs_qoff_logitem_t *
874xfs_trans_get_qoff_item(
875 xfs_trans_t *tp,
876 xfs_qoff_logitem_t *startqoff,
877 uint flags)
878{
879 xfs_qoff_logitem_t *q;
880
881 ASSERT(tp != NULL);
882
883 q = xfs_qm_qoff_logitem_init(tp->t_mountp, startqoff, flags);
884 ASSERT(q != NULL);
885
886 /*
887 * Get a log_item_desc to point at the new item.
888 */
889 (void) xfs_trans_add_item(tp, (xfs_log_item_t*)q);
890
891 return (q);
892}
893
894
895/*
896 * This is called to mark the quotaoff logitem as needing
897 * to be logged when the transaction is committed. The logitem must
898 * already be associated with the given transaction.
899 */
900void
901xfs_trans_log_quotaoff_item(
902 xfs_trans_t *tp,
903 xfs_qoff_logitem_t *qlp)
904{
905 xfs_log_item_desc_t *lidp;
906
907 lidp = xfs_trans_find_item(tp, (xfs_log_item_t *)qlp);
908 ASSERT(lidp != NULL);
909
910 tp->t_flags |= XFS_TRANS_DIRTY;
911 lidp->lid_flags |= XFS_LID_DIRTY;
912}
913
914STATIC void
915xfs_trans_alloc_dqinfo(
916 xfs_trans_t *tp)
917{
918 (tp)->t_dqinfo = kmem_zone_zalloc(xfs_Gqm->qm_dqtrxzone, KM_SLEEP);
919}
920
921STATIC void
922xfs_trans_free_dqinfo(
923 xfs_trans_t *tp)
924{
925 if (!tp->t_dqinfo)
926 return;
927 kmem_zone_free(xfs_Gqm->qm_dqtrxzone, (tp)->t_dqinfo);
928 (tp)->t_dqinfo = NULL;
929}
930
931xfs_dqtrxops_t xfs_trans_dquot_ops = {
932 .qo_dup_dqinfo = xfs_trans_dup_dqinfo,
933 .qo_free_dqinfo = xfs_trans_free_dqinfo,
934 .qo_mod_dquot_byino = xfs_trans_mod_dquot_byino,
935 .qo_apply_dquot_deltas = xfs_trans_apply_dquot_deltas,
936 .qo_reserve_quota_nblks = xfs_trans_reserve_quota_nblks,
937 .qo_reserve_quota_bydquots = xfs_trans_reserve_quota_bydquots,
938 .qo_unreserve_and_mod_dquots = xfs_trans_unreserve_and_mod_dquots,
939};