Initialize root directory to have proper i_size.
[omfsprogs.git] / fix.c
blob0f81989c3814a4be48537671706c2e902093dca6
1 /*
2 * Here is where we supposedly fix things.
3 */
5 #include <stdlib.h>
6 #include "omfs.h"
7 #include "check.h"
8 #include "fix.h"
9 #include "io.h"
11 static char *output_strings[] =
13 "Hey, no error here!",
14 "Header XOR for inode $I is incorrect",
15 "Header CRC for inode $I is incorrect",
16 "Inode $I is not linked in any directory",
17 "In-use bit for inode $I should be set",
18 "Block bitmap is inconsistent",
19 "File $F is in wrong hash index $H",
20 "Blocksize is unheard of",
21 "System blocksize is invalid",
22 "Mirror count is clearly wrong",
23 "Extent count for $I is out of range",
24 "Extent terminator for inode $I checksum doesn't add up",
25 "Filesystem magic number is wrong (is this really an OMFS partition?)",
26 "Inode magic number is wrong for $I",
27 "Self pointer on $I is wrong",
28 "Parent pointer on $I is wrong",
29 "Could not read super block",
30 "Could not read root block",
31 "Inode $I is totally busted",
32 "Directory scan failed",
33 "Loop detected for block $B"
36 static void hack_exit(check_context_t *ctx)
38 printf("Made changes; re-run omfsck to continue scan\n");
39 fclose(ctx->omfs_info->dev);
40 exit(1);
43 // returns inode containing current file
44 omfs_inode_t *find_node(check_context_t *ctx, int *is_parent)
46 omfs_inode_t *parent, *inode =
47 omfs_get_inode(ctx->omfs_info, ctx->parent);
49 u64 *chain_ptr = (u64*) ((u8*) inode + OMFS_DIR_START);
51 parent = inode;
52 if (!inode)
53 return NULL;
55 chain_ptr += ctx->hash;
56 while (*chain_ptr != swap_be64(ctx->block) && *chain_ptr != ~0)
58 omfs_release_inode(inode);
59 inode = omfs_get_inode(ctx->omfs_info, swap_be64(*chain_ptr));
60 chain_ptr = &inode->sibling;
63 if (*chain_ptr == ~0)
65 omfs_release_inode(inode);
66 return NULL;
68 *is_parent = parent == inode;
69 return inode;
72 static u64 *get_entry(struct omfs_inode *inode, int hash, int is_parent)
74 u64 *entry;
75 if (is_parent)
76 entry = (u64 *) ((u8 *) inode + OMFS_DIR_START) + hash;
77 else
78 entry = &inode->sibling;
79 return entry;
82 static void delete_file(check_context_t *ctx)
84 int res;
85 int is_parent;
86 u64 *entry;
87 omfs_inode_t *inode = find_node(ctx, &is_parent);
89 if (!inode)
91 fprintf(stderr, "Oops, didn't find it. Odd.\n");
92 return;
94 entry = get_entry(inode, ctx->hash, is_parent);
95 *entry = ~0;
96 res = omfs_write_inode(ctx->omfs_info, inode);
97 if (res)
98 perror("omfsck");
100 omfs_release_inode(inode);
101 omfs_sync(ctx->omfs_info);
103 // force clear bit later when we consistency-check the bitmap.
104 hack_exit(ctx);
107 // can be used to fix hash bugs or move around FS
108 static void move_file(check_context_t *ctx, u64 dest_dir)
110 omfs_inode_t *source;
111 omfs_inode_t *dest;
112 u64 *entry;
113 int is_parent, res;
114 int hash;
116 source = find_node(ctx, &is_parent);
117 if (!source)
119 fprintf(stderr, "Oops, didn't find it. Odd.\n");
120 return;
122 entry = get_entry(source, ctx->hash, is_parent);
123 *entry = ctx->current_inode->sibling;
124 res = omfs_write_inode(ctx->omfs_info, source);
125 omfs_release_inode(source);
126 if (res)
127 perror("omfsck");
129 dest = omfs_get_inode(ctx->omfs_info, dest_dir);
130 if (dest->type != OMFS_DIR)
132 printf("Huh, tried to move it to a non-dir.. oh well.\n");
133 return;
135 hash = omfs_compute_hash(ctx->omfs_info, ctx->current_inode->name);
136 entry = get_entry(dest, hash, 1);
137 ctx->current_inode->sibling = *entry;
138 *entry = swap_be64(ctx->block);
139 res = omfs_write_inode(ctx->omfs_info, dest);
140 if (res)
141 perror("omfsck");
142 res = omfs_write_inode(ctx->omfs_info, ctx->current_inode);
143 if (res)
144 perror("omfsck");
146 omfs_release_inode(ctx->current_inode);
147 omfs_release_inode(dest);
148 omfs_sync(ctx->omfs_info);
150 // force clear bit later when we consistency-check the bitmap.
151 hack_exit(ctx);
154 void fix_problem(check_error_t error, check_context_t *ctx)
156 sad_print(output_strings[error], ctx);
158 switch (error)
160 case E_SELF_PTR:
161 case E_PARENT_PTR:
162 case E_LOOP:
163 case E_INSANE:
164 /* for now, a take no prisoners approach */
165 if (prompt_yesno("Delete the offending file?"))
167 printf("Okay, deleting.\n");
168 delete_file(ctx);
170 else
171 printf("Skipping.\n");
172 break;
173 case E_HEADER_XOR:
174 case E_HEADER_CRC:
175 if (prompt_yesno("Correct?"))
177 printf("Okay, fixing.\n");
178 // write recomputes checksums
179 omfs_write_inode(ctx->omfs_info, ctx->current_inode);
180 omfs_sync(ctx->omfs_info);
182 else
183 printf("Skipping.\n");
184 break;
185 case E_HASH_WRONG:
186 if (prompt_yesno("Correct?"))
188 printf("Okay, moving to proper location.\n");
189 move_file(ctx, ctx->parent);
191 else
192 printf("Skipping.\n");
193 break;
194 case E_BITMAP:
195 if (prompt_yesno("Rebuild?"))
197 printf("Okay writing computed bitmap.\n");
198 omfs_write_bitmap(ctx->omfs_info, ctx->visited);
200 else
201 printf("Skipping.\n");
202 break;
203 default:
204 printf("Weird, I don't do anything about that yet\n");
205 break;