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_log_priv.h"
13#include "xfs_trans_resv.h"
14#include "xfs_mount.h"
15#include "xfs_extent_busy.h"
16#include "xfs_quota.h"
17#include "xfs_trans.h"
18#include "xfs_trans_priv.h"
19#include "xfs_log.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_sb_version_haslazysbcount(&mp->m_sb));
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 error = xfs_blockgc_free_space(mp, NULL);
299 if (error)
300 return error;
301
302 want_retry = false;
303 goto retry;
304 }
305 if (error) {
306 xfs_trans_cancel(tp);
307 return error;
308 }
309
310 trace_xfs_trans_alloc(tp, _RET_IP_);
311
312 *tpp = tp;
313 return 0;
314}
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332int
333xfs_trans_alloc_empty(
334 struct xfs_mount *mp,
335 struct xfs_trans **tpp)
336{
337 struct xfs_trans_res resv = {0};
338
339 return xfs_trans_alloc(mp, &resv, 0, 0, XFS_TRANS_NO_WRITECOUNT, tpp);
340}
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358void
359xfs_trans_mod_sb(
360 xfs_trans_t *tp,
361 uint field,
362 int64_t delta)
363{
364 uint32_t flags = (XFS_TRANS_DIRTY|XFS_TRANS_SB_DIRTY);
365 xfs_mount_t *mp = tp->t_mountp;
366
367 switch (field) {
368 case XFS_TRANS_SB_ICOUNT:
369 tp->t_icount_delta += delta;
370 if (xfs_sb_version_haslazysbcount(&mp->m_sb))
371 flags &= ~XFS_TRANS_SB_DIRTY;
372 break;
373 case XFS_TRANS_SB_IFREE:
374 tp->t_ifree_delta += delta;
375 if (xfs_sb_version_haslazysbcount(&mp->m_sb))
376 flags &= ~XFS_TRANS_SB_DIRTY;
377 break;
378 case XFS_TRANS_SB_FDBLOCKS:
379
380
381
382
383
384 if (delta < 0) {
385 tp->t_blk_res_used += (uint)-delta;
386 if (tp->t_blk_res_used > tp->t_blk_res)
387 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
388 } else if (delta > 0 && (tp->t_flags & XFS_TRANS_RES_FDBLKS)) {
389 int64_t blkres_delta;
390
391
392
393
394
395
396
397
398 blkres_delta = min_t(int64_t, delta,
399 UINT_MAX - tp->t_blk_res);
400 tp->t_blk_res += blkres_delta;
401 delta -= blkres_delta;
402 }
403 tp->t_fdblocks_delta += delta;
404 if (xfs_sb_version_haslazysbcount(&mp->m_sb))
405 flags &= ~XFS_TRANS_SB_DIRTY;
406 break;
407 case XFS_TRANS_SB_RES_FDBLOCKS:
408
409
410
411
412
413 tp->t_res_fdblocks_delta += delta;
414 if (xfs_sb_version_haslazysbcount(&mp->m_sb))
415 flags &= ~XFS_TRANS_SB_DIRTY;
416 break;
417 case XFS_TRANS_SB_FREXTENTS:
418
419
420
421
422
423 if (delta < 0) {
424 tp->t_rtx_res_used += (uint)-delta;
425 ASSERT(tp->t_rtx_res_used <= tp->t_rtx_res);
426 }
427 tp->t_frextents_delta += delta;
428 break;
429 case XFS_TRANS_SB_RES_FREXTENTS:
430
431
432
433
434
435 ASSERT(delta < 0);
436 tp->t_res_frextents_delta += delta;
437 break;
438 case XFS_TRANS_SB_DBLOCKS:
439 tp->t_dblocks_delta += delta;
440 break;
441 case XFS_TRANS_SB_AGCOUNT:
442 ASSERT(delta > 0);
443 tp->t_agcount_delta += delta;
444 break;
445 case XFS_TRANS_SB_IMAXPCT:
446 tp->t_imaxpct_delta += delta;
447 break;
448 case XFS_TRANS_SB_REXTSIZE:
449 tp->t_rextsize_delta += delta;
450 break;
451 case XFS_TRANS_SB_RBMBLOCKS:
452 tp->t_rbmblocks_delta += delta;
453 break;
454 case XFS_TRANS_SB_RBLOCKS:
455 tp->t_rblocks_delta += delta;
456 break;
457 case XFS_TRANS_SB_REXTENTS:
458 tp->t_rextents_delta += delta;
459 break;
460 case XFS_TRANS_SB_REXTSLOG:
461 tp->t_rextslog_delta += delta;
462 break;
463 default:
464 ASSERT(0);
465 return;
466 }
467
468 tp->t_flags |= flags;
469}
470
471
472
473
474
475
476
477
478
479STATIC void
480xfs_trans_apply_sb_deltas(
481 xfs_trans_t *tp)
482{
483 xfs_dsb_t *sbp;
484 struct xfs_buf *bp;
485 int whole = 0;
486
487 bp = xfs_trans_getsb(tp);
488 sbp = bp->b_addr;
489
490
491
492
493 if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) {
494 if (tp->t_icount_delta)
495 be64_add_cpu(&sbp->sb_icount, tp->t_icount_delta);
496 if (tp->t_ifree_delta)
497 be64_add_cpu(&sbp->sb_ifree, tp->t_ifree_delta);
498 if (tp->t_fdblocks_delta)
499 be64_add_cpu(&sbp->sb_fdblocks, tp->t_fdblocks_delta);
500 if (tp->t_res_fdblocks_delta)
501 be64_add_cpu(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta);
502 }
503
504 if (tp->t_frextents_delta)
505 be64_add_cpu(&sbp->sb_frextents, tp->t_frextents_delta);
506 if (tp->t_res_frextents_delta)
507 be64_add_cpu(&sbp->sb_frextents, tp->t_res_frextents_delta);
508
509 if (tp->t_dblocks_delta) {
510 be64_add_cpu(&sbp->sb_dblocks, tp->t_dblocks_delta);
511 whole = 1;
512 }
513 if (tp->t_agcount_delta) {
514 be32_add_cpu(&sbp->sb_agcount, tp->t_agcount_delta);
515 whole = 1;
516 }
517 if (tp->t_imaxpct_delta) {
518 sbp->sb_imax_pct += tp->t_imaxpct_delta;
519 whole = 1;
520 }
521 if (tp->t_rextsize_delta) {
522 be32_add_cpu(&sbp->sb_rextsize, tp->t_rextsize_delta);
523 whole = 1;
524 }
525 if (tp->t_rbmblocks_delta) {
526 be32_add_cpu(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta);
527 whole = 1;
528 }
529 if (tp->t_rblocks_delta) {
530 be64_add_cpu(&sbp->sb_rblocks, tp->t_rblocks_delta);
531 whole = 1;
532 }
533 if (tp->t_rextents_delta) {
534 be64_add_cpu(&sbp->sb_rextents, tp->t_rextents_delta);
535 whole = 1;
536 }
537 if (tp->t_rextslog_delta) {
538 sbp->sb_rextslog += tp->t_rextslog_delta;
539 whole = 1;
540 }
541
542 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF);
543 if (whole)
544
545
546
547 xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_dsb_t) - 1);
548 else
549
550
551
552
553 xfs_trans_log_buf(tp, bp, offsetof(xfs_dsb_t, sb_icount),
554 offsetof(xfs_dsb_t, sb_frextents) +
555 sizeof(sbp->sb_frextents) - 1);
556}
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573#define XFS_ICOUNT_BATCH 128
574
575void
576xfs_trans_unreserve_and_mod_sb(
577 struct xfs_trans *tp)
578{
579 struct xfs_mount *mp = tp->t_mountp;
580 bool rsvd = (tp->t_flags & XFS_TRANS_RESERVE) != 0;
581 int64_t blkdelta = 0;
582 int64_t rtxdelta = 0;
583 int64_t idelta = 0;
584 int64_t ifreedelta = 0;
585 int error;
586
587
588 if (tp->t_blk_res > 0)
589 blkdelta = tp->t_blk_res;
590 if ((tp->t_fdblocks_delta != 0) &&
591 (xfs_sb_version_haslazysbcount(&mp->m_sb) ||
592 (tp->t_flags & XFS_TRANS_SB_DIRTY)))
593 blkdelta += tp->t_fdblocks_delta;
594
595 if (tp->t_rtx_res > 0)
596 rtxdelta = tp->t_rtx_res;
597 if ((tp->t_frextents_delta != 0) &&
598 (tp->t_flags & XFS_TRANS_SB_DIRTY))
599 rtxdelta += tp->t_frextents_delta;
600
601 if (xfs_sb_version_haslazysbcount(&mp->m_sb) ||
602 (tp->t_flags & XFS_TRANS_SB_DIRTY)) {
603 idelta = tp->t_icount_delta;
604 ifreedelta = tp->t_ifree_delta;
605 }
606
607
608 if (blkdelta) {
609 error = xfs_mod_fdblocks(mp, blkdelta, rsvd);
610 ASSERT(!error);
611 }
612
613 if (idelta)
614 percpu_counter_add_batch(&mp->m_icount, idelta,
615 XFS_ICOUNT_BATCH);
616
617 if (ifreedelta)
618 percpu_counter_add(&mp->m_ifree, ifreedelta);
619
620 if (rtxdelta == 0 && !(tp->t_flags & XFS_TRANS_SB_DIRTY))
621 return;
622
623
624 spin_lock(&mp->m_sb_lock);
625 mp->m_sb.sb_fdblocks += tp->t_fdblocks_delta + tp->t_res_fdblocks_delta;
626 mp->m_sb.sb_icount += idelta;
627 mp->m_sb.sb_ifree += ifreedelta;
628 mp->m_sb.sb_frextents += rtxdelta;
629 mp->m_sb.sb_dblocks += tp->t_dblocks_delta;
630 mp->m_sb.sb_agcount += tp->t_agcount_delta;
631 mp->m_sb.sb_imax_pct += tp->t_imaxpct_delta;
632 mp->m_sb.sb_rextsize += tp->t_rextsize_delta;
633 mp->m_sb.sb_rbmblocks += tp->t_rbmblocks_delta;
634 mp->m_sb.sb_rblocks += tp->t_rblocks_delta;
635 mp->m_sb.sb_rextents += tp->t_rextents_delta;
636 mp->m_sb.sb_rextslog += tp->t_rextslog_delta;
637 spin_unlock(&mp->m_sb_lock);
638
639
640
641
642
643 ASSERT(mp->m_sb.sb_imax_pct >= 0);
644 ASSERT(mp->m_sb.sb_rextslog >= 0);
645 return;
646}
647
648
649void
650xfs_trans_add_item(
651 struct xfs_trans *tp,
652 struct xfs_log_item *lip)
653{
654 ASSERT(lip->li_mountp == tp->t_mountp);
655 ASSERT(lip->li_ailp == tp->t_mountp->m_ail);
656 ASSERT(list_empty(&lip->li_trans));
657 ASSERT(!test_bit(XFS_LI_DIRTY, &lip->li_flags));
658
659 list_add_tail(&lip->li_trans, &tp->t_items);
660 trace_xfs_trans_add_item(tp, _RET_IP_);
661}
662
663
664
665
666
667
668void
669xfs_trans_del_item(
670 struct xfs_log_item *lip)
671{
672 clear_bit(XFS_LI_DIRTY, &lip->li_flags);
673 list_del_init(&lip->li_trans);
674}
675
676
677static void
678xfs_trans_free_items(
679 struct xfs_trans *tp,
680 bool abort)
681{
682 struct xfs_log_item *lip, *next;
683
684 trace_xfs_trans_free_items(tp, _RET_IP_);
685
686 list_for_each_entry_safe(lip, next, &tp->t_items, li_trans) {
687 xfs_trans_del_item(lip);
688 if (abort)
689 set_bit(XFS_LI_ABORTED, &lip->li_flags);
690 if (lip->li_ops->iop_release)
691 lip->li_ops->iop_release(lip);
692 }
693}
694
695static inline void
696xfs_log_item_batch_insert(
697 struct xfs_ail *ailp,
698 struct xfs_ail_cursor *cur,
699 struct xfs_log_item **log_items,
700 int nr_items,
701 xfs_lsn_t commit_lsn)
702{
703 int i;
704
705 spin_lock(&ailp->ail_lock);
706
707 xfs_trans_ail_update_bulk(ailp, cur, log_items, nr_items, commit_lsn);
708
709 for (i = 0; i < nr_items; i++) {
710 struct xfs_log_item *lip = log_items[i];
711
712 if (lip->li_ops->iop_unpin)
713 lip->li_ops->iop_unpin(lip, 0);
714 }
715}
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737void
738xfs_trans_committed_bulk(
739 struct xfs_ail *ailp,
740 struct xfs_log_vec *log_vector,
741 xfs_lsn_t commit_lsn,
742 bool aborted)
743{
744#define LOG_ITEM_BATCH_SIZE 32
745 struct xfs_log_item *log_items[LOG_ITEM_BATCH_SIZE];
746 struct xfs_log_vec *lv;
747 struct xfs_ail_cursor cur;
748 int i = 0;
749
750 spin_lock(&ailp->ail_lock);
751 xfs_trans_ail_cursor_last(ailp, &cur, commit_lsn);
752 spin_unlock(&ailp->ail_lock);
753
754
755 for (lv = log_vector; lv; lv = lv->lv_next ) {
756 struct xfs_log_item *lip = lv->lv_item;
757 xfs_lsn_t item_lsn;
758
759 if (aborted)
760 set_bit(XFS_LI_ABORTED, &lip->li_flags);
761
762 if (lip->li_ops->flags & XFS_ITEM_RELEASE_WHEN_COMMITTED) {
763 lip->li_ops->iop_release(lip);
764 continue;
765 }
766
767 if (lip->li_ops->iop_committed)
768 item_lsn = lip->li_ops->iop_committed(lip, commit_lsn);
769 else
770 item_lsn = commit_lsn;
771
772
773 if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0)
774 continue;
775
776
777
778
779
780 if (aborted) {
781 ASSERT(XFS_FORCED_SHUTDOWN(ailp->ail_mount));
782 if (lip->li_ops->iop_unpin)
783 lip->li_ops->iop_unpin(lip, 1);
784 continue;
785 }
786
787 if (item_lsn != commit_lsn) {
788
789
790
791
792
793
794
795
796 spin_lock(&ailp->ail_lock);
797 if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0)
798 xfs_trans_ail_update(ailp, lip, item_lsn);
799 else
800 spin_unlock(&ailp->ail_lock);
801 if (lip->li_ops->iop_unpin)
802 lip->li_ops->iop_unpin(lip, 0);
803 continue;
804 }
805
806
807 log_items[i++] = lv->lv_item;
808 if (i >= LOG_ITEM_BATCH_SIZE) {
809 xfs_log_item_batch_insert(ailp, &cur, log_items,
810 LOG_ITEM_BATCH_SIZE, commit_lsn);
811 i = 0;
812 }
813 }
814
815
816 if (i)
817 xfs_log_item_batch_insert(ailp, &cur, log_items, i, commit_lsn);
818
819 spin_lock(&ailp->ail_lock);
820 xfs_trans_ail_cursor_done(&cur);
821 spin_unlock(&ailp->ail_lock);
822}
823
824
825
826
827
828
829
830
831
832
833
834
835
836static int
837__xfs_trans_commit(
838 struct xfs_trans *tp,
839 bool regrant)
840{
841 struct xfs_mount *mp = tp->t_mountp;
842 xfs_lsn_t commit_lsn = -1;
843 int error = 0;
844 int sync = tp->t_flags & XFS_TRANS_SYNC;
845
846 trace_xfs_trans_commit(tp, _RET_IP_);
847
848
849
850
851
852 WARN_ON_ONCE(!list_empty(&tp->t_dfops) &&
853 !(tp->t_flags & XFS_TRANS_PERM_LOG_RES));
854 if (!regrant && (tp->t_flags & XFS_TRANS_PERM_LOG_RES)) {
855 error = xfs_defer_finish_noroll(&tp);
856 if (error)
857 goto out_unreserve;
858 }
859
860
861
862
863
864
865
866
867 if (!(tp->t_flags & XFS_TRANS_DIRTY))
868 goto out_unreserve;
869
870 if (XFS_FORCED_SHUTDOWN(mp)) {
871 error = -EIO;
872 goto out_unreserve;
873 }
874
875 ASSERT(tp->t_ticket != NULL);
876
877
878
879
880 if (tp->t_flags & XFS_TRANS_SB_DIRTY)
881 xfs_trans_apply_sb_deltas(tp);
882 xfs_trans_apply_dquot_deltas(tp);
883
884 xfs_log_commit_cil(mp, tp, &commit_lsn, regrant);
885
886 xfs_trans_free(tp);
887
888
889
890
891
892 if (sync) {
893 error = xfs_log_force_lsn(mp, commit_lsn, XFS_LOG_SYNC, NULL);
894 XFS_STATS_INC(mp, xs_trans_sync);
895 } else {
896 XFS_STATS_INC(mp, xs_trans_async);
897 }
898
899 return error;
900
901out_unreserve:
902 xfs_trans_unreserve_and_mod_sb(tp);
903
904
905
906
907
908
909 xfs_trans_unreserve_and_mod_dquots(tp);
910 if (tp->t_ticket) {
911 if (regrant && !XLOG_FORCED_SHUTDOWN(mp->m_log))
912 xfs_log_ticket_regrant(mp->m_log, tp->t_ticket);
913 else
914 xfs_log_ticket_ungrant(mp->m_log, tp->t_ticket);
915 tp->t_ticket = NULL;
916 }
917 xfs_trans_free_items(tp, !!error);
918 xfs_trans_free(tp);
919
920 XFS_STATS_INC(mp, xs_trans_empty);
921 return error;
922}
923
924int
925xfs_trans_commit(
926 struct xfs_trans *tp)
927{
928 return __xfs_trans_commit(tp, false);
929}
930
931
932
933
934
935
936
937
938
939void
940xfs_trans_cancel(
941 struct xfs_trans *tp)
942{
943 struct xfs_mount *mp = tp->t_mountp;
944 bool dirty = (tp->t_flags & XFS_TRANS_DIRTY);
945
946 trace_xfs_trans_cancel(tp, _RET_IP_);
947
948 if (tp->t_flags & XFS_TRANS_PERM_LOG_RES)
949 xfs_defer_cancel(tp);
950
951
952
953
954
955
956 if (dirty && !XFS_FORCED_SHUTDOWN(mp)) {
957 XFS_ERROR_REPORT("xfs_trans_cancel", XFS_ERRLEVEL_LOW, mp);
958 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
959 }
960#ifdef DEBUG
961 if (!dirty && !XFS_FORCED_SHUTDOWN(mp)) {
962 struct xfs_log_item *lip;
963
964 list_for_each_entry(lip, &tp->t_items, li_trans)
965 ASSERT(!xlog_item_is_intent_done(lip));
966 }
967#endif
968 xfs_trans_unreserve_and_mod_sb(tp);
969 xfs_trans_unreserve_and_mod_dquots(tp);
970
971 if (tp->t_ticket) {
972 xfs_log_ticket_ungrant(mp->m_log, tp->t_ticket);
973 tp->t_ticket = NULL;
974 }
975
976 xfs_trans_free_items(tp, dirty);
977 xfs_trans_free(tp);
978}
979
980
981
982
983
984
985
986
987int
988xfs_trans_roll(
989 struct xfs_trans **tpp)
990{
991 struct xfs_trans *trans = *tpp;
992 struct xfs_trans_res tres;
993 int error;
994
995 trace_xfs_trans_roll(trans, _RET_IP_);
996
997
998
999
1000 tres.tr_logres = trans->t_log_res;
1001 tres.tr_logcount = trans->t_log_count;
1002
1003 *tpp = xfs_trans_dup(trans);
1004
1005
1006
1007
1008
1009
1010
1011
1012 error = __xfs_trans_commit(trans, true);
1013 if (error)
1014 return error;
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024 tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
1025 return xfs_trans_reserve(*tpp, &tres, 0, 0);
1026}
1027
1028
1029
1030
1031
1032
1033
1034
1035int
1036xfs_trans_alloc_inode(
1037 struct xfs_inode *ip,
1038 struct xfs_trans_res *resv,
1039 unsigned int dblocks,
1040 unsigned int rblocks,
1041 bool force,
1042 struct xfs_trans **tpp)
1043{
1044 struct xfs_trans *tp;
1045 struct xfs_mount *mp = ip->i_mount;
1046 bool retried = false;
1047 int error;
1048
1049retry:
1050 error = xfs_trans_alloc(mp, resv, dblocks,
1051 rblocks / mp->m_sb.sb_rextsize,
1052 force ? XFS_TRANS_RESERVE : 0, &tp);
1053 if (error)
1054 return error;
1055
1056 xfs_ilock(ip, XFS_ILOCK_EXCL);
1057 xfs_trans_ijoin(tp, ip, 0);
1058
1059 error = xfs_qm_dqattach_locked(ip, false);
1060 if (error) {
1061
1062 ASSERT(error != -ENOENT);
1063 goto out_cancel;
1064 }
1065
1066 error = xfs_trans_reserve_quota_nblks(tp, ip, dblocks, rblocks, force);
1067 if ((error == -EDQUOT || error == -ENOSPC) && !retried) {
1068 xfs_trans_cancel(tp);
1069 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1070 xfs_blockgc_free_quota(ip, 0);
1071 retried = true;
1072 goto retry;
1073 }
1074 if (error)
1075 goto out_cancel;
1076
1077 *tpp = tp;
1078 return 0;
1079
1080out_cancel:
1081 xfs_trans_cancel(tp);
1082 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1083 return error;
1084}
1085
1086
1087
1088
1089
1090int
1091xfs_trans_alloc_icreate(
1092 struct xfs_mount *mp,
1093 struct xfs_trans_res *resv,
1094 struct xfs_dquot *udqp,
1095 struct xfs_dquot *gdqp,
1096 struct xfs_dquot *pdqp,
1097 unsigned int dblocks,
1098 struct xfs_trans **tpp)
1099{
1100 struct xfs_trans *tp;
1101 bool retried = false;
1102 int error;
1103
1104retry:
1105 error = xfs_trans_alloc(mp, resv, dblocks, 0, 0, &tp);
1106 if (error)
1107 return error;
1108
1109 error = xfs_trans_reserve_quota_icreate(tp, udqp, gdqp, pdqp, dblocks);
1110 if ((error == -EDQUOT || error == -ENOSPC) && !retried) {
1111 xfs_trans_cancel(tp);
1112 xfs_blockgc_free_dquots(mp, udqp, gdqp, pdqp, 0);
1113 retried = true;
1114 goto retry;
1115 }
1116 if (error) {
1117 xfs_trans_cancel(tp);
1118 return error;
1119 }
1120
1121 *tpp = tp;
1122 return 0;
1123}
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134int
1135xfs_trans_alloc_ichange(
1136 struct xfs_inode *ip,
1137 struct xfs_dquot *new_udqp,
1138 struct xfs_dquot *new_gdqp,
1139 struct xfs_dquot *new_pdqp,
1140 bool force,
1141 struct xfs_trans **tpp)
1142{
1143 struct xfs_trans *tp;
1144 struct xfs_mount *mp = ip->i_mount;
1145 struct xfs_dquot *udqp;
1146 struct xfs_dquot *gdqp;
1147 struct xfs_dquot *pdqp;
1148 bool retried = false;
1149 int error;
1150
1151retry:
1152 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_ichange, 0, 0, 0, &tp);
1153 if (error)
1154 return error;
1155
1156 xfs_ilock(ip, XFS_ILOCK_EXCL);
1157 xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
1158
1159 error = xfs_qm_dqattach_locked(ip, false);
1160 if (error) {
1161
1162 ASSERT(error != -ENOENT);
1163 goto out_cancel;
1164 }
1165
1166
1167
1168
1169
1170
1171
1172 udqp = (new_udqp != ip->i_udquot) ? new_udqp : NULL;
1173 gdqp = (new_gdqp != ip->i_gdquot) ? new_gdqp : NULL;
1174 pdqp = (new_pdqp != ip->i_pdquot) ? new_pdqp : NULL;
1175 if (udqp || gdqp || pdqp) {
1176 unsigned int qflags = XFS_QMOPT_RES_REGBLKS;
1177
1178 if (force)
1179 qflags |= XFS_QMOPT_FORCE_RES;
1180
1181
1182
1183
1184
1185
1186
1187 error = xfs_trans_reserve_quota_bydquots(tp, mp, udqp, gdqp,
1188 pdqp, ip->i_nblocks + ip->i_delayed_blks,
1189 1, qflags);
1190 if ((error == -EDQUOT || error == -ENOSPC) && !retried) {
1191 xfs_trans_cancel(tp);
1192 xfs_blockgc_free_dquots(mp, udqp, gdqp, pdqp, 0);
1193 retried = true;
1194 goto retry;
1195 }
1196 if (error)
1197 goto out_cancel;
1198 }
1199
1200 *tpp = tp;
1201 return 0;
1202
1203out_cancel:
1204 xfs_trans_cancel(tp);
1205 return error;
1206}
1207