aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2012-04-17 15:59:35 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2012-05-29 23:28:38 -0400
commitddc19e6e04c1131a48f5b9a25aa433bbd8430cdd (patch)
tree6aab35223ee49c737a18199707d03488ebaf86eb
parent39413c6046de282a92739110cfafb8f1e862680d (diff)
hpfs: annotate btree nodes, get rid of bitfields mess
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/hpfs/anode.c35
-rw-r--r--fs/hpfs/hpfs.h60
-rw-r--r--fs/hpfs/map.c8
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
376struct bplus_leaf_node 376struct 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
383struct bplus_internal_node 383struct 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
389enum {
390 BP_hbff = 1,
391 BP_fnode_parent = 0x20,
392 BP_binary_search = 0x40,
393 BP_internal = 0x80
394};
389struct bplus_header 395struct 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
417static inline bool bp_internal(struct bplus_header *bp)
418{
419 return bp->flags & BP_internal;
420}
421
422static 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 }