1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
14 #include "err_protos.h"
17 * array of inode tree ptrs, one per ag
19 avltree_desc_t
**inode_tree_ptrs
;
22 * ditto for uncertain inodes
24 static avltree_desc_t
**inode_uncertain_tree_ptrs
;
26 /* memory optimised nlink counting for all inodes */
29 alloc_nlink_array(uint8_t nlink_size
)
33 ptr
= calloc(XFS_INODES_PER_CHUNK
, nlink_size
);
35 do_error(_("could not allocate nlink array\n"));
40 nlink_grow_8_to_16(ino_tree_node_t
*irec
)
45 irec
->nlink_size
= sizeof(uint16_t);
47 new_nlinks
= alloc_nlink_array(irec
->nlink_size
);
48 for (i
= 0; i
< XFS_INODES_PER_CHUNK
; i
++)
49 new_nlinks
[i
] = irec
->disk_nlinks
.un8
[i
];
50 free(irec
->disk_nlinks
.un8
);
51 irec
->disk_nlinks
.un16
= new_nlinks
;
53 if (full_ino_ex_data
) {
54 new_nlinks
= alloc_nlink_array(irec
->nlink_size
);
55 for (i
= 0; i
< XFS_INODES_PER_CHUNK
; i
++) {
57 irec
->ino_un
.ex_data
->counted_nlinks
.un8
[i
];
59 free(irec
->ino_un
.ex_data
->counted_nlinks
.un8
);
60 irec
->ino_un
.ex_data
->counted_nlinks
.un16
= new_nlinks
;
65 nlink_grow_16_to_32(ino_tree_node_t
*irec
)
70 irec
->nlink_size
= sizeof(uint32_t);
72 new_nlinks
= alloc_nlink_array(irec
->nlink_size
);
73 for (i
= 0; i
< XFS_INODES_PER_CHUNK
; i
++)
74 new_nlinks
[i
] = irec
->disk_nlinks
.un16
[i
];
75 free(irec
->disk_nlinks
.un16
);
76 irec
->disk_nlinks
.un32
= new_nlinks
;
78 if (full_ino_ex_data
) {
79 new_nlinks
= alloc_nlink_array(irec
->nlink_size
);
81 for (i
= 0; i
< XFS_INODES_PER_CHUNK
; i
++) {
83 irec
->ino_un
.ex_data
->counted_nlinks
.un16
[i
];
85 free(irec
->ino_un
.ex_data
->counted_nlinks
.un16
);
86 irec
->ino_un
.ex_data
->counted_nlinks
.un32
= new_nlinks
;
90 void add_inode_ref(struct ino_tree_node
*irec
, int ino_offset
)
92 ASSERT(irec
->ino_un
.ex_data
!= NULL
);
94 pthread_mutex_lock(&irec
->lock
);
95 switch (irec
->nlink_size
) {
97 if (irec
->ino_un
.ex_data
->counted_nlinks
.un8
[ino_offset
] < 0xff) {
98 irec
->ino_un
.ex_data
->counted_nlinks
.un8
[ino_offset
]++;
101 nlink_grow_8_to_16(irec
);
103 case sizeof(uint16_t):
104 if (irec
->ino_un
.ex_data
->counted_nlinks
.un16
[ino_offset
] < 0xffff) {
105 irec
->ino_un
.ex_data
->counted_nlinks
.un16
[ino_offset
]++;
108 nlink_grow_16_to_32(irec
);
110 case sizeof(uint32_t):
111 irec
->ino_un
.ex_data
->counted_nlinks
.un32
[ino_offset
]++;
116 pthread_mutex_unlock(&irec
->lock
);
119 void drop_inode_ref(struct ino_tree_node
*irec
, int ino_offset
)
123 ASSERT(irec
->ino_un
.ex_data
!= NULL
);
125 pthread_mutex_lock(&irec
->lock
);
126 switch (irec
->nlink_size
) {
127 case sizeof(uint8_t):
128 ASSERT(irec
->ino_un
.ex_data
->counted_nlinks
.un8
[ino_offset
] > 0);
129 refs
= --irec
->ino_un
.ex_data
->counted_nlinks
.un8
[ino_offset
];
131 case sizeof(uint16_t):
132 ASSERT(irec
->ino_un
.ex_data
->counted_nlinks
.un16
[ino_offset
] > 0);
133 refs
= --irec
->ino_un
.ex_data
->counted_nlinks
.un16
[ino_offset
];
135 case sizeof(uint32_t):
136 ASSERT(irec
->ino_un
.ex_data
->counted_nlinks
.un32
[ino_offset
] > 0);
137 refs
= --irec
->ino_un
.ex_data
->counted_nlinks
.un32
[ino_offset
];
144 irec
->ino_un
.ex_data
->ino_reached
&= ~IREC_MASK(ino_offset
);
145 pthread_mutex_unlock(&irec
->lock
);
148 uint32_t num_inode_references(struct ino_tree_node
*irec
, int ino_offset
)
150 ASSERT(irec
->ino_un
.ex_data
!= NULL
);
152 switch (irec
->nlink_size
) {
153 case sizeof(uint8_t):
154 return irec
->ino_un
.ex_data
->counted_nlinks
.un8
[ino_offset
];
155 case sizeof(uint16_t):
156 return irec
->ino_un
.ex_data
->counted_nlinks
.un16
[ino_offset
];
157 case sizeof(uint32_t):
158 return irec
->ino_un
.ex_data
->counted_nlinks
.un32
[ino_offset
];
165 void set_inode_disk_nlinks(struct ino_tree_node
*irec
, int ino_offset
,
168 pthread_mutex_lock(&irec
->lock
);
169 switch (irec
->nlink_size
) {
170 case sizeof(uint8_t):
172 irec
->disk_nlinks
.un8
[ino_offset
] = nlinks
;
175 nlink_grow_8_to_16(irec
);
177 case sizeof(uint16_t):
178 if (nlinks
< 0xffff) {
179 irec
->disk_nlinks
.un16
[ino_offset
] = nlinks
;
182 nlink_grow_16_to_32(irec
);
184 case sizeof(uint32_t):
185 irec
->disk_nlinks
.un32
[ino_offset
] = nlinks
;
190 pthread_mutex_unlock(&irec
->lock
);
193 uint32_t get_inode_disk_nlinks(struct ino_tree_node
*irec
, int ino_offset
)
195 switch (irec
->nlink_size
) {
196 case sizeof(uint8_t):
197 return irec
->disk_nlinks
.un8
[ino_offset
];
198 case sizeof(uint16_t):
199 return irec
->disk_nlinks
.un16
[ino_offset
];
200 case sizeof(uint32_t):
201 return irec
->disk_nlinks
.un32
[ino_offset
];
210 struct xfs_mount
*mp
)
214 if (!xfs_has_ftype(mp
))
217 ptr
= calloc(XFS_INODES_PER_CHUNK
, sizeof(*ptr
));
219 do_error(_("could not allocate ftypes array\n"));
224 * Next is the uncertain inode list -- a sorted (in ascending order)
225 * list of inode records sorted on the starting inode number. There
226 * is one list per ag.
230 * Common code for creating inode records for use by trees and lists.
231 * called only from add_inodes and add_inodes_uncertain
233 * IMPORTANT: all inodes (inode records) start off as free and
236 static struct ino_tree_node
*
238 struct xfs_mount
*mp
,
239 xfs_agino_t starting_ino
)
241 struct ino_tree_node
*irec
;
243 irec
= malloc(sizeof(*irec
));
245 do_error(_("inode map malloc failed\n"));
247 irec
->avl_node
.avl_nextino
= NULL
;
248 irec
->avl_node
.avl_forw
= NULL
;
249 irec
->avl_node
.avl_back
= NULL
;
251 irec
->ino_startnum
= starting_ino
;
252 irec
->ino_confirmed
= 0;
253 irec
->ino_isa_dir
= 0;
254 irec
->ino_was_rl
= 0;
256 irec
->ir_free
= (xfs_inofree_t
) - 1;
258 irec
->ino_un
.ex_data
= NULL
;
259 irec
->nlink_size
= sizeof(uint8_t);
260 irec
->disk_nlinks
.un8
= alloc_nlink_array(irec
->nlink_size
);
261 irec
->ftypes
= alloc_ftypes_array(mp
);
262 pthread_mutex_init(&irec
->lock
, NULL
);
267 free_nlink_array(union ino_nlink nlinks
, uint8_t nlink_size
)
269 switch (nlink_size
) {
270 case sizeof(uint8_t):
273 case sizeof(uint16_t):
276 case sizeof(uint32_t):
286 struct ino_tree_node
*irec
)
288 irec
->avl_node
.avl_nextino
= NULL
;
289 irec
->avl_node
.avl_forw
= NULL
;
290 irec
->avl_node
.avl_back
= NULL
;
292 free_nlink_array(irec
->disk_nlinks
, irec
->nlink_size
);
293 if (irec
->ino_un
.ex_data
!= NULL
) {
294 if (full_ino_ex_data
) {
295 free(irec
->ino_un
.ex_data
->parents
);
296 free_nlink_array(irec
->ino_un
.ex_data
->counted_nlinks
,
299 free(irec
->ino_un
.ex_data
);
304 pthread_mutex_destroy(&irec
->lock
);
309 * last referenced cache for uncertain inodes
311 static ino_tree_node_t
**last_rec
;
314 * ok, the uncertain inodes are a set of trees just like the
315 * good inodes but all starting inode records are (arbitrarily)
316 * aligned on XFS_CHUNK_PER_INODE boundaries to prevent overlaps.
317 * this means we may have partials records in the tree (e.g. records
318 * without 64 confirmed uncertain inodes). Tough.
320 * free is set to 1 if the inode is thought to be free, 0 if used
323 add_aginode_uncertain(
324 struct xfs_mount
*mp
,
329 ino_tree_node_t
*ino_rec
;
333 ASSERT(agno
< glob_agcount
);
334 ASSERT(last_rec
!= NULL
);
336 s_ino
= rounddown(ino
, XFS_INODES_PER_CHUNK
);
339 * check for a cache hit
341 if (last_rec
[agno
] != NULL
&& last_rec
[agno
]->ino_startnum
== s_ino
) {
342 offset
= ino
- s_ino
;
344 set_inode_free(last_rec
[agno
], offset
);
346 set_inode_used(last_rec
[agno
], offset
);
352 * check to see if record containing inode is already in the tree.
355 ino_rec
= (ino_tree_node_t
*)
356 avl_findrange(inode_uncertain_tree_ptrs
[agno
], s_ino
);
358 ino_rec
= alloc_ino_node(mp
, s_ino
);
360 if (!avl_insert(inode_uncertain_tree_ptrs
[agno
],
363 _("add_aginode_uncertain - duplicate inode range\n"));
367 set_inode_free(ino_rec
, ino
- s_ino
);
369 set_inode_used(ino_rec
, ino
- s_ino
);
374 last_rec
[agno
] = ino_rec
;
378 * like add_aginode_uncertain() only it needs an xfs_mount_t *
379 * to perform the inode number conversion.
382 add_inode_uncertain(xfs_mount_t
*mp
, xfs_ino_t ino
, int free
)
384 add_aginode_uncertain(mp
, XFS_INO_TO_AGNO(mp
, ino
),
385 XFS_INO_TO_AGINO(mp
, ino
), free
);
389 * pull the indicated inode record out of the uncertain inode tree
392 get_uncertain_inode_rec(struct xfs_mount
*mp
, xfs_agnumber_t agno
,
393 ino_tree_node_t
*ino_rec
)
395 ASSERT(inode_tree_ptrs
!= NULL
);
396 ASSERT(agno
< mp
->m_sb
.sb_agcount
);
397 ASSERT(inode_tree_ptrs
[agno
] != NULL
);
399 avl_delete(inode_uncertain_tree_ptrs
[agno
], &ino_rec
->avl_node
);
401 ino_rec
->avl_node
.avl_nextino
= NULL
;
402 ino_rec
->avl_node
.avl_forw
= NULL
;
403 ino_rec
->avl_node
.avl_back
= NULL
;
407 findfirst_uncertain_inode_rec(xfs_agnumber_t agno
)
409 return((ino_tree_node_t
*)
410 inode_uncertain_tree_ptrs
[agno
]->avl_firstino
);
414 find_uncertain_inode_rec(xfs_agnumber_t agno
, xfs_agino_t ino
)
416 return((ino_tree_node_t
*)
417 avl_findrange(inode_uncertain_tree_ptrs
[agno
], ino
));
421 clear_uncertain_ino_cache(xfs_agnumber_t agno
)
423 last_rec
[agno
] = NULL
;
428 * Next comes the inode trees. One per AG, AVL trees of inode records, each
429 * inode record tracking 64 inodes
433 * Set up an inode tree record for a group of inodes that will include the
436 * This does NOT do error-check for duplicate records. The caller is
437 * responsible for checking that. Ino must be the start of an
438 * XFS_INODES_PER_CHUNK (64) inode chunk
440 * Each inode resides in a 64-inode chunk which can be part one or more chunks
441 * (max(64, inodes-per-block). The fs allocates in chunks (as opposed to 1
442 * chunk) when a block can hold more than one chunk (inodes per block > 64).
443 * Allocating in one chunk pieces causes us problems when it takes more than
444 * one fs block to contain an inode chunk because the chunks can start on
445 * *any* block boundary. So we assume that the caller has a clue because at
446 * this level, we don't.
448 static struct ino_tree_node
*
450 struct xfs_mount
*mp
,
454 struct ino_tree_node
*irec
;
456 irec
= alloc_ino_node(mp
, agino
);
457 if (!avl_insert(inode_tree_ptrs
[agno
], &irec
->avl_node
))
458 do_warn(_("add_inode - duplicate inode range\n"));
463 * pull the indicated inode record out of the inode tree
466 get_inode_rec(struct xfs_mount
*mp
, xfs_agnumber_t agno
, ino_tree_node_t
*ino_rec
)
468 ASSERT(inode_tree_ptrs
!= NULL
);
469 ASSERT(agno
< mp
->m_sb
.sb_agcount
);
470 ASSERT(inode_tree_ptrs
[agno
] != NULL
);
472 avl_delete(inode_tree_ptrs
[agno
], &ino_rec
->avl_node
);
474 ino_rec
->avl_node
.avl_nextino
= NULL
;
475 ino_rec
->avl_node
.avl_forw
= NULL
;
476 ino_rec
->avl_node
.avl_back
= NULL
;
480 * free the designated inode record (return it to the free pool)
484 free_inode_rec(xfs_agnumber_t agno
, ino_tree_node_t
*ino_rec
)
486 free_ino_tree_node(ino_rec
);
490 find_inode_rec_range(struct xfs_mount
*mp
, xfs_agnumber_t agno
,
491 xfs_agino_t start_ino
, xfs_agino_t end_ino
,
492 ino_tree_node_t
**first
, ino_tree_node_t
**last
)
494 *first
= *last
= NULL
;
497 * Is the AG inside the file system ?
499 if (agno
< mp
->m_sb
.sb_agcount
)
500 avl_findranges(inode_tree_ptrs
[agno
], start_ino
,
501 end_ino
, (avlnode_t
**) first
, (avlnode_t
**) last
);
505 * if ino doesn't exist, it must be properly aligned -- on a
506 * filesystem block boundary or XFS_INODES_PER_CHUNK boundary,
507 * whichever alignment is larger.
510 set_inode_used_alloc(struct xfs_mount
*mp
, xfs_agnumber_t agno
, xfs_agino_t ino
)
512 ino_tree_node_t
*ino_rec
;
515 * check alignment -- the only way to detect this
516 * is too see if the chunk overlaps another chunk
517 * already in the tree
519 ino_rec
= add_inode(mp
, agno
, ino
);
521 ASSERT(ino_rec
!= NULL
);
522 ASSERT(ino
>= ino_rec
->ino_startnum
&&
523 ino
- ino_rec
->ino_startnum
< XFS_INODES_PER_CHUNK
);
525 set_inode_used(ino_rec
, ino
- ino_rec
->ino_startnum
);
531 set_inode_free_alloc(struct xfs_mount
*mp
, xfs_agnumber_t agno
, xfs_agino_t ino
)
533 ino_tree_node_t
*ino_rec
;
535 ino_rec
= add_inode(mp
, agno
, ino
);
537 ASSERT(ino_rec
!= NULL
);
538 ASSERT(ino
>= ino_rec
->ino_startnum
&&
539 ino
- ino_rec
->ino_startnum
< XFS_INODES_PER_CHUNK
);
541 set_inode_free(ino_rec
, ino
- ino_rec
->ino_startnum
);
547 print_inode_list_int(xfs_agnumber_t agno
, int uncertain
)
549 ino_tree_node_t
*ino_rec
;
552 fprintf(stderr
, _("good inode list is --\n"));
553 ino_rec
= findfirst_inode_rec(agno
);
555 fprintf(stderr
, _("uncertain inode list is --\n"));
556 ino_rec
= findfirst_uncertain_inode_rec(agno
);
559 if (ino_rec
== NULL
) {
560 fprintf(stderr
, _("agno %d -- no inodes\n"), agno
);
564 printf(_("agno %d\n"), agno
);
566 while(ino_rec
!= NULL
) {
568 _("\tptr = %lx, start = 0x%x, free = 0x%llx, confirmed = 0x%llx\n"),
569 (unsigned long)ino_rec
,
570 ino_rec
->ino_startnum
,
571 (unsigned long long)ino_rec
->ir_free
,
572 (unsigned long long)ino_rec
->ino_confirmed
);
573 if (ino_rec
->ino_startnum
== 0)
575 ino_rec
= next_ino_rec(ino_rec
);
580 print_inode_list(xfs_agnumber_t agno
)
582 print_inode_list_int(agno
, 0);
586 print_uncertain_inode_list(xfs_agnumber_t agno
)
588 print_inode_list_int(agno
, 1);
592 * set parent -- use a bitmask and a packed array. The bitmask
593 * indicate which inodes have an entry in the array. An inode that
594 * is the Nth bit set in the mask is stored in the Nth location in
595 * the array where N starts at 0.
600 ino_tree_node_t
*irec
,
611 pthread_mutex_lock(&irec
->lock
);
612 if (full_ino_ex_data
)
613 ptbl
= irec
->ino_un
.ex_data
->parents
;
615 ptbl
= irec
->ino_un
.plist
;
618 ptbl
= (parent_list_t
*)malloc(sizeof(parent_list_t
));
620 do_error(_("couldn't malloc parent list table\n"));
622 if (full_ino_ex_data
)
623 irec
->ino_un
.ex_data
->parents
= ptbl
;
625 irec
->ino_un
.plist
= ptbl
;
627 ptbl
->pmask
= 1ULL << offset
;
628 ptbl
->pentries
= (xfs_ino_t
*)memalign(sizeof(xfs_ino_t
),
631 do_error(_("couldn't memalign pentries table\n"));
635 ptbl
->pentries
[0] = parent
;
637 pthread_mutex_unlock(&irec
->lock
);
641 if (ptbl
->pmask
& (1ULL << offset
)) {
645 for (i
= 0; i
< offset
; i
++) {
646 if (ptbl
->pmask
& bitmask
)
651 ASSERT(target
< ptbl
->cnt
);
653 ptbl
->pentries
[target
] = parent
;
655 pthread_mutex_unlock(&irec
->lock
);
662 for (i
= 0; i
< XFS_INODES_PER_CHUNK
; i
++) {
663 if (ptbl
->pmask
& bitmask
) {
673 ASSERT(cnt
== ptbl
->cnt
);
675 ASSERT(cnt
>= target
);
677 tmp
= (xfs_ino_t
*)memalign(sizeof(xfs_ino_t
), (cnt
+ 1) * sizeof(xfs_ino_t
));
679 do_error(_("couldn't memalign pentries table\n"));
681 memmove(tmp
, ptbl
->pentries
, target
* sizeof(parent_entry_t
));
684 memmove(tmp
+ target
+ 1, ptbl
->pentries
+ target
,
685 (cnt
- target
) * sizeof(parent_entry_t
));
687 free(ptbl
->pentries
);
689 ptbl
->pentries
= tmp
;
694 ptbl
->pentries
[target
] = parent
;
695 ptbl
->pmask
|= (1ULL << offset
);
696 pthread_mutex_unlock(&irec
->lock
);
700 get_inode_parent(ino_tree_node_t
*irec
, int offset
)
707 pthread_mutex_lock(&irec
->lock
);
708 if (full_ino_ex_data
)
709 ptbl
= irec
->ino_un
.ex_data
->parents
;
711 ptbl
= irec
->ino_un
.plist
;
713 if (ptbl
->pmask
& (1ULL << offset
)) {
717 for (i
= 0; i
< offset
; i
++) {
718 if (ptbl
->pmask
& bitmask
)
723 ASSERT(target
< ptbl
->cnt
);
725 pthread_mutex_unlock(&irec
->lock
);
726 return(ptbl
->pentries
[target
]);
729 pthread_mutex_unlock(&irec
->lock
);
734 alloc_ex_data(ino_tree_node_t
*irec
)
738 ptbl
= irec
->ino_un
.plist
;
739 irec
->ino_un
.ex_data
= (ino_ex_data_t
*)calloc(1, sizeof(ino_ex_data_t
));
740 if (irec
->ino_un
.ex_data
== NULL
)
741 do_error(_("could not malloc inode extra data\n"));
743 irec
->ino_un
.ex_data
->parents
= ptbl
;
745 switch (irec
->nlink_size
) {
746 case sizeof(uint8_t):
747 irec
->ino_un
.ex_data
->counted_nlinks
.un8
=
748 alloc_nlink_array(irec
->nlink_size
);
750 case sizeof(uint16_t):
751 irec
->ino_un
.ex_data
->counted_nlinks
.un16
=
752 alloc_nlink_array(irec
->nlink_size
);
754 case sizeof(uint32_t):
755 irec
->ino_un
.ex_data
->counted_nlinks
.un32
=
756 alloc_nlink_array(irec
->nlink_size
);
764 add_ino_ex_data(xfs_mount_t
*mp
)
766 ino_tree_node_t
*ino_rec
;
769 for (i
= 0; i
< mp
->m_sb
.sb_agcount
; i
++) {
770 ino_rec
= findfirst_inode_rec(i
);
772 while (ino_rec
!= NULL
) {
773 alloc_ex_data(ino_rec
);
774 ino_rec
= next_ino_rec(ino_rec
);
777 full_ino_ex_data
= 1;
781 avl_ino_start(avlnode_t
*node
)
783 return((uintptr_t) ((ino_tree_node_t
*) node
)->ino_startnum
);
787 avl_ino_end(avlnode_t
*node
)
790 ((ino_tree_node_t
*) node
)->ino_startnum
+
791 XFS_INODES_PER_CHUNK
));
794 static avlops_t avl_ino_tree_ops
= {
800 incore_ino_init(xfs_mount_t
*mp
)
803 int agcount
= mp
->m_sb
.sb_agcount
;
805 if ((inode_tree_ptrs
= malloc(agcount
*
806 sizeof(avltree_desc_t
*))) == NULL
)
807 do_error(_("couldn't malloc inode tree descriptor table\n"));
808 if ((inode_uncertain_tree_ptrs
= malloc(agcount
*
809 sizeof(avltree_desc_t
*))) == NULL
)
811 _("couldn't malloc uncertain ino tree descriptor table\n"));
813 for (i
= 0; i
< agcount
; i
++) {
814 if ((inode_tree_ptrs
[i
] =
815 malloc(sizeof(avltree_desc_t
))) == NULL
)
816 do_error(_("couldn't malloc inode tree descriptor\n"));
817 if ((inode_uncertain_tree_ptrs
[i
] =
818 malloc(sizeof(avltree_desc_t
))) == NULL
)
820 _("couldn't malloc uncertain ino tree descriptor\n"));
822 for (i
= 0; i
< agcount
; i
++) {
823 avl_init_tree(inode_tree_ptrs
[i
], &avl_ino_tree_ops
);
824 avl_init_tree(inode_uncertain_tree_ptrs
[i
], &avl_ino_tree_ops
);
827 if ((last_rec
= malloc(sizeof(ino_tree_node_t
*) * agcount
)) == NULL
)
828 do_error(_("couldn't malloc uncertain inode cache area\n"));
830 memset(last_rec
, 0, sizeof(ino_tree_node_t
*) * agcount
);
832 full_ino_ex_data
= 0;