1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include "xfs.h"
19#include "xfs_fs.h"
20#include "xfs_shared.h"
21#include "xfs_format.h"
22#include "xfs_log_format.h"
23#include "xfs_trans_resv.h"
24#include "xfs_bit.h"
25#include "xfs_sb.h"
26#include "xfs_mount.h"
27#include "xfs_defer.h"
28#include "xfs_inode.h"
29#include "xfs_btree.h"
30#include "xfs_ialloc.h"
31#include "xfs_ialloc_btree.h"
32#include "xfs_alloc.h"
33#include "xfs_rtalloc.h"
34#include "xfs_errortag.h"
35#include "xfs_error.h"
36#include "xfs_bmap.h"
37#include "xfs_cksum.h"
38#include "xfs_trans.h"
39#include "xfs_buf_item.h"
40#include "xfs_icreate_item.h"
41#include "xfs_icache.h"
42#include "xfs_trace.h"
43#include "xfs_log.h"
44#include "xfs_rmap.h"
45
46
47
48
49
50int
51xfs_ialloc_cluster_alignment(
52 struct xfs_mount *mp)
53{
54 if (xfs_sb_version_hasalign(&mp->m_sb) &&
55 mp->m_sb.sb_inoalignmt >= xfs_icluster_size_fsb(mp))
56 return mp->m_sb.sb_inoalignmt;
57 return 1;
58}
59
60
61
62
63int
64xfs_inobt_lookup(
65 struct xfs_btree_cur *cur,
66 xfs_agino_t ino,
67 xfs_lookup_t dir,
68 int *stat)
69{
70 cur->bc_rec.i.ir_startino = ino;
71 cur->bc_rec.i.ir_holemask = 0;
72 cur->bc_rec.i.ir_count = 0;
73 cur->bc_rec.i.ir_freecount = 0;
74 cur->bc_rec.i.ir_free = 0;
75 return xfs_btree_lookup(cur, dir, stat);
76}
77
78
79
80
81
82STATIC int
83xfs_inobt_update(
84 struct xfs_btree_cur *cur,
85 xfs_inobt_rec_incore_t *irec)
86{
87 union xfs_btree_rec rec;
88
89 rec.inobt.ir_startino = cpu_to_be32(irec->ir_startino);
90 if (xfs_sb_version_hassparseinodes(&cur->bc_mp->m_sb)) {
91 rec.inobt.ir_u.sp.ir_holemask = cpu_to_be16(irec->ir_holemask);
92 rec.inobt.ir_u.sp.ir_count = irec->ir_count;
93 rec.inobt.ir_u.sp.ir_freecount = irec->ir_freecount;
94 } else {
95
96 rec.inobt.ir_u.f.ir_freecount = cpu_to_be32(irec->ir_freecount);
97 }
98 rec.inobt.ir_free = cpu_to_be64(irec->ir_free);
99 return xfs_btree_update(cur, &rec);
100}
101
102
103void
104xfs_inobt_btrec_to_irec(
105 struct xfs_mount *mp,
106 union xfs_btree_rec *rec,
107 struct xfs_inobt_rec_incore *irec)
108{
109 irec->ir_startino = be32_to_cpu(rec->inobt.ir_startino);
110 if (xfs_sb_version_hassparseinodes(&mp->m_sb)) {
111 irec->ir_holemask = be16_to_cpu(rec->inobt.ir_u.sp.ir_holemask);
112 irec->ir_count = rec->inobt.ir_u.sp.ir_count;
113 irec->ir_freecount = rec->inobt.ir_u.sp.ir_freecount;
114 } else {
115
116
117
118
119 irec->ir_holemask = XFS_INOBT_HOLEMASK_FULL;
120 irec->ir_count = XFS_INODES_PER_CHUNK;
121 irec->ir_freecount =
122 be32_to_cpu(rec->inobt.ir_u.f.ir_freecount);
123 }
124 irec->ir_free = be64_to_cpu(rec->inobt.ir_free);
125}
126
127
128
129
130int
131xfs_inobt_get_rec(
132 struct xfs_btree_cur *cur,
133 struct xfs_inobt_rec_incore *irec,
134 int *stat)
135{
136 union xfs_btree_rec *rec;
137 int error;
138
139 error = xfs_btree_get_rec(cur, &rec, stat);
140 if (error || *stat == 0)
141 return error;
142
143 xfs_inobt_btrec_to_irec(cur->bc_mp, rec, irec);
144
145 return 0;
146}
147
148
149
150
151STATIC int
152xfs_inobt_insert_rec(
153 struct xfs_btree_cur *cur,
154 uint16_t holemask,
155 uint8_t count,
156 int32_t freecount,
157 xfs_inofree_t free,
158 int *stat)
159{
160 cur->bc_rec.i.ir_holemask = holemask;
161 cur->bc_rec.i.ir_count = count;
162 cur->bc_rec.i.ir_freecount = freecount;
163 cur->bc_rec.i.ir_free = free;
164 return xfs_btree_insert(cur, stat);
165}
166
167
168
169
170STATIC int
171xfs_inobt_insert(
172 struct xfs_mount *mp,
173 struct xfs_trans *tp,
174 struct xfs_buf *agbp,
175 xfs_agino_t newino,
176 xfs_agino_t newlen,
177 xfs_btnum_t btnum)
178{
179 struct xfs_btree_cur *cur;
180 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
181 xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno);
182 xfs_agino_t thisino;
183 int i;
184 int error;
185
186 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, btnum);
187
188 for (thisino = newino;
189 thisino < newino + newlen;
190 thisino += XFS_INODES_PER_CHUNK) {
191 error = xfs_inobt_lookup(cur, thisino, XFS_LOOKUP_EQ, &i);
192 if (error) {
193 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
194 return error;
195 }
196 ASSERT(i == 0);
197
198 error = xfs_inobt_insert_rec(cur, XFS_INOBT_HOLEMASK_FULL,
199 XFS_INODES_PER_CHUNK,
200 XFS_INODES_PER_CHUNK,
201 XFS_INOBT_ALL_FREE, &i);
202 if (error) {
203 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
204 return error;
205 }
206 ASSERT(i == 1);
207 }
208
209 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
210
211 return 0;
212}
213
214
215
216
217#ifdef DEBUG
218STATIC int
219xfs_check_agi_freecount(
220 struct xfs_btree_cur *cur,
221 struct xfs_agi *agi)
222{
223 if (cur->bc_nlevels == 1) {
224 xfs_inobt_rec_incore_t rec;
225 int freecount = 0;
226 int error;
227 int i;
228
229 error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);
230 if (error)
231 return error;
232
233 do {
234 error = xfs_inobt_get_rec(cur, &rec, &i);
235 if (error)
236 return error;
237
238 if (i) {
239 freecount += rec.ir_freecount;
240 error = xfs_btree_increment(cur, 0, &i);
241 if (error)
242 return error;
243 }
244 } while (i == 1);
245
246 if (!XFS_FORCED_SHUTDOWN(cur->bc_mp))
247 ASSERT(freecount == be32_to_cpu(agi->agi_freecount));
248 }
249 return 0;
250}
251#else
252#define xfs_check_agi_freecount(cur, agi) 0
253#endif
254
255
256
257
258
259
260
261int
262xfs_ialloc_inode_init(
263 struct xfs_mount *mp,
264 struct xfs_trans *tp,
265 struct list_head *buffer_list,
266 int icount,
267 xfs_agnumber_t agno,
268 xfs_agblock_t agbno,
269 xfs_agblock_t length,
270 unsigned int gen)
271{
272 struct xfs_buf *fbuf;
273 struct xfs_dinode *free;
274 int nbufs, blks_per_cluster, inodes_per_cluster;
275 int version;
276 int i, j;
277 xfs_daddr_t d;
278 xfs_ino_t ino = 0;
279
280
281
282
283
284
285 blks_per_cluster = xfs_icluster_size_fsb(mp);
286 inodes_per_cluster = blks_per_cluster << mp->m_sb.sb_inopblog;
287 nbufs = length / blks_per_cluster;
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308 if (xfs_sb_version_hascrc(&mp->m_sb)) {
309 version = 3;
310 ino = XFS_AGINO_TO_INO(mp, agno,
311 XFS_OFFBNO_TO_AGINO(mp, agbno, 0));
312
313
314
315
316
317
318
319
320
321 if (tp)
322 xfs_icreate_log(tp, agno, agbno, icount,
323 mp->m_sb.sb_inodesize, length, gen);
324 } else
325 version = 2;
326
327 for (j = 0; j < nbufs; j++) {
328
329
330
331 d = XFS_AGB_TO_DADDR(mp, agno, agbno + (j * blks_per_cluster));
332 fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
333 mp->m_bsize * blks_per_cluster,
334 XBF_UNMAPPED);
335 if (!fbuf)
336 return -ENOMEM;
337
338
339 fbuf->b_ops = &xfs_inode_buf_ops;
340 xfs_buf_zero(fbuf, 0, BBTOB(fbuf->b_length));
341 for (i = 0; i < inodes_per_cluster; i++) {
342 int ioffset = i << mp->m_sb.sb_inodelog;
343 uint isize = xfs_dinode_size(version);
344
345 free = xfs_make_iptr(mp, fbuf, i);
346 free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
347 free->di_version = version;
348 free->di_gen = cpu_to_be32(gen);
349 free->di_next_unlinked = cpu_to_be32(NULLAGINO);
350
351 if (version == 3) {
352 free->di_ino = cpu_to_be64(ino);
353 ino++;
354 uuid_copy(&free->di_uuid,
355 &mp->m_sb.sb_meta_uuid);
356 xfs_dinode_calc_crc(mp, free);
357 } else if (tp) {
358
359 xfs_trans_log_buf(tp, fbuf, ioffset,
360 ioffset + isize - 1);
361 }
362 }
363
364 if (tp) {
365
366
367
368
369
370
371
372
373 xfs_trans_inode_alloc_buf(tp, fbuf);
374 if (version == 3) {
375
376
377
378
379
380
381 xfs_trans_ordered_buf(tp, fbuf);
382 }
383 } else {
384 fbuf->b_flags |= XBF_DONE;
385 xfs_buf_delwri_queue(fbuf, buffer_list);
386 xfs_buf_relse(fbuf);
387 }
388 }
389 return 0;
390}
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415STATIC void
416xfs_align_sparse_ino(
417 struct xfs_mount *mp,
418 xfs_agino_t *startino,
419 uint16_t *allocmask)
420{
421 xfs_agblock_t agbno;
422 xfs_agblock_t mod;
423 int offset;
424
425 agbno = XFS_AGINO_TO_AGBNO(mp, *startino);
426 mod = agbno % mp->m_sb.sb_inoalignmt;
427 if (!mod)
428 return;
429
430
431 offset = mod << mp->m_sb.sb_inopblog;
432 *startino -= offset;
433
434
435
436
437
438
439 *allocmask <<= offset / XFS_INODES_PER_HOLEMASK_BIT;
440}
441
442
443
444
445
446
447STATIC bool
448__xfs_inobt_can_merge(
449 struct xfs_inobt_rec_incore *trec,
450 struct xfs_inobt_rec_incore *srec)
451{
452 uint64_t talloc;
453 uint64_t salloc;
454
455
456 if (trec->ir_startino != srec->ir_startino)
457 return false;
458
459
460 if (!xfs_inobt_issparse(trec->ir_holemask) ||
461 !xfs_inobt_issparse(srec->ir_holemask))
462 return false;
463
464
465 if (!trec->ir_count || !srec->ir_count)
466 return false;
467
468
469 if (trec->ir_count + srec->ir_count > XFS_INODES_PER_CHUNK)
470 return false;
471
472
473 talloc = xfs_inobt_irec_to_allocmask(trec);
474 salloc = xfs_inobt_irec_to_allocmask(srec);
475 if (talloc & salloc)
476 return false;
477
478 return true;
479}
480
481
482
483
484
485STATIC void
486__xfs_inobt_rec_merge(
487 struct xfs_inobt_rec_incore *trec,
488 struct xfs_inobt_rec_incore *srec)
489{
490 ASSERT(trec->ir_startino == srec->ir_startino);
491
492
493 trec->ir_count += srec->ir_count;
494 trec->ir_freecount += srec->ir_freecount;
495
496
497
498
499
500 trec->ir_holemask &= srec->ir_holemask;
501 trec->ir_free &= srec->ir_free;
502}
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519STATIC int
520xfs_inobt_insert_sprec(
521 struct xfs_mount *mp,
522 struct xfs_trans *tp,
523 struct xfs_buf *agbp,
524 int btnum,
525 struct xfs_inobt_rec_incore *nrec,
526 bool merge)
527{
528 struct xfs_btree_cur *cur;
529 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
530 xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno);
531 int error;
532 int i;
533 struct xfs_inobt_rec_incore rec;
534
535 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, btnum);
536
537
538 error = xfs_inobt_lookup(cur, nrec->ir_startino, XFS_LOOKUP_EQ, &i);
539 if (error)
540 goto error;
541
542 if (i == 0) {
543 error = xfs_inobt_insert_rec(cur, nrec->ir_holemask,
544 nrec->ir_count, nrec->ir_freecount,
545 nrec->ir_free, &i);
546 if (error)
547 goto error;
548 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error);
549
550 goto out;
551 }
552
553
554
555
556
557 if (merge) {
558 error = xfs_inobt_get_rec(cur, &rec, &i);
559 if (error)
560 goto error;
561 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error);
562 XFS_WANT_CORRUPTED_GOTO(mp,
563 rec.ir_startino == nrec->ir_startino,
564 error);
565
566
567
568
569
570 XFS_WANT_CORRUPTED_GOTO(mp, __xfs_inobt_can_merge(nrec, &rec),
571 error);
572
573 trace_xfs_irec_merge_pre(mp, agno, rec.ir_startino,
574 rec.ir_holemask, nrec->ir_startino,
575 nrec->ir_holemask);
576
577
578 __xfs_inobt_rec_merge(nrec, &rec);
579
580 trace_xfs_irec_merge_post(mp, agno, nrec->ir_startino,
581 nrec->ir_holemask);
582
583 error = xfs_inobt_rec_check_count(mp, nrec);
584 if (error)
585 goto error;
586 }
587
588 error = xfs_inobt_update(cur, nrec);
589 if (error)
590 goto error;
591
592out:
593 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
594 return 0;
595error:
596 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
597 return error;
598}
599
600
601
602
603
604STATIC int
605xfs_ialloc_ag_alloc(
606 xfs_trans_t *tp,
607 xfs_buf_t *agbp,
608 int *alloc)
609{
610 xfs_agi_t *agi;
611 xfs_alloc_arg_t args;
612 xfs_agnumber_t agno;
613 int error;
614 xfs_agino_t newino;
615 xfs_agino_t newlen;
616 int isaligned = 0;
617
618 uint16_t allocmask = (uint16_t) -1;
619 struct xfs_inobt_rec_incore rec;
620 struct xfs_perag *pag;
621 int do_sparse = 0;
622
623 memset(&args, 0, sizeof(args));
624 args.tp = tp;
625 args.mp = tp->t_mountp;
626 args.fsbno = NULLFSBLOCK;
627 xfs_rmap_ag_owner(&args.oinfo, XFS_RMAP_OWN_INODES);
628
629#ifdef DEBUG
630
631 if (xfs_sb_version_hassparseinodes(&tp->t_mountp->m_sb) &&
632 args.mp->m_ialloc_min_blks < args.mp->m_ialloc_blks)
633 do_sparse = prandom_u32() & 1;
634#endif
635
636
637
638
639
640 newlen = args.mp->m_ialloc_inos;
641 if (args.mp->m_maxicount &&
642 percpu_counter_read_positive(&args.mp->m_icount) + newlen >
643 args.mp->m_maxicount)
644 return -ENOSPC;
645 args.minlen = args.maxlen = args.mp->m_ialloc_blks;
646
647
648
649
650
651 agi = XFS_BUF_TO_AGI(agbp);
652 newino = be32_to_cpu(agi->agi_newino);
653 agno = be32_to_cpu(agi->agi_seqno);
654 args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) +
655 args.mp->m_ialloc_blks;
656 if (do_sparse)
657 goto sparse_alloc;
658 if (likely(newino != NULLAGINO &&
659 (args.agbno < be32_to_cpu(agi->agi_length)))) {
660 args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
661 args.type = XFS_ALLOCTYPE_THIS_BNO;
662 args.prod = 1;
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677 args.alignment = 1;
678 args.minalignslop = xfs_ialloc_cluster_alignment(args.mp) - 1;
679
680
681 args.minleft = args.mp->m_in_maxlevels - 1;
682 if ((error = xfs_alloc_vextent(&args)))
683 return error;
684
685
686
687
688
689
690
691
692
693
694
695 args.minalignslop = 0;
696 }
697
698 if (unlikely(args.fsbno == NULLFSBLOCK)) {
699
700
701
702
703
704
705
706
707 isaligned = 0;
708 if (args.mp->m_sinoalign) {
709 ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN));
710 args.alignment = args.mp->m_dalign;
711 isaligned = 1;
712 } else
713 args.alignment = xfs_ialloc_cluster_alignment(args.mp);
714
715
716
717
718
719 args.agbno = be32_to_cpu(agi->agi_root);
720 args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
721
722
723
724 args.type = XFS_ALLOCTYPE_NEAR_BNO;
725 args.prod = 1;
726
727
728
729 args.minleft = args.mp->m_in_maxlevels - 1;
730 if ((error = xfs_alloc_vextent(&args)))
731 return error;
732 }
733
734
735
736
737
738 if (isaligned && args.fsbno == NULLFSBLOCK) {
739 args.type = XFS_ALLOCTYPE_NEAR_BNO;
740 args.agbno = be32_to_cpu(agi->agi_root);
741 args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
742 args.alignment = xfs_ialloc_cluster_alignment(args.mp);
743 if ((error = xfs_alloc_vextent(&args)))
744 return error;
745 }
746
747
748
749
750
751 if (xfs_sb_version_hassparseinodes(&args.mp->m_sb) &&
752 args.mp->m_ialloc_min_blks < args.mp->m_ialloc_blks &&
753 args.fsbno == NULLFSBLOCK) {
754sparse_alloc:
755 args.type = XFS_ALLOCTYPE_NEAR_BNO;
756 args.agbno = be32_to_cpu(agi->agi_root);
757 args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
758 args.alignment = args.mp->m_sb.sb_spino_align;
759 args.prod = 1;
760
761 args.minlen = args.mp->m_ialloc_min_blks;
762 args.maxlen = args.minlen;
763
764
765
766
767
768
769
770
771
772
773
774 args.min_agbno = args.mp->m_sb.sb_inoalignmt;
775 args.max_agbno = round_down(args.mp->m_sb.sb_agblocks,
776 args.mp->m_sb.sb_inoalignmt) -
777 args.mp->m_ialloc_blks;
778
779 error = xfs_alloc_vextent(&args);
780 if (error)
781 return error;
782
783 newlen = args.len << args.mp->m_sb.sb_inopblog;
784 ASSERT(newlen <= XFS_INODES_PER_CHUNK);
785 allocmask = (1 << (newlen / XFS_INODES_PER_HOLEMASK_BIT)) - 1;
786 }
787
788 if (args.fsbno == NULLFSBLOCK) {
789 *alloc = 0;
790 return 0;
791 }
792 ASSERT(args.len == args.minlen);
793
794
795
796
797
798
799
800
801
802
803 error = xfs_ialloc_inode_init(args.mp, tp, NULL, newlen, agno,
804 args.agbno, args.len, prandom_u32());
805
806 if (error)
807 return error;
808
809
810
811 newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0);
812
813 if (xfs_inobt_issparse(~allocmask)) {
814
815
816
817 xfs_align_sparse_ino(args.mp, &newino, &allocmask);
818
819 rec.ir_startino = newino;
820 rec.ir_holemask = ~allocmask;
821 rec.ir_count = newlen;
822 rec.ir_freecount = newlen;
823 rec.ir_free = XFS_INOBT_ALL_FREE;
824
825
826
827
828
829
830 error = xfs_inobt_insert_sprec(args.mp, tp, agbp, XFS_BTNUM_INO,
831 &rec, true);
832 if (error == -EFSCORRUPTED) {
833 xfs_alert(args.mp,
834 "invalid sparse inode record: ino 0x%llx holemask 0x%x count %u",
835 XFS_AGINO_TO_INO(args.mp, agno,
836 rec.ir_startino),
837 rec.ir_holemask, rec.ir_count);
838 xfs_force_shutdown(args.mp, SHUTDOWN_CORRUPT_INCORE);
839 }
840 if (error)
841 return error;
842
843
844
845
846
847
848
849
850
851
852
853
854 if (xfs_sb_version_hasfinobt(&args.mp->m_sb)) {
855 error = xfs_inobt_insert_sprec(args.mp, tp, agbp,
856 XFS_BTNUM_FINO, &rec,
857 false);
858 if (error)
859 return error;
860 }
861 } else {
862
863 error = xfs_inobt_insert(args.mp, tp, agbp, newino, newlen,
864 XFS_BTNUM_INO);
865 if (error)
866 return error;
867
868 if (xfs_sb_version_hasfinobt(&args.mp->m_sb)) {
869 error = xfs_inobt_insert(args.mp, tp, agbp, newino,
870 newlen, XFS_BTNUM_FINO);
871 if (error)
872 return error;
873 }
874 }
875
876
877
878
879 be32_add_cpu(&agi->agi_count, newlen);
880 be32_add_cpu(&agi->agi_freecount, newlen);
881 pag = xfs_perag_get(args.mp, agno);
882 pag->pagi_freecount += newlen;
883 xfs_perag_put(pag);
884 agi->agi_newino = cpu_to_be32(newino);
885
886
887
888
889 xfs_ialloc_log_agi(tp, agbp,
890 XFS_AGI_COUNT | XFS_AGI_FREECOUNT | XFS_AGI_NEWINO);
891
892
893
894 xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, (long)newlen);
895 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, (long)newlen);
896 *alloc = 1;
897 return 0;
898}
899
900STATIC xfs_agnumber_t
901xfs_ialloc_next_ag(
902 xfs_mount_t *mp)
903{
904 xfs_agnumber_t agno;
905
906 spin_lock(&mp->m_agirotor_lock);
907 agno = mp->m_agirotor;
908 if (++mp->m_agirotor >= mp->m_maxagi)
909 mp->m_agirotor = 0;
910 spin_unlock(&mp->m_agirotor_lock);
911
912 return agno;
913}
914
915
916
917
918
919STATIC xfs_agnumber_t
920xfs_ialloc_ag_select(
921 xfs_trans_t *tp,
922 xfs_ino_t parent,
923 umode_t mode)
924{
925 xfs_agnumber_t agcount;
926 xfs_agnumber_t agno;
927 int flags;
928 xfs_extlen_t ineed;
929 xfs_extlen_t longest = 0;
930 xfs_mount_t *mp;
931 int needspace;
932 xfs_perag_t *pag;
933 xfs_agnumber_t pagno;
934 int error;
935
936
937
938
939
940 needspace = S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode);
941 mp = tp->t_mountp;
942 agcount = mp->m_maxagi;
943 if (S_ISDIR(mode))
944 pagno = xfs_ialloc_next_ag(mp);
945 else {
946 pagno = XFS_INO_TO_AGNO(mp, parent);
947 if (pagno >= agcount)
948 pagno = 0;
949 }
950
951 ASSERT(pagno < agcount);
952
953
954
955
956
957
958
959
960 agno = pagno;
961 flags = XFS_ALLOC_FLAG_TRYLOCK;
962 for (;;) {
963 pag = xfs_perag_get(mp, agno);
964 if (!pag->pagi_inodeok) {
965 xfs_ialloc_next_ag(mp);
966 goto nextag;
967 }
968
969 if (!pag->pagi_init) {
970 error = xfs_ialloc_pagi_init(mp, tp, agno);
971 if (error)
972 goto nextag;
973 }
974
975 if (pag->pagi_freecount) {
976 xfs_perag_put(pag);
977 return agno;
978 }
979
980 if (!pag->pagf_init) {
981 error = xfs_alloc_pagf_init(mp, tp, agno, flags);
982 if (error)
983 goto nextag;
984 }
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002 ineed = mp->m_ialloc_min_blks;
1003 if (flags && ineed > 1)
1004 ineed += xfs_ialloc_cluster_alignment(mp);
1005 longest = pag->pagf_longest;
1006 if (!longest)
1007 longest = pag->pagf_flcount > 0;
1008
1009 if (pag->pagf_freeblks >= needspace + ineed &&
1010 longest >= ineed) {
1011 xfs_perag_put(pag);
1012 return agno;
1013 }
1014nextag:
1015 xfs_perag_put(pag);
1016
1017
1018
1019
1020 if (XFS_FORCED_SHUTDOWN(mp))
1021 return NULLAGNUMBER;
1022 agno++;
1023 if (agno >= agcount)
1024 agno = 0;
1025 if (agno == pagno) {
1026 if (flags == 0)
1027 return NULLAGNUMBER;
1028 flags = 0;
1029 }
1030 }
1031}
1032
1033
1034
1035
1036STATIC int
1037xfs_ialloc_next_rec(
1038 struct xfs_btree_cur *cur,
1039 xfs_inobt_rec_incore_t *rec,
1040 int *done,
1041 int left)
1042{
1043 int error;
1044 int i;
1045
1046 if (left)
1047 error = xfs_btree_decrement(cur, 0, &i);
1048 else
1049 error = xfs_btree_increment(cur, 0, &i);
1050
1051 if (error)
1052 return error;
1053 *done = !i;
1054 if (i) {
1055 error = xfs_inobt_get_rec(cur, rec, &i);
1056 if (error)
1057 return error;
1058 XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1);
1059 }
1060
1061 return 0;
1062}
1063
1064STATIC int
1065xfs_ialloc_get_rec(
1066 struct xfs_btree_cur *cur,
1067 xfs_agino_t agino,
1068 xfs_inobt_rec_incore_t *rec,
1069 int *done)
1070{
1071 int error;
1072 int i;
1073
1074 error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_EQ, &i);
1075 if (error)
1076 return error;
1077 *done = !i;
1078 if (i) {
1079 error = xfs_inobt_get_rec(cur, rec, &i);
1080 if (error)
1081 return error;
1082 XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1);
1083 }
1084
1085 return 0;
1086}
1087
1088
1089
1090
1091
1092
1093STATIC int
1094xfs_inobt_first_free_inode(
1095 struct xfs_inobt_rec_incore *rec)
1096{
1097 xfs_inofree_t realfree;
1098
1099
1100 if (!xfs_inobt_issparse(rec->ir_holemask))
1101 return xfs_lowbit64(rec->ir_free);
1102
1103 realfree = xfs_inobt_irec_to_allocmask(rec);
1104 realfree &= rec->ir_free;
1105
1106 return xfs_lowbit64(realfree);
1107}
1108
1109
1110
1111
1112STATIC int
1113xfs_dialloc_ag_inobt(
1114 struct xfs_trans *tp,
1115 struct xfs_buf *agbp,
1116 xfs_ino_t parent,
1117 xfs_ino_t *inop)
1118{
1119 struct xfs_mount *mp = tp->t_mountp;
1120 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
1121 xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno);
1122 xfs_agnumber_t pagno = XFS_INO_TO_AGNO(mp, parent);
1123 xfs_agino_t pagino = XFS_INO_TO_AGINO(mp, parent);
1124 struct xfs_perag *pag;
1125 struct xfs_btree_cur *cur, *tcur;
1126 struct xfs_inobt_rec_incore rec, trec;
1127 xfs_ino_t ino;
1128 int error;
1129 int offset;
1130 int i, j;
1131 int searchdistance = 10;
1132
1133 pag = xfs_perag_get(mp, agno);
1134
1135 ASSERT(pag->pagi_init);
1136 ASSERT(pag->pagi_inodeok);
1137 ASSERT(pag->pagi_freecount > 0);
1138
1139 restart_pagno:
1140 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO);
1141
1142
1143
1144
1145 if (!pagino)
1146 pagino = be32_to_cpu(agi->agi_newino);
1147
1148 error = xfs_check_agi_freecount(cur, agi);
1149 if (error)
1150 goto error0;
1151
1152
1153
1154
1155 if (pagno == agno) {
1156 int doneleft;
1157 int doneright;
1158
1159 error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i);
1160 if (error)
1161 goto error0;
1162 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
1163
1164 error = xfs_inobt_get_rec(cur, &rec, &j);
1165 if (error)
1166 goto error0;
1167 XFS_WANT_CORRUPTED_GOTO(mp, j == 1, error0);
1168
1169 if (rec.ir_freecount > 0) {
1170
1171
1172
1173
1174 goto alloc_inode;
1175 }
1176
1177
1178
1179
1180
1181
1182
1183 error = xfs_btree_dup_cursor(cur, &tcur);
1184 if (error)
1185 goto error0;
1186
1187
1188
1189
1190 if (pagino != NULLAGINO &&
1191 pag->pagl_pagino == pagino &&
1192 pag->pagl_leftrec != NULLAGINO &&
1193 pag->pagl_rightrec != NULLAGINO) {
1194 error = xfs_ialloc_get_rec(tcur, pag->pagl_leftrec,
1195 &trec, &doneleft);
1196 if (error)
1197 goto error1;
1198
1199 error = xfs_ialloc_get_rec(cur, pag->pagl_rightrec,
1200 &rec, &doneright);
1201 if (error)
1202 goto error1;
1203 } else {
1204
1205 error = xfs_ialloc_next_rec(tcur, &trec, &doneleft, 1);
1206 if (error)
1207 goto error1;
1208
1209
1210 error = xfs_ialloc_next_rec(cur, &rec, &doneright, 0);
1211 if (error)
1212 goto error1;
1213 }
1214
1215
1216
1217
1218 while (--searchdistance > 0 && (!doneleft || !doneright)) {
1219 int useleft;
1220
1221
1222 if (!doneleft && !doneright) {
1223 useleft = pagino -
1224 (trec.ir_startino + XFS_INODES_PER_CHUNK - 1) <
1225 rec.ir_startino - pagino;
1226 } else {
1227 useleft = !doneleft;
1228 }
1229
1230
1231 if (useleft && trec.ir_freecount) {
1232 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1233 cur = tcur;
1234
1235 pag->pagl_leftrec = trec.ir_startino;
1236 pag->pagl_rightrec = rec.ir_startino;
1237 pag->pagl_pagino = pagino;
1238 rec = trec;
1239 goto alloc_inode;
1240 }
1241
1242
1243 if (!useleft && rec.ir_freecount) {
1244 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
1245
1246 pag->pagl_leftrec = trec.ir_startino;
1247 pag->pagl_rightrec = rec.ir_startino;
1248 pag->pagl_pagino = pagino;
1249 goto alloc_inode;
1250 }
1251
1252
1253 if (useleft) {
1254 error = xfs_ialloc_next_rec(tcur, &trec,
1255 &doneleft, 1);
1256 } else {
1257 error = xfs_ialloc_next_rec(cur, &rec,
1258 &doneright, 0);
1259 }
1260 if (error)
1261 goto error1;
1262 }
1263
1264 if (searchdistance <= 0) {
1265
1266
1267
1268
1269 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
1270 pag->pagl_leftrec = trec.ir_startino;
1271 pag->pagl_rightrec = rec.ir_startino;
1272 pag->pagl_pagino = pagino;
1273
1274 } else {
1275
1276
1277
1278
1279
1280
1281
1282 pag->pagl_pagino = NULLAGINO;
1283 pag->pagl_leftrec = NULLAGINO;
1284 pag->pagl_rightrec = NULLAGINO;
1285 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
1286 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1287 goto restart_pagno;
1288 }
1289 }
1290
1291
1292
1293
1294
1295 if (agi->agi_newino != cpu_to_be32(NULLAGINO)) {
1296 error = xfs_inobt_lookup(cur, be32_to_cpu(agi->agi_newino),
1297 XFS_LOOKUP_EQ, &i);
1298 if (error)
1299 goto error0;
1300
1301 if (i == 1) {
1302 error = xfs_inobt_get_rec(cur, &rec, &j);
1303 if (error)
1304 goto error0;
1305
1306 if (j == 1 && rec.ir_freecount > 0) {
1307
1308
1309
1310
1311 goto alloc_inode;
1312 }
1313 }
1314 }
1315
1316
1317
1318
1319 error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);
1320 if (error)
1321 goto error0;
1322 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
1323
1324 for (;;) {
1325 error = xfs_inobt_get_rec(cur, &rec, &i);
1326 if (error)
1327 goto error0;
1328 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
1329 if (rec.ir_freecount > 0)
1330 break;
1331 error = xfs_btree_increment(cur, 0, &i);
1332 if (error)
1333 goto error0;
1334 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
1335 }
1336
1337alloc_inode:
1338 offset = xfs_inobt_first_free_inode(&rec);
1339 ASSERT(offset >= 0);
1340 ASSERT(offset < XFS_INODES_PER_CHUNK);
1341 ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) %
1342 XFS_INODES_PER_CHUNK) == 0);
1343 ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset);
1344 rec.ir_free &= ~XFS_INOBT_MASK(offset);
1345 rec.ir_freecount--;
1346 error = xfs_inobt_update(cur, &rec);
1347 if (error)
1348 goto error0;
1349 be32_add_cpu(&agi->agi_freecount, -1);
1350 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
1351 pag->pagi_freecount--;
1352
1353 error = xfs_check_agi_freecount(cur, agi);
1354 if (error)
1355 goto error0;
1356
1357 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1358 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
1359 xfs_perag_put(pag);
1360 *inop = ino;
1361 return 0;
1362error1:
1363 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
1364error0:
1365 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
1366 xfs_perag_put(pag);
1367 return error;
1368}
1369
1370
1371
1372
1373
1374STATIC int
1375xfs_dialloc_ag_finobt_near(
1376 xfs_agino_t pagino,
1377 struct xfs_btree_cur **ocur,
1378 struct xfs_inobt_rec_incore *rec)
1379{
1380 struct xfs_btree_cur *lcur = *ocur;
1381 struct xfs_btree_cur *rcur;
1382 struct xfs_inobt_rec_incore rrec;
1383 int error;
1384 int i, j;
1385
1386 error = xfs_inobt_lookup(lcur, pagino, XFS_LOOKUP_LE, &i);
1387 if (error)
1388 return error;
1389
1390 if (i == 1) {
1391 error = xfs_inobt_get_rec(lcur, rec, &i);
1392 if (error)
1393 return error;
1394 XFS_WANT_CORRUPTED_RETURN(lcur->bc_mp, i == 1);
1395
1396
1397
1398
1399
1400
1401 if (pagino >= rec->ir_startino &&
1402 pagino < (rec->ir_startino + XFS_INODES_PER_CHUNK))
1403 return 0;
1404 }
1405
1406 error = xfs_btree_dup_cursor(lcur, &rcur);
1407 if (error)
1408 return error;
1409
1410 error = xfs_inobt_lookup(rcur, pagino, XFS_LOOKUP_GE, &j);
1411 if (error)
1412 goto error_rcur;
1413 if (j == 1) {
1414 error = xfs_inobt_get_rec(rcur, &rrec, &j);
1415 if (error)
1416 goto error_rcur;
1417 XFS_WANT_CORRUPTED_GOTO(lcur->bc_mp, j == 1, error_rcur);
1418 }
1419
1420 XFS_WANT_CORRUPTED_GOTO(lcur->bc_mp, i == 1 || j == 1, error_rcur);
1421 if (i == 1 && j == 1) {
1422
1423
1424
1425
1426 if ((pagino - rec->ir_startino + XFS_INODES_PER_CHUNK - 1) >
1427 (rrec.ir_startino - pagino)) {
1428 *rec = rrec;
1429 xfs_btree_del_cursor(lcur, XFS_BTREE_NOERROR);
1430 *ocur = rcur;
1431 } else {
1432 xfs_btree_del_cursor(rcur, XFS_BTREE_NOERROR);
1433 }
1434 } else if (j == 1) {
1435
1436 *rec = rrec;
1437 xfs_btree_del_cursor(lcur, XFS_BTREE_NOERROR);
1438 *ocur = rcur;
1439 } else if (i == 1) {
1440
1441 xfs_btree_del_cursor(rcur, XFS_BTREE_NOERROR);
1442 }
1443
1444 return 0;
1445
1446error_rcur:
1447 xfs_btree_del_cursor(rcur, XFS_BTREE_ERROR);
1448 return error;
1449}
1450
1451
1452
1453
1454
1455STATIC int
1456xfs_dialloc_ag_finobt_newino(
1457 struct xfs_agi *agi,
1458 struct xfs_btree_cur *cur,
1459 struct xfs_inobt_rec_incore *rec)
1460{
1461 int error;
1462 int i;
1463
1464 if (agi->agi_newino != cpu_to_be32(NULLAGINO)) {
1465 error = xfs_inobt_lookup(cur, be32_to_cpu(agi->agi_newino),
1466 XFS_LOOKUP_EQ, &i);
1467 if (error)
1468 return error;
1469 if (i == 1) {
1470 error = xfs_inobt_get_rec(cur, rec, &i);
1471 if (error)
1472 return error;
1473 XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1);
1474 return 0;
1475 }
1476 }
1477
1478
1479
1480
1481 error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);
1482 if (error)
1483 return error;
1484 XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1);
1485
1486 error = xfs_inobt_get_rec(cur, rec, &i);
1487 if (error)
1488 return error;
1489 XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1);
1490
1491 return 0;
1492}
1493
1494
1495
1496
1497
1498STATIC int
1499xfs_dialloc_ag_update_inobt(
1500 struct xfs_btree_cur *cur,
1501 struct xfs_inobt_rec_incore *frec,
1502 int offset)
1503{
1504 struct xfs_inobt_rec_incore rec;
1505 int error;
1506 int i;
1507
1508 error = xfs_inobt_lookup(cur, frec->ir_startino, XFS_LOOKUP_EQ, &i);
1509 if (error)
1510 return error;
1511 XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1);
1512
1513 error = xfs_inobt_get_rec(cur, &rec, &i);
1514 if (error)
1515 return error;
1516 XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, i == 1);
1517 ASSERT((XFS_AGINO_TO_OFFSET(cur->bc_mp, rec.ir_startino) %
1518 XFS_INODES_PER_CHUNK) == 0);
1519
1520 rec.ir_free &= ~XFS_INOBT_MASK(offset);
1521 rec.ir_freecount--;
1522
1523 XFS_WANT_CORRUPTED_RETURN(cur->bc_mp, (rec.ir_free == frec->ir_free) &&
1524 (rec.ir_freecount == frec->ir_freecount));
1525
1526 return xfs_inobt_update(cur, &rec);
1527}
1528
1529
1530
1531
1532
1533
1534
1535
1536STATIC int
1537xfs_dialloc_ag(
1538 struct xfs_trans *tp,
1539 struct xfs_buf *agbp,
1540 xfs_ino_t parent,
1541 xfs_ino_t *inop)
1542{
1543 struct xfs_mount *mp = tp->t_mountp;
1544 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
1545 xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno);
1546 xfs_agnumber_t pagno = XFS_INO_TO_AGNO(mp, parent);
1547 xfs_agino_t pagino = XFS_INO_TO_AGINO(mp, parent);
1548 struct xfs_perag *pag;
1549 struct xfs_btree_cur *cur;
1550 struct xfs_btree_cur *icur;
1551 struct xfs_inobt_rec_incore rec;
1552 xfs_ino_t ino;
1553 int error;
1554 int offset;
1555 int i;
1556
1557 if (!xfs_sb_version_hasfinobt(&mp->m_sb))
1558 return xfs_dialloc_ag_inobt(tp, agbp, parent, inop);
1559
1560 pag = xfs_perag_get(mp, agno);
1561
1562
1563
1564
1565
1566 if (!pagino)
1567 pagino = be32_to_cpu(agi->agi_newino);
1568
1569 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_FINO);
1570
1571 error = xfs_check_agi_freecount(cur, agi);
1572 if (error)
1573 goto error_cur;
1574
1575
1576
1577
1578
1579
1580 if (agno == pagno)
1581 error = xfs_dialloc_ag_finobt_near(pagino, &cur, &rec);
1582 else
1583 error = xfs_dialloc_ag_finobt_newino(agi, cur, &rec);
1584 if (error)
1585 goto error_cur;
1586
1587 offset = xfs_inobt_first_free_inode(&rec);
1588 ASSERT(offset >= 0);
1589 ASSERT(offset < XFS_INODES_PER_CHUNK);
1590 ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) %
1591 XFS_INODES_PER_CHUNK) == 0);
1592 ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset);
1593
1594
1595
1596
1597 rec.ir_free &= ~XFS_INOBT_MASK(offset);
1598 rec.ir_freecount--;
1599 if (rec.ir_freecount)
1600 error = xfs_inobt_update(cur, &rec);
1601 else
1602 error = xfs_btree_delete(cur, &i);
1603 if (error)
1604 goto error_cur;
1605
1606
1607
1608
1609
1610
1611
1612 icur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO);
1613
1614 error = xfs_check_agi_freecount(icur, agi);
1615 if (error)
1616 goto error_icur;
1617
1618 error = xfs_dialloc_ag_update_inobt(icur, &rec, offset);
1619 if (error)
1620 goto error_icur;
1621
1622
1623
1624
1625
1626 be32_add_cpu(&agi->agi_freecount, -1);
1627 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
1628 pag->pagi_freecount--;
1629
1630 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
1631
1632 error = xfs_check_agi_freecount(icur, agi);
1633 if (error)
1634 goto error_icur;
1635 error = xfs_check_agi_freecount(cur, agi);
1636 if (error)
1637 goto error_icur;
1638
1639 xfs_btree_del_cursor(icur, XFS_BTREE_NOERROR);
1640 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1641 xfs_perag_put(pag);
1642 *inop = ino;
1643 return 0;
1644
1645error_icur:
1646 xfs_btree_del_cursor(icur, XFS_BTREE_ERROR);
1647error_cur:
1648 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
1649 xfs_perag_put(pag);
1650 return error;
1651}
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674int
1675xfs_dialloc(
1676 struct xfs_trans *tp,
1677 xfs_ino_t parent,
1678 umode_t mode,
1679 struct xfs_buf **IO_agbp,
1680 xfs_ino_t *inop)
1681{
1682 struct xfs_mount *mp = tp->t_mountp;
1683 struct xfs_buf *agbp;
1684 xfs_agnumber_t agno;
1685 int error;
1686 int ialloced;
1687 int noroom = 0;
1688 xfs_agnumber_t start_agno;
1689 struct xfs_perag *pag;
1690 int okalloc = 1;
1691
1692 if (*IO_agbp) {
1693
1694
1695
1696
1697
1698 agbp = *IO_agbp;
1699 goto out_alloc;
1700 }
1701
1702
1703
1704
1705
1706 start_agno = xfs_ialloc_ag_select(tp, parent, mode);
1707 if (start_agno == NULLAGNUMBER) {
1708 *inop = NULLFSINO;
1709 return 0;
1710 }
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720 if (mp->m_maxicount &&
1721 percpu_counter_read_positive(&mp->m_icount) + mp->m_ialloc_inos
1722 > mp->m_maxicount) {
1723 noroom = 1;
1724 okalloc = 0;
1725 }
1726
1727
1728
1729
1730
1731
1732 agno = start_agno;
1733 for (;;) {
1734 pag = xfs_perag_get(mp, agno);
1735 if (!pag->pagi_inodeok) {
1736 xfs_ialloc_next_ag(mp);
1737 goto nextag;
1738 }
1739
1740 if (!pag->pagi_init) {
1741 error = xfs_ialloc_pagi_init(mp, tp, agno);
1742 if (error)
1743 goto out_error;
1744 }
1745
1746
1747
1748
1749 if (!pag->pagi_freecount && !okalloc)
1750 goto nextag;
1751
1752
1753
1754
1755
1756 error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
1757 if (error)
1758 goto out_error;
1759
1760 if (pag->pagi_freecount) {
1761 xfs_perag_put(pag);
1762 goto out_alloc;
1763 }
1764
1765 if (!okalloc)
1766 goto nextag_relse_buffer;
1767
1768
1769 error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced);
1770 if (error) {
1771 xfs_trans_brelse(tp, agbp);
1772
1773 if (error != -ENOSPC)
1774 goto out_error;
1775
1776 xfs_perag_put(pag);
1777 *inop = NULLFSINO;
1778 return 0;
1779 }
1780
1781 if (ialloced) {
1782
1783
1784
1785
1786
1787
1788 ASSERT(pag->pagi_freecount > 0);
1789 xfs_perag_put(pag);
1790
1791 *IO_agbp = agbp;
1792 *inop = NULLFSINO;
1793 return 0;
1794 }
1795
1796nextag_relse_buffer:
1797 xfs_trans_brelse(tp, agbp);
1798nextag:
1799 xfs_perag_put(pag);
1800 if (++agno == mp->m_sb.sb_agcount)
1801 agno = 0;
1802 if (agno == start_agno) {
1803 *inop = NULLFSINO;
1804 return noroom ? -ENOSPC : 0;
1805 }
1806 }
1807
1808out_alloc:
1809 *IO_agbp = NULL;
1810 return xfs_dialloc_ag(tp, agbp, parent, inop);
1811out_error:
1812 xfs_perag_put(pag);
1813 return error;
1814}
1815
1816
1817
1818
1819
1820
1821STATIC void
1822xfs_difree_inode_chunk(
1823 struct xfs_mount *mp,
1824 xfs_agnumber_t agno,
1825 struct xfs_inobt_rec_incore *rec,
1826 struct xfs_defer_ops *dfops)
1827{
1828 xfs_agblock_t sagbno = XFS_AGINO_TO_AGBNO(mp, rec->ir_startino);
1829 int startidx, endidx;
1830 int nextbit;
1831 xfs_agblock_t agbno;
1832 int contigblk;
1833 struct xfs_owner_info oinfo;
1834 DECLARE_BITMAP(holemask, XFS_INOBT_HOLEMASK_BITS);
1835 xfs_rmap_ag_owner(&oinfo, XFS_RMAP_OWN_INODES);
1836
1837 if (!xfs_inobt_issparse(rec->ir_holemask)) {
1838
1839 xfs_bmap_add_free(mp, dfops, XFS_AGB_TO_FSB(mp, agno, sagbno),
1840 mp->m_ialloc_blks, &oinfo);
1841 return;
1842 }
1843
1844
1845 ASSERT(sizeof(rec->ir_holemask) <= sizeof(holemask[0]));
1846 holemask[0] = rec->ir_holemask;
1847
1848
1849
1850
1851
1852
1853
1854 startidx = endidx = find_first_zero_bit(holemask,
1855 XFS_INOBT_HOLEMASK_BITS);
1856 nextbit = startidx + 1;
1857 while (startidx < XFS_INOBT_HOLEMASK_BITS) {
1858 nextbit = find_next_zero_bit(holemask, XFS_INOBT_HOLEMASK_BITS,
1859 nextbit);
1860
1861
1862
1863
1864 if (nextbit != XFS_INOBT_HOLEMASK_BITS &&
1865 nextbit == endidx + 1) {
1866 endidx = nextbit;
1867 goto next;
1868 }
1869
1870
1871
1872
1873
1874
1875 agbno = sagbno + (startidx * XFS_INODES_PER_HOLEMASK_BIT) /
1876 mp->m_sb.sb_inopblock;
1877 contigblk = ((endidx - startidx + 1) *
1878 XFS_INODES_PER_HOLEMASK_BIT) /
1879 mp->m_sb.sb_inopblock;
1880
1881 ASSERT(agbno % mp->m_sb.sb_spino_align == 0);
1882 ASSERT(contigblk % mp->m_sb.sb_spino_align == 0);
1883 xfs_bmap_add_free(mp, dfops, XFS_AGB_TO_FSB(mp, agno, agbno),
1884 contigblk, &oinfo);
1885
1886
1887 startidx = endidx = nextbit;
1888
1889next:
1890 nextbit++;
1891 }
1892}
1893
1894STATIC int
1895xfs_difree_inobt(
1896 struct xfs_mount *mp,
1897 struct xfs_trans *tp,
1898 struct xfs_buf *agbp,
1899 xfs_agino_t agino,
1900 struct xfs_defer_ops *dfops,
1901 struct xfs_icluster *xic,
1902 struct xfs_inobt_rec_incore *orec)
1903{
1904 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
1905 xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno);
1906 struct xfs_perag *pag;
1907 struct xfs_btree_cur *cur;
1908 struct xfs_inobt_rec_incore rec;
1909 int ilen;
1910 int error;
1911 int i;
1912 int off;
1913
1914 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
1915 ASSERT(XFS_AGINO_TO_AGBNO(mp, agino) < be32_to_cpu(agi->agi_length));
1916
1917
1918
1919
1920 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO);
1921
1922 error = xfs_check_agi_freecount(cur, agi);
1923 if (error)
1924 goto error0;
1925
1926
1927
1928
1929 if ((error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i))) {
1930 xfs_warn(mp, "%s: xfs_inobt_lookup() returned error %d.",
1931 __func__, error);
1932 goto error0;
1933 }
1934 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
1935 error = xfs_inobt_get_rec(cur, &rec, &i);
1936 if (error) {
1937 xfs_warn(mp, "%s: xfs_inobt_get_rec() returned error %d.",
1938 __func__, error);
1939 goto error0;
1940 }
1941 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error0);
1942
1943
1944
1945 off = agino - rec.ir_startino;
1946 ASSERT(off >= 0 && off < XFS_INODES_PER_CHUNK);
1947 ASSERT(!(rec.ir_free & XFS_INOBT_MASK(off)));
1948
1949
1950
1951 rec.ir_free |= XFS_INOBT_MASK(off);
1952 rec.ir_freecount++;
1953
1954
1955
1956
1957
1958
1959 if (!(mp->m_flags & XFS_MOUNT_IKEEP) &&
1960 rec.ir_free == XFS_INOBT_ALL_FREE &&
1961 mp->m_sb.sb_inopblock <= XFS_INODES_PER_CHUNK) {
1962 xic->deleted = true;
1963 xic->first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino);
1964 xic->alloc = xfs_inobt_irec_to_allocmask(&rec);
1965
1966
1967
1968
1969
1970
1971 ilen = rec.ir_freecount;
1972 be32_add_cpu(&agi->agi_count, -ilen);
1973 be32_add_cpu(&agi->agi_freecount, -(ilen - 1));
1974 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT);
1975 pag = xfs_perag_get(mp, agno);
1976 pag->pagi_freecount -= ilen - 1;
1977 xfs_perag_put(pag);
1978 xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen);
1979 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1));
1980
1981 if ((error = xfs_btree_delete(cur, &i))) {
1982 xfs_warn(mp, "%s: xfs_btree_delete returned error %d.",
1983 __func__, error);
1984 goto error0;
1985 }
1986
1987 xfs_difree_inode_chunk(mp, agno, &rec, dfops);
1988 } else {
1989 xic->deleted = false;
1990
1991 error = xfs_inobt_update(cur, &rec);
1992 if (error) {
1993 xfs_warn(mp, "%s: xfs_inobt_update returned error %d.",
1994 __func__, error);
1995 goto error0;
1996 }
1997
1998
1999
2000
2001 be32_add_cpu(&agi->agi_freecount, 1);
2002 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
2003 pag = xfs_perag_get(mp, agno);
2004 pag->pagi_freecount++;
2005 xfs_perag_put(pag);
2006 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1);
2007 }
2008
2009 error = xfs_check_agi_freecount(cur, agi);
2010 if (error)
2011 goto error0;
2012
2013 *orec = rec;
2014 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
2015 return 0;
2016
2017error0:
2018 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
2019 return error;
2020}
2021
2022
2023
2024
2025STATIC int
2026xfs_difree_finobt(
2027 struct xfs_mount *mp,
2028 struct xfs_trans *tp,
2029 struct xfs_buf *agbp,
2030 xfs_agino_t agino,
2031 struct xfs_inobt_rec_incore *ibtrec)
2032{
2033 struct xfs_agi *agi = XFS_BUF_TO_AGI(agbp);
2034 xfs_agnumber_t agno = be32_to_cpu(agi->agi_seqno);
2035 struct xfs_btree_cur *cur;
2036 struct xfs_inobt_rec_incore rec;
2037 int offset = agino - ibtrec->ir_startino;
2038 int error;
2039 int i;
2040
2041 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_FINO);
2042
2043 error = xfs_inobt_lookup(cur, ibtrec->ir_startino, XFS_LOOKUP_EQ, &i);
2044 if (error)
2045 goto error;
2046 if (i == 0) {
2047
2048
2049
2050
2051
2052 XFS_WANT_CORRUPTED_GOTO(mp, ibtrec->ir_freecount == 1, error);
2053
2054 error = xfs_inobt_insert_rec(cur, ibtrec->ir_holemask,
2055 ibtrec->ir_count,
2056 ibtrec->ir_freecount,
2057 ibtrec->ir_free, &i);
2058 if (error)
2059 goto error;
2060 ASSERT(i == 1);
2061
2062 goto out;
2063 }
2064
2065
2066
2067
2068
2069
2070
2071
2072 error = xfs_inobt_get_rec(cur, &rec, &i);
2073 if (error)
2074 goto error;
2075 XFS_WANT_CORRUPTED_GOTO(mp, i == 1, error);
2076
2077 rec.ir_free |= XFS_INOBT_MASK(offset);
2078 rec.ir_freecount++;
2079
2080 XFS_WANT_CORRUPTED_GOTO(mp, (rec.ir_free == ibtrec->ir_free) &&
2081 (rec.ir_freecount == ibtrec->ir_freecount),
2082 error);
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096 if (rec.ir_free == XFS_INOBT_ALL_FREE &&
2097 mp->m_sb.sb_inopblock <= XFS_INODES_PER_CHUNK &&
2098 !(mp->m_flags & XFS_MOUNT_IKEEP)) {
2099 error = xfs_btree_delete(cur, &i);
2100 if (error)
2101 goto error;
2102 ASSERT(i == 1);
2103 } else {
2104 error = xfs_inobt_update(cur, &rec);
2105 if (error)
2106 goto error;
2107 }
2108
2109out:
2110 error = xfs_check_agi_freecount(cur, agi);
2111 if (error)
2112 goto error;
2113
2114 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
2115 return 0;
2116
2117error:
2118 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
2119 return error;
2120}
2121
2122
2123
2124
2125
2126
2127
2128int
2129xfs_difree(
2130 struct xfs_trans *tp,
2131 xfs_ino_t inode,
2132 struct xfs_defer_ops *dfops,
2133 struct xfs_icluster *xic)
2134{
2135
2136 xfs_agblock_t agbno;
2137 struct xfs_buf *agbp;
2138 xfs_agino_t agino;
2139 xfs_agnumber_t agno;
2140 int error;
2141 struct xfs_mount *mp;
2142 struct xfs_inobt_rec_incore rec;
2143
2144 mp = tp->t_mountp;
2145
2146
2147
2148
2149 agno = XFS_INO_TO_AGNO(mp, inode);
2150 if (agno >= mp->m_sb.sb_agcount) {
2151 xfs_warn(mp, "%s: agno >= mp->m_sb.sb_agcount (%d >= %d).",
2152 __func__, agno, mp->m_sb.sb_agcount);
2153 ASSERT(0);
2154 return -EINVAL;
2155 }
2156 agino = XFS_INO_TO_AGINO(mp, inode);
2157 if (inode != XFS_AGINO_TO_INO(mp, agno, agino)) {
2158 xfs_warn(mp, "%s: inode != XFS_AGINO_TO_INO() (%llu != %llu).",
2159 __func__, (unsigned long long)inode,
2160 (unsigned long long)XFS_AGINO_TO_INO(mp, agno, agino));
2161 ASSERT(0);
2162 return -EINVAL;
2163 }
2164 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
2165 if (agbno >= mp->m_sb.sb_agblocks) {
2166 xfs_warn(mp, "%s: agbno >= mp->m_sb.sb_agblocks (%d >= %d).",
2167 __func__, agbno, mp->m_sb.sb_agblocks);
2168 ASSERT(0);
2169 return -EINVAL;
2170 }
2171
2172
2173
2174 error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
2175 if (error) {
2176 xfs_warn(mp, "%s: xfs_ialloc_read_agi() returned error %d.",
2177 __func__, error);
2178 return error;
2179 }
2180
2181
2182
2183
2184 error = xfs_difree_inobt(mp, tp, agbp, agino, dfops, xic, &rec);
2185 if (error)
2186 goto error0;
2187
2188
2189
2190
2191 if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
2192 error = xfs_difree_finobt(mp, tp, agbp, agino, &rec);
2193 if (error)
2194 goto error0;
2195 }
2196
2197 return 0;
2198
2199error0:
2200 return error;
2201}
2202
2203STATIC int
2204xfs_imap_lookup(
2205 struct xfs_mount *mp,
2206 struct xfs_trans *tp,
2207 xfs_agnumber_t agno,
2208 xfs_agino_t agino,
2209 xfs_agblock_t agbno,
2210 xfs_agblock_t *chunk_agbno,
2211 xfs_agblock_t *offset_agbno,
2212 int flags)
2213{
2214 struct xfs_inobt_rec_incore rec;
2215 struct xfs_btree_cur *cur;
2216 struct xfs_buf *agbp;
2217 int error;
2218 int i;
2219
2220 error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
2221 if (error) {
2222 xfs_alert(mp,
2223 "%s: xfs_ialloc_read_agi() returned error %d, agno %d",
2224 __func__, error, agno);
2225 return error;
2226 }
2227
2228
2229
2230
2231
2232
2233
2234 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno, XFS_BTNUM_INO);
2235 error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i);
2236 if (!error) {
2237 if (i)
2238 error = xfs_inobt_get_rec(cur, &rec, &i);
2239 if (!error && i == 0)
2240 error = -EINVAL;
2241 }
2242
2243 xfs_trans_brelse(tp, agbp);
2244 xfs_btree_del_cursor(cur, error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
2245 if (error)
2246 return error;
2247
2248
2249 if (rec.ir_startino > agino ||
2250 rec.ir_startino + mp->m_ialloc_inos <= agino)
2251 return -EINVAL;
2252
2253
2254 if ((flags & XFS_IGET_UNTRUSTED) &&
2255 (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino)))
2256 return -EINVAL;
2257
2258 *chunk_agbno = XFS_AGINO_TO_AGBNO(mp, rec.ir_startino);
2259 *offset_agbno = agbno - *chunk_agbno;
2260 return 0;
2261}
2262
2263
2264
2265
2266int
2267xfs_imap(
2268 xfs_mount_t *mp,
2269 xfs_trans_t *tp,
2270 xfs_ino_t ino,
2271 struct xfs_imap *imap,
2272 uint flags)
2273{
2274 xfs_agblock_t agbno;
2275 xfs_agino_t agino;
2276 xfs_agnumber_t agno;
2277 int blks_per_cluster;
2278 xfs_agblock_t chunk_agbno;
2279 xfs_agblock_t cluster_agbno;
2280 int error;
2281 int offset;
2282 xfs_agblock_t offset_agbno;
2283
2284 ASSERT(ino != NULLFSINO);
2285
2286
2287
2288
2289 agno = XFS_INO_TO_AGNO(mp, ino);
2290 agino = XFS_INO_TO_AGINO(mp, ino);
2291 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
2292 if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
2293 ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
2294#ifdef DEBUG
2295
2296
2297
2298
2299 if (flags & XFS_IGET_UNTRUSTED)
2300 return -EINVAL;
2301 if (agno >= mp->m_sb.sb_agcount) {
2302 xfs_alert(mp,
2303 "%s: agno (%d) >= mp->m_sb.sb_agcount (%d)",
2304 __func__, agno, mp->m_sb.sb_agcount);
2305 }
2306 if (agbno >= mp->m_sb.sb_agblocks) {
2307 xfs_alert(mp,
2308 "%s: agbno (0x%llx) >= mp->m_sb.sb_agblocks (0x%lx)",
2309 __func__, (unsigned long long)agbno,
2310 (unsigned long)mp->m_sb.sb_agblocks);
2311 }
2312 if (ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
2313 xfs_alert(mp,
2314 "%s: ino (0x%llx) != XFS_AGINO_TO_INO() (0x%llx)",
2315 __func__, ino,
2316 XFS_AGINO_TO_INO(mp, agno, agino));
2317 }
2318 xfs_stack_trace();
2319#endif
2320 return -EINVAL;
2321 }
2322
2323 blks_per_cluster = xfs_icluster_size_fsb(mp);
2324
2325
2326
2327
2328
2329
2330
2331
2332 if (flags & XFS_IGET_UNTRUSTED) {
2333 error = xfs_imap_lookup(mp, tp, agno, agino, agbno,
2334 &chunk_agbno, &offset_agbno, flags);
2335 if (error)
2336 return error;
2337 goto out_map;
2338 }
2339
2340
2341
2342
2343
2344 if (blks_per_cluster == 1) {
2345 offset = XFS_INO_TO_OFFSET(mp, ino);
2346 ASSERT(offset < mp->m_sb.sb_inopblock);
2347
2348 imap->im_blkno = XFS_AGB_TO_DADDR(mp, agno, agbno);
2349 imap->im_len = XFS_FSB_TO_BB(mp, 1);
2350 imap->im_boffset = (unsigned short)(offset <<
2351 mp->m_sb.sb_inodelog);
2352 return 0;
2353 }
2354
2355
2356
2357
2358
2359
2360 if (mp->m_inoalign_mask) {
2361 offset_agbno = agbno & mp->m_inoalign_mask;
2362 chunk_agbno = agbno - offset_agbno;
2363 } else {
2364 error = xfs_imap_lookup(mp, tp, agno, agino, agbno,
2365 &chunk_agbno, &offset_agbno, flags);
2366 if (error)
2367 return error;
2368 }
2369
2370out_map:
2371 ASSERT(agbno >= chunk_agbno);
2372 cluster_agbno = chunk_agbno +
2373 ((offset_agbno / blks_per_cluster) * blks_per_cluster);
2374 offset = ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock) +
2375 XFS_INO_TO_OFFSET(mp, ino);
2376
2377 imap->im_blkno = XFS_AGB_TO_DADDR(mp, agno, cluster_agbno);
2378 imap->im_len = XFS_FSB_TO_BB(mp, blks_per_cluster);
2379 imap->im_boffset = (unsigned short)(offset << mp->m_sb.sb_inodelog);
2380
2381
2382
2383
2384
2385
2386
2387 if ((imap->im_blkno + imap->im_len) >
2388 XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)) {
2389 xfs_alert(mp,
2390 "%s: (im_blkno (0x%llx) + im_len (0x%llx)) > sb_dblocks (0x%llx)",
2391 __func__, (unsigned long long) imap->im_blkno,
2392 (unsigned long long) imap->im_len,
2393 XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks));
2394 return -EINVAL;
2395 }
2396 return 0;
2397}
2398
2399
2400
2401
2402void
2403xfs_ialloc_compute_maxlevels(
2404 xfs_mount_t *mp)
2405{
2406 uint inodes;
2407
2408 inodes = (1LL << XFS_INO_AGINO_BITS(mp)) >> XFS_INODES_PER_CHUNK_LOG;
2409 mp->m_in_maxlevels = xfs_btree_compute_maxlevels(mp, mp->m_inobt_mnr,
2410 inodes);
2411}
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425void
2426xfs_ialloc_log_agi(
2427 xfs_trans_t *tp,
2428 xfs_buf_t *bp,
2429 int fields)
2430{
2431 int first;
2432 int last;
2433 static const short offsets[] = {
2434
2435 offsetof(xfs_agi_t, agi_magicnum),
2436 offsetof(xfs_agi_t, agi_versionnum),
2437 offsetof(xfs_agi_t, agi_seqno),
2438 offsetof(xfs_agi_t, agi_length),
2439 offsetof(xfs_agi_t, agi_count),
2440 offsetof(xfs_agi_t, agi_root),
2441 offsetof(xfs_agi_t, agi_level),
2442 offsetof(xfs_agi_t, agi_freecount),
2443 offsetof(xfs_agi_t, agi_newino),
2444 offsetof(xfs_agi_t, agi_dirino),
2445 offsetof(xfs_agi_t, agi_unlinked),
2446 offsetof(xfs_agi_t, agi_free_root),
2447 offsetof(xfs_agi_t, agi_free_level),
2448 sizeof(xfs_agi_t)
2449 };
2450#ifdef DEBUG
2451 xfs_agi_t *agi;
2452
2453 agi = XFS_BUF_TO_AGI(bp);
2454 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
2455#endif
2456
2457
2458
2459
2460
2461
2462 if (fields & XFS_AGI_ALL_BITS_R1) {
2463 xfs_btree_offsets(fields, offsets, XFS_AGI_NUM_BITS_R1,
2464 &first, &last);
2465 xfs_trans_log_buf(tp, bp, first, last);
2466 }
2467
2468
2469
2470
2471
2472 fields &= ~XFS_AGI_ALL_BITS_R1;
2473 if (fields) {
2474 xfs_btree_offsets(fields, offsets, XFS_AGI_NUM_BITS_R2,
2475 &first, &last);
2476 xfs_trans_log_buf(tp, bp, first, last);
2477 }
2478}
2479
2480#ifdef DEBUG
2481STATIC void
2482xfs_check_agi_unlinked(
2483 struct xfs_agi *agi)
2484{
2485 int i;
2486
2487 for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++)
2488 ASSERT(agi->agi_unlinked[i]);
2489}
2490#else
2491#define xfs_check_agi_unlinked(agi)
2492#endif
2493
2494static xfs_failaddr_t
2495xfs_agi_verify(
2496 struct xfs_buf *bp)
2497{
2498 struct xfs_mount *mp = bp->b_target->bt_mount;
2499 struct xfs_agi *agi = XFS_BUF_TO_AGI(bp);
2500
2501 if (xfs_sb_version_hascrc(&mp->m_sb)) {
2502 if (!uuid_equal(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid))
2503 return __this_address;
2504 if (!xfs_log_check_lsn(mp,
2505 be64_to_cpu(XFS_BUF_TO_AGI(bp)->agi_lsn)))
2506 return __this_address;
2507 }
2508
2509
2510
2511
2512 if (agi->agi_magicnum != cpu_to_be32(XFS_AGI_MAGIC))
2513 return __this_address;
2514 if (!XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)))
2515 return __this_address;
2516
2517 if (be32_to_cpu(agi->agi_level) < 1 ||
2518 be32_to_cpu(agi->agi_level) > XFS_BTREE_MAXLEVELS)
2519 return __this_address;
2520
2521 if (xfs_sb_version_hasfinobt(&mp->m_sb) &&
2522 (be32_to_cpu(agi->agi_free_level) < 1 ||
2523 be32_to_cpu(agi->agi_free_level) > XFS_BTREE_MAXLEVELS))
2524 return __this_address;
2525
2526
2527
2528
2529
2530
2531
2532 if (bp->b_pag && be32_to_cpu(agi->agi_seqno) != bp->b_pag->pag_agno)
2533 return __this_address;
2534
2535 xfs_check_agi_unlinked(agi);
2536 return NULL;
2537}
2538
2539static void
2540xfs_agi_read_verify(
2541 struct xfs_buf *bp)
2542{
2543 struct xfs_mount *mp = bp->b_target->bt_mount;
2544 xfs_failaddr_t fa;
2545
2546 if (xfs_sb_version_hascrc(&mp->m_sb) &&
2547 !xfs_buf_verify_cksum(bp, XFS_AGI_CRC_OFF))
2548 xfs_verifier_error(bp, -EFSBADCRC, __this_address);
2549 else {
2550 fa = xfs_agi_verify(bp);
2551 if (XFS_TEST_ERROR(fa, mp, XFS_ERRTAG_IALLOC_READ_AGI))
2552 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
2553 }
2554}
2555
2556static void
2557xfs_agi_write_verify(
2558 struct xfs_buf *bp)
2559{
2560 struct xfs_mount *mp = bp->b_target->bt_mount;
2561 struct xfs_buf_log_item *bip = bp->b_log_item;
2562 xfs_failaddr_t fa;
2563
2564 fa = xfs_agi_verify(bp);
2565 if (fa) {
2566 xfs_verifier_error(bp, -EFSCORRUPTED, fa);
2567 return;
2568 }
2569
2570 if (!xfs_sb_version_hascrc(&mp->m_sb))
2571 return;
2572
2573 if (bip)
2574 XFS_BUF_TO_AGI(bp)->agi_lsn = cpu_to_be64(bip->bli_item.li_lsn);
2575 xfs_buf_update_cksum(bp, XFS_AGI_CRC_OFF);
2576}
2577
2578const struct xfs_buf_ops xfs_agi_buf_ops = {
2579 .name = "xfs_agi",
2580 .verify_read = xfs_agi_read_verify,
2581 .verify_write = xfs_agi_write_verify,
2582 .verify_struct = xfs_agi_verify,
2583};
2584
2585
2586
2587
2588int
2589xfs_read_agi(
2590 struct xfs_mount *mp,
2591 struct xfs_trans *tp,
2592 xfs_agnumber_t agno,
2593 struct xfs_buf **bpp)
2594{
2595 int error;
2596
2597 trace_xfs_read_agi(mp, agno);
2598
2599 ASSERT(agno != NULLAGNUMBER);
2600 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
2601 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
2602 XFS_FSS_TO_BB(mp, 1), 0, bpp, &xfs_agi_buf_ops);
2603 if (error)
2604 return error;
2605 if (tp)
2606 xfs_trans_buf_set_type(tp, *bpp, XFS_BLFT_AGI_BUF);
2607
2608 xfs_buf_set_ref(*bpp, XFS_AGI_REF);
2609 return 0;
2610}
2611
2612int
2613xfs_ialloc_read_agi(
2614 struct xfs_mount *mp,
2615 struct xfs_trans *tp,
2616 xfs_agnumber_t agno,
2617 struct xfs_buf **bpp)
2618{
2619 struct xfs_agi *agi;
2620 struct xfs_perag *pag;
2621 int error;
2622
2623 trace_xfs_ialloc_read_agi(mp, agno);
2624
2625 error = xfs_read_agi(mp, tp, agno, bpp);
2626 if (error)
2627 return error;
2628
2629 agi = XFS_BUF_TO_AGI(*bpp);
2630 pag = xfs_perag_get(mp, agno);
2631 if (!pag->pagi_init) {
2632 pag->pagi_freecount = be32_to_cpu(agi->agi_freecount);
2633 pag->pagi_count = be32_to_cpu(agi->agi_count);
2634 pag->pagi_init = 1;
2635 }
2636
2637
2638
2639
2640
2641 ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
2642 XFS_FORCED_SHUTDOWN(mp));
2643 xfs_perag_put(pag);
2644 return 0;
2645}
2646
2647
2648
2649
2650int
2651xfs_ialloc_pagi_init(
2652 xfs_mount_t *mp,
2653 xfs_trans_t *tp,
2654 xfs_agnumber_t agno)
2655{
2656 xfs_buf_t *bp = NULL;
2657 int error;
2658
2659 error = xfs_ialloc_read_agi(mp, tp, agno, &bp);
2660 if (error)
2661 return error;
2662 if (bp)
2663 xfs_trans_brelse(tp, bp);
2664 return 0;
2665}
2666
2667
2668void
2669xfs_ialloc_agino_range(
2670 struct xfs_mount *mp,
2671 xfs_agnumber_t agno,
2672 xfs_agino_t *first,
2673 xfs_agino_t *last)
2674{
2675 xfs_agblock_t bno;
2676 xfs_agblock_t eoag;
2677
2678 eoag = xfs_ag_block_count(mp, agno);
2679
2680
2681
2682
2683
2684 bno = round_up(XFS_AGFL_BLOCK(mp) + 1,
2685 xfs_ialloc_cluster_alignment(mp));
2686 *first = XFS_OFFBNO_TO_AGINO(mp, bno, 0);
2687
2688
2689
2690
2691
2692 bno = round_down(eoag, xfs_ialloc_cluster_alignment(mp));
2693 *last = XFS_OFFBNO_TO_AGINO(mp, bno, 0) - 1;
2694}
2695
2696
2697
2698
2699
2700bool
2701xfs_verify_agino(
2702 struct xfs_mount *mp,
2703 xfs_agnumber_t agno,
2704 xfs_agino_t agino)
2705{
2706 xfs_agino_t first;
2707 xfs_agino_t last;
2708
2709 xfs_ialloc_agino_range(mp, agno, &first, &last);
2710 return agino >= first && agino <= last;
2711}
2712
2713
2714
2715
2716
2717bool
2718xfs_verify_ino(
2719 struct xfs_mount *mp,
2720 xfs_ino_t ino)
2721{
2722 xfs_agnumber_t agno = XFS_INO_TO_AGNO(mp, ino);
2723 xfs_agino_t agino = XFS_INO_TO_AGINO(mp, ino);
2724
2725 if (agno >= mp->m_sb.sb_agcount)
2726 return false;
2727 if (XFS_AGINO_TO_INO(mp, agno, agino) != ino)
2728 return false;
2729 return xfs_verify_agino(mp, agno, agino);
2730}
2731
2732
2733bool
2734xfs_internal_inum(
2735 struct xfs_mount *mp,
2736 xfs_ino_t ino)
2737{
2738 return ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
2739 (xfs_sb_version_hasquota(&mp->m_sb) &&
2740 xfs_is_quota_inode(&mp->m_sb, ino));
2741}
2742
2743
2744
2745
2746
2747bool
2748xfs_verify_dir_ino(
2749 struct xfs_mount *mp,
2750 xfs_ino_t ino)
2751{
2752 if (xfs_internal_inum(mp, ino))
2753 return false;
2754 return xfs_verify_ino(mp, ino);
2755}
2756
2757
2758int
2759xfs_ialloc_has_inode_record(
2760 struct xfs_btree_cur *cur,
2761 xfs_agino_t low,
2762 xfs_agino_t high,
2763 bool *exists)
2764{
2765 struct xfs_inobt_rec_incore irec;
2766 xfs_agino_t agino;
2767 uint16_t holemask;
2768 int has_record;
2769 int i;
2770 int error;
2771
2772 *exists = false;
2773 error = xfs_inobt_lookup(cur, low, XFS_LOOKUP_LE, &has_record);
2774 while (error == 0 && has_record) {
2775 error = xfs_inobt_get_rec(cur, &irec, &has_record);
2776 if (error || irec.ir_startino > high)
2777 break;
2778
2779 agino = irec.ir_startino;
2780 holemask = irec.ir_holemask;
2781 for (i = 0; i < XFS_INOBT_HOLEMASK_BITS; holemask >>= 1,
2782 i++, agino += XFS_INODES_PER_HOLEMASK_BIT) {
2783 if (holemask & 1)
2784 continue;
2785 if (agino + XFS_INODES_PER_HOLEMASK_BIT > low &&
2786 agino <= high) {
2787 *exists = true;
2788 return 0;
2789 }
2790 }
2791
2792 error = xfs_btree_increment(cur, 0, &has_record);
2793 }
2794 return error;
2795}
2796
2797
2798int
2799xfs_ialloc_has_inodes_at_extent(
2800 struct xfs_btree_cur *cur,
2801 xfs_agblock_t bno,
2802 xfs_extlen_t len,
2803 bool *exists)
2804{
2805 xfs_agino_t low;
2806 xfs_agino_t high;
2807
2808 low = XFS_OFFBNO_TO_AGINO(cur->bc_mp, bno, 0);
2809 high = XFS_OFFBNO_TO_AGINO(cur->bc_mp, bno + len, 0) - 1;
2810
2811 return xfs_ialloc_has_inode_record(cur, low, high, exists);
2812}
2813
2814struct xfs_ialloc_count_inodes {
2815 xfs_agino_t count;
2816 xfs_agino_t freecount;
2817};
2818
2819
2820STATIC int
2821xfs_ialloc_count_inodes_rec(
2822 struct xfs_btree_cur *cur,
2823 union xfs_btree_rec *rec,
2824 void *priv)
2825{
2826 struct xfs_inobt_rec_incore irec;
2827 struct xfs_ialloc_count_inodes *ci = priv;
2828
2829 xfs_inobt_btrec_to_irec(cur->bc_mp, rec, &irec);
2830 ci->count += irec.ir_count;
2831 ci->freecount += irec.ir_freecount;
2832
2833 return 0;
2834}
2835
2836
2837int
2838xfs_ialloc_count_inodes(
2839 struct xfs_btree_cur *cur,
2840 xfs_agino_t *count,
2841 xfs_agino_t *freecount)
2842{
2843 struct xfs_ialloc_count_inodes ci = {0};
2844 int error;
2845
2846 ASSERT(cur->bc_btnum == XFS_BTNUM_INO);
2847 error = xfs_btree_query_all(cur, xfs_ialloc_count_inodes_rec, &ci);
2848 if (error)
2849 return error;
2850
2851 *count = ci.count;
2852 *freecount = ci.freecount;
2853 return 0;
2854}
2855