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

📄 inode.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
static intspufs_create_context(struct inode *inode, struct dentry *dentry,			struct vfsmount *mnt, int flags, int mode,			struct file *aff_filp){	int ret;	int affinity;	struct spu_gang *gang;	struct spu_context *neighbor;	ret = -EPERM;	if ((flags & SPU_CREATE_NOSCHED) &&	    !capable(CAP_SYS_NICE))		goto out_unlock;	ret = -EINVAL;	if ((flags & (SPU_CREATE_NOSCHED | SPU_CREATE_ISOLATE))	    == SPU_CREATE_ISOLATE)		goto out_unlock;	ret = -ENODEV;	if ((flags & SPU_CREATE_ISOLATE) && !isolated_loader)		goto out_unlock;	gang = NULL;	neighbor = NULL;	affinity = flags & (SPU_CREATE_AFFINITY_MEM | SPU_CREATE_AFFINITY_SPU);	if (affinity) {		gang = SPUFS_I(inode)->i_gang;		ret = -EINVAL;		if (!gang)			goto out_unlock;		mutex_lock(&gang->aff_mutex);		neighbor = spufs_assert_affinity(flags, gang, aff_filp);		if (IS_ERR(neighbor)) {			ret = PTR_ERR(neighbor);			goto out_aff_unlock;		}	}	ret = spufs_mkdir(inode, dentry, flags, mode & S_IRWXUGO);	if (ret)		goto out_aff_unlock;	if (affinity)		spufs_set_affinity(flags, SPUFS_I(dentry->d_inode)->i_ctx,								neighbor);	/*	 * get references for dget and mntget, will be released	 * in error path of *_open().	 */	ret = spufs_context_open(dget(dentry), mntget(mnt));	if (ret < 0) {		WARN_ON(spufs_rmdir(inode, dentry));		mutex_unlock(&inode->i_mutex);		spu_forget(SPUFS_I(dentry->d_inode)->i_ctx);		goto out;	}out_aff_unlock:	if (affinity)		mutex_unlock(&gang->aff_mutex);out_unlock:	mutex_unlock(&inode->i_mutex);out:	dput(dentry);	return ret;}static intspufs_mkgang(struct inode *dir, struct dentry *dentry, int mode){	int ret;	struct inode *inode;	struct spu_gang *gang;	ret = -ENOSPC;	inode = spufs_new_inode(dir->i_sb, mode | S_IFDIR);	if (!inode)		goto out;	ret = 0;	if (dir->i_mode & S_ISGID) {		inode->i_gid = dir->i_gid;		inode->i_mode &= S_ISGID;	}	gang = alloc_spu_gang();	SPUFS_I(inode)->i_ctx = NULL;	SPUFS_I(inode)->i_gang = gang;	if (!gang)		goto out_iput;	inode->i_op = &simple_dir_inode_operations;	inode->i_fop = &simple_dir_operations;	d_instantiate(dentry, inode);	dir->i_nlink++;	dentry->d_inode->i_nlink++;	return ret;out_iput:	iput(inode);out:	return ret;}static int spufs_gang_open(struct dentry *dentry, struct vfsmount *mnt){	int ret;	struct file *filp;	ret = get_unused_fd();	if (ret < 0) {		dput(dentry);		mntput(mnt);		goto out;	}	filp = dentry_open(dentry, mnt, O_RDONLY);	if (IS_ERR(filp)) {		put_unused_fd(ret);		ret = PTR_ERR(filp);		goto out;	}	filp->f_op = &simple_dir_operations;	fd_install(ret, filp);out:	return ret;}static int spufs_create_gang(struct inode *inode,			struct dentry *dentry,			struct vfsmount *mnt, int mode){	int ret;	ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO);	if (ret)		goto out;	/*	 * get references for dget and mntget, will be released	 * in error path of *_open().	 */	ret = spufs_gang_open(dget(dentry), mntget(mnt));	if (ret < 0) {		int err = simple_rmdir(inode, dentry);		WARN_ON(err);	}out:	mutex_unlock(&inode->i_mutex);	dput(dentry);	return ret;}static struct file_system_type spufs_type;long spufs_create(struct nameidata *nd, unsigned int flags, mode_t mode,							struct file *filp){	struct dentry *dentry;	int ret;	ret = -EINVAL;	/* check if we are on spufs */	if (nd->dentry->d_sb->s_type != &spufs_type)		goto out;	/* don't accept undefined flags */	if (flags & (~SPU_CREATE_FLAG_ALL))		goto out;	/* only threads can be underneath a gang */	if (nd->dentry != nd->dentry->d_sb->s_root) {		if ((flags & SPU_CREATE_GANG) ||		    !SPUFS_I(nd->dentry->d_inode)->i_gang)			goto out;	}	dentry = lookup_create(nd, 1);	ret = PTR_ERR(dentry);	if (IS_ERR(dentry))		goto out_dir;	ret = -EEXIST;	if (dentry->d_inode)		goto out_dput;	mode &= ~current->fs->umask;	if (flags & SPU_CREATE_GANG)		return spufs_create_gang(nd->dentry->d_inode,					dentry, nd->mnt, mode);	else		return spufs_create_context(nd->dentry->d_inode,					dentry, nd->mnt, flags, mode, filp);out_dput:	dput(dentry);out_dir:	mutex_unlock(&nd->dentry->d_inode->i_mutex);out:	return ret;}/* File system initialization */enum {	Opt_uid, Opt_gid, Opt_mode, Opt_err,};static match_table_t spufs_tokens = {	{ Opt_uid,  "uid=%d" },	{ Opt_gid,  "gid=%d" },	{ Opt_mode, "mode=%o" },	{ Opt_err,   NULL  },};static intspufs_parse_options(char *options, struct inode *root){	char *p;	substring_t args[MAX_OPT_ARGS];	while ((p = strsep(&options, ",")) != NULL) {		int token, option;		if (!*p)			continue;		token = match_token(p, spufs_tokens, args);		switch (token) {		case Opt_uid:			if (match_int(&args[0], &option))				return 0;			root->i_uid = option;			break;		case Opt_gid:			if (match_int(&args[0], &option))				return 0;			root->i_gid = option;			break;		case Opt_mode:			if (match_octal(&args[0], &option))				return 0;			root->i_mode = option | S_IFDIR;			break;		default:			return 0;		}	}	return 1;}static void spufs_exit_isolated_loader(void){	free_pages((unsigned long) isolated_loader,			get_order(isolated_loader_size));}static voidspufs_init_isolated_loader(void){	struct device_node *dn;	const char *loader;	int size;	dn = of_find_node_by_path("/spu-isolation");	if (!dn)		return;	loader = of_get_property(dn, "loader", &size);	if (!loader)		return;	/* the loader must be align on a 16 byte boundary */	isolated_loader = (char *)__get_free_pages(GFP_KERNEL, get_order(size));	if (!isolated_loader)		return;	isolated_loader_size = size;	memcpy(isolated_loader, loader, size);	printk(KERN_INFO "spufs: SPU isolation mode enabled\n");}static intspufs_create_root(struct super_block *sb, void *data){	struct inode *inode;	int ret;	ret = -ENODEV;	if (!spu_management_ops)		goto out;	ret = -ENOMEM;	inode = spufs_new_inode(sb, S_IFDIR | 0775);	if (!inode)		goto out;	inode->i_op = &simple_dir_inode_operations;	inode->i_fop = &simple_dir_operations;	SPUFS_I(inode)->i_ctx = NULL;	ret = -EINVAL;	if (!spufs_parse_options(data, inode))		goto out_iput;	ret = -ENOMEM;	sb->s_root = d_alloc_root(inode);	if (!sb->s_root)		goto out_iput;	return 0;out_iput:	iput(inode);out:	return ret;}static intspufs_fill_super(struct super_block *sb, void *data, int silent){	static struct super_operations s_ops = {		.alloc_inode = spufs_alloc_inode,		.destroy_inode = spufs_destroy_inode,		.statfs = simple_statfs,		.delete_inode = spufs_delete_inode,		.drop_inode = generic_delete_inode,	};	sb->s_maxbytes = MAX_LFS_FILESIZE;	sb->s_blocksize = PAGE_CACHE_SIZE;	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;	sb->s_magic = SPUFS_MAGIC;	sb->s_op = &s_ops;	return spufs_create_root(sb, data);}static intspufs_get_sb(struct file_system_type *fstype, int flags,		const char *name, void *data, struct vfsmount *mnt){	return get_sb_single(fstype, flags, data, spufs_fill_super, mnt);}static struct file_system_type spufs_type = {	.owner = THIS_MODULE,	.name = "spufs",	.get_sb = spufs_get_sb,	.kill_sb = kill_litter_super,};static int __init spufs_init(void){	int ret;	ret = -ENODEV;	if (!spu_management_ops)		goto out;	ret = -ENOMEM;	spufs_inode_cache = kmem_cache_create("spufs_inode_cache",			sizeof(struct spufs_inode_info), 0,			SLAB_HWCACHE_ALIGN, spufs_init_once);	if (!spufs_inode_cache)		goto out;	ret = spu_sched_init();	if (ret)		goto out_cache;	ret = register_filesystem(&spufs_type);	if (ret)		goto out_sched;	ret = register_spu_syscalls(&spufs_calls);	if (ret)		goto out_fs;	spufs_init_isolated_loader();	return 0;out_fs:	unregister_filesystem(&spufs_type);out_sched:	spu_sched_exit();out_cache:	kmem_cache_destroy(spufs_inode_cache);out:	return ret;}module_init(spufs_init);static void __exit spufs_exit(void){	spu_sched_exit();	spufs_exit_isolated_loader();	unregister_spu_syscalls(&spufs_calls);	unregister_filesystem(&spufs_type);	kmem_cache_destroy(spufs_inode_cache);}module_exit(spufs_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("Arnd Bergmann <arndb@de.ibm.com>");

⌨️ 快捷键说明

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