1
2
3
4
5
6
7#include "xfs.h"
8#include "xfs_fs.h"
9#include "xfs_shared.h"
10#include "xfs_format.h"
11#include "xfs_log_format.h"
12#include "xfs_trans_resv.h"
13#include "xfs_mount.h"
14#include "xfs_extent_busy.h"
15#include "xfs_quota.h"
16#include "xfs_trans.h"
17#include "xfs_trans_priv.h"
18#include "xfs_log.h"
19#include "xfs_log_priv.h"
20#include "xfs_trace.h"
21#include "xfs_error.h"
22#include "xfs_defer.h"
23#include "xfs_inode.h"
24#include "xfs_dquot_item.h"
25#include "xfs_dquot.h"
26#include "xfs_icache.h"
27
28kmem_zone_t *xfs_trans_zone;
29
30#if defined(CONFIG_TRACEPOINTS)
31static void
32xfs_trans_trace_reservations(
33 struct xfs_mount *mp)
34{
35 struct xfs_trans_res resv;
36 struct xfs_trans_res *res;
37 struct xfs_trans_res *end_res;
38 int i;
39
40 res = (struct xfs_trans_res *)M_RES(mp);
41 end_res = (struct xfs_trans_res *)(M_RES(mp) + 1);
42 for (i = 0; res < end_res; i++, res++)
43 trace_xfs_trans_resv_calc(mp, i, res);
44 xfs_log_get_max_trans_res(mp, &resv);
45 trace_xfs_trans_resv_calc(mp, -1, &resv);
46}
47#else
48# define xfs_trans_trace_reservations(mp)
49#endif
50
51
52
53
54
55void
56xfs_trans_init(
57 struct xfs_mount *mp)
58{
59 xfs_trans_resv_calc(mp, M_RES(mp));
60 xfs_trans_trace_reservations(mp);
61}
62
63
64
65
66
67STATIC void
68xfs_trans_free(
69 struct xfs_trans *tp)
70{
71 xfs_extent_busy_sort(&tp->t_busy);
72 xfs_extent_busy_clear(tp->t_mountp, &tp->t_busy, false);
73
74 trace_xfs_trans_free(tp, _RET_IP_);
75 xfs_trans_clear_context(tp);
76 if (!(tp->t_flags & XFS_TRANS_NO_WRITECOUNT))
77 sb_end_intwrite(tp->t_mountp->m_super);
78 xfs_trans_free_dqinfo(tp);
79 kmem_cache_free(xfs_trans_zone, tp);
80}
81
82
83
84
85
86
87
88
89
90STATIC struct xfs_trans *
91xfs_trans_dup(
92 struct xfs_trans *tp)
93{
94 struct xfs_trans *ntp;
95
96 trace_xfs_trans_dup(tp, _RET_IP_);
97
98 ntp = kmem_cache_zalloc(xfs_trans_zone, GFP_KERNEL | __GFP_NOFAIL);
99
100
101
102
103 ntp->t_magic = XFS_TRANS_HEADER_MAGIC;
104 ntp->t_mountp = tp->t_mountp;
105 INIT_LIST_HEAD(&ntp->t_items);
106 INIT_LIST_HEAD(&ntp->t_busy);
107 INIT_LIST_HEAD(&ntp->t_dfops);
108 ntp->t_firstblock = NULLFSBLOCK;
109
110 ASSERT(tp->t_flags & XFS_TRANS_PERM_LOG_RES);
111 ASSERT(tp->t_ticket != NULL);
112
113 ntp->t_flags = XFS_TRANS_PERM_LOG_RES |
114 (tp->t_flags & XFS_TRANS_RESERVE) |
115 (tp->t_flags & XFS_TRANS_NO_WRITECOUNT) |
116 (tp->t_flags & XFS_TRANS_RES_FDBLKS);
117
118 tp->t_flags |= XFS_TRANS_NO_WRITECOUNT;
119 ntp->t_ticket = xfs_log_ticket_get(tp->t_ticket);
120
121 ASSERT(tp->t_blk_res >= tp->t_blk_res_used);
122 ntp->t_blk_res = tp->t_blk_res - tp->t_blk_res_used;
123 tp->t_blk_res = tp->t_blk_res_used;
124
125 ntp->t_rtx_res = tp->t_rtx_res - tp->t_rtx_res_used;
126 tp->t_rtx_res = tp->t_rtx_res_used;
127
128 xfs_trans_switch_context(tp, ntp);
129
130
131 xfs_defer_move(ntp, tp);
132
133 xfs_trans_dup_dqinfo(tp, ntp);
134 return ntp;
135}
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151static int
152xfs_trans_reserve(
153 struct xfs_trans *tp,
154 struct xfs_trans_res *resp,
155 uint blocks,
156 uint rtextents)
157{
158 struct xfs_mount *mp = tp->t_mountp;
159 int error = 0;
160 bool rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
161
162
163
164
165
166
167 if (blocks > 0) {
168 error = xfs_mod_fdblocks(mp, -((int64_t)blocks), rsvd);
169 if (error != 0)
170 return -ENOSPC;
171 tp->t_blk_res += blocks;
172 }
173
174
175
176
177 if (resp->tr_logres > 0) {
178 bool permanent = false;
179
180 ASSERT(tp->t_log_res == 0 ||
181 tp->t_log_res == resp->tr_logres);
182 ASSERT(tp->t_log_count == 0 ||
183 tp->t_log_count == resp->tr_logcount);
184
185 if (resp->tr_logflags & XFS_TRANS_PERM_LOG_RES) {
186 tp->t_flags |= XFS_TRANS_PERM_LOG_RES;
187 permanent = true;
188 } else {
189 ASSERT(tp->t_ticket == NULL);
190 ASSERT(!(tp->t_flags & XFS_TRANS_PERM_LOG_RES));
191 }
192
193 if (tp->t_ticket != NULL) {
194 ASSERT(resp->tr_logflags & XFS_TRANS_PERM_LOG_RES);
195 error = xfs_log_regrant(mp, tp->t_ticket);
196 } else {
197 error = xfs_log_reserve(mp,
198 resp->tr_logres,
199 resp->tr_logcount,
200 &tp->t_ticket, XFS_TRANSACTION,
201 permanent);
202 }
203
204 if (error)
205 goto undo_blocks;
206
207 tp->t_log_res = resp->tr_logres;
208 tp->t_log_count = resp->tr_logcount;
209 }
210
211
212
213
214
215
216 if (rtextents > 0) {
217 error = xfs_mod_frextents(mp, -((int64_t)rtextents));
218 if (error) {
219 error = -ENOSPC;
220 goto undo_log;
221 }
222 tp->t_rtx_res += rtextents;
223 }
224
225 return 0;
226
227
228
229
230
231undo_log:
232 if (resp->tr_logres > 0) {
233 xfs_log_ticket_ungrant(mp->m_log, tp->t_ticket);
234 tp->t_ticket = NULL;
235 tp->t_log_res = 0;
236 tp->t_flags &= ~XFS_TRANS_PERM_LOG_RES;
237 }
238
239undo_blocks:
240 if (blocks > 0) {
241 xfs_mod_fdblocks(mp, (int64_t)blocks, rsvd);
242 tp->t_blk_res = 0;
243 }
244 return error;
245}
246
247int
248xfs_trans_alloc(
249 struct xfs_mount *mp,
250 struct xfs_trans_res *resp,
251 uint blocks,
252 uint rtextents,
253 uint flags,
254 struct xfs_trans **tpp)
255{
256 struct xfs_trans *tp;
257 bool want_retry = true;
258 int error;
259
260
261
262
263
264
265retry:
266 tp = kmem_cache_zalloc(xfs_trans_zone, GFP_KERNEL | __GFP_NOFAIL);
267 if (!(flags & XFS_TRANS_NO_WRITECOUNT))
268 sb_start_intwrite(mp->m_super);
269 xfs_trans_set_context(tp);
270
271
272
273
274
275 WARN_ON(resp->tr_logres > 0 &&
276 mp->m_super->s_writers.frozen == SB_FREEZE_COMPLETE);
277 ASSERT(!(flags & XFS_TRANS_RES_FDBLKS) ||
278 xfs_has_lazysbcount(mp));
279
280 tp->t_magic = XFS_TRANS_HEADER_MAGIC;
281 tp->t_flags = flags;
282 tp->t_mountp = mp;
283 INIT_LIST_HEAD(&tp->t_items);
284 INIT_LIST_HEAD(&tp->t_busy);
285 INIT_LIST_HEAD(&tp->t_dfops);
286 tp->t_firstblock = NULLFSBLOCK;
287
288 error = xfs_trans_reserve(tp, resp, blocks, rtextents);
289 if (error == -ENOSPC && want_retry) {
290 xfs_trans_cancel(tp);
291
292
293
294
295
296
297
298 xfs_blockgc_flush_all(mp);
299 want_retry = false;
300 goto retry;
301 }
302 if (error) {
303 xfs_trans_cancel(tp);
304 return error;
305 }
306
307 trace_xfs_trans_alloc(tp, _RET_IP_);
308
309 *tpp = tp;
310 return 0;
311}
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329int
330xfs_trans_alloc_empty(
331 struct xfs_mount *mp,
332 struct xfs_trans **tpp)
333{
334 struct xfs_trans_res resv = {0};
335
336 return xfs_trans_alloc(mp, &resv, 0, 0, XFS_TRANS_NO_WRITECOUNT, tpp);
337}
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355void
356xfs_trans_mod_sb(
357 xfs_trans_t *tp,
358 uint field,
359 int64_t delta)
360{
361 uint32_t flags = (XFS_TRANS_DIRTY|XFS_TRANS_SB_DIRTY);
362 xfs_mount_t *mp = tp->t_mountp;
363
364 switch (field) {
365 case XFS_TRANS_SB_ICOUNT:
366 tp->t_icount_delta += delta;
367 if (xfs_has_lazysbcount(mp))
368 flags &= ~XFS_TRANS_SB_DIRTY;
369 break;
370 case XFS_TRANS_SB_IFREE:
371 tp->t_ifree_delta += delta;
372 if (xfs_has_lazysbcount(mp))
373 flags &= ~XFS_TRANS_SB_DIRTY;
374 break;
375 case XFS_TRANS_SB_FDBLOCKS:
376
377
378
379
380
381 if (delta < 0) {
382 tp->t_blk_res_used += (uint)-delta;
383 if (tp->t_blk_res_used > tp->t_blk_res)
384 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
385 } else if (delta > 0 && (tp->t_flags & XFS_TRANS_RES_FDBLKS)) {
386 int64_t blkres_delta;
387
388
389
390
391
392
393
394
395 blkres_delta = min_t(int64_t, delta,
396 UINT_MAX - tp->t_blk_res);
397 tp->t_blk_res += blkres_delta;
398 delta -= blkres_delta;
399 }
400 tp->t_fdblocks_delta += delta;
401 if (xfs_has_lazysbcount(mp))
402 flags &= ~XFS_TRANS_SB_DIRTY;
403 break;
404 case XFS_TRANS_SB_RES_FDBLOCKS:
405
406
407
408
409
410 tp->t_res_fdblocks_delta += delta;
411 if (xfs_has_lazysbcount(mp))
412 flags &= ~XFS_TRANS_SB_DIRTY;
413 break;
414 case XFS_TRANS_SB_FREXTENTS:
415
416
417
418
419
420 if (delta < 0) {
421 tp->t_rtx_res_used += (uint)-delta;
422 ASSERT(tp->t_rtx_res_used <= tp->t_rtx_res);
423 }
424 tp->t_frextents_delta += delta;
425 break;
426 case XFS_TRANS_SB_RES_FREXTENTS:
427
428
429
430
431
432 ASSERT(delta < 0);
433 tp->t_res_frextents_delta += delta;
434 break;
435 case XFS_TRANS_SB_DBLOCKS:
436 tp->t_dblocks_delta += delta;
437 break;
438 case XFS_TRANS_SB_AGCOUNT:
439 ASSERT(delta > 0);
440 tp->t_agcount_delta += delta;
441 break;
442 case XFS_TRANS_SB_IMAXPCT:
443 tp->t_imaxpct_delta += delta;
444 break;
445 case XFS_TRANS_SB_REXTSIZE:
446 tp->t_rextsize_delta += delta;
447 break;
448 case XFS_TRANS_SB_RBMBLOCKS:
449 tp->t_rbmblocks_delta += delta;
450 break;
451 case XFS_TRANS_SB_RBLOCKS:
452 tp->t_rblocks_delta += delta;
453 break;
454 case XFS_TRANS_SB_REXTENTS:
455 tp->t_rextents_delta += delta;
456 break;
457 case XFS_TRANS_SB_REXTSLOG:
458 tp->t_rextslog_delta += delta;
459 break;
460 default:
461 ASSERT(0);
462 return;
463 }
464
465 tp->t_flags |= flags;
466}
467
468
469
470
471
472
473
474
475
476STATIC void
477xfs_trans_apply_sb_deltas(
478 xfs_trans_t *tp)
479{
480 xfs_dsb_t *sbp;
481 struct xfs_buf *bp;
482 int whole = 0;
483
484 bp = xfs_trans_getsb(tp);
485 sbp = bp->b_addr;
486
487
488
489
490 if (!xfs_has_lazysbcount((tp->t_mountp))) {
491 if (tp->t_icount_delta)
492 be64_add_cpu(&sbp->sb_icount, tp->t_icount_delta);
493 if (tp->t_ifree_delta)
494 be64_add_cpu(&sbp->sb_ifree, tp->t_ifree_delta);
495 if (tp->t_fdblocks_delta)
496 be64_add_cpu(&sbp->sb_fdblocks, tp->t_fdblocks_delta);
497 if (tp->t_res_fdblocks_delta)
498 be64_add_cpu(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta);
499 }
500
501 if (tp->t_frextents_delta)
502 be64_add_cpu(&sbp->sb_frextents, tp->t_frextents_delta);
503 if (tp->t_res_frextents_delta)
504 be64_add_cpu(&sbp->sb_frextents, tp->t_res_frextents_delta);
505
506 if (tp->t_dblocks_delta) {
507 be64_add_cpu(&sbp->sb_dblocks, tp->t_dblocks_delta);
508 whole = 1;
509 }
510 if (tp->t_agcount_delta) {
511 be32_add_cpu(&sbp->sb_agcount, tp->t_agcount_delta);
512 whole = 1;
513 }
514 if (tp->t_imaxpct_delta) {
515 sbp->sb_imax_pct += tp->t_imaxpct_delta;
516 whole = 1;
517 }
518 if (tp->t_rextsize_delta) {
519 be32_add_cpu(&sbp->sb_rextsize, tp->t_rextsize_delta);
520 whole = 1;
521 }
522 if (tp->t_rbmblocks_delta) {
523 be32_add_cpu(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta);
524 whole = 1;
525 }
526 if (tp->t_rblocks_delta) {
527 be64_add_cpu(&sbp->sb_rblocks, tp->t_rblocks_delta);
528 whole = 1;
529 }
530 if (tp->t_rextents_delta) {
531 be64_add_cpu(&sbp->sb_rextents, tp->t_rextents_delta);
532 whole = 1;
533 }
534 if (tp->t_rextslog_delta) {
535 sbp->sb_rextslog += tp->t_rextslog_delta;
536 whole = 1;
537 }
538
539 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF);
540 if (whole)
541
542
543
544 xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_dsb_t) - 1);
545 else
546
547
548
549
550 xfs_trans_log_buf(tp, bp, offsetof(xfs_dsb_t, sb_icount),
551 offsetof(xfs_dsb_t, sb_frextents) +
552 sizeof(sbp->sb_frextents) - 1);
553}
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570#define XFS_ICOUNT_BATCH 128
571
572void
573xfs_trans_unreserve_and_mod_sb(
574 struct xfs_trans *tp)
575{
576 struct xfs_mount *mp = tp->t_mountp;
577 bool rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
578 int64_t blkdelta = 0;
579 int64_t rtxdelta = 0;
580 int64_t idelta = 0;
581 int64_t ifreedelta = 0;
582 int error;
583
584
585 if (tp->t_blk_res > 0)
586 blkdelta = tp->t_blk_res;
587 if ((tp->t_fdblocks_delta != 0) &&
588 (xfs_has_lazysbcount(mp) ||
589 (tp->t_flags & XFS_TRANS_SB_DIRTY)))
590 blkdelta += tp->t_fdblocks_delta;
591
592 if (tp->t_rtx_res > 0)
593 rtxdelta = tp->t_rtx_res;
594 if ((tp->t_frextents_delta != 0) &&
595 (tp->t_flags & XFS_TRANS_SB_DIRTY))
596 rtxdelta += tp->t_frextents_delta;
597
598 if (xfs_has_lazysbcount(mp) ||
599 (tp->t_flags & XFS_TRANS_SB_DIRTY)) {
600 idelta = tp->t_icount_delta;
601 ifreedelta = tp->t_ifree_delta;
602 }
603
604
605 if (blkdelta) {
606 error = xfs_mod_fdblocks(mp, blkdelta, rsvd);
607 ASSERT(!error);
608 }
609
610 if (idelta)
611 percpu_counter_add_batch(&mp->m_icount, idelta,
612 XFS_ICOUNT_BATCH);
613
614 if (ifreedelta)
615 percpu_counter_add(&mp->m_ifree, ifreedelta);
616
617 if (rtxdelta == 0 && !(tp->t_flags & XFS_TRANS_SB_DIRTY))
618 return;
619
620
621 spin_lock(&mp->m_sb_lock);
622 mp->m_sb.sb_fdblocks += tp->t_fdblocks_delta + tp->t_res_fdblocks_delta;
623 mp->m_sb.sb_icount += idelta;
624 mp->m_sb.sb_ifree += ifreedelta;
625 mp->m_sb.sb_frextents += rtxdelta;
626 mp->m_sb.sb_dblocks += tp->t_dblocks_delta;
627 mp->m_sb.sb_agcount += tp->t_agcount_delta;
628 mp->m_sb.sb_imax_pct += tp->t_imaxpct_delta;
629 mp->m_sb.sb_rextsize += tp->t_rextsize_delta;
630 mp->m_sb.sb_rbmblocks += tp->t_rbmblocks_delta;
631 mp->m_sb.sb_rblocks += tp->t_rblocks_delta;
632 mp->m_sb.sb_rextents += tp->t_rextents_delta;
633 mp->m_sb.sb_rextslog += tp->t_rextslog_delta;
634 spin_unlock(&mp->m_sb_lock);
635
636
637
638
639
640 ASSERT(mp->m_sb.sb_imax_pct >= 0);
641 ASSERT(mp->m_sb.sb_rextslog >= 0);
642 return;
643}
644
645
646void
647xfs_trans_add_item(
648 struct xfs_trans *tp,
649 struct xfs_log_item *lip)
650{
651 ASSERT(lip->li_mountp == tp->t_mountp);
652 ASSERT(lip->li_ailp == tp->t_mountp->m_ail);
653 ASSERT(list_empty(&lip->li_trans));
654 ASSERT(!test_bit(XFS_LI_DIRTY, &lip->li_flags));
655
656 list_add_tail(&lip->li_trans, &tp->t_items);
657 trace_xfs_trans_add_item(tp, _RET_IP_);
658}
659
660
661
662
663
664
665void
666xfs_trans_del_item(
667 struct xfs_log_item *lip)
668{
669 clear_bit(XFS_LI_DIRTY, &lip->li_flags);
670 list_del_init(&lip->li_trans);
671}
672
673
674static void
675xfs_trans_free_items(
676 struct xfs_trans *tp,
677 bool abort)
678{
679 struct xfs_log_item *lip, *next;
680
681 trace_xfs_trans_free_items(tp, _RET_IP_);
682
683 list_for_each_entry_safe(lip, next, &tp->t_items, li_trans) {
684 xfs_trans_del_item(lip);
685 if (abort)
686 set_bit(XFS_LI_ABORTED, &lip->li_flags);
687 if (lip->li_ops->iop_release)
688 lip->li_ops->iop_release(lip);
689 }
690}
691
692static inline void
693xfs_log_item_batch_insert(
694 struct xfs_ail *ailp,
695 struct xfs_ail_cursor *cur,
696 struct xfs_log_item **log_items,
697 int nr_items,
698 xfs_lsn_t commit_lsn)
699{
700 int i;
701
702 spin_lock(&ailp->ail_lock);
703
704 xfs_trans_ail_update_bulk(ailp, cur, log_items, nr_items, commit_lsn);
705
706 for (i = 0; i < nr_items; i++) {
707 struct xfs_log_item *lip = log_items[i];
708
709 if (lip->li_ops->iop_unpin)
710 lip->li_ops->iop_unpin(lip, 0);
711 }
712}
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734void
735xfs_trans_committed_bulk(
736 struct xfs_ail *ailp,
737 struct xfs_log_vec *log_vector,
738 xfs_lsn_t commit_lsn,
739 bool aborted)
740{
741#define LOG_ITEM_BATCH_SIZE 32
742 struct xfs_log_item *log_items[LOG_ITEM_BATCH_SIZE];
743 struct xfs_log_vec *lv;
744 struct xfs_ail_cursor cur;
745 int i = 0;
746
747 spin_lock(&ailp->ail_lock);
748 xfs_trans_ail_cursor_last(ailp, &cur, commit_lsn);
749 spin_unlock(&ailp->ail_lock);
750
751
752 for (lv = log_vector; lv; lv = lv->lv_next ) {
753 struct xfs_log_item *lip = lv->lv_item;
754 xfs_lsn_t item_lsn;
755
756 if (aborted)
757 set_bit(XFS_LI_ABORTED, &lip->li_flags);
758
759 if (lip->li_ops->flags & XFS_ITEM_RELEASE_WHEN_COMMITTED) {
760 lip->li_ops->iop_release(lip);
761 continue;
762 }
763
764 if (lip->li_ops->iop_committed)
765 item_lsn = lip->li_ops->iop_committed(lip, commit_lsn);
766 else
767 item_lsn = commit_lsn;
768
769
770 if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0)
771 continue;
772
773
774
775
776
777 if (aborted) {
778 ASSERT(xfs_is_shutdown(ailp->ail_mount));
779 if (lip->li_ops->iop_unpin)
780 lip->li_ops->iop_unpin(lip, 1);
781 continue;
782 }
783
784 if (item_lsn != commit_lsn) {
785
786
787
788
789
790
791
792
793 spin_lock(&ailp->ail_lock);
794 if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0)
795 xfs_trans_ail_update(ailp, lip, item_lsn);
796 else
797 spin_unlock(&ailp->ail_lock);
798 if (lip->li_ops->iop_unpin)
799 lip->li_ops->iop_unpin(lip, 0);
800 continue;
801 }
802
803
804 log_items[i++] = lv->lv_item;
805 if (i >= LOG_ITEM_BATCH_SIZE) {
806 xfs_log_item_batch_insert(ailp, &cur, log_items,
807 LOG_ITEM_BATCH_SIZE, commit_lsn);
808 i = 0;
809 }
810 }
811
812
813 if (i)
814 xfs_log_item_batch_insert(ailp, &cur, log_items, i, commit_lsn);
815
816 spin_lock(&ailp->ail_lock);
817 xfs_trans_ail_cursor_done(&cur);
818 spin_unlock(&ailp->ail_lock);
819}
820
821
822
823
824
825
826
827
828
829
830
831
832
833static int
834__xfs_trans_commit(
835 struct xfs_trans *tp,
836 bool regrant)
837{
838 struct xfs_mount *mp = tp->t_mountp;
839 xfs_csn_t commit_seq = 0;
840 int error = 0;
841 int sync = tp->t_flags & XFS_TRANS_SYNC;
842
843 trace_xfs_trans_commit(tp, _RET_IP_);
844
845
846
847
848
849 WARN_ON_ONCE(!list_empty(&tp->t_dfops) &&
850 !(tp->t_flags & XFS_TRANS_PERM_LOG_RES));
851 if (!regrant && (tp->t_flags & XFS_TRANS_PERM_LOG_RES)) {
852 error = xfs_defer_finish_noroll(&tp);
853 if (error)
854 goto out_unreserve;
855 }
856
857
858
859
860
861
862
863
864 if (!(tp->t_flags & XFS_TRANS_DIRTY))
865 goto out_unreserve;
866
867 if (xfs_is_shutdown(mp)) {
868 error = -EIO;
869 goto out_unreserve;
870 }
871
872 ASSERT(tp->t_ticket != NULL);
873
874
875
876
877 if (tp->t_flags & XFS_TRANS_SB_DIRTY)
878 xfs_trans_apply_sb_deltas(tp);
879 xfs_trans_apply_dquot_deltas(tp);
880
881 xlog_cil_commit(mp->m_log, tp, &commit_seq, regrant);
882
883 xfs_trans_free(tp);
884
885
886
887
888
889 if (sync) {
890 error = xfs_log_force_seq(mp, commit_seq, XFS_LOG_SYNC, NULL);
891 XFS_STATS_INC(mp, xs_trans_sync);
892 } else {
893 XFS_STATS_INC(mp, xs_trans_async);
894 }
895
896 return error;
897
898out_unreserve:
899 xfs_trans_unreserve_and_mod_sb(tp);
900
901
902
903
904
905
906 xfs_trans_unreserve_and_mod_dquots(tp);
907 if (tp->t_ticket) {
908 if (regrant && !xlog_is_shutdown(mp->m_log))
909 xfs_log_ticket_regrant(mp->m_log, tp->t_ticket);
910 else
911 xfs_log_ticket_ungrant(mp->m_log, tp->t_ticket);
912 tp->t_ticket = NULL;
913 }
914 xfs_trans_free_items(tp, !!error);
915 xfs_trans_free(tp);
916
917 XFS_STATS_INC(mp, xs_trans_empty);
918 return error;
919}
920
921int
922xfs_trans_commit(
923 struct xfs_trans *tp)
924{
925 return __xfs_trans_commit(tp, false);
926}
927
928
929
930
931
932
933
934
935
936void
937xfs_trans_cancel(
938 struct xfs_trans *tp)
939{
940 struct xfs_mount *mp = tp->t_mountp;
941 bool dirty = (tp->t_flags & XFS_TRANS_DIRTY);
942
943 trace_xfs_trans_cancel(tp, _RET_IP_);
944
945 if (tp->t_flags & XFS_TRANS_PERM_LOG_RES)
946 xfs_defer_cancel(tp);
947
948
949
950
951
952
953 if (dirty && !xfs_is_shutdown(mp)) {
954 XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp);
955 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
956 }
957#ifdef DEBUG
958 if (!dirty && !xfs_is_shutdown(mp)) {
959 struct xfs_log_item *lip;
960
961 list_for_each_entry(lip, &tp->t_items, li_trans)
962 ASSERT(!xlog_item_is_intent_done(lip));
963 }
964#endif
965 xfs_trans_unreserve_and_mod_sb(tp);
966 xfs_trans_unreserve_and_mod_dquots(tp);
967
968 if (tp->t_ticket) {
969 xfs_log_ticket_ungrant(mp->m_log, tp->t_ticket);
970 tp->t_ticket = NULL;
971 }
972
973 xfs_trans_free_items(tp, dirty);
974 xfs_trans_free(tp);
975}
976
977
978
979
980
981
982
983
984int
985xfs_trans_roll(
986 struct xfs_trans **tpp)
987{
988 struct xfs_trans *trans = *tpp;
989 struct xfs_trans_res tres;
990 int error;
991
992 trace_xfs_trans_roll(trans, _RET_IP_);
993
994
995
996
997 tres.tr_logres = trans->t_log_res;
998 tres.tr_logcount = trans->t_log_count;
999
1000 *tpp = xfs_trans_dup(trans);
1001
1002
1003
1004
1005
1006
1007
1008
1009 error = __xfs_trans_commit(trans, true);
1010 if (error)
1011 return error;
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021 tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
1022 return xfs_trans_reserve(*tpp, &tres, 0, 0);
1023}
1024
1025
1026
1027
1028
1029
1030
1031
1032int
1033xfs_trans_alloc_inode(
1034 struct xfs_inode *ip,
1035 struct xfs_trans_res *resv,
1036 unsigned int dblocks,
1037 unsigned int rblocks,
1038 bool force,
1039 struct xfs_trans **tpp)
1040{
1041 struct xfs_trans *tp;
1042 struct xfs_mount *mp = ip->i_mount;
1043 bool retried = false;
1044 int error;
1045
1046retry:
1047 error = xfs_trans_alloc(mp, resv, dblocks,
1048 rblocks / mp->m_sb.sb_rextsize,
1049 force ? XFS_TRANS_RESERVE : 0, &tp);
1050 if (error)
1051 return error;
1052
1053 xfs_ilock(ip, XFS_ILOCK_EXCL);
1054 xfs_trans_ijoin(tp, ip, 0);
1055
1056 error = xfs_qm_dqattach_locked(ip, false);
1057 if (error) {
1058
1059 ASSERT(error != -ENOENT);
1060 goto out_cancel;
1061 }
1062
1063 error = xfs_trans_reserve_quota_nblks(tp, ip, dblocks, rblocks, force);
1064 if ((error == -EDQUOT || error == -ENOSPC) && !retried) {
1065 xfs_trans_cancel(tp);
1066 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1067 xfs_blockgc_free_quota(ip, 0);
1068 retried = true;
1069 goto retry;
1070 }
1071 if (error)
1072 goto out_cancel;
1073
1074 *tpp = tp;
1075 return 0;
1076
1077out_cancel:
1078 xfs_trans_cancel(tp);
1079 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1080 return error;
1081}
1082
1083
1084
1085
1086
1087int
1088xfs_trans_alloc_icreate(
1089 struct xfs_mount *mp,
1090 struct xfs_trans_res *resv,
1091 struct xfs_dquot *udqp,
1092 struct xfs_dquot *gdqp,
1093 struct xfs_dquot *pdqp,
1094 unsigned int dblocks,
1095 struct xfs_trans **tpp)
1096{
1097 struct xfs_trans *tp;
1098 bool retried = false;
1099 int error;
1100
1101retry:
1102 error = xfs_trans_alloc(mp, resv, dblocks, 0, 0, &tp);
1103 if (error)
1104 return error;
1105
1106 error = xfs_trans_reserve_quota_icreate(tp, udqp, gdqp, pdqp, dblocks);
1107 if ((error == -EDQUOT || error == -ENOSPC) && !retried) {
1108 xfs_trans_cancel(tp);
1109 xfs_blockgc_free_dquots(mp, udqp, gdqp, pdqp, 0);
1110 retried = true;
1111 goto retry;
1112 }
1113 if (error) {
1114 xfs_trans_cancel(tp);
1115 return error;
1116 }
1117
1118 *tpp = tp;
1119 return 0;
1120}
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131int
1132xfs_trans_alloc_ichange(
1133 struct xfs_inode *ip,
1134 struct xfs_dquot *new_udqp,
1135 struct xfs_dquot *new_gdqp,
1136 struct xfs_dquot *new_pdqp,
1137 bool force,
1138 struct xfs_trans **tpp)
1139{
1140 struct xfs_trans *tp;
1141 struct xfs_mount *mp = ip->i_mount;
1142 struct xfs_dquot *udqp;
1143 struct xfs_dquot *gdqp;
1144 struct xfs_dquot *pdqp;
1145 bool retried = false;
1146 int error;
1147
1148retry:
1149 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
1150 if (error)
1151 return error;
1152
1153 xfs_ilock(ip, XFS_ILOCK_EXCL);
1154 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
1155
1156 error = xfs_qm_dqattach_locked(ip, false);
1157 if (error) {
1158
1159 ASSERT(error != -ENOENT);
1160 goto out_cancel;
1161 }
1162
1163
1164
1165
1166
1167
1168
1169 udqp = (new_udqp != ip->i_udquot) ? new_udqp : NULL;
1170 gdqp = (new_gdqp != ip->i_gdquot) ? new_gdqp : NULL;
1171 pdqp = (new_pdqp != ip->i_pdquot) ? new_pdqp : NULL;
1172 if (udqp || gdqp || pdqp) {
1173 unsigned int qflags = XFS_QMOPT_RES_REGBLKS;
1174
1175 if (force)
1176 qflags |= XFS_QMOPT_FORCE_RES;
1177
1178
1179
1180
1181
1182
1183
1184 error = xfs_trans_reserve_quota_bydquots(tp, mp, udqp, gdqp,
1185 pdqp, ip->i_nblocks + ip->i_delayed_blks,
1186 1, qflags);
1187 if ((error == -EDQUOT || error == -ENOSPC) && !retried) {
1188 xfs_trans_cancel(tp);
1189 xfs_blockgc_free_dquots(mp, udqp, gdqp, pdqp, 0);
1190 retried = true;
1191 goto retry;
1192 }
1193 if (error)
1194 goto out_cancel;
1195 }
1196
1197 *tpp = tp;
1198 return 0;
1199
1200out_cancel:
1201 xfs_trans_cancel(tp);
1202 return error;
1203}
1204