diff options
-rw-r--r-- | fs/hpfs/anode.c | 35 | ||||
-rw-r--r-- | fs/hpfs/hpfs.h | 60 | ||||
-rw-r--r-- | fs/hpfs/map.c | 8 |
3 files changed, 52 insertions, 51 deletions
diff --git a/fs/hpfs/anode.c b/fs/hpfs/anode.c index ec5f8b9e5c2a..4bae4a4a60b1 100644 --- a/fs/hpfs/anode.c +++ b/fs/hpfs/anode.c | |||
@@ -20,7 +20,7 @@ secno hpfs_bplus_lookup(struct super_block *s, struct inode *inode, | |||
20 | int c1, c2 = 0; | 20 | int c1, c2 = 0; |
21 | go_down: | 21 | go_down: |
22 | if (hpfs_sb(s)->sb_chk) if (hpfs_stop_cycles(s, a, &c1, &c2, "hpfs_bplus_lookup")) return -1; | 22 | if (hpfs_sb(s)->sb_chk) if (hpfs_stop_cycles(s, a, &c1, &c2, "hpfs_bplus_lookup")) return -1; |
23 | if (btree->internal) { | 23 | if (bp_internal(btree)) { |
24 | for (i = 0; i < btree->n_used_nodes; i++) | 24 | for (i = 0; i < btree->n_used_nodes; i++) |
25 | if (le32_to_cpu(btree->u.internal[i].file_secno) > sec) { | 25 | if (le32_to_cpu(btree->u.internal[i].file_secno) > sec) { |
26 | a = le32_to_cpu(btree->u.internal[i].down); | 26 | a = le32_to_cpu(btree->u.internal[i].down); |
@@ -82,7 +82,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi | |||
82 | brelse(bh); | 82 | brelse(bh); |
83 | return -1; | 83 | return -1; |
84 | } | 84 | } |
85 | if (btree->internal) { | 85 | if (bp_internal(btree)) { |
86 | a = le32_to_cpu(btree->u.internal[n].down); | 86 | a = le32_to_cpu(btree->u.internal[n].down); |
87 | btree->u.internal[n].file_secno = cpu_to_le32(-1); | 87 | btree->u.internal[n].file_secno = cpu_to_le32(-1); |
88 | mark_buffer_dirty(bh); | 88 | mark_buffer_dirty(bh); |
@@ -129,12 +129,12 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi | |||
129 | } | 129 | } |
130 | if (a == node && fnod) { | 130 | if (a == node && fnod) { |
131 | anode->up = cpu_to_le32(node); | 131 | anode->up = cpu_to_le32(node); |
132 | anode->btree.fnode_parent = 1; | 132 | anode->btree.flags |= BP_fnode_parent; |
133 | anode->btree.n_used_nodes = btree->n_used_nodes; | 133 | anode->btree.n_used_nodes = btree->n_used_nodes; |
134 | anode->btree.first_free = btree->first_free; | 134 | anode->btree.first_free = btree->first_free; |
135 | anode->btree.n_free_nodes = 40 - anode->btree.n_used_nodes; | 135 | anode->btree.n_free_nodes = 40 - anode->btree.n_used_nodes; |
136 | memcpy(&anode->u, &btree->u, btree->n_used_nodes * 12); | 136 | memcpy(&anode->u, &btree->u, btree->n_used_nodes * 12); |
137 | btree->internal = 1; | 137 | btree->flags |= BP_internal; |
138 | btree->n_free_nodes = 11; | 138 | btree->n_free_nodes = 11; |
139 | btree->n_used_nodes = 1; | 139 | btree->n_used_nodes = 1; |
140 | btree->first_free = cpu_to_le16((char *)&(btree->u.internal[1]) - (char *)btree); | 140 | btree->first_free = cpu_to_le16((char *)&(btree->u.internal[1]) - (char *)btree); |
@@ -184,7 +184,10 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi | |||
184 | hpfs_free_sectors(s, ra, 1); | 184 | hpfs_free_sectors(s, ra, 1); |
185 | if ((anode = hpfs_map_anode(s, na, &bh))) { | 185 | if ((anode = hpfs_map_anode(s, na, &bh))) { |
186 | anode->up = cpu_to_le32(up); | 186 | anode->up = cpu_to_le32(up); |
187 | anode->btree.fnode_parent = up == node && fnod; | 187 | if (up == node && fnod) |
188 | anode->btree.flags |= BP_fnode_parent; | ||
189 | else | ||
190 | anode->btree.flags &= ~BP_fnode_parent; | ||
188 | mark_buffer_dirty(bh); | 191 | mark_buffer_dirty(bh); |
189 | brelse(bh); | 192 | brelse(bh); |
190 | } | 193 | } |
@@ -198,7 +201,7 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi | |||
198 | if ((new_anode = hpfs_alloc_anode(s, a, &na, &bh))) { | 201 | if ((new_anode = hpfs_alloc_anode(s, a, &na, &bh))) { |
199 | anode = new_anode; | 202 | anode = new_anode; |
200 | /*anode->up = cpu_to_le32(up != -1 ? up : ra);*/ | 203 | /*anode->up = cpu_to_le32(up != -1 ? up : ra);*/ |
201 | anode->btree.internal = 1; | 204 | anode->btree.flags |= BP_internal; |
202 | anode->btree.n_used_nodes = 1; | 205 | anode->btree.n_used_nodes = 1; |
203 | anode->btree.n_free_nodes = 59; | 206 | anode->btree.n_free_nodes = 59; |
204 | anode->btree.first_free = cpu_to_le16(16); | 207 | anode->btree.first_free = cpu_to_le16(16); |
@@ -215,7 +218,8 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi | |||
215 | } | 218 | } |
216 | if ((anode = hpfs_map_anode(s, na, &bh))) { | 219 | if ((anode = hpfs_map_anode(s, na, &bh))) { |
217 | anode->up = cpu_to_le32(node); | 220 | anode->up = cpu_to_le32(node); |
218 | if (fnod) anode->btree.fnode_parent = 1; | 221 | if (fnod) |
222 | anode->btree.flags |= BP_fnode_parent; | ||
219 | mark_buffer_dirty(bh); | 223 | mark_buffer_dirty(bh); |
220 | brelse(bh); | 224 | brelse(bh); |
221 | } | 225 | } |
@@ -234,18 +238,19 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi | |||
234 | } | 238 | } |
235 | ranode->up = cpu_to_le32(node); | 239 | ranode->up = cpu_to_le32(node); |
236 | memcpy(&ranode->btree, btree, le16_to_cpu(btree->first_free)); | 240 | memcpy(&ranode->btree, btree, le16_to_cpu(btree->first_free)); |
237 | if (fnod) ranode->btree.fnode_parent = 1; | 241 | if (fnod) |
238 | ranode->btree.n_free_nodes = (ranode->btree.internal ? 60 : 40) - ranode->btree.n_used_nodes; | 242 | ranode->btree.flags |= BP_fnode_parent; |
239 | if (ranode->btree.internal) for (n = 0; n < ranode->btree.n_used_nodes; n++) { | 243 | ranode->btree.n_free_nodes = (bp_internal(&ranode->btree) ? 60 : 40) - ranode->btree.n_used_nodes; |
244 | if (bp_internal(&ranode->btree)) for (n = 0; n < ranode->btree.n_used_nodes; n++) { | ||
240 | struct anode *unode; | 245 | struct anode *unode; |
241 | if ((unode = hpfs_map_anode(s, le32_to_cpu(ranode->u.internal[n].down), &bh1))) { | 246 | if ((unode = hpfs_map_anode(s, le32_to_cpu(ranode->u.internal[n].down), &bh1))) { |
242 | unode->up = cpu_to_le32(ra); | 247 | unode->up = cpu_to_le32(ra); |
243 | unode->btree.fnode_parent = 0; | 248 | unode->btree.flags &= ~BP_fnode_parent; |
244 | mark_buffer_dirty(bh1); | 249 | mark_buffer_dirty(bh1); |
245 | brelse(bh1); | 250 | brelse(bh1); |
246 | } | 251 | } |
247 | } | 252 | } |
248 | btree->internal = 1; | 253 | btree->flags |= BP_internal; |
249 | btree->n_free_nodes = fnod ? 10 : 58; | 254 | btree->n_free_nodes = fnod ? 10 : 58; |
250 | btree->n_used_nodes = 2; | 255 | btree->n_used_nodes = 2; |
251 | btree->first_free = cpu_to_le16((char *)&btree->u.internal[2] - (char *)btree); | 256 | btree->first_free = cpu_to_le16((char *)&btree->u.internal[2] - (char *)btree); |
@@ -278,7 +283,7 @@ void hpfs_remove_btree(struct super_block *s, struct bplus_header *btree) | |||
278 | int d1, d2; | 283 | int d1, d2; |
279 | go_down: | 284 | go_down: |
280 | d2 = 0; | 285 | d2 = 0; |
281 | while (btree1->internal) { | 286 | while (bp_internal(btree1)) { |
282 | ano = le32_to_cpu(btree1->u.internal[pos].down); | 287 | ano = le32_to_cpu(btree1->u.internal[pos].down); |
283 | if (level) brelse(bh); | 288 | if (level) brelse(bh); |
284 | if (hpfs_sb(s)->sb_chk) | 289 | if (hpfs_sb(s)->sb_chk) |
@@ -412,13 +417,13 @@ void hpfs_truncate_btree(struct super_block *s, secno f, int fno, unsigned secs) | |||
412 | btree->n_free_nodes = 8; | 417 | btree->n_free_nodes = 8; |
413 | btree->n_used_nodes = 0; | 418 | btree->n_used_nodes = 0; |
414 | btree->first_free = cpu_to_le16(8); | 419 | btree->first_free = cpu_to_le16(8); |
415 | btree->internal = 0; | 420 | btree->flags &= ~BP_internal; |
416 | mark_buffer_dirty(bh); | 421 | mark_buffer_dirty(bh); |
417 | } else hpfs_free_sectors(s, f, 1); | 422 | } else hpfs_free_sectors(s, f, 1); |
418 | brelse(bh); | 423 | brelse(bh); |
419 | return; | 424 | return; |
420 | } | 425 | } |
421 | while (btree->internal) { | 426 | while (bp_internal(btree)) { |
422 | nodes = btree->n_used_nodes + btree->n_free_nodes; | 427 | nodes = btree->n_used_nodes + btree->n_free_nodes; |
423 | for (i = 0; i < btree->n_used_nodes; i++) | 428 | for (i = 0; i < btree->n_used_nodes; i++) |
424 | if (le32_to_cpu(btree->u.internal[i].file_secno) >= secs) goto f; | 429 | if (le32_to_cpu(btree->u.internal[i].file_secno) >= secs) goto f; |
diff --git a/fs/hpfs/hpfs.h b/fs/hpfs/hpfs.h index b4e035ce65db..49d9315492d8 100644 --- a/fs/hpfs/hpfs.h +++ b/fs/hpfs/hpfs.h | |||
@@ -375,50 +375,36 @@ struct hpfs_dirent { | |||
375 | 375 | ||
376 | struct bplus_leaf_node | 376 | struct bplus_leaf_node |
377 | { | 377 | { |
378 | u32 file_secno; /* first file sector in extent */ | 378 | __le32 file_secno; /* first file sector in extent */ |
379 | u32 length; /* length, sectors */ | 379 | __le32 length; /* length, sectors */ |
380 | secno disk_secno; /* first corresponding disk sector */ | 380 | __le32 disk_secno; /* first corresponding disk sector */ |
381 | }; | 381 | }; |
382 | 382 | ||
383 | struct bplus_internal_node | 383 | struct bplus_internal_node |
384 | { | 384 | { |
385 | u32 file_secno; /* subtree maps sectors < this */ | 385 | __le32 file_secno; /* subtree maps sectors < this */ |
386 | anode_secno down; /* pointer to subtree */ | 386 | __le32 down; /* pointer to subtree */ |
387 | }; | 387 | }; |
388 | 388 | ||
389 | enum { | ||
390 | BP_hbff = 1, | ||
391 | BP_fnode_parent = 0x20, | ||
392 | BP_binary_search = 0x40, | ||
393 | BP_internal = 0x80 | ||
394 | }; | ||
389 | struct bplus_header | 395 | struct bplus_header |
390 | { | 396 | { |
391 | #ifdef __LITTLE_ENDIAN | 397 | u8 flags; /* bit 0 - high bit of first free entry offset |
392 | u8 hbff: 1; /* high bit of first free entry offset */ | 398 | bit 5 - we're pointed to by an fnode, |
393 | u8 flag1234: 4; | ||
394 | u8 fnode_parent: 1; /* ? we're pointed to by an fnode, | ||
395 | the data btree or some ea or the | ||
396 | main ea bootage pointer ea_secno */ | ||
397 | /* also can get set in fnodes, which | ||
398 | may be a chkdsk glitch or may mean | ||
399 | this bit is irrelevant in fnodes, | ||
400 | or this interpretation is all wet */ | ||
401 | u8 binary_search: 1; /* suggest binary search (unused) */ | ||
402 | u8 internal: 1; /* 1 -> (internal) tree of anodes | ||
403 | 0 -> (leaf) list of extents */ | ||
404 | #else | ||
405 | u8 internal: 1; /* 1 -> (internal) tree of anodes | ||
406 | 0 -> (leaf) list of extents */ | ||
407 | u8 binary_search: 1; /* suggest binary search (unused) */ | ||
408 | u8 fnode_parent: 1; /* ? we're pointed to by an fnode, | ||
409 | the data btree or some ea or the | 399 | the data btree or some ea or the |
410 | main ea bootage pointer ea_secno */ | 400 | main ea bootage pointer ea_secno |
411 | /* also can get set in fnodes, which | 401 | bit 6 - suggest binary search (unused) |
412 | may be a chkdsk glitch or may mean | 402 | bit 7 - 1 -> (internal) tree of anodes |
413 | this bit is irrelevant in fnodes, | 403 | 0 -> (leaf) list of extents */ |
414 | or this interpretation is all wet */ | ||
415 | u8 flag1234: 4; | ||
416 | u8 hbff: 1; /* high bit of first free entry offset */ | ||
417 | #endif | ||
418 | u8 fill[3]; | 404 | u8 fill[3]; |
419 | u8 n_free_nodes; /* free nodes in following array */ | 405 | u8 n_free_nodes; /* free nodes in following array */ |
420 | u8 n_used_nodes; /* used nodes in following array */ | 406 | u8 n_used_nodes; /* used nodes in following array */ |
421 | u16 first_free; /* offset from start of header to | 407 | __le16 first_free; /* offset from start of header to |
422 | first free node in array */ | 408 | first free node in array */ |
423 | union { | 409 | union { |
424 | struct bplus_internal_node internal[0]; /* (internal) 2-word entries giving | 410 | struct bplus_internal_node internal[0]; /* (internal) 2-word entries giving |
@@ -428,6 +414,16 @@ struct bplus_header | |||
428 | } u; | 414 | } u; |
429 | }; | 415 | }; |
430 | 416 | ||
417 | static inline bool bp_internal(struct bplus_header *bp) | ||
418 | { | ||
419 | return bp->flags & BP_internal; | ||
420 | } | ||
421 | |||
422 | static inline bool bp_fnode_parent(struct bplus_header *bp) | ||
423 | { | ||
424 | return bp->flags & BP_fnode_parent; | ||
425 | } | ||
426 | |||
431 | /* fnode: root of allocation b+ tree, and EA's */ | 427 | /* fnode: root of allocation b+ tree, and EA's */ |
432 | 428 | ||
433 | /* Every file and every directory has one fnode, pointed to by the directory | 429 | /* Every file and every directory has one fnode, pointed to by the directory |
diff --git a/fs/hpfs/map.c b/fs/hpfs/map.c index bbb174df7f95..d8bed6da053c 100644 --- a/fs/hpfs/map.c +++ b/fs/hpfs/map.c | |||
@@ -132,14 +132,14 @@ struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_hea | |||
132 | } | 132 | } |
133 | if (!fnode_is_dir(fnode)) { | 133 | if (!fnode_is_dir(fnode)) { |
134 | if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes != | 134 | if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes != |
135 | (fnode->btree.internal ? 12 : 8)) { | 135 | (bp_internal(&fnode->btree) ? 12 : 8)) { |
136 | hpfs_error(s, | 136 | hpfs_error(s, |
137 | "bad number of nodes in fnode %08lx", | 137 | "bad number of nodes in fnode %08lx", |
138 | (unsigned long)ino); | 138 | (unsigned long)ino); |
139 | goto bail; | 139 | goto bail; |
140 | } | 140 | } |
141 | if (le16_to_cpu(fnode->btree.first_free) != | 141 | if (le16_to_cpu(fnode->btree.first_free) != |
142 | 8 + fnode->btree.n_used_nodes * (fnode->btree.internal ? 8 : 12)) { | 142 | 8 + fnode->btree.n_used_nodes * (bp_internal(&fnode->btree) ? 8 : 12)) { |
143 | hpfs_error(s, | 143 | hpfs_error(s, |
144 | "bad first_free pointer in fnode %08lx", | 144 | "bad first_free pointer in fnode %08lx", |
145 | (unsigned long)ino); | 145 | (unsigned long)ino); |
@@ -187,12 +187,12 @@ struct anode *hpfs_map_anode(struct super_block *s, anode_secno ano, struct buff | |||
187 | goto bail; | 187 | goto bail; |
188 | } | 188 | } |
189 | if ((unsigned)anode->btree.n_used_nodes + (unsigned)anode->btree.n_free_nodes != | 189 | if ((unsigned)anode->btree.n_used_nodes + (unsigned)anode->btree.n_free_nodes != |
190 | (anode->btree.internal ? 60 : 40)) { | 190 | (bp_internal(&anode->btree) ? 60 : 40)) { |
191 | hpfs_error(s, "bad number of nodes in anode %08x", ano); | 191 | hpfs_error(s, "bad number of nodes in anode %08x", ano); |
192 | goto bail; | 192 | goto bail; |
193 | } | 193 | } |
194 | if (le16_to_cpu(anode->btree.first_free) != | 194 | if (le16_to_cpu(anode->btree.first_free) != |
195 | 8 + anode->btree.n_used_nodes * (anode->btree.internal ? 8 : 12)) { | 195 | 8 + anode->btree.n_used_nodes * (bp_internal(&anode->btree) ? 8 : 12)) { |
196 | hpfs_error(s, "bad first_free pointer in anode %08x", ano); | 196 | hpfs_error(s, "bad first_free pointer in anode %08x", ano); |
197 | goto bail; | 197 | goto bail; |
198 | } | 198 | } |