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

📄 inode.c

📁 linux下的用户文件系统fuse-2.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
				return 0;			d->user_id = value;			d->user_id_present = 1;			break;		case OPT_GROUP_ID:			if (match_int(&args[0], &value))				return 0;			d->group_id = value;			d->group_id_present = 1;			break;		case OPT_DEFAULT_PERMISSIONS:			d->flags |= FUSE_DEFAULT_PERMISSIONS;			break;		case OPT_ALLOW_OTHER:			d->flags |= FUSE_ALLOW_OTHER;			break;#ifndef KERNEL_2_6		case OPT_LARGE_READ:			d->flags |= FUSE_LARGE_READ;			break;#endif		case OPT_MAX_READ:			if (match_int(&args[0], &value))				return 0;			d->max_read = value;			break;		default:			return 0;		}	}	if (!d->fd_present || !d->rootmode_present ||	    !d->user_id_present || !d->group_id_present)		return 0;	return 1;}static int fuse_show_options(struct seq_file *m, struct vfsmount *mnt){	struct fuse_conn *fc = get_fuse_conn_super(mnt->mnt_sb);	seq_printf(m, ",user_id=%u", fc->user_id);	seq_printf(m, ",group_id=%u", fc->group_id);	if (fc->flags & FUSE_DEFAULT_PERMISSIONS)		seq_puts(m, ",default_permissions");	if (fc->flags & FUSE_ALLOW_OTHER)		seq_puts(m, ",allow_other");#ifndef KERNEL_2_6	if (fc->flags & FUSE_LARGE_READ)		seq_puts(m, ",large_read");#endif	if (fc->max_read != ~0)		seq_printf(m, ",max_read=%u", fc->max_read);	return 0;}static void free_conn(struct fuse_conn *fc){	while (!list_empty(&fc->unused_list)) {		struct fuse_req *req;		req = list_entry(fc->unused_list.next, struct fuse_req, list);		list_del(&req->list);		fuse_request_free(req);	}	kfree(fc);}/* Must be called with the fuse lock held */void fuse_release_conn(struct fuse_conn *fc){	fc->count--;	if (!fc->count)		free_conn(fc);}static struct fuse_conn *new_conn(void){	struct fuse_conn *fc;	fc = kmalloc(sizeof(*fc), GFP_KERNEL);	if (fc != NULL) {		int i;		memset(fc, 0, sizeof(*fc));		init_waitqueue_head(&fc->waitq);		INIT_LIST_HEAD(&fc->pending);		INIT_LIST_HEAD(&fc->processing);		INIT_LIST_HEAD(&fc->unused_list);		INIT_LIST_HEAD(&fc->background);		sema_init(&fc->outstanding_sem, 0);		init_rwsem(&fc->sbput_sem);		for (i = 0; i < FUSE_MAX_OUTSTANDING; i++) {			struct fuse_req *req = fuse_request_alloc();			if (!req) {				free_conn(fc);				return NULL;			}			list_add(&req->list, &fc->unused_list);		}#ifdef KERNEL_2_6_6_PLUS		fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE;		fc->bdi.unplug_io_fn = default_unplug_io_fn;#endif		fc->reqctr = 0;	}	return fc;}static struct fuse_conn *get_conn(struct file *file, struct super_block *sb){	struct fuse_conn *fc;	if (file->f_op != &fuse_dev_operations)		return ERR_PTR(-EINVAL);	fc = new_conn();	if (fc == NULL)		return ERR_PTR(-ENOMEM);	spin_lock(&fuse_lock);	if (file->private_data) {		free_conn(fc);		fc = ERR_PTR(-EINVAL);	} else {		file->private_data = fc;		*get_fuse_conn_super_p(sb) = fc;		fc->mounted = 1;		fc->connected = 1;		fc->count = 2;	}	spin_unlock(&fuse_lock);	return fc;}static struct inode *get_root_inode(struct super_block *sb, unsigned mode){	struct fuse_attr attr;	memset(&attr, 0, sizeof(attr));	attr.mode = mode;	attr.ino = FUSE_ROOT_ID;	return fuse_iget(sb, 1, 0, &attr);}#ifndef FUSE_MAINLINE#ifdef KERNEL_2_6static struct dentry *fuse_get_dentry(struct super_block *sb, void *vobjp){	__u32 *objp = vobjp;	unsigned long nodeid = objp[0];	__u32 generation = objp[1];	struct inode *inode;	struct dentry *entry;	if (nodeid == 0)		return ERR_PTR(-ESTALE);	inode = ilookup5(sb, nodeid, fuse_inode_eq, &nodeid);	if (!inode)		return ERR_PTR(-ESTALE);	if (inode->i_generation != generation) {		iput(inode);		return ERR_PTR(-ESTALE);	}	entry = d_alloc_anon(inode);	if (!entry) {		iput(inode);		return ERR_PTR(-ENOMEM);	}	return entry;}static int fuse_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len,			  int connectable){	struct inode *inode = dentry->d_inode;	int len = *max_len;	int type = 1;	if (len < 2 || (connectable && len < 4))		return 255;	len = 2;	fh[0] = get_fuse_inode(inode)->nodeid;	fh[1] = inode->i_generation;	if (connectable && !S_ISDIR(inode->i_mode)) {		struct inode *parent;		spin_lock(&dentry->d_lock);		parent = dentry->d_parent->d_inode;		fh[2] = get_fuse_inode(parent)->nodeid;		fh[3] = parent->i_generation;		spin_unlock(&dentry->d_lock);		len = 4;		type = 2;	}	*max_len = len;	return type;}static struct export_operations fuse_export_operations = {	.get_dentry	= fuse_get_dentry,	.encode_fh      = fuse_encode_fh,};#endif#endifstatic struct super_operations fuse_super_operations = {	.alloc_inode    = fuse_alloc_inode,	.destroy_inode  = fuse_destroy_inode,	.read_inode	= fuse_read_inode,	.clear_inode	= fuse_clear_inode,	.put_super	= fuse_put_super,	.statfs		= fuse_statfs,	.show_options	= fuse_show_options,};static int fuse_fill_super(struct super_block *sb, void *data, int silent){	struct fuse_conn *fc;	struct inode *root;	struct fuse_mount_data d;	struct file *file;	int err;	if (!parse_fuse_opt((char *) data, &d))		return -EINVAL;	sb->s_blocksize = PAGE_CACHE_SIZE;	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;	sb->s_magic = FUSE_SUPER_MAGIC;	sb->s_op = &fuse_super_operations;	sb->s_maxbytes = MAX_LFS_FILESIZE;#ifndef FUSE_MAINLINE#ifdef KERNEL_2_6	sb->s_export_op = &fuse_export_operations;#endif#endif	file = fget(d.fd);	if (!file)		return -EINVAL;	fc = get_conn(file, sb);	fput(file);	if (IS_ERR(fc))		return PTR_ERR(fc);	fc->flags = d.flags;	fc->user_id = d.user_id;	fc->group_id = d.group_id;	fc->max_read = d.max_read;#ifdef KERNEL_2_6	if (fc->max_read / PAGE_CACHE_SIZE < fc->bdi.ra_pages)		fc->bdi.ra_pages = fc->max_read / PAGE_CACHE_SIZE;#endif	err = -ENOMEM;	root = get_root_inode(sb, d.rootmode);	if (root == NULL)		goto err;	sb->s_root = d_alloc_root(root);	if (!sb->s_root) {		iput(root);		goto err;	}	fuse_send_init(fc);	return 0; err:	spin_lock(&fuse_lock);	fuse_release_conn(fc);	spin_unlock(&fuse_lock);	return err;}#ifdef KERNEL_2_6static struct super_block *fuse_get_sb(struct file_system_type *fs_type,				       int flags, const char *dev_name,				       void *raw_data){	return get_sb_nodev(fs_type, flags, raw_data, fuse_fill_super);}static struct file_system_type fuse_fs_type = {	.owner		= THIS_MODULE,	.name		= "fuse",	.get_sb		= fuse_get_sb,	.kill_sb	= kill_anon_super,};#elsestatic struct super_block *fuse_read_super_compat(struct super_block *sb,						  void *data, int silent){	int err = fuse_fill_super(sb, data, silent);	if (err)		return NULL;	else		return sb;}static DECLARE_FSTYPE(fuse_fs_type, "fuse", fuse_read_super_compat, 0);#endifstatic void fuse_inode_init_once(void *foo, kmem_cache_t *cachep,				 unsigned long flags){	struct inode * inode = foo;	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==	    SLAB_CTOR_CONSTRUCTOR)		inode_init_once(inode);}static int __init fuse_fs_init(void){	int err;	err = register_filesystem(&fuse_fs_type);	if (err)		printk("fuse: failed to register filesystem\n");	else {		fuse_inode_cachep = kmem_cache_create("fuse_inode",						      sizeof(struct fuse_inode),						      0, SLAB_HWCACHE_ALIGN,						      fuse_inode_init_once, NULL);		if (!fuse_inode_cachep) {			unregister_filesystem(&fuse_fs_type);			err = -ENOMEM;		}	}	return err;}static void fuse_fs_cleanup(void){	unregister_filesystem(&fuse_fs_type);	kmem_cache_destroy(fuse_inode_cachep);}static int __init fuse_init(void){	int res;	printk("fuse init (API version %i.%i)\n",	       FUSE_KERNEL_VERSION, FUSE_KERNEL_MINOR_VERSION);#ifndef FUSE_MAINLINE	printk("fuse distribution version: %s\n", FUSE_VERSION);#endif	spin_lock_init(&fuse_lock);	res = fuse_fs_init();	if (res)		goto err;	res = fuse_dev_init();	if (res)		goto err_fs_cleanup;	return 0; err_fs_cleanup:	fuse_fs_cleanup(); err:	return res;}static void __exit fuse_exit(void){	printk(KERN_DEBUG "fuse exit\n");	fuse_fs_cleanup();	fuse_dev_cleanup();}module_init(fuse_init);module_exit(fuse_exit);

⌨️ 快捷键说明

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