/* * Load first code page into kernel memory, return pointer to 256-byte array, * first 128 bytes are uppercasing table for chars 128-255, next 128 bytes are * lowercasing table
*/
if (n_hotfixes > 256 || n_used_hotfixes > n_hotfixes) {
hpfs_error(s, "invalid number of hotfixes: %u, used: %u", n_hotfixes, n_used_hotfixes); return;
} if (!(directory = hpfs_map_4sectors(s, le32_to_cpu(spareblock->hotfix_map), &qbh, 0))) {
hpfs_error(s, "can't load hotfix map"); return;
} for (i = 0; i < n_used_hotfixes; i++) {
hpfs_sb(s)->hotfix_from[i] = le32_to_cpu(directory[i]);
hpfs_sb(s)->hotfix_to[i] = le32_to_cpu(directory[n_hotfixes + i]);
}
hpfs_sb(s)->n_hotfixes = n_used_hotfixes;
hpfs_brelse4(&qbh);
}
/* * Load fnode to memory
*/
struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_head **bhp)
{ struct fnode *fnode; if (hpfs_sb(s)->sb_chk) if (hpfs_chk_sectors(s, ino, 1, "fnode")) { return NULL;
} if ((fnode = hpfs_map_sector(s, ino, bhp, FNODE_RD_AHEAD))) { if (hpfs_sb(s)->sb_chk) { struct extended_attribute *ea; struct extended_attribute *ea_end; if (le32_to_cpu(fnode->magic) != FNODE_MAGIC) {
hpfs_error(s, "bad magic on fnode %08lx",
(unsignedlong)ino); goto bail;
} if (!fnode_is_dir(fnode)) { if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes !=
(bp_internal(&fnode->btree) ? 12 : 8)) {
hpfs_error(s, "bad number of nodes in fnode %08lx",
(unsignedlong)ino); goto bail;
} if (le16_to_cpu(fnode->btree.first_free) !=
8 + fnode->btree.n_used_nodes * (bp_internal(&fnode->btree) ? 8 : 12)) {
hpfs_error(s, "bad first_free pointer in fnode %08lx",
(unsignedlong)ino); goto bail;
}
} if (le16_to_cpu(fnode->ea_size_s) && (le16_to_cpu(fnode->ea_offs) < 0xc4 ||
le16_to_cpu(fnode->ea_offs) + le16_to_cpu(fnode->acl_size_s) + le16_to_cpu(fnode->ea_size_s) > 0x200)) {
hpfs_error(s, "bad EA info in fnode %08lx: ea_offs == %04x ea_size_s == %04x",
(unsignedlong)ino,
le16_to_cpu(fnode->ea_offs), le16_to_cpu(fnode->ea_size_s)); goto bail;
}
ea = fnode_ea(fnode);
ea_end = fnode_end_ea(fnode); while (ea != ea_end) { if (ea > ea_end) {
hpfs_error(s, "bad EA in fnode %08lx",
(unsignedlong)ino); goto bail;
}
ea = next_ea(ea);
}
}
} return fnode;
bail:
brelse(*bhp); return NULL;
}
struct anode *hpfs_map_anode(struct super_block *s, anode_secno ano, struct buffer_head **bhp)
{ struct anode *anode; if (hpfs_sb(s)->sb_chk) if (hpfs_chk_sectors(s, ano, 1, "anode")) return NULL; if ((anode = hpfs_map_sector(s, ano, bhp, ANODE_RD_AHEAD))) if (hpfs_sb(s)->sb_chk) { if (le32_to_cpu(anode->magic) != ANODE_MAGIC) {
hpfs_error(s, "bad magic on anode %08x", ano); goto bail;
} if (le32_to_cpu(anode->self) != ano) {
hpfs_error(s, "self pointer invalid on anode %08x", ano); goto bail;
} if ((unsigned)anode->btree.n_used_nodes + (unsigned)anode->btree.n_free_nodes !=
(bp_internal(&anode->btree) ? 60 : 40)) {
hpfs_error(s, "bad number of nodes in anode %08x", ano); goto bail;
} if (le16_to_cpu(anode->btree.first_free) !=
8 + anode->btree.n_used_nodes * (bp_internal(&anode->btree) ? 8 : 12)) {
hpfs_error(s, "bad first_free pointer in anode %08x", ano); goto bail;
}
} return anode;
bail:
brelse(*bhp); return NULL;
}
/* * Load dnode to memory and do some checks
*/
struct dnode *hpfs_map_dnode(struct super_block *s, unsigned secno, struct quad_buffer_head *qbh)
{ struct dnode *dnode; if (hpfs_sb(s)->sb_chk) { if (hpfs_chk_sectors(s, secno, 4, "dnode")) return NULL; if (secno & 3) {
hpfs_error(s, "dnode %08x not byte-aligned", secno); return NULL;
}
} if ((dnode = hpfs_map_4sectors(s, secno, qbh, DNODE_RD_AHEAD))) if (hpfs_sb(s)->sb_chk) { unsigned p, pp = 0; unsignedchar *d = (unsignedchar *)dnode; int b = 0; if (le32_to_cpu(dnode->magic) != DNODE_MAGIC) {
hpfs_error(s, "bad magic on dnode %08x", secno); goto bail;
} if (le32_to_cpu(dnode->self) != secno)
hpfs_error(s, "bad self pointer on dnode %08x self = %08x", secno, le32_to_cpu(dnode->self)); /* Check dirents - bad dirents would cause infinite
loops or shooting to memory */ if (le32_to_cpu(dnode->first_free) > 2048) {
hpfs_error(s, "dnode %08x has first_free == %08x", secno, le32_to_cpu(dnode->first_free)); goto bail;
} for (p = 20; p < le32_to_cpu(dnode->first_free); p += d[p] + (d[p+1] << 8)) { struct hpfs_dirent *de = (struct hpfs_dirent *)((char *)dnode + p); if (le16_to_cpu(de->length) > 292 || (le16_to_cpu(de->length) < 32) || (le16_to_cpu(de->length) & 3) || p + le16_to_cpu(de->length) > 2048) {
hpfs_error(s, "bad dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp); goto bail;
} if (((31 + de->namelen + de->down*4 + 3) & ~3) != le16_to_cpu(de->length)) { if (((31 + de->namelen + de->down*4 + 3) & ~3) < le16_to_cpu(de->length) && s->s_flags & SB_RDONLY) goto ok;
hpfs_error(s, "namelen does not match dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp); goto bail;
}
ok: if (hpfs_sb(s)->sb_chk >= 2) b |= 1 << de->down; if (de->down) if (de_down_pointer(de) < 0x10) {
hpfs_error(s, "bad down pointer in dnode %08x, dirent %03x, last %03x", secno, p, pp); goto bail;
}
pp = p;
} if (p != le32_to_cpu(dnode->first_free)) {
hpfs_error(s, "size on last dirent does not match first_free; dnode %08x", secno); goto bail;
} if (d[pp + 30] != 1 || d[pp + 31] != 255) {
hpfs_error(s, "dnode %08x does not end with \\377 entry", secno); goto bail;
} if (b == 3)
pr_err("unbalanced dnode tree, dnode %08x; see hpfs.txt 4 more info\n",
secno);
} return dnode;
bail:
hpfs_brelse4(qbh); return NULL;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.