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

📄 inode.c

📁 linux core 函数例程
💻 C
📖 第 1 页 / 共 2 页
字号:
	}

	*dentry = NULL;
	qstr.name = name;
	qstr.len = strlen(name);
 	qstr.hash = full_name_hash(name,qstr.len);

	parent = dget(parent);

	down(&parent->d_inode->i_sem);

	d = lookup_hash(&qstr,parent);

	error = PTR_ERR(d);
	if (!IS_ERR(d)) {
		switch(mode & S_IFMT) {
			case 0: 
			case S_IFREG:
				error = vfs_create(parent->d_inode,d,mode);
				break;
			case S_IFDIR:
				error = vfs_mkdir(parent->d_inode,d,mode);
				break;
			default:
				err("cannot create special files\n");
		}
		*dentry = d;
	}
	up(&parent->d_inode->i_sem);

	dput(parent);
	return error;
}

static struct dentry *fs_create_file (const char *name, mode_t mode,
				      struct dentry *parent, void *data,
				      struct file_operations *fops,
				      uid_t uid, gid_t gid)
{
	struct dentry *dentry;
	int error;

	dbg("creating file '%s'\n",name);

	error = fs_create_by_name(name,mode,parent,&dentry);
	if (error) {
		dentry = NULL;
	} else {
		if (dentry->d_inode) {
			if (data)
				dentry->d_inode->u.generic_ip = data;
			if (fops)
				dentry->d_inode->i_fop = fops;
			dentry->d_inode->i_uid = uid;
			dentry->d_inode->i_gid = gid;
		}
	}

	return dentry;
}

static void fs_remove_file (struct dentry *dentry)
{
	struct dentry *parent = dentry->d_parent;
	
	if (!parent || !parent->d_inode)
		return;

	down(&parent->d_inode->i_sem);
	if (usbfs_positive(dentry)) {
		if (dentry->d_inode) {
			if (S_ISDIR(dentry->d_inode->i_mode))
				vfs_rmdir(parent->d_inode,dentry);
			else
				vfs_unlink(parent->d_inode,dentry);
		}

		dput(dentry);
	}
	up(&parent->d_inode->i_sem);
}

/* --------------------------------------------------------------------- */



/*
 * The usbdevfs name is now deprecated (as of 2.5.1).
 * It will be removed when the 2.7.x development cycle is started.
 * You have been warned :)
 */

static struct super_block *usb_get_sb(struct file_system_type *fs_type,
	int flags, char *dev_name, void *data)
{
	return get_sb_single(fs_type, flags, data, usbfs_fill_super);
}

static struct file_system_type usbdevice_fs_type = {
	owner:		THIS_MODULE,
	name:		"usbdevfs",
	get_sb:		usb_get_sb,
	kill_sb:	kill_anon_super,
};

static struct file_system_type usb_fs_type = {
	owner:		THIS_MODULE,
	name:		"usbfs",
	get_sb:		usb_get_sb,
	kill_sb:	kill_anon_super,
};

/* --------------------------------------------------------------------- */
static int get_mount (void)
{
	struct vfsmount *mnt;

	spin_lock (&mount_lock);
	if (usbfs_mount) {
		mntget(usbfs_mount);
		++mount_count;
		spin_unlock (&mount_lock);
		goto go_ahead;
	}

	spin_unlock (&mount_lock);
	mnt = kern_mount (&usbdevice_fs_type);
	if (IS_ERR(mnt)) {
		err ("could not mount the fs...erroring out!\n");
		return -ENODEV;
	}
	spin_lock (&mount_lock);
	if (!usbfs_mount) {
		usbfs_mount = mnt;
		++mount_count;
		spin_unlock (&mount_lock);
		goto go_ahead;
	}
	mntget(usbfs_mount);
	++mount_count;
	spin_unlock (&mount_lock);
	mntput(mnt);

go_ahead:
	dbg("mount_count = %d\n", mount_count);
	return 0;
}

static void remove_mount (void)
{
	struct vfsmount *mnt;

	spin_lock (&mount_lock);
	mnt = usbfs_mount;
	--mount_count;
	if (!mount_count)
		usbfs_mount = NULL;

	spin_unlock (&mount_lock);
	mntput(mnt);
	dbg("mount_count = %d\n", mount_count);
}

static int create_special_files (void)
{
	int retval;

	/* create the devices and drivers special files */
	retval = get_mount ();
	if (retval)
		return retval;
	devices_dentry = fs_create_file ("devices",
					 listmode | S_IFREG,
					 NULL, NULL,
					 &usbdevfs_devices_fops,
					 listuid, listgid);
	if (devices_dentry == NULL) {
		err ("Unable to create devices usbfs file");
		return -ENODEV;
	}

	drivers_dentry = fs_create_file ("drivers",
					 listmode | S_IFREG,
					 NULL, NULL,
					 &usbdevfs_drivers_fops,
					 listuid, listgid);
	if (drivers_dentry == NULL) {
		err ("Unable to create drivers usbfs file");
		return -ENODEV;
	}

	return 0;
}

