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_types.h"
21#include "xfs_bit.h"
22#include "xfs_log.h"
23#include "xfs_inum.h"
24#include "xfs_trans.h"
25#include "xfs_sb.h"
26#include "xfs_ag.h"
27#include "xfs_mount.h"
28#include "xfs_bmap_btree.h"
29#include "xfs_alloc_btree.h"
30#include "xfs_ialloc_btree.h"
31#include "xfs_dinode.h"
32#include "xfs_inode.h"
33#include "xfs_btree.h"
34#include "xfs_ialloc.h"
35#include "xfs_alloc.h"
36#include "xfs_rtalloc.h"
37#include "xfs_error.h"
38#include "xfs_bmap.h"
39
40
41
42
43
44static inline int
45xfs_ialloc_cluster_alignment(
46 xfs_alloc_arg_t *args)
47{
48 if (xfs_sb_version_hasalign(&args->mp->m_sb) &&
49 args->mp->m_sb.sb_inoalignmt >=
50 XFS_B_TO_FSBT(args->mp, XFS_INODE_CLUSTER_SIZE(args->mp)))
51 return args->mp->m_sb.sb_inoalignmt;
52 return 1;
53}
54
55
56
57
58int
59xfs_inobt_lookup(
60 struct xfs_btree_cur *cur,
61 xfs_agino_t ino,
62 xfs_lookup_t dir,
63 int *stat)
64{
65 cur->bc_rec.i.ir_startino = ino;
66 cur->bc_rec.i.ir_freecount = 0;
67 cur->bc_rec.i.ir_free = 0;
68 return xfs_btree_lookup(cur, dir, stat);
69}
70
71
72
73
74
75STATIC int
76xfs_inobt_update(
77 struct xfs_btree_cur *cur,
78 xfs_inobt_rec_incore_t *irec)
79{
80 union xfs_btree_rec rec;
81
82 rec.inobt.ir_startino = cpu_to_be32(irec->ir_startino);
83 rec.inobt.ir_freecount = cpu_to_be32(irec->ir_freecount);
84 rec.inobt.ir_free = cpu_to_be64(irec->ir_free);
85 return xfs_btree_update(cur, &rec);
86}
87
88
89
90
91int
92xfs_inobt_get_rec(
93 struct xfs_btree_cur *cur,
94 xfs_inobt_rec_incore_t *irec,
95 int *stat)
96{
97 union xfs_btree_rec *rec;
98 int error;
99
100 error = xfs_btree_get_rec(cur, &rec, stat);
101 if (!error && *stat == 1) {
102 irec->ir_startino = be32_to_cpu(rec->inobt.ir_startino);
103 irec->ir_freecount = be32_to_cpu(rec->inobt.ir_freecount);
104 irec->ir_free = be64_to_cpu(rec->inobt.ir_free);
105 }
106 return error;
107}
108
109
110
111
112#ifdef DEBUG
113STATIC int
114xfs_check_agi_freecount(
115 struct xfs_btree_cur *cur,
116 struct xfs_agi *agi)
117{
118 if (cur->bc_nlevels == 1) {
119 xfs_inobt_rec_incore_t rec;
120 int freecount = 0;
121 int error;
122 int i;
123
124 error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);
125 if (error)
126 return error;
127
128 do {
129 error = xfs_inobt_get_rec(cur, &rec, &i);
130 if (error)
131 return error;
132
133 if (i) {
134 freecount += rec.ir_freecount;
135 error = xfs_btree_increment(cur, 0, &i);
136 if (error)
137 return error;
138 }
139 } while (i == 1);
140
141 if (!XFS_FORCED_SHUTDOWN(cur->bc_mp))
142 ASSERT(freecount == be32_to_cpu(agi->agi_freecount));
143 }
144 return 0;
145}
146#else
147#define xfs_check_agi_freecount(cur, agi) 0
148#endif
149
150
151
152
153STATIC int
154xfs_ialloc_inode_init(
155 struct xfs_mount *mp,
156 struct xfs_trans *tp,
157 xfs_agnumber_t agno,
158 xfs_agblock_t agbno,
159 xfs_agblock_t length,
160 unsigned int gen)
161{
162 struct xfs_buf *fbuf;
163 struct xfs_dinode *free;
164 int blks_per_cluster, nbufs, ninodes;
165 int version;
166 int i, j;
167 xfs_daddr_t d;
168
169
170
171
172
173
174 if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) {
175 blks_per_cluster = 1;
176 nbufs = length;
177 ninodes = mp->m_sb.sb_inopblock;
178 } else {
179 blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) /
180 mp->m_sb.sb_blocksize;
181 nbufs = length / blks_per_cluster;
182 ninodes = blks_per_cluster * mp->m_sb.sb_inopblock;
183 }
184
185
186
187
188
189
190
191
192 if (xfs_sb_version_hasnlink(&mp->m_sb))
193 version = 2;
194 else
195 version = 1;
196
197 for (j = 0; j < nbufs; j++) {
198
199
200
201 d = XFS_AGB_TO_DADDR(mp, agno, agbno + (j * blks_per_cluster));
202 fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
203 mp->m_bsize * blks_per_cluster,
204 XBF_LOCK);
205 if (!fbuf)
206 return ENOMEM;
207
208
209
210
211
212
213
214 xfs_buf_zero(fbuf, 0, ninodes << mp->m_sb.sb_inodelog);
215 for (i = 0; i < ninodes; i++) {
216 int ioffset = i << mp->m_sb.sb_inodelog;
217 uint isize = sizeof(struct xfs_dinode);
218
219 free = xfs_make_iptr(mp, fbuf, i);
220 free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
221 free->di_version = version;
222 free->di_gen = cpu_to_be32(gen);
223 free->di_next_unlinked = cpu_to_be32(NULLAGINO);
224 xfs_trans_log_buf(tp, fbuf, ioffset, ioffset + isize - 1);
225 }
226 xfs_trans_inode_alloc_buf(tp, fbuf);
227 }
228 return 0;
229}
230
231
232
233
234
235STATIC int
236xfs_ialloc_ag_alloc(
237 xfs_trans_t *tp,
238 xfs_buf_t *agbp,
239 int *alloc)
240{
241 xfs_agi_t *agi;
242 xfs_alloc_arg_t args;
243 xfs_btree_cur_t *cur;
244 xfs_agnumber_t agno;
245 int error;
246 int i;
247 xfs_agino_t newino;
248 xfs_agino_t newlen;
249 xfs_agino_t thisino;
250 int isaligned = 0;
251
252 struct xfs_perag *pag;
253
254 args.tp = tp;
255 args.mp = tp->t_mountp;
256
257
258
259
260
261 newlen = XFS_IALLOC_INODES(args.mp);
262 if (args.mp->m_maxicount &&
263 args.mp->m_sb.sb_icount + newlen > args.mp->m_maxicount)
264 return XFS_ERROR(ENOSPC);
265 args.minlen = args.maxlen = XFS_IALLOC_BLOCKS(args.mp);
266
267
268
269
270
271 agi = XFS_BUF_TO_AGI(agbp);
272 newino = be32_to_cpu(agi->agi_newino);
273 agno = be32_to_cpu(agi->agi_seqno);
274 args.agbno = XFS_AGINO_TO_AGBNO(args.mp, newino) +
275 XFS_IALLOC_BLOCKS(args.mp);
276 if (likely(newino != NULLAGINO &&
277 (args.agbno < be32_to_cpu(agi->agi_length)))) {
278 args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
279 args.type = XFS_ALLOCTYPE_THIS_BNO;
280 args.mod = args.total = args.wasdel = args.isfl =
281 args.userdata = args.minalignslop = 0;
282 args.prod = 1;
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297 args.alignment = 1;
298 args.minalignslop = xfs_ialloc_cluster_alignment(&args) - 1;
299
300
301 args.minleft = args.mp->m_in_maxlevels - 1;
302 if ((error = xfs_alloc_vextent(&args)))
303 return error;
304 } else
305 args.fsbno = NULLFSBLOCK;
306
307 if (unlikely(args.fsbno == NULLFSBLOCK)) {
308
309
310
311
312
313
314
315
316 isaligned = 0;
317 if (args.mp->m_sinoalign) {
318 ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN));
319 args.alignment = args.mp->m_dalign;
320 isaligned = 1;
321 } else
322 args.alignment = xfs_ialloc_cluster_alignment(&args);
323
324
325
326
327
328 args.agbno = be32_to_cpu(agi->agi_root);
329 args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
330
331
332
333 args.type = XFS_ALLOCTYPE_NEAR_BNO;
334 args.mod = args.total = args.wasdel = args.isfl =
335 args.userdata = args.minalignslop = 0;
336 args.prod = 1;
337
338
339
340 args.minleft = args.mp->m_in_maxlevels - 1;
341 if ((error = xfs_alloc_vextent(&args)))
342 return error;
343 }
344
345
346
347
348
349 if (isaligned && args.fsbno == NULLFSBLOCK) {
350 args.type = XFS_ALLOCTYPE_NEAR_BNO;
351 args.agbno = be32_to_cpu(agi->agi_root);
352 args.fsbno = XFS_AGB_TO_FSB(args.mp, agno, args.agbno);
353 args.alignment = xfs_ialloc_cluster_alignment(&args);
354 if ((error = xfs_alloc_vextent(&args)))
355 return error;
356 }
357
358 if (args.fsbno == NULLFSBLOCK) {
359 *alloc = 0;
360 return 0;
361 }
362 ASSERT(args.len == args.minlen);
363
364
365
366
367
368
369
370
371
372
373 error = xfs_ialloc_inode_init(args.mp, tp, agno, args.agbno,
374 args.len, random32());
375
376 if (error)
377 return error;
378
379
380
381 newino = XFS_OFFBNO_TO_AGINO(args.mp, args.agbno, 0);
382 be32_add_cpu(&agi->agi_count, newlen);
383 be32_add_cpu(&agi->agi_freecount, newlen);
384 pag = xfs_perag_get(args.mp, agno);
385 pag->pagi_freecount += newlen;
386 xfs_perag_put(pag);
387 agi->agi_newino = cpu_to_be32(newino);
388
389
390
391
392 cur = xfs_inobt_init_cursor(args.mp, tp, agbp, agno);
393 for (thisino = newino;
394 thisino < newino + newlen;
395 thisino += XFS_INODES_PER_CHUNK) {
396 cur->bc_rec.i.ir_startino = thisino;
397 cur->bc_rec.i.ir_freecount = XFS_INODES_PER_CHUNK;
398 cur->bc_rec.i.ir_free = XFS_INOBT_ALL_FREE;
399 error = xfs_btree_lookup(cur, XFS_LOOKUP_EQ, &i);
400 if (error) {
401 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
402 return error;
403 }
404 ASSERT(i == 0);
405 error = xfs_btree_insert(cur, &i);
406 if (error) {
407 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
408 return error;
409 }
410 ASSERT(i == 1);
411 }
412 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
413
414
415
416 xfs_ialloc_log_agi(tp, agbp,
417 XFS_AGI_COUNT | XFS_AGI_FREECOUNT | XFS_AGI_NEWINO);
418
419
420
421 xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, (long)newlen);
422 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, (long)newlen);
423 *alloc = 1;
424 return 0;
425}
426
427STATIC xfs_agnumber_t
428xfs_ialloc_next_ag(
429 xfs_mount_t *mp)
430{
431 xfs_agnumber_t agno;
432
433 spin_lock(&mp->m_agirotor_lock);
434 agno = mp->m_agirotor;
435 if (++mp->m_agirotor == mp->m_maxagi)
436 mp->m_agirotor = 0;
437 spin_unlock(&mp->m_agirotor_lock);
438
439 return agno;
440}
441
442
443
444
445
446STATIC xfs_buf_t *
447xfs_ialloc_ag_select(
448 xfs_trans_t *tp,
449 xfs_ino_t parent,
450 umode_t mode,
451 int okalloc)
452{
453 xfs_buf_t *agbp;
454 xfs_agnumber_t agcount;
455 xfs_agnumber_t agno;
456 int flags;
457 xfs_extlen_t ineed;
458 xfs_extlen_t longest = 0;
459 xfs_mount_t *mp;
460 int needspace;
461 xfs_perag_t *pag;
462 xfs_agnumber_t pagno;
463
464
465
466
467
468 needspace = S_ISDIR(mode) || S_ISREG(mode) || S_ISLNK(mode);
469 mp = tp->t_mountp;
470 agcount = mp->m_maxagi;
471 if (S_ISDIR(mode))
472 pagno = xfs_ialloc_next_ag(mp);
473 else {
474 pagno = XFS_INO_TO_AGNO(mp, parent);
475 if (pagno >= agcount)
476 pagno = 0;
477 }
478 ASSERT(pagno < agcount);
479
480
481
482
483
484
485
486 agno = pagno;
487 flags = XFS_ALLOC_FLAG_TRYLOCK;
488 for (;;) {
489 pag = xfs_perag_get(mp, agno);
490 if (!pag->pagi_init) {
491 if (xfs_ialloc_read_agi(mp, tp, agno, &agbp)) {
492 agbp = NULL;
493 goto nextag;
494 }
495 } else
496 agbp = NULL;
497
498 if (!pag->pagi_inodeok) {
499 xfs_ialloc_next_ag(mp);
500 goto unlock_nextag;
501 }
502
503
504
505
506
507 ineed = pag->pagi_freecount ? 0 : XFS_IALLOC_BLOCKS(mp);
508 if (ineed && !pag->pagf_init) {
509 if (agbp == NULL &&
510 xfs_ialloc_read_agi(mp, tp, agno, &agbp)) {
511 agbp = NULL;
512 goto nextag;
513 }
514 (void)xfs_alloc_pagf_init(mp, tp, agno, flags);
515 }
516 if (!ineed || pag->pagf_init) {
517 if (ineed && !(longest = pag->pagf_longest))
518 longest = pag->pagf_flcount > 0;
519 if (!ineed ||
520 (pag->pagf_freeblks >= needspace + ineed &&
521 longest >= ineed &&
522 okalloc)) {
523 if (agbp == NULL &&
524 xfs_ialloc_read_agi(mp, tp, agno, &agbp)) {
525 agbp = NULL;
526 goto nextag;
527 }
528 xfs_perag_put(pag);
529 return agbp;
530 }
531 }
532unlock_nextag:
533 if (agbp)
534 xfs_trans_brelse(tp, agbp);
535nextag:
536 xfs_perag_put(pag);
537
538
539
540
541 if (XFS_FORCED_SHUTDOWN(mp))
542 return NULL;
543 agno++;
544 if (agno >= agcount)
545 agno = 0;
546 if (agno == pagno) {
547 if (flags == 0)
548 return NULL;
549 flags = 0;
550 }
551 }
552}
553
554
555
556
557STATIC int
558xfs_ialloc_next_rec(
559 struct xfs_btree_cur *cur,
560 xfs_inobt_rec_incore_t *rec,
561 int *done,
562 int left)
563{
564 int error;
565 int i;
566
567 if (left)
568 error = xfs_btree_decrement(cur, 0, &i);
569 else
570 error = xfs_btree_increment(cur, 0, &i);
571
572 if (error)
573 return error;
574 *done = !i;
575 if (i) {
576 error = xfs_inobt_get_rec(cur, rec, &i);
577 if (error)
578 return error;
579 XFS_WANT_CORRUPTED_RETURN(i == 1);
580 }
581
582 return 0;
583}
584
585STATIC int
586xfs_ialloc_get_rec(
587 struct xfs_btree_cur *cur,
588 xfs_agino_t agino,
589 xfs_inobt_rec_incore_t *rec,
590 int *done,
591 int left)
592{
593 int error;
594 int i;
595
596 error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_EQ, &i);
597 if (error)
598 return error;
599 *done = !i;
600 if (i) {
601 error = xfs_inobt_get_rec(cur, rec, &i);
602 if (error)
603 return error;
604 XFS_WANT_CORRUPTED_RETURN(i == 1);
605 }
606
607 return 0;
608}
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639int
640xfs_dialloc(
641 xfs_trans_t *tp,
642 xfs_ino_t parent,
643 umode_t mode,
644 int okalloc,
645 xfs_buf_t **IO_agbp,
646 boolean_t *alloc_done,
647
648 xfs_ino_t *inop)
649{
650 xfs_agnumber_t agcount;
651 xfs_buf_t *agbp;
652 xfs_agnumber_t agno;
653 xfs_agi_t *agi;
654 xfs_btree_cur_t *cur;
655 int error;
656 int i;
657 int ialloced;
658 int noroom = 0;
659 xfs_ino_t ino;
660
661 int j;
662 xfs_mount_t *mp;
663 int offset;
664 xfs_agino_t pagino;
665 xfs_agnumber_t pagno;
666 xfs_inobt_rec_incore_t rec;
667 xfs_agnumber_t tagno;
668 xfs_btree_cur_t *tcur;
669 xfs_inobt_rec_incore_t trec;
670 struct xfs_perag *pag;
671
672
673 if (*IO_agbp == NULL) {
674
675
676
677
678 agbp = xfs_ialloc_ag_select(tp, parent, mode, okalloc);
679
680
681
682
683 if (!agbp) {
684 *inop = NULLFSINO;
685 return 0;
686 }
687 agi = XFS_BUF_TO_AGI(agbp);
688 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
689 } else {
690
691
692
693
694 agbp = *IO_agbp;
695 agi = XFS_BUF_TO_AGI(agbp);
696 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
697 ASSERT(be32_to_cpu(agi->agi_freecount) > 0);
698 }
699 mp = tp->t_mountp;
700 agcount = mp->m_sb.sb_agcount;
701 agno = be32_to_cpu(agi->agi_seqno);
702 tagno = agno;
703 pagno = XFS_INO_TO_AGNO(mp, parent);
704 pagino = XFS_INO_TO_AGINO(mp, parent);
705
706
707
708
709
710
711
712 if (mp->m_maxicount &&
713 mp->m_sb.sb_icount + XFS_IALLOC_INODES(mp) > mp->m_maxicount) {
714 noroom = 1;
715 okalloc = 0;
716 }
717
718
719
720
721
722
723 *alloc_done = B_FALSE;
724 while (!agi->agi_freecount) {
725
726
727
728
729 if (okalloc) {
730
731
732
733
734 if ((error = xfs_ialloc_ag_alloc(tp, agbp, &ialloced))) {
735 xfs_trans_brelse(tp, agbp);
736 if (error == ENOSPC) {
737 *inop = NULLFSINO;
738 return 0;
739 } else
740 return error;
741 }
742 if (ialloced) {
743
744
745
746
747
748
749 ASSERT(be32_to_cpu(agi->agi_freecount) > 0);
750 *alloc_done = B_TRUE;
751 *IO_agbp = agbp;
752 *inop = NULLFSINO;
753 return 0;
754 }
755 }
756
757
758
759 xfs_trans_brelse(tp, agbp);
760
761
762
763nextag:
764 if (++tagno == agcount)
765 tagno = 0;
766 if (tagno == agno) {
767 *inop = NULLFSINO;
768 return noroom ? ENOSPC : 0;
769 }
770 pag = xfs_perag_get(mp, tagno);
771 if (pag->pagi_inodeok == 0) {
772 xfs_perag_put(pag);
773 goto nextag;
774 }
775 error = xfs_ialloc_read_agi(mp, tp, tagno, &agbp);
776 xfs_perag_put(pag);
777 if (error)
778 goto nextag;
779 agi = XFS_BUF_TO_AGI(agbp);
780 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
781 }
782
783
784
785
786
787 agno = tagno;
788 *IO_agbp = NULL;
789 pag = xfs_perag_get(mp, agno);
790
791 restart_pagno:
792 cur = xfs_inobt_init_cursor(mp, tp, agbp, be32_to_cpu(agi->agi_seqno));
793
794
795
796
797 if (!pagino)
798 pagino = be32_to_cpu(agi->agi_newino);
799
800 error = xfs_check_agi_freecount(cur, agi);
801 if (error)
802 goto error0;
803
804
805
806
807 if (pagno == agno) {
808 int doneleft;
809 int doneright;
810 int searchdistance = 10;
811
812 error = xfs_inobt_lookup(cur, pagino, XFS_LOOKUP_LE, &i);
813 if (error)
814 goto error0;
815 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
816
817 error = xfs_inobt_get_rec(cur, &rec, &j);
818 if (error)
819 goto error0;
820 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
821
822 if (rec.ir_freecount > 0) {
823
824
825
826
827 goto alloc_inode;
828 }
829
830
831
832
833
834
835
836 error = xfs_btree_dup_cursor(cur, &tcur);
837 if (error)
838 goto error0;
839
840
841
842
843 if (pagino != NULLAGINO &&
844 pag->pagl_pagino == pagino &&
845 pag->pagl_leftrec != NULLAGINO &&
846 pag->pagl_rightrec != NULLAGINO) {
847 error = xfs_ialloc_get_rec(tcur, pag->pagl_leftrec,
848 &trec, &doneleft, 1);
849 if (error)
850 goto error1;
851
852 error = xfs_ialloc_get_rec(cur, pag->pagl_rightrec,
853 &rec, &doneright, 0);
854 if (error)
855 goto error1;
856 } else {
857
858 error = xfs_ialloc_next_rec(tcur, &trec, &doneleft, 1);
859 if (error)
860 goto error1;
861
862
863 error = xfs_ialloc_next_rec(cur, &rec, &doneright, 0);
864 if (error)
865 goto error1;
866 }
867
868
869
870
871 while (!doneleft || !doneright) {
872 int useleft;
873
874 if (!--searchdistance) {
875
876
877
878
879 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
880 pag->pagl_leftrec = trec.ir_startino;
881 pag->pagl_rightrec = rec.ir_startino;
882 pag->pagl_pagino = pagino;
883 goto newino;
884 }
885
886
887 if (!doneleft && !doneright) {
888 useleft = pagino -
889 (trec.ir_startino + XFS_INODES_PER_CHUNK - 1) <
890 rec.ir_startino - pagino;
891 } else {
892 useleft = !doneleft;
893 }
894
895
896 if (useleft && trec.ir_freecount) {
897 rec = trec;
898 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
899 cur = tcur;
900
901 pag->pagl_leftrec = trec.ir_startino;
902 pag->pagl_rightrec = rec.ir_startino;
903 pag->pagl_pagino = pagino;
904 goto alloc_inode;
905 }
906
907
908 if (!useleft && rec.ir_freecount) {
909 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
910
911 pag->pagl_leftrec = trec.ir_startino;
912 pag->pagl_rightrec = rec.ir_startino;
913 pag->pagl_pagino = pagino;
914 goto alloc_inode;
915 }
916
917
918 if (useleft) {
919 error = xfs_ialloc_next_rec(tcur, &trec,
920 &doneleft, 1);
921 } else {
922 error = xfs_ialloc_next_rec(cur, &rec,
923 &doneright, 0);
924 }
925 if (error)
926 goto error1;
927 }
928
929
930
931
932
933
934
935
936 pag->pagl_pagino = NULLAGINO;
937 pag->pagl_leftrec = NULLAGINO;
938 pag->pagl_rightrec = NULLAGINO;
939 xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
940 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
941 goto restart_pagno;
942 }
943
944
945
946
947
948newino:
949 if (agi->agi_newino != cpu_to_be32(NULLAGINO)) {
950 error = xfs_inobt_lookup(cur, be32_to_cpu(agi->agi_newino),
951 XFS_LOOKUP_EQ, &i);
952 if (error)
953 goto error0;
954
955 if (i == 1) {
956 error = xfs_inobt_get_rec(cur, &rec, &j);
957 if (error)
958 goto error0;
959
960 if (j == 1 && rec.ir_freecount > 0) {
961
962
963
964
965 goto alloc_inode;
966 }
967 }
968 }
969
970
971
972
973 error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &i);
974 if (error)
975 goto error0;
976 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
977
978 for (;;) {
979 error = xfs_inobt_get_rec(cur, &rec, &i);
980 if (error)
981 goto error0;
982 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
983 if (rec.ir_freecount > 0)
984 break;
985 error = xfs_btree_increment(cur, 0, &i);
986 if (error)
987 goto error0;
988 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
989 }
990
991alloc_inode:
992 offset = xfs_ialloc_find_free(&rec.ir_free);
993 ASSERT(offset >= 0);
994 ASSERT(offset < XFS_INODES_PER_CHUNK);
995 ASSERT((XFS_AGINO_TO_OFFSET(mp, rec.ir_startino) %
996 XFS_INODES_PER_CHUNK) == 0);
997 ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino + offset);
998 rec.ir_free &= ~XFS_INOBT_MASK(offset);
999 rec.ir_freecount--;
1000 error = xfs_inobt_update(cur, &rec);
1001 if (error)
1002 goto error0;
1003 be32_add_cpu(&agi->agi_freecount, -1);
1004 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
1005 pag->pagi_freecount--;
1006
1007 error = xfs_check_agi_freecount(cur, agi);
1008 if (error)
1009 goto error0;
1010
1011 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1012 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -1);
1013 xfs_perag_put(pag);
1014 *inop = ino;
1015 return 0;
1016error1:
1017 xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
1018error0:
1019 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
1020 xfs_perag_put(pag);
1021 return error;
1022}
1023
1024
1025
1026
1027
1028
1029
1030int
1031xfs_difree(
1032 xfs_trans_t *tp,
1033 xfs_ino_t inode,
1034 xfs_bmap_free_t *flist,
1035 int *delete,
1036 xfs_ino_t *first_ino)
1037{
1038
1039 xfs_agblock_t agbno;
1040 xfs_buf_t *agbp;
1041 xfs_agino_t agino;
1042 xfs_agnumber_t agno;
1043 xfs_agi_t *agi;
1044 xfs_btree_cur_t *cur;
1045 int error;
1046 int i;
1047 int ilen;
1048 xfs_mount_t *mp;
1049 int off;
1050 xfs_inobt_rec_incore_t rec;
1051 struct xfs_perag *pag;
1052
1053 mp = tp->t_mountp;
1054
1055
1056
1057
1058 agno = XFS_INO_TO_AGNO(mp, inode);
1059 if (agno >= mp->m_sb.sb_agcount) {
1060 xfs_warn(mp, "%s: agno >= mp->m_sb.sb_agcount (%d >= %d).",
1061 __func__, agno, mp->m_sb.sb_agcount);
1062 ASSERT(0);
1063 return XFS_ERROR(EINVAL);
1064 }
1065 agino = XFS_INO_TO_AGINO(mp, inode);
1066 if (inode != XFS_AGINO_TO_INO(mp, agno, agino)) {
1067 xfs_warn(mp, "%s: inode != XFS_AGINO_TO_INO() (%llu != %llu).",
1068 __func__, (unsigned long long)inode,
1069 (unsigned long long)XFS_AGINO_TO_INO(mp, agno, agino));
1070 ASSERT(0);
1071 return XFS_ERROR(EINVAL);
1072 }
1073 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
1074 if (agbno >= mp->m_sb.sb_agblocks) {
1075 xfs_warn(mp, "%s: agbno >= mp->m_sb.sb_agblocks (%d >= %d).",
1076 __func__, agbno, mp->m_sb.sb_agblocks);
1077 ASSERT(0);
1078 return XFS_ERROR(EINVAL);
1079 }
1080
1081
1082
1083 error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
1084 if (error) {
1085 xfs_warn(mp, "%s: xfs_ialloc_read_agi() returned error %d.",
1086 __func__, error);
1087 return error;
1088 }
1089 agi = XFS_BUF_TO_AGI(agbp);
1090 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
1091 ASSERT(agbno < be32_to_cpu(agi->agi_length));
1092
1093
1094
1095 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno);
1096
1097 error = xfs_check_agi_freecount(cur, agi);
1098 if (error)
1099 goto error0;
1100
1101
1102
1103
1104 if ((error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i))) {
1105 xfs_warn(mp, "%s: xfs_inobt_lookup() returned error %d.",
1106 __func__, error);
1107 goto error0;
1108 }
1109 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1110 error = xfs_inobt_get_rec(cur, &rec, &i);
1111 if (error) {
1112 xfs_warn(mp, "%s: xfs_inobt_get_rec() returned error %d.",
1113 __func__, error);
1114 goto error0;
1115 }
1116 XFS_WANT_CORRUPTED_GOTO(i == 1, error0);
1117
1118
1119
1120 off = agino - rec.ir_startino;
1121 ASSERT(off >= 0 && off < XFS_INODES_PER_CHUNK);
1122 ASSERT(!(rec.ir_free & XFS_INOBT_MASK(off)));
1123
1124
1125
1126 rec.ir_free |= XFS_INOBT_MASK(off);
1127 rec.ir_freecount++;
1128
1129
1130
1131
1132 if (!(mp->m_flags & XFS_MOUNT_IKEEP) &&
1133 (rec.ir_freecount == XFS_IALLOC_INODES(mp))) {
1134
1135 *delete = 1;
1136 *first_ino = XFS_AGINO_TO_INO(mp, agno, rec.ir_startino);
1137
1138
1139
1140
1141
1142
1143 ilen = XFS_IALLOC_INODES(mp);
1144 be32_add_cpu(&agi->agi_count, -ilen);
1145 be32_add_cpu(&agi->agi_freecount, -(ilen - 1));
1146 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_COUNT | XFS_AGI_FREECOUNT);
1147 pag = xfs_perag_get(mp, agno);
1148 pag->pagi_freecount -= ilen - 1;
1149 xfs_perag_put(pag);
1150 xfs_trans_mod_sb(tp, XFS_TRANS_SB_ICOUNT, -ilen);
1151 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, -(ilen - 1));
1152
1153 if ((error = xfs_btree_delete(cur, &i))) {
1154 xfs_warn(mp, "%s: xfs_btree_delete returned error %d.",
1155 __func__, error);
1156 goto error0;
1157 }
1158
1159 xfs_bmap_add_free(XFS_AGB_TO_FSB(mp,
1160 agno, XFS_INO_TO_AGBNO(mp,rec.ir_startino)),
1161 XFS_IALLOC_BLOCKS(mp), flist, mp);
1162 } else {
1163 *delete = 0;
1164
1165 error = xfs_inobt_update(cur, &rec);
1166 if (error) {
1167 xfs_warn(mp, "%s: xfs_inobt_update returned error %d.",
1168 __func__, error);
1169 goto error0;
1170 }
1171
1172
1173
1174
1175 be32_add_cpu(&agi->agi_freecount, 1);
1176 xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREECOUNT);
1177 pag = xfs_perag_get(mp, agno);
1178 pag->pagi_freecount++;
1179 xfs_perag_put(pag);
1180 xfs_trans_mod_sb(tp, XFS_TRANS_SB_IFREE, 1);
1181 }
1182
1183 error = xfs_check_agi_freecount(cur, agi);
1184 if (error)
1185 goto error0;
1186
1187 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1188 return 0;
1189
1190error0:
1191 xfs_btree_del_cursor(cur, XFS_BTREE_ERROR);
1192 return error;
1193}
1194
1195STATIC int
1196xfs_imap_lookup(
1197 struct xfs_mount *mp,
1198 struct xfs_trans *tp,
1199 xfs_agnumber_t agno,
1200 xfs_agino_t agino,
1201 xfs_agblock_t agbno,
1202 xfs_agblock_t *chunk_agbno,
1203 xfs_agblock_t *offset_agbno,
1204 int flags)
1205{
1206 struct xfs_inobt_rec_incore rec;
1207 struct xfs_btree_cur *cur;
1208 struct xfs_buf *agbp;
1209 int error;
1210 int i;
1211
1212 error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
1213 if (error) {
1214 xfs_alert(mp,
1215 "%s: xfs_ialloc_read_agi() returned error %d, agno %d",
1216 __func__, error, agno);
1217 return error;
1218 }
1219
1220
1221
1222
1223
1224
1225
1226 cur = xfs_inobt_init_cursor(mp, tp, agbp, agno);
1227 error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &i);
1228 if (!error) {
1229 if (i)
1230 error = xfs_inobt_get_rec(cur, &rec, &i);
1231 if (!error && i == 0)
1232 error = EINVAL;
1233 }
1234
1235 xfs_trans_brelse(tp, agbp);
1236 xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR);
1237 if (error)
1238 return error;
1239
1240
1241 if (rec.ir_startino > agino ||
1242 rec.ir_startino + XFS_IALLOC_INODES(mp) <= agino)
1243 return EINVAL;
1244
1245
1246 if ((flags & XFS_IGET_UNTRUSTED) &&
1247 (rec.ir_free & XFS_INOBT_MASK(agino - rec.ir_startino)))
1248 return EINVAL;
1249
1250 *chunk_agbno = XFS_AGINO_TO_AGBNO(mp, rec.ir_startino);
1251 *offset_agbno = agbno - *chunk_agbno;
1252 return 0;
1253}
1254
1255
1256
1257
1258int
1259xfs_imap(
1260 xfs_mount_t *mp,
1261 xfs_trans_t *tp,
1262 xfs_ino_t ino,
1263 struct xfs_imap *imap,
1264 uint flags)
1265{
1266 xfs_agblock_t agbno;
1267 xfs_agino_t agino;
1268 xfs_agnumber_t agno;
1269 int blks_per_cluster;
1270 xfs_agblock_t chunk_agbno;
1271 xfs_agblock_t cluster_agbno;
1272 int error;
1273 int offset;
1274 int offset_agbno;
1275
1276 ASSERT(ino != NULLFSINO);
1277
1278
1279
1280
1281 agno = XFS_INO_TO_AGNO(mp, ino);
1282 agino = XFS_INO_TO_AGINO(mp, ino);
1283 agbno = XFS_AGINO_TO_AGBNO(mp, agino);
1284 if (agno >= mp->m_sb.sb_agcount || agbno >= mp->m_sb.sb_agblocks ||
1285 ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
1286#ifdef DEBUG
1287
1288
1289
1290
1291 if (flags & XFS_IGET_UNTRUSTED)
1292 return XFS_ERROR(EINVAL);
1293 if (agno >= mp->m_sb.sb_agcount) {
1294 xfs_alert(mp,
1295 "%s: agno (%d) >= mp->m_sb.sb_agcount (%d)",
1296 __func__, agno, mp->m_sb.sb_agcount);
1297 }
1298 if (agbno >= mp->m_sb.sb_agblocks) {
1299 xfs_alert(mp,
1300 "%s: agbno (0x%llx) >= mp->m_sb.sb_agblocks (0x%lx)",
1301 __func__, (unsigned long long)agbno,
1302 (unsigned long)mp->m_sb.sb_agblocks);
1303 }
1304 if (ino != XFS_AGINO_TO_INO(mp, agno, agino)) {
1305 xfs_alert(mp,
1306 "%s: ino (0x%llx) != XFS_AGINO_TO_INO() (0x%llx)",
1307 __func__, ino,
1308 XFS_AGINO_TO_INO(mp, agno, agino));
1309 }
1310 xfs_stack_trace();
1311#endif
1312 return XFS_ERROR(EINVAL);
1313 }
1314
1315 blks_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_blocklog;
1316
1317
1318
1319
1320
1321
1322
1323
1324 if (flags & XFS_IGET_UNTRUSTED) {
1325 error = xfs_imap_lookup(mp, tp, agno, agino, agbno,
1326 &chunk_agbno, &offset_agbno, flags);
1327 if (error)
1328 return error;
1329 goto out_map;
1330 }
1331
1332
1333
1334
1335
1336 if (XFS_INODE_CLUSTER_SIZE(mp) <= mp->m_sb.sb_blocksize) {
1337 offset = XFS_INO_TO_OFFSET(mp, ino);
1338 ASSERT(offset < mp->m_sb.sb_inopblock);
1339
1340 imap->im_blkno = XFS_AGB_TO_DADDR(mp, agno, agbno);
1341 imap->im_len = XFS_FSB_TO_BB(mp, 1);
1342 imap->im_boffset = (ushort)(offset << mp->m_sb.sb_inodelog);
1343 return 0;
1344 }
1345
1346
1347
1348
1349
1350
1351 if (mp->m_inoalign_mask) {
1352 offset_agbno = agbno & mp->m_inoalign_mask;
1353 chunk_agbno = agbno - offset_agbno;
1354 } else {
1355 error = xfs_imap_lookup(mp, tp, agno, agino, agbno,
1356 &chunk_agbno, &offset_agbno, flags);
1357 if (error)
1358 return error;
1359 }
1360
1361out_map:
1362 ASSERT(agbno >= chunk_agbno);
1363 cluster_agbno = chunk_agbno +
1364 ((offset_agbno / blks_per_cluster) * blks_per_cluster);
1365 offset = ((agbno - cluster_agbno) * mp->m_sb.sb_inopblock) +
1366 XFS_INO_TO_OFFSET(mp, ino);
1367
1368 imap->im_blkno = XFS_AGB_TO_DADDR(mp, agno, cluster_agbno);
1369 imap->im_len = XFS_FSB_TO_BB(mp, blks_per_cluster);
1370 imap->im_boffset = (ushort)(offset << mp->m_sb.sb_inodelog);
1371
1372
1373
1374
1375
1376
1377
1378 if ((imap->im_blkno + imap->im_len) >
1379 XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)) {
1380 xfs_alert(mp,
1381 "%s: (im_blkno (0x%llx) + im_len (0x%llx)) > sb_dblocks (0x%llx)",
1382 __func__, (unsigned long long) imap->im_blkno,
1383 (unsigned long long) imap->im_len,
1384 XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks));
1385 return XFS_ERROR(EINVAL);
1386 }
1387 return 0;
1388}
1389
1390
1391
1392
1393void
1394xfs_ialloc_compute_maxlevels(
1395 xfs_mount_t *mp)
1396{
1397 int level;
1398 uint maxblocks;
1399 uint maxleafents;
1400 int minleafrecs;
1401 int minnoderecs;
1402
1403 maxleafents = (1LL << XFS_INO_AGINO_BITS(mp)) >>
1404 XFS_INODES_PER_CHUNK_LOG;
1405 minleafrecs = mp->m_alloc_mnr[0];
1406 minnoderecs = mp->m_alloc_mnr[1];
1407 maxblocks = (maxleafents + minleafrecs - 1) / minleafrecs;
1408 for (level = 1; maxblocks > 1; level++)
1409 maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs;
1410 mp->m_in_maxlevels = level;
1411}
1412
1413
1414
1415
1416void
1417xfs_ialloc_log_agi(
1418 xfs_trans_t *tp,
1419 xfs_buf_t *bp,
1420 int fields)
1421{
1422 int first;
1423 int last;
1424 static const short offsets[] = {
1425
1426 offsetof(xfs_agi_t, agi_magicnum),
1427 offsetof(xfs_agi_t, agi_versionnum),
1428 offsetof(xfs_agi_t, agi_seqno),
1429 offsetof(xfs_agi_t, agi_length),
1430 offsetof(xfs_agi_t, agi_count),
1431 offsetof(xfs_agi_t, agi_root),
1432 offsetof(xfs_agi_t, agi_level),
1433 offsetof(xfs_agi_t, agi_freecount),
1434 offsetof(xfs_agi_t, agi_newino),
1435 offsetof(xfs_agi_t, agi_dirino),
1436 offsetof(xfs_agi_t, agi_unlinked),
1437 sizeof(xfs_agi_t)
1438 };
1439#ifdef DEBUG
1440 xfs_agi_t *agi;
1441
1442 agi = XFS_BUF_TO_AGI(bp);
1443 ASSERT(agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC));
1444#endif
1445
1446
1447
1448 xfs_btree_offsets(fields, offsets, XFS_AGI_NUM_BITS, &first, &last);
1449
1450
1451
1452 xfs_trans_log_buf(tp, bp, first, last);
1453}
1454
1455#ifdef DEBUG
1456STATIC void
1457xfs_check_agi_unlinked(
1458 struct xfs_agi *agi)
1459{
1460 int i;
1461
1462 for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++)
1463 ASSERT(agi->agi_unlinked[i]);
1464}
1465#else
1466#define xfs_check_agi_unlinked(agi)
1467#endif
1468
1469
1470
1471
1472int
1473xfs_read_agi(
1474 struct xfs_mount *mp,
1475 struct xfs_trans *tp,
1476 xfs_agnumber_t agno,
1477 struct xfs_buf **bpp)
1478{
1479 struct xfs_agi *agi;
1480 int agi_ok;
1481 int error;
1482
1483 ASSERT(agno != NULLAGNUMBER);
1484
1485 error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
1486 XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)),
1487 XFS_FSS_TO_BB(mp, 1), 0, bpp);
1488 if (error)
1489 return error;
1490
1491 ASSERT(!xfs_buf_geterror(*bpp));
1492 agi = XFS_BUF_TO_AGI(*bpp);
1493
1494
1495
1496
1497 agi_ok = agi->agi_magicnum == cpu_to_be32(XFS_AGI_MAGIC) &&
1498 XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)) &&
1499 be32_to_cpu(agi->agi_seqno) == agno;
1500 if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IALLOC_READ_AGI,
1501 XFS_RANDOM_IALLOC_READ_AGI))) {
1502 XFS_CORRUPTION_ERROR("xfs_read_agi", XFS_ERRLEVEL_LOW,
1503 mp, agi);
1504 xfs_trans_brelse(tp, *bpp);
1505 return XFS_ERROR(EFSCORRUPTED);
1506 }
1507
1508 xfs_buf_set_ref(*bpp, XFS_AGI_REF);
1509
1510 xfs_check_agi_unlinked(agi);
1511 return 0;
1512}
1513
1514int
1515xfs_ialloc_read_agi(
1516 struct xfs_mount *mp,
1517 struct xfs_trans *tp,
1518 xfs_agnumber_t agno,
1519 struct xfs_buf **bpp)
1520{
1521 struct xfs_agi *agi;
1522 struct xfs_perag *pag;
1523 int error;
1524
1525 error = xfs_read_agi(mp, tp, agno, bpp);
1526 if (error)
1527 return error;
1528
1529 agi = XFS_BUF_TO_AGI(*bpp);
1530 pag = xfs_perag_get(mp, agno);
1531 if (!pag->pagi_init) {
1532 pag->pagi_freecount = be32_to_cpu(agi->agi_freecount);
1533 pag->pagi_count = be32_to_cpu(agi->agi_count);
1534 pag->pagi_init = 1;
1535 }
1536
1537
1538
1539
1540
1541 ASSERT(pag->pagi_freecount == be32_to_cpu(agi->agi_freecount) ||
1542 XFS_FORCED_SHUTDOWN(mp));
1543 xfs_perag_put(pag);
1544 return 0;
1545}
1546
1547
1548
1549
1550int
1551xfs_ialloc_pagi_init(
1552 xfs_mount_t *mp,
1553 xfs_trans_t *tp,
1554 xfs_agnumber_t agno)
1555{
1556 xfs_buf_t *bp = NULL;
1557 int error;
1558
1559 error = xfs_ialloc_read_agi(mp, tp, agno, &bp);
1560 if (error)
1561 return error;
1562 if (bp)
1563 xfs_trans_brelse(tp, bp);
1564 return 0;
1565}
1566