ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / fs / xfs / quota / xfs_trans_dquot.c
1 /*
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
71 STATIC 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  */
78 void
79 xfs_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  */
113 void
114 xfs_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  */
134 STATIC void
135 xfs_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  */
190 void
191 xfs_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
210         if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot) {
211                 (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta);
212         }
213         if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot) {
214                 (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
215         }
216 }
217
218 STATIC xfs_dqtrx_t *
219 xfs_trans_get_dqtrx(
220         xfs_trans_t     *tp,
221         xfs_dquot_t     *dqp)
222 {
223         int             i;
224         xfs_dqtrx_t     *qa;
225
226         for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
227                 qa = XFS_QM_DQP_TO_DQACCT(tp, dqp);
228
229                 if (qa[i].qt_dquot == NULL ||
230                     qa[i].qt_dquot == dqp) {
231                         return (&qa[i]);
232                 }
233         }
234
235         return (NULL);
236 }
237
238 /*
239  * Make the changes in the transaction structure.
240  * The moral equivalent to xfs_trans_mod_sb().
241  * We don't touch any fields in the dquot, so we don't care
242  * if it's locked or not (most of the time it won't be).
243  */
244 void
245 xfs_trans_mod_dquot(
246         xfs_trans_t     *tp,
247         xfs_dquot_t     *dqp,
248         uint            field,
249         long            delta)
250 {
251         xfs_dqtrx_t     *qtrx;
252
253         ASSERT(tp);
254         qtrx = NULL;
255
256         if (tp->t_dqinfo == NULL)
257                 xfs_trans_alloc_dqinfo(tp);
258         /*
259          * Find either the first free slot or the slot that belongs
260          * to this dquot.
261          */
262         qtrx = xfs_trans_get_dqtrx(tp, dqp);
263         ASSERT(qtrx);
264         if (qtrx->qt_dquot == NULL)
265                 qtrx->qt_dquot = dqp;
266
267         switch (field) {
268
269                 /*
270                  * regular disk blk reservation
271                  */
272               case XFS_TRANS_DQ_RES_BLKS:
273                 qtrx->qt_blk_res += (ulong)delta;
274                 break;
275
276                 /*
277                  * inode reservation
278                  */
279               case XFS_TRANS_DQ_RES_INOS:
280                 qtrx->qt_ino_res += (ulong)delta;
281                 break;
282
283                 /*
284                  * disk blocks used.
285                  */
286               case XFS_TRANS_DQ_BCOUNT:
287                 if (qtrx->qt_blk_res && delta > 0) {
288                         qtrx->qt_blk_res_used += (ulong)delta;
289                         ASSERT(qtrx->qt_blk_res >= qtrx->qt_blk_res_used);
290                 }
291                 qtrx->qt_bcount_delta += delta;
292                 break;
293
294               case XFS_TRANS_DQ_DELBCOUNT:
295                 qtrx->qt_delbcnt_delta += delta;
296                 break;
297
298                 /*
299                  * Inode Count
300                  */
301               case XFS_TRANS_DQ_ICOUNT:
302                 if (qtrx->qt_ino_res && delta > 0) {
303                         qtrx->qt_ino_res_used += (ulong)delta;
304                         ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used);
305                 }
306                 qtrx->qt_icount_delta += delta;
307                 break;
308
309                 /*
310                  * rtblk reservation
311                  */
312               case XFS_TRANS_DQ_RES_RTBLKS:
313                 qtrx->qt_rtblk_res += (ulong)delta;
314                 break;
315
316                 /*
317                  * rtblk count
318                  */
319               case XFS_TRANS_DQ_RTBCOUNT:
320                 if (qtrx->qt_rtblk_res && delta > 0) {
321                         qtrx->qt_rtblk_res_used += (ulong)delta;
322                         ASSERT(qtrx->qt_rtblk_res >= qtrx->qt_rtblk_res_used);
323                 }
324                 qtrx->qt_rtbcount_delta += delta;
325                 break;
326
327               case XFS_TRANS_DQ_DELRTBCOUNT:
328                 qtrx->qt_delrtb_delta += delta;
329                 break;
330
331               default:
332                 ASSERT(0);
333         }
334         tp->t_flags |= XFS_TRANS_DQ_DIRTY;
335 }
336
337
338 /*
339  * Given an array of dqtrx structures, lock all the dquots associated
340  * and join them to the transaction, provided they have been modified.
341  * We know that the highest number of dquots (of one type - usr OR grp),
342  * involved in a transaction is 2 and that both usr and grp combined - 3.
343  * So, we don't attempt to make this very generic.
344  */
345 STATIC void
346 xfs_trans_dqlockedjoin(
347         xfs_trans_t     *tp,
348         xfs_dqtrx_t     *q)
349 {
350         ASSERT(q[0].qt_dquot != NULL);
351         if (q[1].qt_dquot == NULL) {
352                 xfs_dqlock(q[0].qt_dquot);
353                 xfs_trans_dqjoin(tp, q[0].qt_dquot);
354         } else {
355                 ASSERT(XFS_QM_TRANS_MAXDQS == 2);
356                 xfs_dqlock2(q[0].qt_dquot, q[1].qt_dquot);
357                 xfs_trans_dqjoin(tp, q[0].qt_dquot);
358                 xfs_trans_dqjoin(tp, q[1].qt_dquot);
359         }
360 }
361
362
363 /*
364  * Called by xfs_trans_commit() and similar in spirit to
365  * xfs_trans_apply_sb_deltas().
366  * Go thru all the dquots belonging to this transaction and modify the
367  * INCORE dquot to reflect the actual usages.
368  * Unreserve just the reservations done by this transaction.
369  * dquot is still left locked at exit.
370  */
371 void
372 xfs_trans_apply_dquot_deltas(
373         xfs_trans_t             *tp)
374 {
375         int                     i, j;
376         xfs_dquot_t             *dqp;
377         xfs_dqtrx_t             *qtrx, *qa;
378         xfs_disk_dquot_t        *d;
379         long                    totalbdelta;
380         long                    totalrtbdelta;
381
382         if (! (tp->t_flags & XFS_TRANS_DQ_DIRTY))
383                 return;
384
385         ASSERT(tp->t_dqinfo);
386         qa = tp->t_dqinfo->dqa_usrdquots;
387         for (j = 0; j < 2; j++) {
388                 if (qa[0].qt_dquot == NULL) {
389                         qa = tp->t_dqinfo->dqa_grpdquots;
390                         continue;
391                 }
392
393                 /*
394                  * Lock all of the dquots and join them to the transaction.
395                  */
396                 xfs_trans_dqlockedjoin(tp, qa);
397
398                 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
399                         qtrx = &qa[i];
400                         /*
401                          * The array of dquots is filled
402                          * sequentially, not sparsely.
403                          */
404                         if ((dqp = qtrx->qt_dquot) == NULL)
405                                 break;
406
407                         ASSERT(XFS_DQ_IS_LOCKED(dqp));
408                         ASSERT(XFS_DQ_IS_ADDEDTO_TRX(tp, dqp));
409
410                         /*
411                          * adjust the actual number of blocks used
412                          */
413                         d = &dqp->q_core;
414
415                         /*
416                          * The issue here is - sometimes we don't make a blkquota
417                          * reservation intentionally to be fair to users
418                          * (when the amount is small). On the other hand,
419                          * delayed allocs do make reservations, but that's
420                          * outside of a transaction, so we have no
421                          * idea how much was really reserved.
422                          * So, here we've accumulated delayed allocation blks and
423                          * non-delay blks. The assumption is that the
424                          * delayed ones are always reserved (outside of a
425                          * transaction), and the others may or may not have
426                          * quota reservations.
427                          */
428                         totalbdelta = qtrx->qt_bcount_delta +
429                                 qtrx->qt_delbcnt_delta;
430                         totalrtbdelta = qtrx->qt_rtbcount_delta +
431                                 qtrx->qt_delrtb_delta;
432 #ifdef QUOTADEBUG
433                         if (totalbdelta < 0)
434                                 ASSERT(INT_GET(d->d_bcount, ARCH_CONVERT) >=
435                                        (xfs_qcnt_t) -totalbdelta);
436
437                         if (totalrtbdelta < 0)
438                                 ASSERT(INT_GET(d->d_rtbcount, ARCH_CONVERT) >=
439                                        (xfs_qcnt_t) -totalrtbdelta);
440
441                         if (qtrx->qt_icount_delta < 0)
442                                 ASSERT(INT_GET(d->d_icount, ARCH_CONVERT) >=
443                                        (xfs_qcnt_t) -qtrx->qt_icount_delta);
444 #endif
445                         if (totalbdelta)
446                                 INT_MOD(d->d_bcount, ARCH_CONVERT, (xfs_qcnt_t)totalbdelta);
447
448                         if (qtrx->qt_icount_delta)
449                                 INT_MOD(d->d_icount, ARCH_CONVERT, (xfs_qcnt_t)qtrx->qt_icount_delta);
450
451                         if (totalrtbdelta)
452                                 INT_MOD(d->d_rtbcount, ARCH_CONVERT, (xfs_qcnt_t)totalrtbdelta);
453
454                         /*
455                          * Start/reset the timer(s) if needed.
456                          */
457                         xfs_qm_adjust_dqtimers(tp->t_mountp, d);
458
459                         dqp->dq_flags |= XFS_DQ_DIRTY;
460                         /*
461                          * add this to the list of items to get logged
462                          */
463                         xfs_trans_log_dquot(tp, dqp);
464                         /*
465                          * Take off what's left of the original reservation.
466                          * In case of delayed allocations, there's no
467                          * reservation that a transaction structure knows of.
468                          */
469                         if (qtrx->qt_blk_res != 0) {
470                                 if (qtrx->qt_blk_res != qtrx->qt_blk_res_used) {
471                                         if (qtrx->qt_blk_res >
472                                             qtrx->qt_blk_res_used)
473                                                 dqp->q_res_bcount -= (xfs_qcnt_t)
474                                                         (qtrx->qt_blk_res -
475                                                          qtrx->qt_blk_res_used);
476                                         else
477                                                 dqp->q_res_bcount -= (xfs_qcnt_t)
478                                                         (qtrx->qt_blk_res_used -
479                                                          qtrx->qt_blk_res);
480                                 }
481                         } else {
482                                 /*
483                                  * These blks were never reserved, either inside
484                                  * a transaction or outside one (in a delayed
485                                  * allocation). Also, this isn't always a
486                                  * negative number since we sometimes
487                                  * deliberately skip quota reservations.
488                                  */
489                                 if (qtrx->qt_bcount_delta) {
490                                         dqp->q_res_bcount +=
491                                               (xfs_qcnt_t)qtrx->qt_bcount_delta;
492                                 }
493                         }
494                         /*
495                          * Adjust the RT reservation.
496                          */
497                         if (qtrx->qt_rtblk_res != 0) {
498                                 if (qtrx->qt_blk_res != qtrx->qt_blk_res_used) {
499                                         if (qtrx->qt_rtblk_res >
500                                             qtrx->qt_rtblk_res_used)
501                                                dqp->q_res_rtbcount -= (xfs_qcnt_t)
502                                                        (qtrx->qt_rtblk_res -
503                                                         qtrx->qt_rtblk_res_used);
504                                         else
505                                                dqp->q_res_rtbcount -= (xfs_qcnt_t)
506                                                        (qtrx->qt_rtblk_res_used -
507                                                         qtrx->qt_rtblk_res);
508                                 }
509                         } else {
510                                 if (qtrx->qt_rtbcount_delta)
511                                         dqp->q_res_rtbcount +=
512                                             (xfs_qcnt_t)qtrx->qt_rtbcount_delta;
513                         }
514
515                         /*
516                          * Adjust the inode reservation.
517                          */
518                         if (qtrx->qt_ino_res != 0) {
519                                 ASSERT(qtrx->qt_ino_res >=
520                                        qtrx->qt_ino_res_used);
521                                 if (qtrx->qt_ino_res > qtrx->qt_ino_res_used)
522                                         dqp->q_res_icount -= (xfs_qcnt_t)
523                                                 (qtrx->qt_ino_res -
524                                                  qtrx->qt_ino_res_used);
525                         } else {
526                                 if (qtrx->qt_icount_delta)
527                                         dqp->q_res_icount +=
528                                             (xfs_qcnt_t)qtrx->qt_icount_delta;
529                         }
530
531
532 #ifdef QUOTADEBUG
533                         if (qtrx->qt_rtblk_res != 0)
534                                 cmn_err(CE_DEBUG, "RT res %d for 0x%p\n",
535                                         (int) qtrx->qt_rtblk_res, dqp);
536 #endif
537                         ASSERT(dqp->q_res_bcount >=
538                                 INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
539                         ASSERT(dqp->q_res_icount >=
540                                 INT_GET(dqp->q_core.d_icount, ARCH_CONVERT));
541                         ASSERT(dqp->q_res_rtbcount >=
542                                 INT_GET(dqp->q_core.d_rtbcount, ARCH_CONVERT));
543                 }
544                 /*
545                  * Do the group quotas next
546                  */
547                 qa = tp->t_dqinfo->dqa_grpdquots;
548         }
549 }
550
551 /*
552  * Release the reservations, and adjust the dquots accordingly.
553  * This is called only when the transaction is being aborted. If by
554  * any chance we have done dquot modifications incore (ie. deltas) already,
555  * we simply throw those away, since that's the expected behavior
556  * when a transaction is curtailed without a commit.
557  */
558 STATIC void
559 xfs_trans_unreserve_and_mod_dquots(
560         xfs_trans_t             *tp)
561 {
562         int                     i, j;
563         xfs_dquot_t             *dqp;
564         xfs_dqtrx_t             *qtrx, *qa;
565         boolean_t               locked;
566
567         if (!tp->t_dqinfo || !(tp->t_flags & XFS_TRANS_DQ_DIRTY))
568                 return;
569
570         qa = tp->t_dqinfo->dqa_usrdquots;
571
572         for (j = 0; j < 2; j++) {
573                 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
574                         qtrx = &qa[i];
575                         /*
576                          * We assume that the array of dquots is filled
577                          * sequentially, not sparsely.
578                          */
579                         if ((dqp = qtrx->qt_dquot) == NULL)
580                                 break;
581                         /*
582                          * Unreserve the original reservation. We don't care
583                          * about the number of blocks used field, or deltas.
584                          * Also we don't bother to zero the fields.
585                          */
586                         locked = B_FALSE;
587                         if (qtrx->qt_blk_res) {
588                                 xfs_dqlock(dqp);
589                                 locked = B_TRUE;
590                                 dqp->q_res_bcount -=
591                                         (xfs_qcnt_t)qtrx->qt_blk_res;
592                         }
593                         if (qtrx->qt_ino_res) {
594                                 if (!locked) {
595                                         xfs_dqlock(dqp);
596                                         locked = B_TRUE;
597                                 }
598                                 dqp->q_res_icount -=
599                                         (xfs_qcnt_t)qtrx->qt_ino_res;
600                         }
601
602                         if (qtrx->qt_rtblk_res) {
603                                 if (!locked) {
604                                         xfs_dqlock(dqp);
605                                         locked = B_TRUE;
606                                 }
607                                 dqp->q_res_rtbcount -=
608                                         (xfs_qcnt_t)qtrx->qt_rtblk_res;
609                         }
610                         if (locked)
611                                 xfs_dqunlock(dqp);
612
613                 }
614                 qa = tp->t_dqinfo->dqa_grpdquots;
615         }
616 }
617
618 /*
619  * This reserves disk blocks and inodes against a dquot.
620  * Flags indicate if the dquot is to be locked here and also
621  * if the blk reservation is for RT or regular blocks.
622  * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check.
623  * Returns EDQUOT if quota is exceeded.
624  */
625 STATIC int
626 xfs_trans_dqresv(
627         xfs_trans_t     *tp,
628         xfs_dquot_t     *dqp,
629         long            nblks,
630         long            ninos,
631         uint            flags)
632 {
633         int             error;
634         xfs_qcnt_t      hardlimit;
635         xfs_qcnt_t      softlimit;
636         time_t          btimer;
637         xfs_qcnt_t      *resbcountp;
638
639         if (! (flags & XFS_QMOPT_DQLOCK)) {
640                 xfs_dqlock(dqp);
641         }
642         ASSERT(XFS_DQ_IS_LOCKED(dqp));
643         if (flags & XFS_TRANS_DQ_RES_BLKS) {
644                 hardlimit = INT_GET(dqp->q_core.d_blk_hardlimit, ARCH_CONVERT);
645                 softlimit = INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT);
646                 btimer = INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT);
647                 resbcountp = &dqp->q_res_bcount;
648         } else {
649                 ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
650                 hardlimit = INT_GET(dqp->q_core.d_rtb_hardlimit, ARCH_CONVERT);
651                 softlimit = INT_GET(dqp->q_core.d_rtb_softlimit, ARCH_CONVERT);
652                 btimer = INT_GET(dqp->q_core.d_rtbtimer, ARCH_CONVERT);
653                 resbcountp = &dqp->q_res_rtbcount;
654         }
655         error = 0;
656
657         if ((flags & XFS_QMOPT_FORCE_RES) == 0 &&
658             !INT_ISZERO(dqp->q_core.d_id, ARCH_CONVERT) &&
659             XFS_IS_QUOTA_ENFORCED(dqp->q_mount)) {
660 #ifdef QUOTADEBUG
661                 cmn_err(CE_DEBUG, "BLK Res: nblks=%ld + resbcount=%Ld"
662                           " > hardlimit=%Ld?", nblks, *resbcountp, hardlimit);
663 #endif
664                 if (nblks > 0) {
665                         /*
666                          * dquot is locked already. See if we'd go over the
667                          * hardlimit or exceed the timelimit if we allocate
668                          * nblks.
669                          */
670                         if (hardlimit > 0ULL &&
671                              (hardlimit <= nblks + *resbcountp)) {
672                                 error = EDQUOT;
673                                 goto error_return;
674                         }
675
676                         if (softlimit > 0ULL &&
677                              (softlimit <= nblks + *resbcountp)) {
678                                 /*
679                                  * If timer or warnings has expired,
680                                  * return EDQUOT
681                                  */
682                                 if ((btimer != 0 && get_seconds() > btimer) ||
683                                     (!INT_ISZERO(dqp->q_core.d_bwarns, ARCH_CONVERT) &&
684                                      INT_GET(dqp->q_core.d_bwarns, ARCH_CONVERT) >=
685                                      XFS_QI_BWARNLIMIT(dqp->q_mount))) {
686                                         error = EDQUOT;
687                                         goto error_return;
688                                 }
689                         }
690                 }
691                 if (ninos > 0) {
692                         if (INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT) > 0ULL &&
693                             INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >=
694                             INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT)) {
695                                 error = EDQUOT;
696                                 goto error_return;
697                         } else if (INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT) > 0ULL &&
698                                    INT_GET(dqp->q_core.d_icount, ARCH_CONVERT) >=
699                                    INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT)) {
700                                 /*
701                                  * If timer or warnings has expired,
702                                  * return EDQUOT
703                                  */
704                                 if ((!INT_ISZERO(dqp->q_core.d_itimer, ARCH_CONVERT) &&
705                                      get_seconds() > INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT)) ||
706                                     (!INT_ISZERO(dqp->q_core.d_iwarns, ARCH_CONVERT) &&
707                                      INT_GET(dqp->q_core.d_iwarns, ARCH_CONVERT) >=
708                                      XFS_QI_IWARNLIMIT(dqp->q_mount))) {
709                                         error = EDQUOT;
710                                         goto error_return;
711                                 }
712                         }
713                 }
714         }
715
716         /*
717          * Change the reservation, but not the actual usage.
718          * Note that q_res_bcount = q_core.d_bcount + resv
719          */
720         (*resbcountp) += (xfs_qcnt_t)nblks;
721         if (ninos != 0)
722                 dqp->q_res_icount += (xfs_qcnt_t)ninos;
723
724         /*
725          * note the reservation amt in the trans struct too,
726          * so that the transaction knows how much was reserved by
727          * it against this particular dquot.
728          * We don't do this when we are reserving for a delayed allocation,
729          * because we don't have the luxury of a transaction envelope then.
730          */
731         if (tp) {
732                 ASSERT(tp->t_dqinfo);
733                 ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
734                 if (nblks != 0)
735                         xfs_trans_mod_dquot(tp, dqp,
736                                             flags & XFS_QMOPT_RESBLK_MASK,
737                                             nblks);
738                 if (ninos != 0)
739                         xfs_trans_mod_dquot(tp, dqp,
740                                             XFS_TRANS_DQ_RES_INOS,
741                                             ninos);
742         }
743         ASSERT(dqp->q_res_bcount >= INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
744         ASSERT(dqp->q_res_rtbcount >= INT_GET(dqp->q_core.d_rtbcount, ARCH_CONVERT));
745         ASSERT(dqp->q_res_icount >= INT_GET(dqp->q_core.d_icount, ARCH_CONVERT));
746
747 error_return:
748         if (! (flags & XFS_QMOPT_DQLOCK)) {
749                 xfs_dqunlock(dqp);
750         }
751         return (error);
752 }
753
754
755 /*
756  * Given a dquot(s), make disk block and/or inode reservations against them.
757  * The fact that this does the reservation against both the usr and
758  * grp quotas is important, because this follows a both-or-nothing
759  * approach.
760  *
761  * flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked.
762  *         XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
763  *         XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
764  *         XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
765  * dquots are unlocked on return, if they were not locked by caller.
766  */
767 int
768 xfs_trans_reserve_quota_bydquots(
769         xfs_trans_t     *tp,
770         xfs_mount_t     *mp,
771         xfs_dquot_t     *udqp,
772         xfs_dquot_t     *gdqp,
773         long            nblks,
774         long            ninos,
775         uint            flags)
776 {
777         int             resvd;
778
779         if (! XFS_IS_QUOTA_ON(mp))
780                 return (0);
781
782         if (tp && tp->t_dqinfo == NULL)
783                 xfs_trans_alloc_dqinfo(tp);
784
785         ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
786         resvd = 0;
787
788         if (udqp) {
789                 if (xfs_trans_dqresv(tp, udqp, nblks, ninos, flags))
790                         return (EDQUOT);
791                 resvd = 1;
792         }
793
794         if (gdqp) {
795                 if (xfs_trans_dqresv(tp, gdqp, nblks, ninos, flags)) {
796                         /*
797                          * can't do it, so backout previous reservation
798                          */
799                         if (resvd) {
800                                 xfs_trans_dqresv(tp, udqp,  -nblks, -ninos,
801                                                  flags);
802                         }
803                         return (EDQUOT);
804                 }
805         }
806
807         /*
808          * Didnt change anything critical, so, no need to log
809          */
810         return (0);
811 }
812
813
814 /*
815  * Lock the dquot and change the reservation if we can.
816  * This doesn't change the actual usage, just the reservation.
817  * The inode sent in is locked.
818  *
819  * Returns 0 on success, EDQUOT or other errors otherwise
820  */
821 STATIC int
822 xfs_trans_reserve_quota_nblks(
823         xfs_trans_t     *tp,
824         xfs_mount_t     *mp,
825         xfs_inode_t     *ip,
826         long            nblks,
827         long            ninos,
828         uint            type)
829 {
830         int             error;
831
832         if (!XFS_IS_QUOTA_ON(mp))
833                 return (0);
834
835         ASSERT(ip->i_ino != mp->m_sb.sb_uquotino);
836         ASSERT(ip->i_ino != mp->m_sb.sb_gquotino);
837
838         ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
839         ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));
840         ASSERT((type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_RTBLKS ||
841                (type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_BLKS);
842
843         /*
844          * Reserve nblks against these dquots, with trans as the mediator.
845          */
846         error = xfs_trans_reserve_quota_bydquots(tp, mp,
847                                                  ip->i_udquot, ip->i_gdquot,
848                                                  nblks, ninos,
849                                                  type);
850         return (error);
851 }
852
853 /*
854  * This routine is called to allocate a quotaoff log item.
855  */
856 xfs_qoff_logitem_t *
857 xfs_trans_get_qoff_item(
858         xfs_trans_t             *tp,
859         xfs_qoff_logitem_t      *startqoff,
860         uint                    flags)
861 {
862         xfs_qoff_logitem_t      *q;
863
864         ASSERT(tp != NULL);
865
866         q = xfs_qm_qoff_logitem_init(tp->t_mountp, startqoff, flags);
867         ASSERT(q != NULL);
868
869         /*
870          * Get a log_item_desc to point at the new item.
871          */
872         (void) xfs_trans_add_item(tp, (xfs_log_item_t*)q);
873
874         return (q);
875 }
876
877
878 /*
879  * This is called to mark the quotaoff logitem as needing
880  * to be logged when the transaction is committed.  The logitem must
881  * already be associated with the given transaction.
882  */
883 void
884 xfs_trans_log_quotaoff_item(
885         xfs_trans_t             *tp,
886         xfs_qoff_logitem_t      *qlp)
887 {
888         xfs_log_item_desc_t     *lidp;
889
890         lidp = xfs_trans_find_item(tp, (xfs_log_item_t *)qlp);
891         ASSERT(lidp != NULL);
892
893         tp->t_flags |= XFS_TRANS_DIRTY;
894         lidp->lid_flags |= XFS_LID_DIRTY;
895 }
896
897 STATIC void
898 xfs_trans_alloc_dqinfo(
899         xfs_trans_t     *tp)
900 {
901         (tp)->t_dqinfo = kmem_zone_zalloc(xfs_Gqm->qm_dqtrxzone, KM_SLEEP);
902 }
903
904 STATIC void
905 xfs_trans_free_dqinfo(
906         xfs_trans_t     *tp)
907 {
908         if (!tp->t_dqinfo)
909                 return;
910         kmem_zone_free(xfs_Gqm->qm_dqtrxzone, (tp)->t_dqinfo);
911         (tp)->t_dqinfo = NULL;
912 }
913
914 xfs_dqtrxops_t  xfs_trans_dquot_ops = {
915         .qo_dup_dqinfo                  = xfs_trans_dup_dqinfo,
916         .qo_free_dqinfo                 = xfs_trans_free_dqinfo,
917         .qo_mod_dquot_byino             = xfs_trans_mod_dquot_byino,
918         .qo_apply_dquot_deltas          = xfs_trans_apply_dquot_deltas,
919         .qo_reserve_quota_nblks         = xfs_trans_reserve_quota_nblks,
920         .qo_reserve_quota_bydquots      = xfs_trans_reserve_quota_bydquots,
921         .qo_unreserve_and_mod_dquots    = xfs_trans_unreserve_and_mod_dquots,
922 };