static void remove_special_files (void)
{
	if (devices_dentry)
		fs_remove_file (devices_dentry);
	if (drivers_dentry)
		fs_remove_file (drivers_dentry);
	devices_dentry = NULL;
	drivers_dentry = NULL;
	remove_mount();
}

void usbfs_update_special (void)
{
	struct inode *inode;

	if (devices_dentry) {
		inode = devices_dentry->d_inode;
		if (inode)
			inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
	}
	if (drivers_dentry) {
		inode = devices_dentry->d_inode;
		if (inode)
			inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
	}
}

void usbfs_add_bus(struct usb_bus *bus)
{
	char name[8];
	int retval;

	/* create the special files if this is the first bus added */
	if (num_buses == 0) {
		retval = create_special_files();
		if (retval)
			return;
	}
	++num_buses;

	sprintf (name, "%03d", bus->busnum);
	bus->dentry = fs_create_file (name,
				      busmode | S_IFDIR,
				      NULL, bus, NULL,
				      busuid, busgid);
	if (bus->dentry == NULL)
		return;

	usbfs_update_special();
	usbdevfs_conn_disc_event();
}


void usbfs_remove_bus(struct usb_bus *bus)
{
	if (bus->dentry) {
		fs_remove_file (bus->dentry);
		bus->dentry = NULL;
	}

	--num_buses;
	if (num_buses <= 0) {
		remove_special_files();
		num_buses = 0;
	}

	usbfs_update_special();
	usbdevfs_conn_disc_event();
}

void usbfs_add_device(struct usb_device *dev)
{
	char name[8];
	int i;
	int i_size;

	sprintf (name, "%03d", dev->devnum);
	dev->dentry = fs_create_file (name,
				      devmode | S_IFREG,
				      dev->bus->dentry, dev,
				      &usbdevfs_device_file_operations,
				      devuid, devgid);
	if (dev->dentry == NULL)
		return;

	/* Set the size of the device's file to be
	 * equal to the size of the device descriptors. */
	i_size = sizeof (struct usb_device_descriptor);
	for (i = 0; i < dev->descriptor.bNumConfigurations; ++i) {
		struct usb_config_descriptor *config =
			(struct usb_config_descriptor *)dev->rawdescriptors[i];
		i_size += le16_to_cpu (config->wTotalLength);
	}
	if (dev->dentry->d_inode)
		dev->dentry->d_inode->i_size = i_size;

	usbfs_update_special();
	usbdevfs_conn_disc_event();
}

void usbfs_remove_device(struct usb_device *dev)
{
	struct dev_state *ds;
	struct siginfo sinfo;

	if (dev->dentry) {
		fs_remove_file (dev->dentry);
		dev->dentry = NULL;
	}
	while (!list_empty(&dev->filelist)) {
		ds = list_entry(dev->filelist.next, struct dev_state, list);
		list_del(&ds->list);
		INIT_LIST_HEAD(&ds->list);
		down_write(&ds->devsem);
		ds->dev = NULL;
		up_write(&ds->devsem);
		if (ds->discsignr) {
			sinfo.si_signo = SIGPIPE;
			sinfo.si_errno = EPIPE;
			sinfo.si_code = SI_ASYNCIO;
			sinfo.si_addr = ds->disccontext;
			send_sig_info(ds->discsignr, &sinfo, ds->disctask);
		}
	}
	usbfs_update_special();
	usbdevfs_conn_disc_event();
}

/* --------------------------------------------------------------------- */

#ifdef CONFIG_PROC_FS		
static struct proc_dir_entry *usbdir = NULL;
#endif	

int __init usbfs_init(void)
{
	int retval;

	retval = usb_register(&usbdevfs_driver);
	if (retval)
		return retval;

	retval = register_filesystem(&usb_fs_type);
	if (retval) {
		usb_deregister(&usbdevfs_driver);
		return retval;
	}
	retval = register_filesystem(&usbdevice_fs_type);
	if (retval) {
		unregister_filesystem(&usb_fs_type);
		usb_deregister(&usbdevfs_driver);
		return retval;
	}

#ifdef CONFIG_PROC_FS		
	/* create mount point for usbdevfs */
	usbdir = proc_mkdir("usb", proc_bus);
#endif	

	return 0;
}

void __exit usbfs_cleanup(void)
{
	usb_deregister(&usbdevfs_driver);
	unregister_filesystem(&usb_fs_type);
	unregister_filesystem(&usbdevice_fs_type);
#ifdef CONFIG_PROC_FS	
	if (usbdir)
		remove_proc_entry("usb", proc_bus);
#endif
}

⌨️ 快捷键说明

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