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

📄 super.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
			s->s_root = NULL;			goto error;		}		if ((errval = reiserfs_xattr_init(s, s->s_flags))) {			dput(s->s_root);			s->s_root = NULL;			goto error;		}		/* look for files which were to be removed in previous session */		finish_unfinished(s);	} else {		if (old_format_only(s) && !silent) {			reiserfs_info(s, "using 3.5.x disk format\n");		}		if ((errval = reiserfs_xattr_init(s, s->s_flags))) {			dput(s->s_root);			s->s_root = NULL;			goto error;		}	}	// mark hash in super block: it could be unset. overwrite should be ok	set_sb_hash_function_code(rs, function2code(sbi->s_hash_function));	handle_attrs(s);	reiserfs_proc_info_init(s);	init_waitqueue_head(&(sbi->s_wait));	spin_lock_init(&sbi->bitmap_lock);	return (0);      error:	if (jinit_done) {	/* kill the commit thread, free journal ram */		journal_release_error(NULL, s);	}	reiserfs_free_bitmap_cache(s);	if (SB_BUFFER_WITH_SB(s))		brelse(SB_BUFFER_WITH_SB(s));#ifdef CONFIG_QUOTA	{		int j;		for (j = 0; j < MAXQUOTAS; j++) {			kfree(sbi->s_qf_names[j]);			sbi->s_qf_names[j] = NULL;		}	}#endif	kfree(sbi);	s->s_fs_info = NULL;	return errval;}static int reiserfs_statfs(struct dentry *dentry, struct kstatfs *buf){	struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(dentry->d_sb);	buf->f_namelen = (REISERFS_MAX_NAME(s->s_blocksize));	buf->f_bfree = sb_free_blocks(rs);	buf->f_bavail = buf->f_bfree;	buf->f_blocks = sb_block_count(rs) - sb_bmap_nr(rs) - 1;	buf->f_bsize = dentry->d_sb->s_blocksize;	/* changed to accommodate gcc folks. */	buf->f_type = REISERFS_SUPER_MAGIC;	return 0;}#ifdef CONFIG_QUOTAstatic int reiserfs_dquot_initialize(struct inode *inode, int type){	struct reiserfs_transaction_handle th;	int ret, err;	/* We may create quota structure so we need to reserve enough blocks */	reiserfs_write_lock(inode->i_sb);	ret =	    journal_begin(&th, inode->i_sb,			  2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb));	if (ret)		goto out;	ret = dquot_initialize(inode, type);	err =	    journal_end(&th, inode->i_sb,			2 * REISERFS_QUOTA_INIT_BLOCKS(inode->i_sb));	if (!ret && err)		ret = err;      out:	reiserfs_write_unlock(inode->i_sb);	return ret;}static int reiserfs_dquot_drop(struct inode *inode){	struct reiserfs_transaction_handle th;	int ret, err;	/* We may delete quota structure so we need to reserve enough blocks */	reiserfs_write_lock(inode->i_sb);	ret =	    journal_begin(&th, inode->i_sb,			  2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb));	if (ret)		goto out;	ret = dquot_drop(inode);	err =	    journal_end(&th, inode->i_sb,			2 * REISERFS_QUOTA_DEL_BLOCKS(inode->i_sb));	if (!ret && err)		ret = err;      out:	reiserfs_write_unlock(inode->i_sb);	return ret;}static int reiserfs_write_dquot(struct dquot *dquot){	struct reiserfs_transaction_handle th;	int ret, err;	reiserfs_write_lock(dquot->dq_sb);	ret =	    journal_begin(&th, dquot->dq_sb,			  REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));	if (ret)		goto out;	ret = dquot_commit(dquot);	err =	    journal_end(&th, dquot->dq_sb,			REISERFS_QUOTA_TRANS_BLOCKS(dquot->dq_sb));	if (!ret && err)		ret = err;      out:	reiserfs_write_unlock(dquot->dq_sb);	return ret;}static int reiserfs_acquire_dquot(struct dquot *dquot){	struct reiserfs_transaction_handle th;	int ret, err;	reiserfs_write_lock(dquot->dq_sb);	ret =	    journal_begin(&th, dquot->dq_sb,			  REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));	if (ret)		goto out;	ret = dquot_acquire(dquot);	err =	    journal_end(&th, dquot->dq_sb,			REISERFS_QUOTA_INIT_BLOCKS(dquot->dq_sb));	if (!ret && err)		ret = err;      out:	reiserfs_write_unlock(dquot->dq_sb);	return ret;}static int reiserfs_release_dquot(struct dquot *dquot){	struct reiserfs_transaction_handle th;	int ret, err;	reiserfs_write_lock(dquot->dq_sb);	ret =	    journal_begin(&th, dquot->dq_sb,			  REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));	if (ret) {		/* Release dquot anyway to avoid endless cycle in dqput() */		dquot_release(dquot);		goto out;	}	ret = dquot_release(dquot);	err =	    journal_end(&th, dquot->dq_sb,			REISERFS_QUOTA_DEL_BLOCKS(dquot->dq_sb));	if (!ret && err)		ret = err;      out:	reiserfs_write_unlock(dquot->dq_sb);	return ret;}static int reiserfs_mark_dquot_dirty(struct dquot *dquot){	/* Are we journalling quotas? */	if (REISERFS_SB(dquot->dq_sb)->s_qf_names[USRQUOTA] ||	    REISERFS_SB(dquot->dq_sb)->s_qf_names[GRPQUOTA]) {		dquot_mark_dquot_dirty(dquot);		return reiserfs_write_dquot(dquot);	} else		return dquot_mark_dquot_dirty(dquot);}static int reiserfs_write_info(struct super_block *sb, int type){	struct reiserfs_transaction_handle th;	int ret, err;	/* Data block + inode block */	reiserfs_write_lock(sb);	ret = journal_begin(&th, sb, 2);	if (ret)		goto out;	ret = dquot_commit_info(sb, type);	err = journal_end(&th, sb, 2);	if (!ret && err)		ret = err;      out:	reiserfs_write_unlock(sb);	return ret;}/* * Turn on quotas during mount time - we need to find the quota file and such... */static int reiserfs_quota_on_mount(struct super_block *sb, int type){	return vfs_quota_on_mount(sb, REISERFS_SB(sb)->s_qf_names[type],				  REISERFS_SB(sb)->s_jquota_fmt, type);}/* * Standard function to be called on quota_on */static int reiserfs_quota_on(struct super_block *sb, int type, int format_id,			     char *path){	int err;	struct nameidata nd;	if (!(REISERFS_SB(sb)->s_mount_opt & (1 << REISERFS_QUOTA)))		return -EINVAL;	err = path_lookup(path, LOOKUP_FOLLOW, &nd);	if (err)		return err;	/* Quotafile not on the same filesystem? */	if (nd.mnt->mnt_sb != sb) {		path_release(&nd);		return -EXDEV;	}	/* We must not pack tails for quota files on reiserfs for quota IO to work */	if (!REISERFS_I(nd.dentry->d_inode)->i_flags & i_nopack_mask) {		reiserfs_warning(sb,				 "reiserfs: Quota file must have tail packing disabled.");		path_release(&nd);		return -EINVAL;	}	/* Not journalling quota? No more tests needed... */	if (!REISERFS_SB(sb)->s_qf_names[USRQUOTA] &&	    !REISERFS_SB(sb)->s_qf_names[GRPQUOTA]) {		path_release(&nd);		return vfs_quota_on(sb, type, format_id, path);	}	/* Quotafile not of fs root? */	if (nd.dentry->d_parent->d_inode != sb->s_root->d_inode)		reiserfs_warning(sb,				 "reiserfs: Quota file not on filesystem root. "				 "Journalled quota will not work.");	path_release(&nd);	return vfs_quota_on(sb, type, format_id, path);}/* Read data from quotafile - avoid pagecache and such because we cannot afford * acquiring the locks... As quota files are never truncated and quota code * itself serializes the operations (and noone else should touch the files) * we don't have to be afraid of races */static ssize_t reiserfs_quota_read(struct super_block *sb, int type, char *data,				   size_t len, loff_t off){	struct inode *inode = sb_dqopt(sb)->files[type];	unsigned long blk = off >> sb->s_blocksize_bits;	int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;	size_t toread;	struct buffer_head tmp_bh, *bh;	loff_t i_size = i_size_read(inode);	if (off > i_size)		return 0;	if (off + len > i_size)		len = i_size - off;	toread = len;	while (toread > 0) {		tocopy =		    sb->s_blocksize - offset <		    toread ? sb->s_blocksize - offset : toread;		tmp_bh.b_state = 0;		/* Quota files are without tails so we can safely use this function */		reiserfs_write_lock(sb);		err = reiserfs_get_block(inode, blk, &tmp_bh, 0);		reiserfs_write_unlock(sb);		if (err)			return err;		if (!buffer_mapped(&tmp_bh))	/* A hole? */			memset(data, 0, tocopy);		else {			bh = sb_bread(sb, tmp_bh.b_blocknr);			if (!bh)				return -EIO;			memcpy(data, bh->b_data + offset, tocopy);			brelse(bh);		}		offset = 0;		toread -= tocopy;		data += tocopy;		blk++;	}	return len;}/* Write to quotafile (we know the transaction is already started and has * enough credits) */static ssize_t reiserfs_quota_write(struct super_block *sb, int type,				    const char *data, size_t len, loff_t off){	struct inode *inode = sb_dqopt(sb)->files[type];	unsigned long blk = off >> sb->s_blocksize_bits;	int err = 0, offset = off & (sb->s_blocksize - 1), tocopy;	int journal_quota = REISERFS_SB(sb)->s_qf_names[type] != NULL;	size_t towrite = len;	struct buffer_head tmp_bh, *bh;	if (!current->journal_info) {		printk(KERN_WARNING "reiserfs: Quota write (off=%Lu, len=%Lu)"			" cancelled because transaction is not started.\n",			(unsigned long long)off, (unsigned long long)len);		return -EIO;	}	mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);	while (towrite > 0) {		tocopy = sb->s_blocksize - offset < towrite ?		    sb->s_blocksize - offset : towrite;		tmp_bh.b_state = 0;		err = reiserfs_get_block(inode, blk, &tmp_bh, GET_BLOCK_CREATE);		if (err)			goto out;		if (offset || tocopy != sb->s_blocksize)			bh = sb_bread(sb, tmp_bh.b_blocknr);		else			bh = sb_getblk(sb, tmp_bh.b_blocknr);		if (!bh) {			err = -EIO;			goto out;		}		lock_buffer(bh);		memcpy(bh->b_data + offset, data, tocopy);		flush_dcache_page(bh->b_page);		set_buffer_uptodate(bh);		unlock_buffer(bh);		reiserfs_prepare_for_journal(sb, bh, 1);		journal_mark_dirty(current->journal_info, sb, bh);		if (!journal_quota)			reiserfs_add_ordered_list(inode, bh);		brelse(bh);		offset = 0;		towrite -= tocopy;		data += tocopy;		blk++;	}out:	if (len == towrite)		return err;	if (inode->i_size < off + len - towrite)		i_size_write(inode, off + len - towrite);	inode->i_version++;	inode->i_mtime = inode->i_ctime = CURRENT_TIME;	mark_inode_dirty(inode);	mutex_unlock(&inode->i_mutex);	return len - towrite;}#endifstatic int get_super_block(struct file_system_type *fs_type,			   int flags, const char *dev_name,			   void *data, struct vfsmount *mnt){	return get_sb_bdev(fs_type, flags, dev_name, data, reiserfs_fill_super,			   mnt);}static int __init init_reiserfs_fs(void){	int ret;	if ((ret = init_inodecache())) {		return ret;	}	if ((ret = reiserfs_xattr_register_handlers()))		goto failed_reiserfs_xattr_register_handlers;	reiserfs_proc_info_global_init();	reiserfs_proc_register_global("version",				      reiserfs_global_version_in_proc);	ret = register_filesystem(&reiserfs_fs_type);	if (ret == 0) {		return 0;	}	reiserfs_xattr_unregister_handlers();      failed_reiserfs_xattr_register_handlers:	reiserfs_proc_unregister_global("version");	reiserfs_proc_info_global_done();	destroy_inodecache();	return ret;}static void __exit exit_reiserfs_fs(void){	reiserfs_xattr_unregister_handlers();	reiserfs_proc_unregister_global("version");	reiserfs_proc_info_global_done();	unregister_filesystem(&reiserfs_fs_type);	destroy_inodecache();}struct file_system_type reiserfs_fs_type = {	.owner = THIS_MODULE,	.name = "reiserfs",	.get_sb = get_super_block,	.kill_sb = reiserfs_kill_sb,	.fs_flags = FS_REQUIRES_DEV,};MODULE_DESCRIPTION("ReiserFS journaled filesystem");MODULE_AUTHOR("Hans Reiser <reiser@namesys.com>");MODULE_LICENSE("GPL");module_init(init_reiserfs_fs);module_exit(exit_reiserfs_fs);

⌨️ 快捷键说明

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