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

📄 inode.c

📁 是关于linux2.5.1的完全源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************//* *	inode.c  --  Inode/Dentry functions for the USB device file system. * *	Copyright (C) 2000 Thomas Sailer (sailer@ife.ee.ethz.ch) *	Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com) * *	This program is free software; you can redistribute it and/or modify *	it under the terms of the GNU General Public License as published by *	the Free Software Foundation; either version 2 of the License, or *	(at your option) any later version. * *	This program is distributed in the hope that it will be useful, *	but WITHOUT ANY WARRANTY; without even the implied warranty of *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *	GNU General Public License for more details. * *	You should have received a copy of the GNU General Public License *	along with this program; if not, write to the Free Software *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * *  History: *   0.1  04.01.2000  Created *   0.2  10.12.2001  converted to use the vfs layer better *//*****************************************************************************/#define __NO_VERSION__#include <linux/config.h>#include <linux/module.h>#include <linux/fs.h>#include <linux/pagemap.h>#include <linux/init.h>#include <linux/proc_fs.h>#include <linux/usb.h>#include <linux/usbdevice_fs.h>#include <linux/smp_lock.h>#include <asm/byteorder.h>static struct super_operations usbfs_ops;static struct file_operations default_file_operations;static struct inode_operations usbfs_dir_inode_operations;static struct vfsmount *usbfs_mount;static spinlock_t mount_lock = SPIN_LOCK_UNLOCKED;static int mount_count;	/* = 0 */static struct dentry *devices_dentry;static struct dentry *drivers_dentry;static int num_buses;	/* = 0 */static uid_t devuid;	/* = 0 */static uid_t busuid;	/* = 0 */static uid_t listuid;	/* = 0 */static gid_t devgid;	/* = 0 */static gid_t busgid;	/* = 0 */static gid_t listgid;	/* = 0 */static umode_t devmode = S_IWUSR | S_IRUGO;static umode_t busmode = S_IXUGO | S_IRUGO;static umode_t listmode = S_IRUGO;static int parse_options(struct super_block *s, char *data){	char *curopt = NULL, *value;	while ((curopt = strsep(&data, ",")) != NULL) {		if (!*curopt)			continue;		if ((value = strchr(curopt, '=')) != NULL)			*value++ = 0;		if (!strcmp(curopt, "devuid")) {			if (!value || !value[0])				return -EINVAL;			devuid = simple_strtoul(value, &value, 0);			if (*value)				return -EINVAL;		}		if (!strcmp(curopt, "devgid")) {			if (!value || !value[0])				return -EINVAL;			devgid = simple_strtoul(value, &value, 0);			if (*value)				return -EINVAL;		}		if (!strcmp(curopt, "devmode")) {			if (!value || !value[0])				return -EINVAL;			devmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;			if (*value)				return -EINVAL;		}		if (!strcmp(curopt, "busuid")) {			if (!value || !value[0])				return -EINVAL;			busuid = simple_strtoul(value, &value, 0);			if (*value)				return -EINVAL;		}		if (!strcmp(curopt, "busgid")) {			if (!value || !value[0])				return -EINVAL;			busgid = simple_strtoul(value, &value, 0);			if (*value)				return -EINVAL;		}		if (!strcmp(curopt, "busmode")) {			if (!value || !value[0])				return -EINVAL;			busmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;			if (*value)				return -EINVAL;		}		if (!strcmp(curopt, "listuid")) {			if (!value || !value[0])				return -EINVAL;			listuid = simple_strtoul(value, &value, 0);			if (*value)				return -EINVAL;		}		if (!strcmp(curopt, "listgid")) {			if (!value || !value[0])				return -EINVAL;			listgid = simple_strtoul(value, &value, 0);			if (*value)				return -EINVAL;		}		if (!strcmp(curopt, "listmode")) {			if (!value || !value[0])				return -EINVAL;			listmode = simple_strtoul(value, &value, 0) & S_IRWXUGO;			if (*value)				return -EINVAL;		}	}	return 0;}/* --------------------------------------------------------------------- */static struct inode *usbfs_get_inode (struct super_block *sb, int mode, int dev){	struct inode *inode = new_inode(sb);	if (inode) {		inode->i_mode = mode;		inode->i_uid = current->fsuid;		inode->i_gid = current->fsgid;		inode->i_blksize = PAGE_CACHE_SIZE;		inode->i_blocks = 0;		inode->i_rdev = NODEV;		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;		switch (mode & S_IFMT) {		default:			init_special_inode(inode, mode, dev);			break;		case S_IFREG:			inode->i_fop = &default_file_operations;			break;		case S_IFDIR:			inode->i_op = &usbfs_dir_inode_operations;			inode->i_fop = &simple_dir_operations;			break;		}	}	return inode; }/* SMP-safe */static int usbfs_mknod (struct inode *dir, struct dentry *dentry, int mode,			int dev){	struct inode *inode = usbfs_get_inode(dir->i_sb, mode, dev);	int error = -ENOSPC;	if (inode) {		d_instantiate(dentry, inode);		dget(dentry);		error = 0;	}	return error;}static int usbfs_mkdir (struct inode *dir, struct dentry *dentry, int mode){	return usbfs_mknod (dir, dentry, mode | S_IFDIR, 0);}static int usbfs_create (struct inode *dir, struct dentry *dentry, int mode){ 	return usbfs_mknod (dir, dentry, mode | S_IFREG, 0);}static inline int usbfs_positive (struct dentry *dentry){	return dentry->d_inode && !d_unhashed(dentry);}static int usbfs_empty (struct dentry *dentry){	struct list_head *list;	spin_lock(&dcache_lock);	list_for_each(list, &dentry->d_subdirs) {		struct dentry *de = list_entry(list, struct dentry, d_child);		if (usbfs_positive(de)) {			spin_unlock(&dcache_lock);			return 0;		}	}	spin_unlock(&dcache_lock);	return 1;}static int usbfs_unlink (struct inode *dir, struct dentry *dentry){	int error = -ENOTEMPTY;	if (usbfs_empty(dentry)) {		struct inode *inode = dentry->d_inode;		lock_kernel();		inode->i_nlink--;		unlock_kernel();		dput(dentry);		error = 0;	}	return error;}#define usbfs_rmdir usbfs_unlink/* default file operations */static ssize_t default_read_file (struct file *file, char *buf,				  size_t count, loff_t *ppos){	return 0;}static ssize_t default_write_file (struct file *file, const char *buf,				   size_t count, loff_t *ppos){	return count;}static loff_t default_file_lseek (struct file *file, loff_t offset, int orig){	loff_t retval = -EINVAL;	lock_kernel();	switch(orig) {	case 0:		if (offset > 0) {			file->f_pos = offset;			retval = file->f_pos;		} 		break;	case 1:		if ((offset + file->f_pos) > 0) {			file->f_pos += offset;			retval = file->f_pos;		} 		break;	default:		break;	}	unlock_kernel();	return retval;}static int default_open (struct inode *inode, struct file *filp){	if (inode->u.generic_ip)		filp->private_data = inode->u.generic_ip;	return 0;}static struct file_operations default_file_operations = {	read:		default_read_file,	write:		default_write_file,	open:		default_open,	llseek:		default_file_lseek,};static struct inode_operations usbfs_dir_inode_operations = {	create:		usbfs_create,	lookup:		simple_lookup,	unlink:		usbfs_unlink,	mkdir:		usbfs_mkdir,	rmdir:		usbfs_rmdir,};static struct super_operations usbfs_ops = {	statfs:		simple_statfs,	put_inode:	force_delete,};static int usbfs_fill_super(struct super_block *sb, void *data, int silent){	struct inode *inode;	struct dentry *root;	if (parse_options(sb, data)) {		warn("usbfs: mount parameter error:");		return -EINVAL;	}	sb->s_blocksize = PAGE_CACHE_SIZE;	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;	sb->s_magic = USBDEVICE_SUPER_MAGIC;	sb->s_op = &usbfs_ops;	inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0);	if (!inode) {		dbg("%s: could not get inode!\n",__FUNCTION__);		return -ENOMEM;	}	root = d_alloc_root(inode);	if (!root) {		dbg("%s: could not get root dentry!\n",__FUNCTION__);		iput(inode);		return -ENOMEM;	}	sb->s_root = root;	return 0;}/** * fs_create_by_name - create a file, given a name * @name:	name of file * @mode:	type of file * @parent:	dentry of directory to create it in * @dentry:	resulting dentry of file * * There is a bit of overhead in creating a file - basically, we  * have to hash the name of the file, then look it up. This will * prevent files of the same name.  * We then call the proper vfs_ function to take care of all the  * file creation details.  * This function handles both regular files and directories. */static int fs_create_by_name (const char *name, mode_t mode,			      struct dentry *parent, struct dentry **dentry){	struct dentry *d = NULL;	struct qstr qstr;	int error;	/* If the parent is not specified, we create it in the root.	 * We need the root dentry to do this, which is in the super 	 * block. A pointer to that is in the struct vfsmount that we	 * have around.	 */	if (!parent ) {		if (usbfs_mount && usbfs_mount->mnt_sb) {			parent = usbfs_mount->mnt_sb->s_root;		}	}	if (!parent) {		dbg("Ah! can not find a parent!\n");		return -EFAULT;

⌨️ 快捷键说明

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