if (!hpfs_sb(s)->sb_was_error) { if (hpfs_sb(s)->sb_err == 2) {
pr_cont("; crashing the system because you wanted it\n");
mark_dirty(s, 0);
panic("HPFS panic");
} elseif (hpfs_sb(s)->sb_err == 1) { if (sb_rdonly(s))
pr_cont("; already mounted read-only\n"); else {
pr_cont("; remounting read-only\n");
mark_dirty(s, 0);
s->s_flags |= SB_RDONLY;
}
} elseif (sb_rdonly(s))
pr_cont("; going on - but anything won't be destroyed because it's read-only\n"); else
pr_cont("; corrupted filesystem mounted read/write - your computer will explode within 20 seconds ... but you wanted it so!\n");
} else
pr_cont("\n");
hpfs_sb(s)->sb_was_error = 1;
}
/* * A little trick to detect cycles in many hpfs structures and don't let the * kernel crash on corrupted filesystem. When first called, set c2 to 0. * * BTW. chkdsk doesn't detect cycles correctly. When I had 2 lost directories * nested each in other, chkdsk locked up happilly.
*/
int hpfs_stop_cycles(struct super_block *s, int key, int *c1, int *c2, char *msg)
{ if (*c2 && *c1 == key) {
hpfs_error(s, "cycle detected on key %08x in %s", key, msg); return 1;
}
(*c2)++; if (!((*c2 - 1) & *c2)) *c1 = key; return 0;
}
staticvoid destroy_inodecache(void)
{ /* * Make sure all delayed rcu free inodes are flushed before we * destroy cache.
*/
rcu_barrier();
kmem_cache_destroy(hpfs_inode_cachep);
}
struct hpfs_fc_context {
kuid_t uid;
kgid_t gid;
umode_t umask; int lowercase; int eas; int chk; int errs; int chkdsk; int timeshift;
};
staticinlinevoid hpfs_help(void)
{
pr_info("\n\
HPFS filesystem options:\n\
help donot mount and display this text\n\
uid=xxx set uid of files that don't have uid specified in eas\n\
gid=xxx set gid of files that don't have gid specified in eas\n\
umask=xxx set mode of files that don't have mode specified in eas\n\ case=lower lowercase all files\n\ case=asis donot lowercase files (default)\n\
check=none no fs checks - kernel may crash on corrupted filesystem\n\
check=normal do some checks - it should not crash (default)\n\
check=strict do extra time-consuming checks, used for debugging\n\
errors=continuecontinue on errors\n\
errors=remount-ro remount read-only if errors found (default)\n\
errors=panic panic on errors\n\
chkdsk=no donot mark fs for chkdsking even if there were errors\n\
chkdsk=errors mark fs dirty if errors found (default)\n\
chkdsk=always always mark fs dirty - used for debugging\n\
eas=no ignore extended attributes\n\
eas=ro read but donot write extended attributes\n\
eas=rw r/w eas => enables chmod, chown, mknod, ln -s (default)\n\
timeshift=nnn add nnn seconds to file times\n\
\n");
}
/* Check magics */ if (/*le16_to_cpu(bootblock->magic) != BB_MAGIC
||*/
|| le32_to_cpu(spareblock->magic) != SP_MAGIC) { if (!silent)
pr_err("Bad magic ... probably not HPFS\n"); goto bail4;
}
/* Check version */ if (!sb_rdonly(s) && superblock->funcversion != 2 && superblock->funcversion != 3) {
pr_err("Bad version %d,%d. Mount readonly to go around\n",
(int)superblock->version, (int)superblock->funcversion);
pr_err("please try recent version of HPFS driver at http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi and if it still can't understand this format, contact author - mikulas@artax.karlin.mff.cuni.cz\n"); goto bail4;
}
if (le32_to_cpu(spareblock->n_dnode_spares) != le32_to_cpu(spareblock->n_dnode_spares_free)) { if (sbi->sb_err >= 2) {
pr_err("Spare dnodes used, try chkdsk\n");
mark_dirty(s, 0); goto bail4;
}
hpfs_error(s, "warning: spare dnodes used, try chkdsk"); if (sbi->sb_err == 0)
pr_err("Proceeding, but your filesystem could be corrupted if you delete files or directories\n");
} if (sbi->sb_chk) { unsigned a; if (le32_to_cpu(superblock->dir_band_end) - le32_to_cpu(superblock->dir_band_start) + 1 != le32_to_cpu(superblock->n_dir_band) ||
le32_to_cpu(superblock->dir_band_end) < le32_to_cpu(superblock->dir_band_start) || le32_to_cpu(superblock->n_dir_band) > 0x4000) {
hpfs_error(s, "dir band size mismatch: dir_band_start==%08x, dir_band_end==%08x, n_dir_band==%08x",
le32_to_cpu(superblock->dir_band_start), le32_to_cpu(superblock->dir_band_end), le32_to_cpu(superblock->n_dir_band)); goto bail4;
}
a = sbi->sb_dirband_size;
sbi->sb_dirband_size = 0; if (hpfs_chk_sectors(s, le32_to_cpu(superblock->dir_band_start), le32_to_cpu(superblock->n_dir_band), "dir_band") ||
hpfs_chk_sectors(s, le32_to_cpu(superblock->dir_band_bitmap), 4, "dir_band_bitmap") ||
hpfs_chk_sectors(s, le32_to_cpu(superblock->bitmaps), 4, "bitmaps")) {
mark_dirty(s, 0); goto bail4;
}
sbi->sb_dirband_size = a;
} else
pr_err("You really don't want any checks? You are crazy...\n");
/* Load code page table */ if (le32_to_cpu(spareblock->n_code_pages)) if (!(sbi->sb_cp_table = hpfs_load_code_page(s, le32_to_cpu(spareblock->code_page_dir))))
pr_err("code page support is disabled\n");
brelse(bh2);
brelse(bh1);
brelse(bh0);
root = iget_locked(s, sbi->sb_root); if (!root) goto bail0;
hpfs_init_inode(root);
hpfs_read_inode(root);
unlock_new_inode(root);
s->s_root = d_make_root(root); if (!s->s_root) goto bail0;
/* * find the root directory's . pointer & finish filling in the inode
*/
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.