/*
* Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
* Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License version 2.
*/
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
#include <linux/crc32.h>
#include <linux/gfs2_ondisk.h>
#include <linux/bio.h>
#include <linux/lm_interface.h>
#include "gfs2.h"
#include "incore.h"
#include "bmap.h"
#include "dir.h"
#include "glock.h"
#include "glops.h"
#include "inode.h"
#include "log.h"
#include "meta_io.h"
#include "quota.h"
#include "recovery.h"
#include "rgrp.h"
#include "super.h"
#include "trans.h"
#include "util.h"
static const u32 gfs2_old_fs_formats[] = {
0
};
static const u32 gfs2_old_multihost_formats[] = {
0
};
/**
* gfs2_tune_init - Fill a gfs2_tune structure with default values
* @gt: tune
*
*/
void gfs2_tune_init(struct gfs2_tune *gt)
{
spin_lock_init(>->gt_spin);
gt->gt_demote_secs = 300;
gt->gt_incore_log_blocks = 1024;
gt->gt_log_flush_secs = 60;
gt->gt_recoverd_secs = 60;
gt->gt_logd_secs = 1;
gt->gt_quotad_secs = 5;
gt->gt_quota_simul_sync = 64;
gt->gt_quota_warn_period = 10;
gt->gt_quota_scale_num = 1;
gt->gt_quota_scale_den = 1;
gt->gt_quota_cache_secs = 300;
gt->gt_quota_quantum = 60;
gt->gt_atime_quantum = 3600;
gt->gt_new_files_jdata = 0;
gt->gt_new_files_directio = 0;
gt->gt_max_readahead = 1 << 18;
gt->gt_stall_secs = 600;
gt->gt_complain_secs = 10;
gt->gt_statfs_quantum = 30;
gt->gt_statfs_slow = 0;
}
/**
* gfs2_check_sb - Check superblock
* @sdp: the filesystem
* @sb: The superblock
* @silent: Don't print a message if the check fails
*
* Checks the version code of the FS is one that we understand how to
* read and that the sizes of the various on-disk structures have not
* changed.
*/
int gfs2_check_sb(struct gfs2_sbd *sdp, struct gfs2_sb_host *sb, int silent)
{
unsigned int x;
if (sb->sb_magic != GFS2_MAGIC ||
sb->sb_type != GFS2_METATYPE_SB) {
if (!silent)
printk(KERN_WARNING "GFS2: not a GFS2 filesystem\n");
return -EINVAL;
}
/* If format numbers match exactly, we're done. */
if (sb->sb_fs_format == GFS2_FORMAT_FS &&
sb->sb_multihost_format == GFS2_FORMAT_MULTI)
return 0;
if (sb->sb_fs_format != GFS2_FORMAT_FS) {
for (x = 0; gfs2_old_fs_formats[x]; x++)
if (gfs2_old_fs_formats[x] == sb->sb_fs_format)
break;
if (!gfs2_old_fs_formats[x]) {
printk(KERN_WARNING
"GFS2: code version (%u, %u) is incompatible "
"with ondisk format (%u, %u)\n",
GFS2_FORMAT_FS, GFS2_FORMAT_MULTI,
sb->sb_fs_format, sb->sb_multihost_format);
printk(KERN_WARNING
"GFS2: I don't know how to upgrade this FS\n");
return -EINVAL;
}
}
if (sb->sb_multihost_format != GFS2_FORMAT_MULTI) {
for (x = 0; gfs2_old_multihost_formats[x]; x++)
if (gfs2_old_multihost_formats[x] ==
sb->sb_multihost_format)
break;
if (!gfs2_old_multihost_formats[x]) {
printk(KERN_WARNING
"GFS2: code version (%u, %u) is incompatible "
"with ondisk format (%u, %u)\n",
GFS2_FORMAT_FS, GFS2_FORMAT_MULTI,
sb->sb_fs_format, sb->sb_multihost_format);
printk(KERN_WARNING
"GFS2: I don't know how to upgrade this FS\n");
return -EINVAL;
}
}
if (!sdp->sd_args.ar_upgrade) {
printk(KERN_WARNING
"GFS2: code version (%u, %u) is incompatible "
"with ondisk format (%u, %u)\n",
GFS2_FORMAT_FS, GFS2_FORMAT_MULTI,
sb->sb_fs_format, sb->sb_multihost_format);
printk(KERN_INFO
"GFS2: Use the \"upgrade\" mount option to upgrade "
"the FS\n");
printk(KERN_INFO "GFS2: See the manual for more details\n");
return -EINVAL;
}
return 0;
}
static void end_bio_io_page(struct bio *bio, int error)
{
struct page *page = bio->bi_private;
if