void ext2_error (struct super_block * sb, const char * function, const char * fmt, ...) { va_list args; struct ext2_super_block *es = EXT2_SB(sb)->s_es; if (!(sb->s_flags & MS_RDONLY)) { sb->u.ext2_sb.s_mount_state |= EXT2_ERROR_FS; es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) | EXT2_ERROR_FS); ext2_sync_super(sb, es); } va_start (args, fmt); vsprintf (error_buf, fmt, args); va_end (args); if (test_opt (sb, ERRORS_PANIC) || (le16_to_cpu(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 %s): %s: %s\n", bdevname(sb->s_dev), function, error_buf); printk (KERN_CRIT "EXT2-fs error (device %s): %s: %s\n", bdevname(sb->s_dev), function, error_buf); if (test_opt (sb, ERRORS_RO) || (le16_to_cpu(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; } }
void ext2_error(struct super_block *sb, const char *function, const char *fmt, ...) { struct va_format vaf; va_list args; struct ext2_sb_info *sbi = EXT2_SB(sb); struct ext2_super_block *es = sbi->s_es; if (!sb_rdonly(sb)) { spin_lock(&sbi->s_lock); sbi->s_mount_state |= EXT2_ERROR_FS; es->s_state |= cpu_to_le16(EXT2_ERROR_FS); spin_unlock(&sbi->s_lock); ext2_sync_super(sb, es, 1); } va_start(args, fmt); vaf.fmt = fmt; vaf.va = &args; printk(KERN_CRIT "EXT2-fs (%s): error: %s: %pV\n", sb->s_id, function, &vaf); va_end(args); if (test_opt(sb, ERRORS_PANIC)) panic("EXT2-fs: panic from previous error\n"); if (!sb_rdonly(sb) && test_opt(sb, ERRORS_RO)) { ext2_msg(sb, KERN_CRIT, "error: remounting filesystem read-only"); sb->s_flags |= SB_RDONLY; } }
void ext2_error (struct super_block * sb, const char * function, const char * fmt, ...) { va_list args; struct ext2_sb_info *sbi = EXT2_SB(sb); struct ext2_super_block *es = sbi->s_es; if (!(sb->s_flags & MS_RDONLY)) { sbi->s_mount_state |= EXT2_ERROR_FS; es->s_state |= cpu_to_le16(EXT2_ERROR_FS); ext2_sync_super(sb, es); } va_start(args, fmt); printk(KERN_CRIT "EXT2-fs error (device %s): %s: ",sb->s_id, function); vprintk(fmt, args); printk("\n"); va_end(args); if (test_opt(sb, ERRORS_PANIC)) panic("EXT2-fs panic from previous error\n"); if (test_opt(sb, ERRORS_RO)) { printk("Remounting filesystem read-only\n"); sb->s_flags |= MS_RDONLY; } }
static void ext2_put_super (struct super_block * sb) { int db_count; int i; struct ext2_sb_info *sbi = EXT2_SB(sb); ext2_quota_off_umount(sb); ext2_xattr_destroy_cache(sbi->s_ea_block_cache); sbi->s_ea_block_cache = NULL; if (!sb_rdonly(sb)) { struct ext2_super_block *es = sbi->s_es; spin_lock(&sbi->s_lock); es->s_state = cpu_to_le16(sbi->s_mount_state); spin_unlock(&sbi->s_lock); ext2_sync_super(sb, es, 1); } db_count = sbi->s_gdb_count; for (i = 0; i < db_count; i++) if (sbi->s_group_desc[i]) brelse (sbi->s_group_desc[i]); kfree(sbi->s_group_desc); kfree(sbi->s_debts); percpu_counter_destroy(&sbi->s_freeblocks_counter); percpu_counter_destroy(&sbi->s_freeinodes_counter); percpu_counter_destroy(&sbi->s_dirs_counter); brelse (sbi->s_sbh); sb->s_fs_info = NULL; kfree(sbi->s_blockgroup_lock); fs_put_dax(sbi->s_daxdev); kfree(sbi); }
static void ext2_put_super (struct super_block * sb) { int db_count; int i; struct ext2_sb_info *sbi = EXT2_SB(sb); dquot_disable(sb, -1, DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); if (sb->s_dirt) ext2_write_super(sb); ext2_xattr_put_super(sb); if (!(sb->s_flags & MS_RDONLY)) { struct ext2_super_block *es = sbi->s_es; spin_lock(&sbi->s_lock); es->s_state = cpu_to_le16(sbi->s_mount_state); spin_unlock(&sbi->s_lock); ext2_sync_super(sb, es, 1); } db_count = sbi->s_gdb_count; for (i = 0; i < db_count; i++) if (sbi->s_group_desc[i]) brelse (sbi->s_group_desc[i]); kfree(sbi->s_group_desc); kfree(sbi->s_debts); percpu_counter_destroy(&sbi->s_freeblocks_counter); percpu_counter_destroy(&sbi->s_freeinodes_counter); percpu_counter_destroy(&sbi->s_dirs_counter); brelse (sbi->s_sbh); sb->s_fs_info = NULL; kfree(sbi->s_blockgroup_lock); kfree(sbi); }
static void ext2_put_super (struct super_block * sb) { int db_count; int i; struct ext2_sb_info *sbi = EXT2_SB(sb); lock_kernel(); if (sb->s_dirt) ext2_write_super(sb); ext2_xattr_put_super(sb); if (!(sb->s_flags & MS_RDONLY)) { struct ext2_super_block *es = sbi->s_es; es->s_state = cpu_to_le16(sbi->s_mount_state); ext2_sync_super(sb, es); } db_count = sbi->s_gdb_count; for (i = 0; i < db_count; i++) if (sbi->s_group_desc[i]) brelse (sbi->s_group_desc[i]); kfree(sbi->s_group_desc); kfree(sbi->s_debts); percpu_counter_destroy(&sbi->s_freeblocks_counter); percpu_counter_destroy(&sbi->s_freeinodes_counter); percpu_counter_destroy(&sbi->s_dirs_counter); brelse (sbi->s_sbh); sb->s_fs_info = NULL; kfree(sbi->s_blockgroup_lock); kfree(sbi); unlock_kernel(); }
void ext2_put_super (struct super_block * sb) { int db_count; int i; if (!(sb->s_flags & MS_RDONLY)) { struct ext2_super_block *es = EXT2_SB(sb)->s_es; es->s_state = le16_to_cpu(EXT2_SB(sb)->s_mount_state); ext2_sync_super(sb, es); } db_count = EXT2_SB(sb)->s_gdb_count; for (i = 0; i < db_count; i++) if (sb->u.ext2_sb.s_group_desc[i]) brelse (sb->u.ext2_sb.s_group_desc[i]); kfree(sb->u.ext2_sb.s_group_desc); 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); return; }
static int ext2_freeze(struct super_block *sb) { struct ext2_sb_info *sbi = EXT2_SB(sb); /* Set EXT2_FS_VALID flag */ lock_kernel(); sbi->s_es->s_state = cpu_to_le16(sbi->s_mount_state); unlock_kernel(); ext2_sync_super(sb, sbi->s_es); return 0; }
int ext2_remount (struct super_block * sb, int * flags, char * data) { struct ext2_super_block * es; unsigned short resuid = sb->u.ext2_sb.s_resuid; unsigned short resgid = sb->u.ext2_sb.s_resgid; unsigned long new_mount_opt; unsigned long tmp; /* * Allow the "check" option to be passed as a remount option. */ new_mount_opt = sb->u.ext2_sb.s_mount_opt; if (!parse_options (data, &tmp, &resuid, &resgid, &new_mount_opt)) return -EINVAL; sb->u.ext2_sb.s_mount_opt = new_mount_opt; sb->u.ext2_sb.s_resuid = resuid; sb->u.ext2_sb.s_resgid = resgid; es = sb->u.ext2_sb.s_es; if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) return 0; if (*flags & MS_RDONLY) { if (le16_to_cpu(es->s_state) & EXT2_VALID_FS || !(sb->u.ext2_sb.s_mount_state & EXT2_VALID_FS)) return 0; /* * OK, we are remounting a valid rw partition rdonly, so set * the rdonly flag and then mark the partition as valid again. */ es->s_state = cpu_to_le16(sb->u.ext2_sb.s_mount_state); es->s_mtime = cpu_to_le32(CURRENT_TIME); } else { int ret; if ((ret = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP))) { printk("EXT2-fs: %s: couldn't remount RDWR because of " "unsupported optional features (%x).\n", bdevname(sb->s_dev), ret); return -EROFS; } /* * Mounting a RDONLY partition read-write, so reread and * store the current valid flag. (It may have been changed * by e2fsck since we originally mounted the partition.) */ sb->u.ext2_sb.s_mount_state = le16_to_cpu(es->s_state); if (!ext2_setup_super (sb, es, 0)) sb->s_flags &= ~MS_RDONLY; } ext2_sync_super(sb, es); return 0; }
/* * In the second extended file system, it is not necessary to * write the super block since we use a mapping of the * disk super block in a buffer. * * However, this function is still used to set the fs valid * flags to 0. We need to set this flag to 0 since the fs * may have been checked while mounted and e2fsck may have * set s_state to EXT2_VALID_FS after some corrections. */ static int ext2_sync_fs(struct super_block *sb, int wait) { struct ext2_sb_info *sbi = EXT2_SB(sb); struct ext2_super_block *es = EXT2_SB(sb)->s_es; spin_lock(&sbi->s_lock); if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) { ext2_debug("setting valid to 0\n"); es->s_state &= cpu_to_le16(~EXT2_VALID_FS); } spin_unlock(&sbi->s_lock); ext2_sync_super(sb, es, wait); return 0; }
static int ext2_remount (struct super_block * sb, int * flags, char * data) { struct ext2_sb_info * sbi = EXT2_SB(sb); struct ext2_super_block * es; /* * Allow the "check" option to be passed as a remount option. */ if (!parse_options (data, sbi)) return -EINVAL; sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); es = sbi->s_es; if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) return 0; if (*flags & MS_RDONLY) { if (le16_to_cpu(es->s_state) & EXT2_VALID_FS || !(sbi->s_mount_state & EXT2_VALID_FS)) return 0; /* * OK, we are remounting a valid rw partition rdonly, so set * the rdonly flag and then mark the partition as valid again. */ es->s_state = cpu_to_le16(sbi->s_mount_state); es->s_mtime = cpu_to_le32(get_seconds()); } else { __le32 ret = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP); if (ret) { printk("EXT2-fs: %s: couldn't remount RDWR because of " "unsupported optional features (%x).\n", sb->s_id, le32_to_cpu(ret)); return -EROFS; } /* * Mounting a RDONLY partition read-write, so reread and * store the current valid flag. (It may have been changed * by e2fsck since we originally mounted the partition.) */ sbi->s_mount_state = le16_to_cpu(es->s_state); if (!ext2_setup_super (sb, es, 0)) sb->s_flags &= ~MS_RDONLY; } ext2_sync_super(sb, es); return 0; }
void ext2_write_super (struct super_block * sb) { struct ext2_super_block * es; if (!(sb->s_flags & MS_RDONLY)) { es = sb->u.ext2_sb.s_es; if (le16_to_cpu(es->s_state) & EXT2_VALID_FS) { ext2_debug ("setting valid to 0\n"); es->s_state = cpu_to_le16(le16_to_cpu(es->s_state) & ~EXT2_VALID_FS); es->s_mtime = cpu_to_le32(CURRENT_TIME); ext2_sync_super(sb, es); } else ext2_commit_super (sb, es); } sb->s_dirt = 0; }
/* * In the second extended file system, it is not necessary to * write the super block since we use a mapping of the * disk super block in a buffer. * * However, this function is still used to set the fs valid * flags to 0. We need to set this flag to 0 since the fs * may have been checked while mounted and e2fsck may have * set s_state to EXT2_VALID_FS after some corrections. */ static int ext2_sync_fs(struct super_block *sb, int wait) { struct ext2_sb_info *sbi = EXT2_SB(sb); struct ext2_super_block *es = EXT2_SB(sb)->s_es; /* * Write quota structures to quota file, sync_blockdev() will write * them to disk later */ dquot_writeback_dquots(sb, -1); spin_lock(&sbi->s_lock); if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) { ext2_debug("setting valid to 0\n"); es->s_state &= cpu_to_le16(~EXT2_VALID_FS); } spin_unlock(&sbi->s_lock); ext2_sync_super(sb, es, wait); return 0; }
void ext2_write_super (struct super_block * sb) { struct ext2_super_block * es; lock_kernel(); if (!(sb->s_flags & MS_RDONLY)) { es = EXT2_SB(sb)->s_es; if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) { ext2_debug ("setting valid to 0\n"); es->s_state &= cpu_to_le16(~EXT2_VALID_FS); es->s_free_blocks_count = cpu_to_le32(ext2_count_free_blocks(sb)); es->s_free_inodes_count = cpu_to_le32(ext2_count_free_inodes(sb)); es->s_mtime = cpu_to_le32(get_seconds()); ext2_sync_super(sb, es); } else ext2_commit_super (sb, es); } sb->s_dirt = 0; unlock_kernel(); }
static int ext2_freeze(struct super_block *sb) { struct ext2_sb_info *sbi = EXT2_SB(sb); /* * Open but unlinked files present? Keep EXT2_VALID_FS flag cleared * because we have unattached inodes and thus filesystem is not fully * consistent. */ if (atomic_long_read(&sb->s_remove_count)) { ext2_sync_fs(sb, 1); return 0; } /* Set EXT2_FS_VALID flag */ spin_lock(&sbi->s_lock); sbi->s_es->s_state = cpu_to_le16(sbi->s_mount_state); spin_unlock(&sbi->s_lock); ext2_sync_super(sb, sbi->s_es, 1); return 0; }
static int ext2_sync_fs(struct super_block *sb, int wait) { struct ext2_super_block *es = EXT2_SB(sb)->s_es; lock_kernel(); if (es->s_state & cpu_to_le16(EXT2_VALID_FS)) { ext2_debug("setting valid to 0\n"); es->s_state &= cpu_to_le16(~EXT2_VALID_FS); es->s_free_blocks_count = cpu_to_le32(ext2_count_free_blocks(sb)); es->s_free_inodes_count = cpu_to_le32(ext2_count_free_inodes(sb)); es->s_mtime = cpu_to_le32(get_seconds()); ext2_sync_super(sb, es); } else { ext2_commit_super(sb, es); } sb->s_dirt = 0; unlock_kernel(); return 0; }
static int ext2_remount (struct super_block * sb, int * flags, char * data) { struct ext2_sb_info * sbi = EXT2_SB(sb); struct ext2_super_block * es; unsigned long old_mount_opt = sbi->s_mount_opt; struct ext2_mount_options old_opts; unsigned long old_sb_flags; int err; lock_kernel(); /* Store the old options */ old_sb_flags = sb->s_flags; old_opts.s_mount_opt = sbi->s_mount_opt; old_opts.s_resuid = sbi->s_resuid; old_opts.s_resgid = sbi->s_resgid; /* * Allow the "check" option to be passed as a remount option. */ if (!parse_options (data, sbi)) { err = -EINVAL; goto restore_opts; } sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); ext2_xip_verify_sb(sb); /* see if bdev supports xip, unset EXT2_MOUNT_XIP if not */ if ((ext2_use_xip(sb)) && (sb->s_blocksize != PAGE_SIZE)) { printk("XIP: Unsupported blocksize\n"); err = -EINVAL; goto restore_opts; } es = sbi->s_es; if (((sbi->s_mount_opt & EXT2_MOUNT_XIP) != (old_mount_opt & EXT2_MOUNT_XIP)) && invalidate_inodes(sb)) { ext2_warning(sb, __func__, "refusing change of xip flag " "with busy inodes while remounting"); sbi->s_mount_opt &= ~EXT2_MOUNT_XIP; sbi->s_mount_opt |= old_mount_opt & EXT2_MOUNT_XIP; } if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { unlock_kernel(); return 0; } if (*flags & MS_RDONLY) { if (le16_to_cpu(es->s_state) & EXT2_VALID_FS || !(sbi->s_mount_state & EXT2_VALID_FS)) { unlock_kernel(); return 0; } /* * OK, we are remounting a valid rw partition rdonly, so set * the rdonly flag and then mark the partition as valid again. */ es->s_state = cpu_to_le16(sbi->s_mount_state); es->s_mtime = cpu_to_le32(get_seconds()); } else { __le32 ret = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP); if (ret) { printk("EXT2-fs: %s: couldn't remount RDWR because of " "unsupported optional features (%x).\n", sb->s_id, le32_to_cpu(ret)); err = -EROFS; goto restore_opts; } /* * Mounting a RDONLY partition read-write, so reread and * store the current valid flag. (It may have been changed * by e2fsck since we originally mounted the partition.) */ sbi->s_mount_state = le16_to_cpu(es->s_state); if (!ext2_setup_super (sb, es, 0)) sb->s_flags &= ~MS_RDONLY; } ext2_sync_super(sb, es); unlock_kernel(); return 0; restore_opts: sbi->s_mount_opt = old_opts.s_mount_opt; sbi->s_resuid = old_opts.s_resuid; sbi->s_resgid = old_opts.s_resgid; sb->s_flags = old_sb_flags; unlock_kernel(); return err; }
static int ext2_remount (struct super_block * sb, int * flags, char * data) { struct ext2_sb_info * sbi = EXT2_SB(sb); struct ext2_super_block * es; struct ext2_mount_options old_opts; unsigned long old_sb_flags; int err; sync_filesystem(sb); spin_lock(&sbi->s_lock); /* Store the old options */ old_sb_flags = sb->s_flags; old_opts.s_mount_opt = sbi->s_mount_opt; old_opts.s_resuid = sbi->s_resuid; old_opts.s_resgid = sbi->s_resgid; /* * Allow the "check" option to be passed as a remount option. */ if (!parse_options(data, sb)) { err = -EINVAL; goto restore_opts; } sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | ((sbi->s_mount_opt & EXT2_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); es = sbi->s_es; if ((sbi->s_mount_opt ^ old_opts.s_mount_opt) & EXT2_MOUNT_DAX) { ext2_msg(sb, KERN_WARNING, "warning: refusing change of " "dax flag with busy inodes while remounting"); sbi->s_mount_opt ^= EXT2_MOUNT_DAX; } if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) { spin_unlock(&sbi->s_lock); return 0; } if (*flags & MS_RDONLY) { if (le16_to_cpu(es->s_state) & EXT2_VALID_FS || !(sbi->s_mount_state & EXT2_VALID_FS)) { spin_unlock(&sbi->s_lock); return 0; } /* * OK, we are remounting a valid rw partition rdonly, so set * the rdonly flag and then mark the partition as valid again. */ es->s_state = cpu_to_le16(sbi->s_mount_state); es->s_mtime = cpu_to_le32(get_seconds()); spin_unlock(&sbi->s_lock); err = dquot_suspend(sb, -1); if (err < 0) { spin_lock(&sbi->s_lock); goto restore_opts; } ext2_sync_super(sb, es, 1); } else { __le32 ret = EXT2_HAS_RO_COMPAT_FEATURE(sb, ~EXT2_FEATURE_RO_COMPAT_SUPP); if (ret) { ext2_msg(sb, KERN_WARNING, "warning: couldn't remount RDWR because of " "unsupported optional features (%x).", le32_to_cpu(ret)); err = -EROFS; goto restore_opts; } /* * Mounting a RDONLY partition read-write, so reread and * store the current valid flag. (It may have been changed * by e2fsck since we originally mounted the partition.) */ sbi->s_mount_state = le16_to_cpu(es->s_state); if (!ext2_setup_super (sb, es, 0)) sb->s_flags &= ~MS_RDONLY; spin_unlock(&sbi->s_lock); ext2_write_super(sb); dquot_resume(sb, -1); } return 0; restore_opts: sbi->s_mount_opt = old_opts.s_mount_opt; sbi->s_resuid = old_opts.s_resuid; sbi->s_resgid = old_opts.s_resgid; sb->s_flags = old_sb_flags; spin_unlock(&sbi->s_lock); return err; }