📄 super.c
字号:
/* * linux/fs/ext2/super.c * * Copyright (C) 1992, 1993, 1994 Remy Card (card@masi.ibp.fr) * Laboratoire MASI - Institut Blaise Pascal * Universite Pierre et Marie Curie (Paris VI) * * from * * linux/fs/minix/inode.c * * Copyright (C) 1991, 1992 Linus Torvalds */#include <stdarg.h>#include <asm/segment.h>#include <asm/system.h>#include <linux/errno.h>#include <linux/fs.h>#include <linux/ext2_fs.h>#include <linux/sched.h>#include <linux/stat.h>#include <linux/string.h>#include <linux/locks.h>extern int vsprintf (char *, const char *, va_list);void ext2_error (struct super_block * sb, const char * function, const char * fmt, ...){ char buf[1024]; va_list args; if (!(sb->s_flags & MS_RDONLY)) { sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS; sb->u.ext2_sb.s_es->s_state |= EXT2_ERROR_FS; sb->u.ext2_sb.s_sbh->b_dirt = 1; sb->s_dirt = 1; } va_start (args, fmt); vsprintf (buf, fmt, args); va_end (args); if (test_opt (sb, ERRORS_PANIC) || (sb->u.ext2_sb.s_es->s_errors == EXT2_ERRORS_PANIC && !test_opt (sb, ERRORS_CONT) && !test_opt (sb, ERRORS_RO))) panic ("EXT2-fs panic (device %d/%d): %s: %s\n", MAJOR(sb->s_dev), MINOR(sb->s_dev), function, buf); printk (KERN_CRIT "EXT2-fs error (device %d/%d): %s: %s\n", MAJOR(sb->s_dev), MINOR(sb->s_dev), function, buf); if (test_opt (sb, ERRORS_RO) || (sb->u.ext2_sb.s_es->s_errors == EXT2_ERRORS_RO && !test_opt (sb, ERRORS_CONT) && !test_opt (sb, ERRORS_PANIC))) { printk ("Remounting filesystem read-only\n"); sb->s_flags |= MS_RDONLY; }}NORET_TYPE void ext2_panic (struct super_block * sb, const char * function, const char * fmt, ...){ char buf[1024]; va_list args; if (!(sb->s_flags & MS_RDONLY)) { sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS; sb->u.ext2_sb.s_es->s_state |= EXT2_ERROR_FS; sb->u.ext2_sb.s_sbh->b_dirt = 1; sb->s_dirt = 1; } va_start (args, fmt); vsprintf (buf, fmt, args); va_end (args); panic ("EXT2-fs panic (device %d/%d): %s: %s\n", MAJOR(sb->s_dev), MINOR(sb->s_dev), function, buf);}void ext2_warning (struct super_block * sb, const char * function, const char * fmt, ...){ char buf[1024]; va_list args; va_start (args, fmt); vsprintf (buf, fmt, args); va_end (args); printk (KERN_WARNING "EXT2-fs warning (device %d/%d): %s: %s\n", MAJOR(sb->s_dev), MINOR(sb->s_dev), function, buf);}void ext2_put_super (struct super_block * sb){ int i; lock_super (sb); if (!(sb->s_flags & MS_RDONLY)) { sb->u.ext2_sb.s_es->s_state = sb->u.ext2_sb.s_mount_state; sb->u.ext2_sb.s_sbh->b_dirt = 1; }#ifndef DONT_USE_DCACHE ext2_dcache_invalidate (sb->s_dev);#endif sb->s_dev = 0; for (i = 0; i < EXT2_MAX_GROUP_DESC; i++) if (sb->u.ext2_sb.s_group_desc[i]) brelse (sb->u.ext2_sb.s_group_desc[i]); for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) if (sb->u.ext2_sb.s_inode_bitmap[i]) brelse (sb->u.ext2_sb.s_inode_bitmap[i]); for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) if (sb->u.ext2_sb.s_block_bitmap[i]) brelse (sb->u.ext2_sb.s_block_bitmap[i]); brelse (sb->u.ext2_sb.s_sbh); unlock_super (sb); return;}static struct super_operations ext2_sops = { ext2_read_inode, NULL, ext2_write_inode, ext2_put_inode, ext2_put_super, ext2_write_super, ext2_statfs, ext2_remount};#ifdef EXT2FS_PRE_02B_COMPATstatic int convert_pre_02b_fs (struct super_block * sb, struct buffer_head * bh){ struct ext2_super_block * es; struct ext2_old_group_desc old_group_desc [BLOCK_SIZE / sizeof (struct ext2_old_group_desc)]; struct ext2_group_desc * gdp; struct buffer_head * bh2; int groups_count; int i; es = (struct ext2_super_block *) bh->b_data; bh2 = bread (sb->s_dev, 2, BLOCK_SIZE); if (!bh2) { printk ("Cannot read descriptor blocks while converting !\n"); return 0; } memcpy (old_group_desc, bh2->b_data, BLOCK_SIZE); groups_count = (sb->u.ext2_sb.s_blocks_count - sb->u.ext2_sb.s_first_data_block + (EXT2_BLOCK_SIZE(sb) * 8) - 1) / (EXT2_BLOCK_SIZE(sb) * 8); memset (bh2->b_data, 0, BLOCK_SIZE); gdp = (struct ext2_group_desc *) bh2->b_data; for (i = 0; i < groups_count; i++) { gdp[i].bg_block_bitmap = old_group_desc[i].bg_block_bitmap; gdp[i].bg_inode_bitmap = old_group_desc[i].bg_inode_bitmap; gdp[i].bg_inode_table = old_group_desc[i].bg_inode_table; gdp[i].bg_free_blocks_count = old_group_desc[i].bg_free_blocks_count; gdp[i].bg_free_inodes_count = old_group_desc[i].bg_free_inodes_count; } bh2->b_dirt = 1; brelse (bh2); es->s_magic = EXT2_SUPER_MAGIC; bh->b_dirt = 1; sb->s_magic = EXT2_SUPER_MAGIC; return 1;}#endif/* * This function has been shamelessly adapted from the msdos fs */static int parse_options (char * options, unsigned long * sb_block, unsigned long * mount_options){ char * this_char; char * value; if (!options) return 1; for (this_char = strtok (options, ","); this_char != NULL; this_char = strtok (NULL, ",")) { if ((value = strchr (this_char, '=')) != NULL) *value++ = 0; if (!strcmp (this_char, "check")) { if (!value || !*value) set_opt (*mount_options, CHECK_NORMAL); else if (!strcmp (value, "none")) { clear_opt (*mount_options, CHECK_NORMAL); clear_opt (*mount_options, CHECK_STRICT); } else if (strcmp (value, "normal")) set_opt (*mount_options, CHECK_NORMAL); else if (strcmp (value, "strict")) { set_opt (*mount_options, CHECK_NORMAL); set_opt (*mount_options, CHECK_STRICT); } else { printk ("EXT2-fs: Invalid check option: %s\n", value); return 0; } } else if (!strcmp (this_char, "debug")) set_opt (*mount_options, DEBUG); else if (!strcmp (this_char, "errors")) { if (!value || !*value) { printk ("EXT2-fs: the errors option requires " "an argument"); return 0; } if (!strcmp (value, "continue")) { clear_opt (*mount_options, ERRORS_RO); clear_opt (*mount_options, ERRORS_PANIC); set_opt (*mount_options, ERRORS_CONT); } else if (!strcmp (value, "remount-ro")) { clear_opt (*mount_options, ERRORS_CONT); clear_opt (*mount_options, ERRORS_PANIC); set_opt (*mount_options, ERRORS_RO); } else if (!strcmp (value, "panic")) { clear_opt (*mount_options, ERRORS_CONT); clear_opt (*mount_options, ERRORS_RO); set_opt (*mount_options, ERRORS_PANIC); } else { printk ("EXT2-fs: Invalid errors option: %s\n", value); return 0; } } else if (!strcmp (this_char, "grpid") || !strcmp (this_char, "bsdgroups")) set_opt (*mount_options, GRPID); else if (!strcmp (this_char, "nocheck")) { clear_opt (*mount_options, CHECK_NORMAL); clear_opt (*mount_options, CHECK_STRICT); } else if (!strcmp (this_char, "nogrpid") || !strcmp (this_char, "sysvgroups")) clear_opt (*mount_options, GRPID); else if (!strcmp (this_char, "sb")) { if (!value || !*value) { printk ("EXT2-fs: the sb option requires " "an argument"); return 0; } *sb_block = simple_strtoul (value, &value, 0); if (*value) { printk ("EXT2-fs: Invalid sb option: %s\n", value); return 0; } } else { printk ("EXT2-fs: Unrecognized mount option %s\n", this_char); return 0; } } return 1;}static void ext2_setup_super (struct super_block * sb, struct ext2_super_block * es){ if (!(sb->s_flags & MS_RDONLY)) { if (!(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS)) printk ("EXT2-fs warning: mounting unchecked fs, " "running e2fsck is recommended\n"); else if ((sb->u.ext2_sb.s_mount_state & EXT2_ERROR_FS)) printk ("EXT2-fs warning: mounting fs with errors, " "running e2fsck is recommended\n"); else if (es->s_max_mnt_count >= 0 && es->s_mnt_count >= (unsigned short) es->s_max_mnt_count) printk ("EXT2-fs warning: maximal mount count reached, " "running e2fsck is recommended\n"); else if (es->s_checkinterval && (es->s_lastcheck + es->s_checkinterval <= CURRENT_TIME)) printk ("EXT2-fs warning: checktime reached, " "running e2fsck is recommended\n"); es->s_state &= ~EXT2_VALID_FS; if (!es->s_max_mnt_count) es->s_max_mnt_count = EXT2_DFL_MAX_MNT_COUNT; es->s_mnt_count++; es->s_mtime = CURRENT_TIME; sb->u.ext2_sb.s_sbh->b_dirt = 1; sb->s_dirt = 1; if (test_opt (sb, DEBUG)) printk ("[EXT II FS %s, %s, bs=%lu, fs=%lu, gc=%lu, " "bpg=%lu, ipg=%lu, mo=%04lx]\n", EXT2FS_VERSION, EXT2FS_DATE, sb->s_blocksize, sb->u.ext2_sb.s_frag_size, sb->u.ext2_sb.s_groups_count, EXT2_BLOCKS_PER_GROUP(sb), EXT2_INODES_PER_GROUP(sb), sb->u.ext2_sb.s_mount_opt); if (test_opt (sb, CHECK)) { ext2_check_blocks_bitmap (sb); ext2_check_inodes_bitmap (sb); } }}static int ext2_check_descriptors (struct super_block * sb){ int i; int desc_block = 0; unsigned long block = sb->u.ext2_sb.s_es->s_first_data_block; struct ext2_group_desc * gdp = NULL; ext2_debug ("Checking group descriptors"); for (i = 0; i < sb->u.ext2_sb.s_groups_count; i++) { if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0) gdp = (struct ext2_group_desc *) sb->u.ext2_sb.s_group_desc[desc_block++]->b_data; if (gdp->bg_block_bitmap < block || gdp->bg_block_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) { ext2_error (sb, "ext2_check_desciptors", "Block bitmap for group %d" " not in group (block %lu)!", i, gdp->bg_block_bitmap); return 0; } if (gdp->bg_inode_bitmap < block || gdp->bg_inode_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) { ext2_error (sb, "ext2_check_desciptors", "Inode bitmap for group %d" " not in group (block %lu)!", i, gdp->bg_inode_bitmap); return 0; } if (gdp->bg_inode_table < block ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -