⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ops_fstype.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved. * Copyright (C) 2004-2006 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/blkdev.h>#include <linux/kthread.h>#include <linux/namei.h>#include <linux/mount.h>#include <linux/gfs2_ondisk.h>#include <linux/lm_interface.h>#include "gfs2.h"#include "incore.h"#include "daemon.h"#include "glock.h"#include "glops.h"#include "inode.h"#include "lm.h"#include "mount.h"#include "ops_fstype.h"#include "ops_dentry.h"#include "ops_super.h"#include "recovery.h"#include "rgrp.h"#include "super.h"#include "sys.h"#include "util.h"#include "log.h"#define DO 0#define UNDO 1static struct gfs2_sbd *init_sbd(struct super_block *sb){	struct gfs2_sbd *sdp;	sdp = kzalloc(sizeof(struct gfs2_sbd), GFP_KERNEL);	if (!sdp)		return NULL;	sb->s_fs_info = sdp;	sdp->sd_vfs = sb;	gfs2_tune_init(&sdp->sd_tune);	INIT_LIST_HEAD(&sdp->sd_reclaim_list);	spin_lock_init(&sdp->sd_reclaim_lock);	init_waitqueue_head(&sdp->sd_reclaim_wq);	mutex_init(&sdp->sd_inum_mutex);	spin_lock_init(&sdp->sd_statfs_spin);	mutex_init(&sdp->sd_statfs_mutex);	spin_lock_init(&sdp->sd_rindex_spin);	mutex_init(&sdp->sd_rindex_mutex);	INIT_LIST_HEAD(&sdp->sd_rindex_list);	INIT_LIST_HEAD(&sdp->sd_rindex_mru_list);	INIT_LIST_HEAD(&sdp->sd_rindex_recent_list);	INIT_LIST_HEAD(&sdp->sd_jindex_list);	spin_lock_init(&sdp->sd_jindex_spin);	mutex_init(&sdp->sd_jindex_mutex);	INIT_LIST_HEAD(&sdp->sd_quota_list);	spin_lock_init(&sdp->sd_quota_spin);	mutex_init(&sdp->sd_quota_mutex);	spin_lock_init(&sdp->sd_log_lock);	INIT_LIST_HEAD(&sdp->sd_log_le_gl);	INIT_LIST_HEAD(&sdp->sd_log_le_buf);	INIT_LIST_HEAD(&sdp->sd_log_le_revoke);	INIT_LIST_HEAD(&sdp->sd_log_le_rg);	INIT_LIST_HEAD(&sdp->sd_log_le_databuf);	INIT_LIST_HEAD(&sdp->sd_log_le_ordered);	mutex_init(&sdp->sd_log_reserve_mutex);	INIT_LIST_HEAD(&sdp->sd_ail1_list);	INIT_LIST_HEAD(&sdp->sd_ail2_list);	init_rwsem(&sdp->sd_log_flush_lock);	atomic_set(&sdp->sd_log_in_flight, 0);	init_waitqueue_head(&sdp->sd_log_flush_wait);	INIT_LIST_HEAD(&sdp->sd_revoke_list);	mutex_init(&sdp->sd_freeze_lock);	return sdp;}static void init_vfs(struct super_block *sb, unsigned noatime){	struct gfs2_sbd *sdp = sb->s_fs_info;	sb->s_magic = GFS2_MAGIC;	sb->s_op = &gfs2_super_ops;	sb->s_export_op = &gfs2_export_ops;	sb->s_time_gran = 1;	sb->s_maxbytes = MAX_LFS_FILESIZE;	if (sb->s_flags & (MS_NOATIME | MS_NODIRATIME))		set_bit(noatime, &sdp->sd_flags);	/* Don't let the VFS update atimes.  GFS2 handles this itself. */	sb->s_flags |= MS_NOATIME | MS_NODIRATIME;}static int init_names(struct gfs2_sbd *sdp, int silent){	char *proto, *table;	int error = 0;	proto = sdp->sd_args.ar_lockproto;	table = sdp->sd_args.ar_locktable;	/*  Try to autodetect  */	if (!proto[0] || !table[0]) {		error = gfs2_read_super(sdp, GFS2_SB_ADDR >> sdp->sd_fsb2bb_shift);		if (error)			return error;		error = gfs2_check_sb(sdp, &sdp->sd_sb, silent);		if (error)			goto out;		if (!proto[0])			proto = sdp->sd_sb.sb_lockproto;		if (!table[0])			table = sdp->sd_sb.sb_locktable;	}	if (!table[0])		table = sdp->sd_vfs->s_id;	snprintf(sdp->sd_proto_name, GFS2_FSNAME_LEN, "%s", proto);	snprintf(sdp->sd_table_name, GFS2_FSNAME_LEN, "%s", table);	table = sdp->sd_table_name;	while ((table = strchr(table, '/')))		*table = '_';out:	return error;}static int init_locking(struct gfs2_sbd *sdp, struct gfs2_holder *mount_gh,			int undo){	struct task_struct *p;	int error = 0;	if (undo)		goto fail_trans;	for (sdp->sd_glockd_num = 0;	     sdp->sd_glockd_num < sdp->sd_args.ar_num_glockd;	     sdp->sd_glockd_num++) {		p = kthread_run(gfs2_glockd, sdp, "gfs2_glockd");		error = IS_ERR(p);		if (error) {			fs_err(sdp, "can't start glockd thread: %d\n", error);			goto fail;		}		sdp->sd_glockd_process[sdp->sd_glockd_num] = p;	}	error = gfs2_glock_nq_num(sdp,				  GFS2_MOUNT_LOCK, &gfs2_nondisk_glops,				  LM_ST_EXCLUSIVE, LM_FLAG_NOEXP | GL_NOCACHE,				  mount_gh);	if (error) {		fs_err(sdp, "can't acquire mount glock: %d\n", error);		goto fail;	}	error = gfs2_glock_nq_num(sdp,				  GFS2_LIVE_LOCK, &gfs2_nondisk_glops,				  LM_ST_SHARED,				  LM_FLAG_NOEXP | GL_EXACT,				  &sdp->sd_live_gh);	if (error) {		fs_err(sdp, "can't acquire live glock: %d\n", error);		goto fail_mount;	}	error = gfs2_glock_get(sdp, GFS2_RENAME_LOCK, &gfs2_nondisk_glops,			       CREATE, &sdp->sd_rename_gl);	if (error) {		fs_err(sdp, "can't create rename glock: %d\n", error);		goto fail_live;	}	error = gfs2_glock_get(sdp, GFS2_TRANS_LOCK, &gfs2_trans_glops,			       CREATE, &sdp->sd_trans_gl);	if (error) {		fs_err(sdp, "can't create transaction glock: %d\n", error);		goto fail_rename;	}	set_bit(GLF_STICKY, &sdp->sd_trans_gl->gl_flags);	return 0;fail_trans:	gfs2_glock_put(sdp->sd_trans_gl);fail_rename:	gfs2_glock_put(sdp->sd_rename_gl);fail_live:	gfs2_glock_dq_uninit(&sdp->sd_live_gh);fail_mount:	gfs2_glock_dq_uninit(mount_gh);fail:	while (sdp->sd_glockd_num--)		kthread_stop(sdp->sd_glockd_process[sdp->sd_glockd_num]);	return error;}static inline struct inode *gfs2_lookup_root(struct super_block *sb,					     u64 no_addr){	return gfs2_inode_lookup(sb, DT_DIR, no_addr, 0, 0);}static int init_sb(struct gfs2_sbd *sdp, int silent, int undo){	struct super_block *sb = sdp->sd_vfs;	struct gfs2_holder sb_gh;	u64 no_addr;	struct inode *inode;	int error = 0;	if (undo) {		if (sb->s_root) {			dput(sb->s_root);			sb->s_root = NULL;		}		return 0;	}	error = gfs2_glock_nq_num(sdp, GFS2_SB_LOCK, &gfs2_meta_glops,				 LM_ST_SHARED, 0, &sb_gh);	if (error) {		fs_err(sdp, "can't acquire superblock glock: %d\n", error);		return error;	}	error = gfs2_read_sb(sdp, sb_gh.gh_gl, silent);	if (error) {		fs_err(sdp, "can't read superblock: %d\n", error);		goto out;	}	/* Set up the buffer cache and SB for real */	if (sdp->sd_sb.sb_bsize < bdev_hardsect_size(sb->s_bdev)) {		error = -EINVAL;		fs_err(sdp, "FS block size (%u) is too small for device "		       "block size (%u)\n",		       sdp->sd_sb.sb_bsize, bdev_hardsect_size(sb->s_bdev));		goto out;	}	if (sdp->sd_sb.sb_bsize > PAGE_SIZE) {		error = -EINVAL;		fs_err(sdp, "FS block size (%u) is too big for machine "		       "page size (%u)\n",		       sdp->sd_sb.sb_bsize, (unsigned int)PAGE_SIZE);		goto out;	}	sb_set_blocksize(sb, sdp->sd_sb.sb_bsize);	/* Get the root inode */	no_addr = sdp->sd_sb.sb_root_dir.no_addr;	if (sb->s_type == &gfs2meta_fs_type)		no_addr = sdp->sd_sb.sb_master_dir.no_addr;	inode = gfs2_lookup_root(sb, no_addr);	if (IS_ERR(inode)) {		error = PTR_ERR(inode);		fs_err(sdp, "can't read in root inode: %d\n", error);		goto out;	}	sb->s_root = d_alloc_root(inode);	if (!sb->s_root) {		fs_err(sdp, "can't get root dentry\n");		error = -ENOMEM;		iput(inode);	} else		sb->s_root->d_op = &gfs2_dops;	out:	gfs2_glock_dq_uninit(&sb_gh);	return error;}static int init_journal(struct gfs2_sbd *sdp, int undo){	struct gfs2_holder ji_gh;	struct task_struct *p;	struct gfs2_inode *ip;	int jindex = 1;	int error = 0;	if (undo) {		jindex = 0;		goto fail_recoverd;	}	sdp->sd_jindex = gfs2_lookup_simple(sdp->sd_master_dir, "jindex");	if (IS_ERR(sdp->sd_jindex)) {		fs_err(sdp, "can't lookup journal index: %d\n", error);		return PTR_ERR(sdp->sd_jindex);	}	ip = GFS2_I(sdp->sd_jindex);	set_bit(GLF_STICKY, &ip->i_gl->gl_flags);	/* Load in the journal index special file */	error = gfs2_jindex_hold(sdp, &ji_gh);	if (error) {		fs_err(sdp, "can't read journal index: %d\n", error);		goto fail;	}	error = -EINVAL;	if (!gfs2_jindex_size(sdp)) {		fs_err(sdp, "no journals!\n");		goto fail_jindex;	}	if (sdp->sd_args.ar_spectator) {		sdp->sd_jdesc = gfs2_jdesc_find(sdp, 0);		sdp->sd_log_blks_free = sdp->sd_jdesc->jd_blocks;	} else {		if (sdp->sd_lockstruct.ls_jid >= gfs2_jindex_size(sdp)) {			fs_err(sdp, "can't mount journal #%u\n",			       sdp->sd_lockstruct.ls_jid);			fs_err(sdp, "there are only %u journals (0 - %u)\n",			       gfs2_jindex_size(sdp),			       gfs2_jindex_size(sdp) - 1);			goto fail_jindex;		}		sdp->sd_jdesc = gfs2_jdesc_find(sdp, sdp->sd_lockstruct.ls_jid);		error = gfs2_glock_nq_num(sdp, sdp->sd_lockstruct.ls_jid,					  &gfs2_journal_glops,					  LM_ST_EXCLUSIVE, LM_FLAG_NOEXP,					  &sdp->sd_journal_gh);		if (error) {			fs_err(sdp, "can't acquire journal glock: %d\n", error);			goto fail_jindex;		}		ip = GFS2_I(sdp->sd_jdesc->jd_inode);		error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED,					   LM_FLAG_NOEXP | GL_EXACT | GL_NOCACHE,					   &sdp->sd_jinode_gh);		if (error) {			fs_err(sdp, "can't acquire journal inode glock: %d\n",			       error);			goto fail_journal_gh;		}		error = gfs2_jdesc_check(sdp->sd_jdesc);		if (error) {			fs_err(sdp, "my journal (%u) is bad: %d\n",			       sdp->sd_jdesc->jd_jid, error);			goto fail_jinode_gh;		}		sdp->sd_log_blks_free = sdp->sd_jdesc->jd_blocks;	}	if (sdp->sd_lockstruct.ls_first) {		unsigned int x;		for (x = 0; x < sdp->sd_journals; x++) {			error = gfs2_recover_journal(gfs2_jdesc_find(sdp, x));			if (error) {				fs_err(sdp, "error recovering journal %u: %d\n",				       x, error);				goto fail_jinode_gh;			}		}		gfs2_lm_others_may_mount(sdp);	} else if (!sdp->sd_args.ar_spectator) {		error = gfs2_recover_journal(sdp->sd_jdesc);		if (error) {			fs_err(sdp, "error recovering my journal: %d\n", error);			goto fail_jinode_gh;		}	}	set_bit(SDF_JOURNAL_CHECKED, &sdp->sd_flags);	gfs2_glock_dq_uninit(&ji_gh);	jindex = 0;	p = kthread_run(gfs2_recoverd, sdp, "gfs2_recoverd");	error = IS_ERR(p);	if (error) {		fs_err(sdp, "can't start recoverd thread: %d\n", error);		goto fail_jinode_gh;	}	sdp->sd_recoverd_process = p;	return 0;fail_recoverd:	kthread_stop(sdp->sd_recoverd_process);fail_jinode_gh:	if (!sdp->sd_args.ar_spectator)		gfs2_glock_dq_uninit(&sdp->sd_jinode_gh);fail_journal_gh:	if (!sdp->sd_args.ar_spectator)		gfs2_glock_dq_uninit(&sdp->sd_journal_gh);fail_jindex:	gfs2_jindex_free(sdp);	if (jindex)		gfs2_glock_dq_uninit(&ji_gh);fail:	iput(sdp->sd_jindex);	return error;}static int init_inodes(struct gfs2_sbd *sdp, int undo){	int error = 0;	struct gfs2_inode *ip;	struct inode *inode;	if (undo)		goto fail_qinode;	inode = gfs2_lookup_root(sdp->sd_vfs, sdp->sd_sb.sb_master_dir.no_addr);	if (IS_ERR(inode)) {		error = PTR_ERR(inode);		fs_err(sdp, "can't read in master directory: %d\n", error);		goto fail;	}	sdp->sd_master_dir = inode;	error = init_journal(sdp, undo);	if (error)		goto fail_master;	/* Read in the master inode number inode */	sdp->sd_inum_inode = gfs2_lookup_simple(sdp->sd_master_dir, "inum");	if (IS_ERR(sdp->sd_inum_inode)) {		error = PTR_ERR(sdp->sd_inum_inode);		fs_err(sdp, "can't read in inum inode: %d\n", error);		goto fail_journal;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -