📄 super.c
字号:
break;#ifdef CONFIG_EXT3_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("EXT3 (no)user_xattr options not supported\n"); break;#endif#ifdef CONFIG_EXT3_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("EXT3 (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 "EXT3-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 "EXT3-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 "EXT3-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 = JBD_DEFAULT_MAX_COMMIT_AGE; sbi->s_commit_interval = HZ * option; break; case Opt_data_journal: data_opt = EXT3_MOUNT_JOURNAL_DATA; goto datacheck; case Opt_data_ordered: data_opt = EXT3_MOUNT_ORDERED_DATA; goto datacheck; case Opt_data_writeback: data_opt = EXT3_MOUNT_WRITEBACK_DATA; datacheck: if (is_remount) { if ((sbi->s_mount_opt & EXT3_MOUNT_DATA_FLAGS) != data_opt) { printk(KERN_ERR "EXT3-fs: cannot change data " "mode on remount\n"); return 0; } } else { sbi->s_mount_opt &= ~EXT3_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 "EXT3-fs: Cannot change journalled " "quota options when quota turned on.\n"); return 0; } qname = match_strdup(&args[0]); if (!qname) { printk(KERN_ERR "EXT3-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 "EXT3-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 "EXT3-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 "EXT3-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 "EXT3-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 "EXT3-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("EXT3-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; default: printk (KERN_ERR "EXT3-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 & EXT3_MOUNT_USRQUOTA) && sbi->s_qf_names[USRQUOTA]) clear_opt(sbi->s_mount_opt, USRQUOTA); if ((sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA) && sbi->s_qf_names[GRPQUOTA]) clear_opt(sbi->s_mount_opt, GRPQUOTA); if ((sbi->s_qf_names[USRQUOTA] && (sbi->s_mount_opt & EXT3_MOUNT_GRPQUOTA)) || (sbi->s_qf_names[GRPQUOTA] && (sbi->s_mount_opt & EXT3_MOUNT_USRQUOTA))) { printk(KERN_ERR "EXT3-fs: old and new quota " "format mixing.\n"); return 0; } if (!sbi->s_jquota_fmt) { printk(KERN_ERR "EXT3-fs: journalled quota format " "not specified.\n"); return 0; } } else { if (sbi->s_jquota_fmt) { printk(KERN_ERR "EXT3-fs: journalled quota format " "specified with no journalling " "enabled.\n"); return 0; } }#endif return 1;}static int ext3_setup_super(struct super_block *sb, struct ext3_super_block *es, int read_only){ struct ext3_sb_info *sbi = EXT3_SB(sb); int res = 0; if (le32_to_cpu(es->s_rev_level) > EXT3_MAX_SUPP_REV) { printk (KERN_ERR "EXT3-fs warning: revision level too high, " "forcing read-only mode\n"); res = MS_RDONLY; } if (read_only) return res; if (!(sbi->s_mount_state & EXT3_VALID_FS)) printk (KERN_WARNING "EXT3-fs warning: mounting unchecked fs, " "running e2fsck is recommended\n"); else if ((sbi->s_mount_state & EXT3_ERROR_FS)) printk (KERN_WARNING "EXT3-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 "EXT3-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 "EXT3-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) & ~EXT3_VALID_FS);#endif if (!(__s16) le16_to_cpu(es->s_max_mnt_count)) es->s_max_mnt_count = cpu_to_le16(EXT3_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()); ext3_update_dynamic_rev(sb); EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); ext3_commit_super(sb, es, 1); if (test_opt(sb, DEBUG)) printk(KERN_INFO "[EXT3 FS bs=%lu, gc=%lu, " "bpg=%lu, ipg=%lu, mo=%04lx]\n", sb->s_blocksize, sbi->s_groups_count, EXT3_BLOCKS_PER_GROUP(sb), EXT3_INODES_PER_GROUP(sb), sbi->s_mount_opt); printk(KERN_INFO "EXT3 FS on %s, ", sb->s_id); if (EXT3_SB(sb)->s_journal->j_inode == NULL) { char b[BDEVNAME_SIZE]; printk("external journal on %s\n", bdevname(EXT3_SB(sb)->s_journal->j_dev, b)); } else { printk("internal journal\n"); } return res;}/* Called at mount-time, super-block is locked */static int ext3_check_descriptors (struct super_block * sb){ struct ext3_sb_info *sbi = EXT3_SB(sb); ext3_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); ext3_fsblk_t last_block; struct ext3_group_desc * gdp = NULL; int desc_block = 0; int i; ext3_debug ("Checking group descriptors"); for (i = 0; i < sbi->s_groups_count; i++) { if (i == sbi->s_groups_count - 1) last_block = le32_to_cpu(sbi->s_es->s_blocks_count) - 1; else last_block = first_block + (EXT3_BLOCKS_PER_GROUP(sb) - 1); if ((i % EXT3_DESC_PER_BLOCK(sb)) == 0) gdp = (struct ext3_group_desc *) sbi->s_group_desc[desc_block++]->b_data; if (le32_to_cpu(gdp->bg_block_bitmap) < first_block || le32_to_cpu(gdp->bg_block_bitmap) > last_block) { ext3_error (sb, "ext3_check_descriptors", "Block bitmap for group %d" " not in group (block %lu)!", i, (unsigned long) le32_to_cpu(gdp->bg_block_bitmap)); return 0; } if (le32_to_cpu(gdp->bg_inode_bitmap) < first_block || le32_to_cpu(gdp->bg_inode_bitmap) > last_block) { ext3_error (sb, "ext3_check_descriptors", "Inode bitmap for group %d" " not in group (block %lu)!", i, (unsigned long) le32_to_cpu(gdp->bg_inode_bitmap)); return 0; } if (le32_to_cpu(gdp->bg_inode_table) < first_block || le32_to_cpu(gdp->bg_inode_table) + sbi->s_itb_per_group - 1 > last_block) { ext3_error (sb, "ext3_check_descriptors", "Inode table for group %d" " not in group (block %lu)!", i, (unsigned long) le32_to_cpu(gdp->bg_inode_table)); return 0; } first_block += EXT3_BLOCKS_PER_GROUP(sb); gdp++; } sbi->s_es->s_free_blocks_count=cpu_to_le32(ext3_count_free_blocks(sb)); sbi->s_es->s_free_inodes_count=cpu_to_le32(ext3_count_free_inodes(sb)); return 1;}/* ext3_orphan_cleanup() walks a singly-linked list of inodes (starting at * the superblock) which were deleted from all directories, but held open by * a process at the time of a crash. We walk the list and try to delete these * inodes at recovery time (only with a read-write filesystem). * * In order to keep the orphan inode chain consistent during traversal (in * case of crash during recovery), we link each inode into the superblock * orphan list_head and handle it the same way as an inode deletion during * normal operation (which journals the operations for us). * * We only do an iget() and an iput() on each inode, which is very safe if we * accidentally point at an in-use or already deleted inode. The worst that * can happen in this case is that we get a "bit already cleared" message from * ext3_free_inode(). The only reason we would point at a wrong inode is if * e2fsck was run on this filesystem, and it must have already done the orphan * inode cleanup for us, so we can safely abort without any further action. */static void ext3_orphan_cleanup (struct super_block * sb, struct ext3_super_block * es){ unsigned int s_flags = sb->s_flags; int nr_orphans = 0, nr_truncates = 0;#ifdef CONFIG_QUOTA int i;#endif if (!es->s_last_orphan) { jbd_debug(4, "no orphan inodes to clean up\n"); return; } if (bdev_read_only(sb->s_bdev)) { printk(KERN_ERR "EXT3-fs: write access " "unavailable, skipping orphan cleanup.\n"); return; } if (EXT3_SB(sb)->s_mount_state & EXT3_ERROR_FS) { if (es->s_last_orphan) jbd_debug(1, "Errors on filesystem, " "clearing orphan list.\n"); es->s_last_orphan = 0; jbd_debug(1, "Skipping orphan recovery on fs with errors.\n"); return; } if (s_flags & MS_RDONLY) { printk(KERN_INFO "EXT3-fs: %s: orphan cleanup on readonly fs\n", sb->s_id); sb->s_flags &= ~MS_RDONLY; }#ifdef CONFIG_QUOTA /* Needed for iput() to work correctly and not trash data */ sb->s_flags |= MS_ACTIVE; /* Turn on quotas so that they are updated correctly */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -