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

📄 file.c

📁 linux 内核源代码
💻 C
字号:
/* * File operations for Coda. * Original version: (C) 1996 Peter Braam  * Rewritten for Linux 2.1: (C) 1997 Carnegie Mellon University * * Carnegie Mellon encourages users of this code to contribute improvements * to the Coda project. Contact Peter Braam <coda@cs.cmu.edu>. */#include <linux/types.h>#include <linux/kernel.h>#include <linux/time.h>#include <linux/file.h>#include <linux/fs.h>#include <linux/stat.h>#include <linux/errno.h>#include <linux/smp_lock.h>#include <linux/string.h>#include <asm/uaccess.h>#include <linux/coda.h>#include <linux/coda_linux.h>#include <linux/coda_fs_i.h>#include <linux/coda_psdev.h>#include "coda_int.h"static ssize_tcoda_file_read(struct file *coda_file, char __user *buf, size_t count, loff_t *ppos){	struct coda_file_info *cfi;	struct file *host_file;	cfi = CODA_FTOC(coda_file);	BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);	host_file = cfi->cfi_container;	if (!host_file->f_op || !host_file->f_op->read)		return -EINVAL;	return host_file->f_op->read(host_file, buf, count, ppos);}static ssize_tcoda_file_splice_read(struct file *coda_file, loff_t *ppos,		      struct pipe_inode_info *pipe, size_t count,		      unsigned int flags){	struct coda_file_info *cfi;	struct file *host_file;	cfi = CODA_FTOC(coda_file);	BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);	host_file = cfi->cfi_container;	if (!host_file->f_op || !host_file->f_op->splice_read)		return -EINVAL;	return host_file->f_op->splice_read(host_file, ppos, pipe, count,flags);}static ssize_tcoda_file_write(struct file *coda_file, const char __user *buf, size_t count, loff_t *ppos){	struct inode *host_inode, *coda_inode = coda_file->f_path.dentry->d_inode;	struct coda_file_info *cfi;	struct file *host_file;	ssize_t ret;	cfi = CODA_FTOC(coda_file);	BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);	host_file = cfi->cfi_container;	if (!host_file->f_op || !host_file->f_op->write)		return -EINVAL;	host_inode = host_file->f_path.dentry->d_inode;	mutex_lock(&coda_inode->i_mutex);	ret = host_file->f_op->write(host_file, buf, count, ppos);	coda_inode->i_size = host_inode->i_size;	coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9;	coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME_SEC;	mutex_unlock(&coda_inode->i_mutex);	return ret;}static intcoda_file_mmap(struct file *coda_file, struct vm_area_struct *vma){	struct coda_file_info *cfi;	struct coda_inode_info *cii;	struct file *host_file;	struct inode *coda_inode, *host_inode;	cfi = CODA_FTOC(coda_file);	BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);	host_file = cfi->cfi_container;	if (!host_file->f_op || !host_file->f_op->mmap)		return -ENODEV;	coda_inode = coda_file->f_path.dentry->d_inode;	host_inode = host_file->f_path.dentry->d_inode;	coda_file->f_mapping = host_file->f_mapping;	if (coda_inode->i_mapping == &coda_inode->i_data)		coda_inode->i_mapping = host_inode->i_mapping;	/* only allow additional mmaps as long as userspace isn't changing	 * the container file on us! */	else if (coda_inode->i_mapping != host_inode->i_mapping)		return -EBUSY;	/* keep track of how often the coda_inode/host_file has been mmapped */	cii = ITOC(coda_inode);	cii->c_mapcount++;	cfi->cfi_mapcount++;	return host_file->f_op->mmap(host_file, vma);}int coda_open(struct inode *coda_inode, struct file *coda_file){	struct file *host_file = NULL;	int error;	unsigned short flags = coda_file->f_flags & (~O_EXCL);	unsigned short coda_flags = coda_flags_to_cflags(flags);	struct coda_file_info *cfi;	cfi = kmalloc(sizeof(struct coda_file_info), GFP_KERNEL);	if (!cfi)		return -ENOMEM;	lock_kernel();	error = venus_open(coda_inode->i_sb, coda_i2f(coda_inode), coda_flags,			   &host_file);	if (!host_file)		error = -EIO;	if (error) {		kfree(cfi);		unlock_kernel();		return error;	}	host_file->f_flags |= coda_file->f_flags & (O_APPEND | O_SYNC);	cfi->cfi_magic = CODA_MAGIC;	cfi->cfi_mapcount = 0;	cfi->cfi_container = host_file;	BUG_ON(coda_file->private_data != NULL);	coda_file->private_data = cfi;	unlock_kernel();	return 0;}int coda_release(struct inode *coda_inode, struct file *coda_file){	unsigned short flags = (coda_file->f_flags) & (~O_EXCL);	unsigned short coda_flags = coda_flags_to_cflags(flags);	struct coda_file_info *cfi;	struct coda_inode_info *cii;	struct inode *host_inode;	int err = 0;	lock_kernel();	cfi = CODA_FTOC(coda_file);	BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);	err = venus_close(coda_inode->i_sb, coda_i2f(coda_inode),			  coda_flags, coda_file->f_uid);	host_inode = cfi->cfi_container->f_path.dentry->d_inode;	cii = ITOC(coda_inode);	/* did we mmap this file? */	if (coda_inode->i_mapping == &host_inode->i_data) {		cii->c_mapcount -= cfi->cfi_mapcount;		if (!cii->c_mapcount)			coda_inode->i_mapping = &coda_inode->i_data;	}	fput(cfi->cfi_container);	kfree(coda_file->private_data);	coda_file->private_data = NULL;	unlock_kernel();	/* VFS fput ignores the return value from file_operations->release, so	 * there is no use returning an error here */	return 0;}int coda_fsync(struct file *coda_file, struct dentry *coda_dentry, int datasync){	struct file *host_file;	struct dentry *host_dentry;	struct inode *host_inode, *coda_inode = coda_dentry->d_inode;	struct coda_file_info *cfi;	int err = 0;	if (!(S_ISREG(coda_inode->i_mode) || S_ISDIR(coda_inode->i_mode) ||	      S_ISLNK(coda_inode->i_mode)))		return -EINVAL;	cfi = CODA_FTOC(coda_file);	BUG_ON(!cfi || cfi->cfi_magic != CODA_MAGIC);	host_file = cfi->cfi_container;	if (host_file->f_op && host_file->f_op->fsync) {		host_dentry = host_file->f_path.dentry;		host_inode = host_dentry->d_inode;		mutex_lock(&host_inode->i_mutex);		err = host_file->f_op->fsync(host_file, host_dentry, datasync);		mutex_unlock(&host_inode->i_mutex);	}	if ( !err && !datasync ) {		lock_kernel();		err = venus_fsync(coda_inode->i_sb, coda_i2f(coda_inode));		unlock_kernel();	}	return err;}const struct file_operations coda_file_operations = {	.llseek		= generic_file_llseek,	.read		= coda_file_read,	.write		= coda_file_write,	.mmap		= coda_file_mmap,	.open		= coda_open,	.release	= coda_release,	.fsync		= coda_fsync,	.splice_read	= coda_file_splice_read,};

⌨️ 快捷键说明

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