]>
git.ipfire.org Git - thirdparty/e2fsprogs.git/blob - e2fsck/dx_dirinfo.c
2 * dirinfo.c --- maintains the directory information table for e2fsck.
4 * Copyright (C) 1993 Theodore Ts'o. This file may be redistributed
5 * under the terms of the GNU Public License.
12 * This subroutine is called during pass1 to create a directory info
13 * entry. During pass1, the passed-in parent is 0; it will get filled
16 void e2fsck_add_dx_dir(e2fsck_t ctx
, ext2_ino_t ino
, struct ext2_inode
*inode
,
19 struct dx_dir_info
*dir
;
22 unsigned long old_size
;
25 printf("add_dx_dir_info for inode %lu...\n", ino
);
27 if (!ctx
->dx_dir_info
) {
28 ctx
->dx_dir_info_count
= 0;
29 ctx
->dx_dir_info_size
= 100; /* Guess */
30 ctx
->dx_dir_info
= (struct dx_dir_info
*)
31 e2fsck_allocate_memory(ctx
, ctx
->dx_dir_info_size
32 * sizeof (struct dx_dir_info
),
36 if (ctx
->dx_dir_info_count
>= ctx
->dx_dir_info_size
) {
37 old_size
= ctx
->dx_dir_info_size
* sizeof(struct dx_dir_info
);
38 ctx
->dx_dir_info_size
+= 10;
39 retval
= ext2fs_resize_mem(old_size
, ctx
->dx_dir_info_size
*
40 sizeof(struct dx_dir_info
),
43 fprintf(stderr
, "Couldn't reallocate dx_dir_info "
44 "structure to %u entries\n",
45 ctx
->dx_dir_info_size
);
47 ctx
->dx_dir_info_size
-= 10;
53 * Normally, add_dx_dir_info is called with each inode in
54 * sequential order; but once in a while (like when pass 3
55 * needs to recreate the root directory or lost+found
56 * directory) it is called out of order. In those cases, we
57 * need to move the dx_dir_info entries down to make room, since
58 * the dx_dir_info array needs to be sorted by inode number for
59 * get_dx_dir_info()'s sake.
61 if (ctx
->dx_dir_info_count
&&
62 ctx
->dx_dir_info
[ctx
->dx_dir_info_count
-1].ino
>= ino
) {
63 for (i
= ctx
->dx_dir_info_count
-1; i
> 0; i
--)
64 if (ctx
->dx_dir_info
[i
-1].ino
< ino
)
66 dir
= &ctx
->dx_dir_info
[i
];
68 for (j
= ctx
->dx_dir_info_count
++; j
> i
; j
--)
69 ctx
->dx_dir_info
[j
] = ctx
->dx_dir_info
[j
-1];
71 dir
= &ctx
->dx_dir_info
[ctx
->dx_dir_info_count
++];
74 dir
->numblocks
= num_blocks
;
76 dir
->casefolded_hash
= inode
->i_flags
& EXT4_CASEFOLD_FL
;
77 dir
->dx_block
= e2fsck_allocate_memory(ctx
, num_blocks
78 * sizeof (struct dx_dirblock_info
),
79 "dx_block info array");
84 * get_dx_dir_info() --- given an inode number, try to find the directory
85 * information entry for it.
87 struct dx_dir_info
*e2fsck_get_dx_dir_info(e2fsck_t ctx
, ext2_ino_t ino
)
89 ext2_ino_t low
, high
, mid
;
92 high
= ctx
->dx_dir_info_count
-1;
93 if (!ctx
->dx_dir_info
)
95 if (ino
== ctx
->dx_dir_info
[low
].ino
)
96 return &ctx
->dx_dir_info
[low
];
97 if (ino
== ctx
->dx_dir_info
[high
].ino
)
98 return &ctx
->dx_dir_info
[high
];
101 /* sum may overflow, but result will fit into mid again */
102 mid
= (unsigned long long)(low
+ high
) / 2;
103 if (mid
== low
|| mid
== high
)
105 if (ino
== ctx
->dx_dir_info
[mid
].ino
)
106 return &ctx
->dx_dir_info
[mid
];
107 if (ino
< ctx
->dx_dir_info
[mid
].ino
)
116 * Free the dx_dir_info structure when it isn't needed any more.
118 void e2fsck_free_dx_dir_info(e2fsck_t ctx
)
120 struct dx_dir_info
*dir
;
123 if (ctx
->dx_dir_info
) {
124 dir
= ctx
->dx_dir_info
;
125 for (i
=0; i
< ctx
->dx_dir_info_count
; i
++,dir
++) {
127 ext2fs_free_mem(&dir
->dx_block
);
131 ext2fs_free_mem(&ctx
->dx_dir_info
);
132 ctx
->dx_dir_info
= 0;
134 ctx
->dx_dir_info_size
= 0;
135 ctx
->dx_dir_info_count
= 0;
139 * Return the count of number of directories in the dx_dir_info structure
141 ext2_ino_t
e2fsck_get_num_dx_dirinfo(e2fsck_t ctx
)
143 return ctx
->dx_dir_info_count
;
147 * A simple interator function
149 struct dx_dir_info
*e2fsck_dx_dir_info_iter(e2fsck_t ctx
, ext2_ino_t
*control
)
151 if (*control
>= ctx
->dx_dir_info_count
)
154 return ctx
->dx_dir_info
+ (*control
)++;