📄 super.c
字号:
int qtype; char *qname;#endif if (!options) return 1; while ((p = strsep (&options, ",")) != NULL) { int token; if (!*p) continue; token = match_token(p, tokens, args); switch (token) { case Opt_bsd_df: clear_opt (sbi->s_mount_opt, MINIX_DF); break; case Opt_minix_df: set_opt (sbi->s_mount_opt, MINIX_DF); break; case Opt_grpid: set_opt (sbi->s_mount_opt, GRPID); break; case Opt_nogrpid: clear_opt (sbi->s_mount_opt, GRPID); break; case Opt_resuid: if (match_int(&args[0], &option)) return 0; sbi->s_resuid = option; break; case Opt_resgid: if (match_int(&args[0], &option)) return 0; sbi->s_resgid = option; break; case Opt_sb: /* handled by get_sb_block() instead of here */ /* *sb_block = match_int(&args[0]); */ break; case Opt_err_panic: clear_opt (sbi->s_mount_opt, ERRORS_CONT); clear_opt (sbi->s_mount_opt, ERRORS_RO); set_opt (sbi->s_mount_opt, ERRORS_PANIC); break; case Opt_err_ro: clear_opt (sbi->s_mount_opt, ERRORS_CONT); clear_opt (sbi->s_mount_opt, ERRORS_PANIC); set_opt (sbi->s_mount_opt, ERRORS_RO); break; case Opt_err_cont: clear_opt (sbi->s_mount_opt, ERRORS_RO); clear_opt (sbi->s_mount_opt, ERRORS_PANIC); set_opt (sbi->s_mount_opt, ERRORS_CONT); break; case Opt_nouid32: set_opt (sbi->s_mount_opt, NO_UID32); break; case Opt_nocheck: clear_opt (sbi->s_mount_opt, CHECK); break; case Opt_debug: set_opt (sbi->s_mount_opt, DEBUG); break; case Opt_oldalloc: set_opt (sbi->s_mount_opt, OLDALLOC); break; case Opt_orlov: clear_opt (sbi->s_mount_opt, OLDALLOC); break;#ifdef CONFIG_EXT4DEV_FS_XATTR case Opt_user_xattr: set_opt (sbi->s_mount_opt, XATTR_USER); break; case Opt_nouser_xattr: clear_opt (sbi->s_mount_opt, XATTR_USER); break;#else case Opt_user_xattr: case Opt_nouser_xattr: printk("EXT4 (no)user_xattr options not supported\n"); break;#endif#ifdef CONFIG_EXT4DEV_FS_POSIX_ACL case Opt_acl: set_opt(sbi->s_mount_opt, POSIX_ACL); break; case Opt_noacl: clear_opt(sbi->s_mount_opt, POSIX_ACL); break;#else case Opt_acl: case Opt_noacl: printk("EXT4 (no)acl options not supported\n"); break;#endif case Opt_reservation: set_opt(sbi->s_mount_opt, RESERVATION); break; case Opt_noreservation: clear_opt(sbi->s_mount_opt, RESERVATION); break; case Opt_journal_update: /* @@@ FIXME */ /* Eventually we will want to be able to create a journal file here. For now, only allow the user to specify an existing inode to be the journal file. */ if (is_remount) { printk(KERN_ERR "EXT4-fs: cannot specify " "journal on remount\n"); return 0; } set_opt (sbi->s_mount_opt, UPDATE_JOURNAL); break; case Opt_journal_inum: if (is_remount) { printk(KERN_ERR "EXT4-fs: cannot specify " "journal on remount\n"); return 0; } if (match_int(&args[0], &option)) return 0; *inum = option; break; case Opt_journal_dev: if (is_remount) { printk(KERN_ERR "EXT4-fs: cannot specify " "journal on remount\n"); return 0; } if (match_int(&args[0], &option)) return 0; *journal_devnum = option; break; case Opt_noload: set_opt (sbi->s_mount_opt, NOLOAD); break; case Opt_commit: if (match_int(&args[0], &option)) return 0; if (option < 0) return 0; if (option == 0) option = JBD2_DEFAULT_MAX_COMMIT_AGE; sbi->s_commit_interval = HZ * option; break; case Opt_data_journal: data_opt = EXT4_MOUNT_JOURNAL_DATA; goto datacheck; case Opt_data_ordered: data_opt = EXT4_MOUNT_ORDERED_DATA; goto datacheck; case Opt_data_writeback: data_opt = EXT4_MOUNT_WRITEBACK_DATA; datacheck: if (is_remount) { if ((sbi->s_mount_opt & EXT4_MOUNT_DATA_FLAGS) != data_opt) { printk(KERN_ERR "EXT4-fs: cannot change data " "mode on remount\n"); return 0; } } else { sbi->s_mount_opt &= ~EXT4_MOUNT_DATA_FLAGS; sbi->s_mount_opt |= data_opt; } break;#ifdef CONFIG_QUOTA case Opt_usrjquota: qtype = USRQUOTA; goto set_qf_name; case Opt_grpjquota: qtype = GRPQUOTA;set_qf_name: if (sb_any_quota_enabled(sb)) { printk(KERN_ERR "EXT4-fs: Cannot change journalled " "quota options when quota turned on.\n"); return 0; } qname = match_strdup(&args[0]); if (!qname) { printk(KERN_ERR "EXT4-fs: not enough memory for " "storing quotafile name.\n"); return 0; } if (sbi->s_qf_names[qtype] && strcmp(sbi->s_qf_names[qtype], qname)) { printk(KERN_ERR "EXT4-fs: %s quota file already " "specified.\n", QTYPE2NAME(qtype)); kfree(qname); return 0; } sbi->s_qf_names[qtype] = qname; if (strchr(sbi->s_qf_names[qtype], '/')) { printk(KERN_ERR "EXT4-fs: quotafile must be on " "filesystem root.\n"); kfree(sbi->s_qf_names[qtype]); sbi->s_qf_names[qtype] = NULL; return 0; } set_opt(sbi->s_mount_opt, QUOTA); break; case Opt_offusrjquota: qtype = USRQUOTA; goto clear_qf_name; case Opt_offgrpjquota: qtype = GRPQUOTA;clear_qf_name: if (sb_any_quota_enabled(sb)) { printk(KERN_ERR "EXT4-fs: Cannot change " "journalled quota options when " "quota turned on.\n"); return 0; } /* * The space will be released later when all options * are confirmed to be correct */ sbi->s_qf_names[qtype] = NULL; break; case Opt_jqfmt_vfsold: sbi->s_jquota_fmt = QFMT_VFS_OLD; break; case Opt_jqfmt_vfsv0: sbi->s_jquota_fmt = QFMT_VFS_V0; break; case Opt_quota: case Opt_usrquota: set_opt(sbi->s_mount_opt, QUOTA); set_opt(sbi->s_mount_opt, USRQUOTA); break; case Opt_grpquota: set_opt(sbi->s_mount_opt, QUOTA); set_opt(sbi->s_mount_opt, GRPQUOTA); break; case Opt_noquota: if (sb_any_quota_enabled(sb)) { printk(KERN_ERR "EXT4-fs: Cannot change quota " "options when quota turned on.\n"); return 0; } clear_opt(sbi->s_mount_opt, QUOTA); clear_opt(sbi->s_mount_opt, USRQUOTA); clear_opt(sbi->s_mount_opt, GRPQUOTA); break;#else case Opt_quota: case Opt_usrquota: case Opt_grpquota: case Opt_usrjquota: case Opt_grpjquota: case Opt_offusrjquota: case Opt_offgrpjquota: case Opt_jqfmt_vfsold: case Opt_jqfmt_vfsv0: printk(KERN_ERR "EXT4-fs: journalled quota options not " "supported.\n"); break; case Opt_noquota: break;#endif case Opt_abort: set_opt(sbi->s_mount_opt, ABORT); break; case Opt_barrier: if (match_int(&args[0], &option)) return 0; if (option) set_opt(sbi->s_mount_opt, BARRIER); else clear_opt(sbi->s_mount_opt, BARRIER); break; case Opt_ignore: break; case Opt_resize: if (!is_remount) { printk("EXT4-fs: resize option only available " "for remount\n"); return 0; } if (match_int(&args[0], &option) != 0) return 0; *n_blocks_count = option; break; case Opt_nobh: set_opt(sbi->s_mount_opt, NOBH); break; case Opt_bh: clear_opt(sbi->s_mount_opt, NOBH); break; case Opt_extents: set_opt (sbi->s_mount_opt, EXTENTS); break; case Opt_noextents: clear_opt (sbi->s_mount_opt, EXTENTS); break; default: printk (KERN_ERR "EXT4-fs: Unrecognized mount option \"%s\" " "or missing value\n", p); return 0; } }#ifdef CONFIG_QUOTA if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { if ((sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA) && sbi->s_qf_names[USRQUOTA]) clear_opt(sbi->s_mount_opt, USRQUOTA); if ((sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA) && sbi->s_qf_names[GRPQUOTA]) clear_opt(sbi->s_mount_opt, GRPQUOTA); if ((sbi->s_qf_names[USRQUOTA] && (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA)) || (sbi->s_qf_names[GRPQUOTA] && (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA))) { printk(KERN_ERR "EXT4-fs: old and new quota " "format mixing.\n"); return 0; } if (!sbi->s_jquota_fmt) { printk(KERN_ERR "EXT4-fs: journalled quota format " "not specified.\n"); return 0; } } else { if (sbi->s_jquota_fmt) { printk(KERN_ERR "EXT4-fs: journalled quota format " "specified with no journalling " "enabled.\n"); return 0; } }#endif return 1;}static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es, int read_only){ struct ext4_sb_info *sbi = EXT4_SB(sb); int res = 0; if (le32_to_cpu(es->s_rev_level) > EXT4_MAX_SUPP_REV) { printk (KERN_ERR "EXT4-fs warning: revision level too high, " "forcing read-only mode\n"); res = MS_RDONLY; } if (read_only) return res; if (!(sbi->s_mount_state & EXT4_VALID_FS)) printk (KERN_WARNING "EXT4-fs warning: mounting unchecked fs, " "running e2fsck is recommended\n"); else if ((sbi->s_mount_state & EXT4_ERROR_FS)) printk (KERN_WARNING "EXT4-fs warning: mounting fs with errors, " "running e2fsck is recommended\n"); else if ((__s16) le16_to_cpu(es->s_max_mnt_count) >= 0 && le16_to_cpu(es->s_mnt_count) >= (unsigned short) (__s16) le16_to_cpu(es->s_max_mnt_count)) printk (KERN_WARNING "EXT4-fs warning: maximal mount count reached, " "running e2fsck is recommended\n"); else if (le32_to_cpu(es->s_checkinterval) && (le32_to_cpu(es->s_lastcheck) + le32_to_cpu(es->s_checkinterval) <= get_seconds())) printk (KERN_WARNING "EXT4-fs warning: checktime reached, " "running e2fsck is recommended\n");#if 0 /* @@@ We _will_ want to clear the valid bit if we find * inconsistencies, to force a fsck at reboot. But for * a plain journaled filesystem we can keep it set as * valid forever! :) */ es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) & ~EXT4_VALID_FS);#endif if (!(__s16) le16_to_cpu(es->s_max_mnt_count)) es->s_max_mnt_count = cpu_to_le16(EXT4_DFL_MAX_MNT_COUNT); es->s_mnt_count=cpu_to_le16(le16_to_cpu(es->s_mnt_count) + 1); es->s_mtime = cpu_to_le32(get_seconds()); ext4_update_dynamic_rev(sb); EXT4_SET_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER); ext4_commit_super(sb, es, 1); if (test_opt(sb, DEBUG)) printk(KERN_INFO "[EXT4 FS bs=%lu, gc=%lu, " "bpg=%lu, ipg=%lu, mo=%04lx]\n", sb->s_blocksize, sbi->s_groups_count, EXT4_BLOCKS_PER_GROUP(sb), EXT4_INODES_PER_GROUP(sb), sbi->s_mount_opt); printk(KERN_INFO "EXT4 FS on %s, ", sb->s_id); if (EXT4_SB(sb)->s_journal->j_inode == NULL) { char b[BDEVNAME_SIZE]; printk("external journal on %s\n", bdevname(EXT4_SB(sb)->s_journal->j_dev, b)); } else { printk("internal journal\n"); } return res;}__le16 ext4_group_desc_csum(struct ext4_sb_info *sbi, __u32 block_group, struct ext4_group_desc *gdp){ __u16 crc = 0; if (sbi->s_es->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) { int offset = offsetof(struct ext4_group_desc, bg_checksum); __le32 le_group = cpu_to_le32(block_group); crc = crc16(~0, sbi->s_es->s_uuid, sizeof(sbi->s_es->s_uuid)); crc = crc16(crc, (__u8 *)&le_group, sizeof(le_group)); crc = crc16(crc, (__u8 *)gdp, offset); offset += sizeof(gdp->bg_checksum); /* skip checksum */ /* for checksum of struct ext4_group_desc do the rest...*/ if ((sbi->s_es->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_64BIT)) && offset < le16_to_cpu(sbi->s_es->s_desc_size)) crc = crc16(crc, (__u8 *)gdp + offset, le16_to_cpu(sbi->s_es->s_desc_size) - offset); } return cpu_to_le16(crc);}int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 block_group, struct ext4_group_desc *gdp){ if ((sbi->s_es->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) && (gdp->bg_checksum != ext4_group_desc_csum(sbi, block_group, gdp))) return 0; return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -