📄 super.c
字号:
(1 << REISERFS_LARGETAIL) | (1 << REISERFS_SMALLTAIL)}, {"conv",.setmask = 1 << REISERFS_CONVERT}, {"attrs",.setmask = 1 << REISERFS_ATTRS}, {"noattrs",.clrmask = 1 << REISERFS_ATTRS},#ifdef CONFIG_REISERFS_FS_XATTR {"user_xattr",.setmask = 1 << REISERFS_XATTRS_USER}, {"nouser_xattr",.clrmask = 1 << REISERFS_XATTRS_USER},#else {"user_xattr",.setmask = 1 << REISERFS_UNSUPPORTED_OPT}, {"nouser_xattr",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT},#endif#ifdef CONFIG_REISERFS_FS_POSIX_ACL {"acl",.setmask = 1 << REISERFS_POSIXACL}, {"noacl",.clrmask = 1 << REISERFS_POSIXACL},#else {"acl",.setmask = 1 << REISERFS_UNSUPPORTED_OPT}, {"noacl",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT},#endif {.option_name = "nolog"}, {"replayonly",.setmask = 1 << REPLAYONLY}, {"block-allocator",.arg_required = 'a',.values = balloc}, {"data",.arg_required = 'd',.values = logging_mode}, {"barrier",.arg_required = 'b',.values = barrier_mode}, {"resize",.arg_required = 'r',.values = NULL}, {"jdev",.arg_required = 'j',.values = NULL}, {"nolargeio",.arg_required = 'w',.values = NULL}, {"commit",.arg_required = 'c',.values = NULL}, {"usrquota",.setmask = 1 << REISERFS_QUOTA}, {"grpquota",.setmask = 1 << REISERFS_QUOTA}, {"noquota",.clrmask = 1 << REISERFS_QUOTA}, {"errors",.arg_required = 'e',.values = error_actions}, {"usrjquota",.arg_required = 'u' | (1 << REISERFS_OPT_ALLOWEMPTY),.values = NULL}, {"grpjquota",.arg_required = 'g' | (1 << REISERFS_OPT_ALLOWEMPTY),.values = NULL}, {"jqfmt",.arg_required = 'f',.values = NULL}, {.option_name = NULL} }; *blocks = 0; if (!options || !*options) /* use default configuration: create tails, journaling on, no conversion to newest format */ return 1; for (pos = options; pos;) { c = reiserfs_getopt(s, &pos, opts, &arg, mount_options); if (c == -1) /* wrong option is given */ return 0; if (c == 'r') { char *p; p = NULL; /* "resize=NNN" or "resize=auto" */ if (!strcmp(arg, "auto")) { /* From JFS code, to auto-get the size. */ *blocks = s->s_bdev->bd_inode->i_size >> s-> s_blocksize_bits; } else { *blocks = simple_strtoul(arg, &p, 0); if (*p != '\0') { /* NNN does not look like a number */ reiserfs_warning(s, "reiserfs_parse_options: bad value %s", arg); return 0; } } } if (c == 'c') { char *p = NULL; unsigned long val = simple_strtoul(arg, &p, 0); /* commit=NNN (time in seconds) */ if (*p != '\0' || val >= (unsigned int)-1) { reiserfs_warning(s, "reiserfs_parse_options: bad value %s", arg); return 0; } *commit_max_age = (unsigned int)val; } if (c == 'w') { reiserfs_warning(s, "reiserfs: nolargeio option is no longer supported"); return 0; } if (c == 'j') { if (arg && *arg && jdev_name) { if (*jdev_name) { //Hm, already assigned? reiserfs_warning(s, "reiserfs_parse_options: journal device was already specified to be %s", *jdev_name); return 0; } *jdev_name = arg; } }#ifdef CONFIG_QUOTA if (c == 'u' || c == 'g') { int qtype = c == 'u' ? USRQUOTA : GRPQUOTA; if (sb_any_quota_enabled(s)) { reiserfs_warning(s, "reiserfs_parse_options: cannot change journalled quota options when quota turned on."); return 0; } if (*arg) { /* Some filename specified? */ if (REISERFS_SB(s)->s_qf_names[qtype] && strcmp(REISERFS_SB(s)->s_qf_names[qtype], arg)) { reiserfs_warning(s, "reiserfs_parse_options: %s quota file already specified.", QTYPE2NAME(qtype)); return 0; } if (strchr(arg, '/')) { reiserfs_warning(s, "reiserfs_parse_options: quotafile must be on filesystem root."); return 0; } REISERFS_SB(s)->s_qf_names[qtype] = kmalloc(strlen(arg) + 1, GFP_KERNEL); if (!REISERFS_SB(s)->s_qf_names[qtype]) { reiserfs_warning(s, "reiserfs_parse_options: not enough memory for storing quotafile name."); return 0; } strcpy(REISERFS_SB(s)->s_qf_names[qtype], arg); *mount_options |= 1 << REISERFS_QUOTA; } else { kfree(REISERFS_SB(s)->s_qf_names[qtype]); REISERFS_SB(s)->s_qf_names[qtype] = NULL; } } if (c == 'f') { if (!strcmp(arg, "vfsold")) REISERFS_SB(s)->s_jquota_fmt = QFMT_VFS_OLD; else if (!strcmp(arg, "vfsv0")) REISERFS_SB(s)->s_jquota_fmt = QFMT_VFS_V0; else { reiserfs_warning(s, "reiserfs_parse_options: unknown quota format specified."); return 0; } }#else if (c == 'u' || c == 'g' || c == 'f') { reiserfs_warning(s, "reiserfs_parse_options: journalled quota options not supported."); return 0; }#endif }#ifdef CONFIG_QUOTA if (!REISERFS_SB(s)->s_jquota_fmt && (REISERFS_SB(s)->s_qf_names[USRQUOTA] || REISERFS_SB(s)->s_qf_names[GRPQUOTA])) { reiserfs_warning(s, "reiserfs_parse_options: journalled quota format not specified."); return 0; } /* This checking is not precise wrt the quota type but for our purposes it is sufficient */ if (!(*mount_options & (1 << REISERFS_QUOTA)) && sb_any_quota_enabled(s)) { reiserfs_warning(s, "reiserfs_parse_options: quota options must be present when quota is turned on."); return 0; }#endif return 1;}static void switch_data_mode(struct super_block *s, unsigned long mode){ REISERFS_SB(s)->s_mount_opt &= ~((1 << REISERFS_DATA_LOG) | (1 << REISERFS_DATA_ORDERED) | (1 << REISERFS_DATA_WRITEBACK)); REISERFS_SB(s)->s_mount_opt |= (1 << mode);}static void handle_data_mode(struct super_block *s, unsigned long mount_options){ if (mount_options & (1 << REISERFS_DATA_LOG)) { if (!reiserfs_data_log(s)) { switch_data_mode(s, REISERFS_DATA_LOG); reiserfs_info(s, "switching to journaled data mode\n"); } } else if (mount_options & (1 << REISERFS_DATA_ORDERED)) { if (!reiserfs_data_ordered(s)) { switch_data_mode(s, REISERFS_DATA_ORDERED); reiserfs_info(s, "switching to ordered data mode\n"); } } else if (mount_options & (1 << REISERFS_DATA_WRITEBACK)) { if (!reiserfs_data_writeback(s)) { switch_data_mode(s, REISERFS_DATA_WRITEBACK); reiserfs_info(s, "switching to writeback data mode\n"); } }}static void handle_barrier_mode(struct super_block *s, unsigned long bits){ int flush = (1 << REISERFS_BARRIER_FLUSH); int none = (1 << REISERFS_BARRIER_NONE); int all_barrier = flush | none; if (bits & all_barrier) { REISERFS_SB(s)->s_mount_opt &= ~all_barrier; if (bits & flush) { REISERFS_SB(s)->s_mount_opt |= flush; printk("reiserfs: enabling write barrier flush mode\n"); } else if (bits & none) { REISERFS_SB(s)->s_mount_opt |= none; printk("reiserfs: write barriers turned off\n"); } }}static void handle_attrs(struct super_block *s){ struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s); if (reiserfs_attrs(s)) { if (old_format_only(s)) { reiserfs_warning(s, "reiserfs: cannot support attributes on 3.5.x disk format"); REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS); return; } if (!(le32_to_cpu(rs->s_flags) & reiserfs_attrs_cleared)) { reiserfs_warning(s, "reiserfs: cannot support attributes until flag is set in super-block"); REISERFS_SB(s)->s_mount_opt &= ~(1 << REISERFS_ATTRS); } }}static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg){ struct reiserfs_super_block *rs; struct reiserfs_transaction_handle th; unsigned long blocks; unsigned long mount_options = REISERFS_SB(s)->s_mount_opt; unsigned long safe_mask = 0; unsigned int commit_max_age = (unsigned int)-1; struct reiserfs_journal *journal = SB_JOURNAL(s); int err;#ifdef CONFIG_QUOTA int i;#endif rs = SB_DISK_SUPER_BLOCK(s); if (!reiserfs_parse_options (s, arg, &mount_options, &blocks, NULL, &commit_max_age)) {#ifdef CONFIG_QUOTA for (i = 0; i < MAXQUOTAS; i++) { kfree(REISERFS_SB(s)->s_qf_names[i]); REISERFS_SB(s)->s_qf_names[i] = NULL; }#endif return -EINVAL; } handle_attrs(s); /* Add options that are safe here */ safe_mask |= 1 << REISERFS_SMALLTAIL; safe_mask |= 1 << REISERFS_LARGETAIL; safe_mask |= 1 << REISERFS_NO_BORDER; safe_mask |= 1 << REISERFS_NO_UNHASHED_RELOCATION; safe_mask |= 1 << REISERFS_HASHED_RELOCATION; safe_mask |= 1 << REISERFS_TEST4; safe_mask |= 1 << REISERFS_ATTRS; safe_mask |= 1 << REISERFS_XATTRS_USER; safe_mask |= 1 << REISERFS_POSIXACL; safe_mask |= 1 << REISERFS_BARRIER_FLUSH; safe_mask |= 1 << REISERFS_BARRIER_NONE; safe_mask |= 1 << REISERFS_ERROR_RO; safe_mask |= 1 << REISERFS_ERROR_CONTINUE; safe_mask |= 1 << REISERFS_ERROR_PANIC; safe_mask |= 1 << REISERFS_QUOTA; /* Update the bitmask, taking care to keep * the bits we're not allowed to change here */ REISERFS_SB(s)->s_mount_opt = (REISERFS_SB(s)-> s_mount_opt & ~safe_mask) | (mount_options & safe_mask); if (commit_max_age != 0 && commit_max_age != (unsigned int)-1) { journal->j_max_commit_age = commit_max_age; journal->j_max_trans_age = commit_max_age; } else if (commit_max_age == 0) { /* 0 means restore defaults. */ journal->j_max_commit_age = journal->j_default_max_commit_age; journal->j_max_trans_age = JOURNAL_MAX_TRANS_AGE; } if (blocks) { int rc = reiserfs_resize(s, blocks); if (rc != 0) return rc; } if (*mount_flags & MS_RDONLY) { reiserfs_xattr_init(s, *mount_flags); /* remount read-only */ if (s->s_flags & MS_RDONLY) /* it is read-only already */ return 0; /* try to remount file system with read-only permissions */ if (sb_umount_state(rs) == REISERFS_VALID_FS || REISERFS_SB(s)->s_mount_state != REISERFS_VALID_FS) { return 0; } err = journal_begin(&th, s, 10); if (err) return err; /* Mounting a rw partition read-only. */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); set_sb_umount_state(rs, REISERFS_SB(s)->s_mount_state); journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s)); } else { /* remount read-write */ if (!(s->s_flags & MS_RDONLY)) { reiserfs_xattr_init(s, *mount_flags); return 0; /* We are read-write already */ } if (reiserfs_is_journal_aborted(journal)) return journal->j_errno; handle_data_mode(s, mount_options); handle_barrier_mode(s, mount_options); REISERFS_SB(s)->s_mount_state = sb_umount_state(rs); s->s_flags &= ~MS_RDONLY; /* now it is safe to call journal_begin */ err = journal_begin(&th, s, 10); if (err) return err; /* Mount a partition which is read-only, read-write */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); REISERFS_SB(s)->s_mount_state = sb_umount_state(rs); s->s_flags &= ~MS_RDONLY; set_sb_umount_state(rs, REISERFS_ERROR_FS); /* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1); */ journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s)); REISERFS_SB(s)->s_mount_state = REISERFS_VALID_FS; } /* this will force a full flush of all journal lists */ SB_JOURNAL(s)->j_must_wait = 1; err = journal_end(&th, s, 10); if (err) return err; s->s_dirt = 0; if (!(*mount_flags & MS_RDONLY)) { finish_unfinished(s); reiserfs_xattr_init(s, *mount_flags); } return 0;}static int read_super_block(struct super_block *s, int offset){ struct buffer_head *bh; struct reiserfs_super_block *rs; int fs_blocksize; bh = sb_bread(s, offset / s->s_blocksize); if (!bh) { reiserfs_warning(s, "sh-2006: read_super_block: " "bread failed (dev %s, block %lu, size %lu)", reiserfs_bdevname(s), offset / s->s_blocksize, s->s_blocksize); return 1; } rs = (struct reiserfs_super_block *)bh->b_data; if (!is_any_reiserfs_magic_string(rs)) { brelse(bh); return 1; } // // ok, reiserfs signature (old or new) found in at the given offset // fs_blocksize = sb_blocksize(rs); brelse(bh); sb_set_blocksize(s, fs_blocksize); bh = sb_bread(s, offset / s->s_blocksize); if (!bh) { reiserfs_warning(s, "sh-2007: read_super_block: " "bread failed (dev %s, block %lu, size %lu)\n", reiserfs_bdevname(s), offset / s->s_blocksize, s->s_blocksize); return 1; } rs = (struct reiserfs_super_block *)bh->b_data; if (sb_blocksize(rs) != s->s_blocksize) { reiserfs_warning(s, "sh-2011: read_super_block: " "can't find a reiserfs filesystem on (dev %s, block %Lu, size %lu)\n", reiserfs_bdevname(s), (unsigned long long)bh->b_blocknr, s->s_blocksize); brelse(bh); return 1; } if (rs->s_v1.s_root_block == cpu_to_le32(-1)) { brelse(bh); reiserfs_warning(s, "Unfinished reiserfsck --rebuild-tree run detected. Please run\n" "reiserfsck --rebuild-tree and wait for a completion. If that fails\n" "get newer reiserfsprogs package"); return 1; } SB_BUFFER_WITH_SB(s) = bh; SB_DISK_SUPER_BLOCK(s) = rs; if (is_reiserfs_jr(rs)) { /* magic is of non-standard journal filesystem, look at s_version to find which format is in use */ if (sb_version(rs) == REISERFS_VERSION_2) reiserfs_warning(s, "read_super_block: found reiserfs format \"3.6\"" " with non-standard journal"); else if (sb_version(rs) == REISERFS_VERSION_1) reiserfs_warning(s, "read_super_block: found reiserfs format \"3.5\""
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -