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