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

📄 inode.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 4 页
字号:
	rpciod_down();		/* release rpciod */	destroy_nfsv4_state(server);	if (server->hostname != NULL)		kfree(server->hostname);	kfree(server);}static struct file_system_type nfs_fs_type = {	.owner		= THIS_MODULE,	.name		= "nfs",	.get_sb		= nfs_get_sb,	.kill_sb	= nfs_kill_super,	.fs_flags	= FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,};#ifdef CONFIG_NFS_V4static void nfs4_clear_inode(struct inode *);static struct super_operations nfs4_sops = { 	.alloc_inode	= nfs_alloc_inode,	.destroy_inode	= nfs_destroy_inode,	.write_inode	= nfs_write_inode,	.delete_inode	= nfs_delete_inode,	.statfs		= nfs_statfs,	.clear_inode	= nfs4_clear_inode,	.umount_begin	= nfs_umount_begin,	.show_options	= nfs_show_options,};/* * Clean out any remaining NFSv4 state that might be left over due * to open() calls that passed nfs_atomic_lookup, but failed to call * nfs_open(). */static void nfs4_clear_inode(struct inode *inode){	struct nfs_inode *nfsi = NFS_I(inode);	/* If we are holding a delegation, return it! */	if (nfsi->delegation != NULL)		nfs_inode_return_delegation(inode);	/* First call standard NFS clear_inode() code */	nfs_clear_inode(inode);	/* Now clear out any remaining state */	while (!list_empty(&nfsi->open_states)) {		struct nfs4_state *state;				state = list_entry(nfsi->open_states.next,				struct nfs4_state,				inode_states);		dprintk("%s(%s/%Ld): found unclaimed NFSv4 state %p\n",				__FUNCTION__,				inode->i_sb->s_id,				(long long)NFS_FILEID(inode),				state);		BUG_ON(atomic_read(&state->count) != 1);		nfs4_close_state(state, state->state);	}}static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, int silent){	struct nfs_server *server;	struct nfs4_client *clp = NULL;	struct rpc_xprt *xprt = NULL;	struct rpc_clnt *clnt = NULL;	struct rpc_timeout timeparms;	rpc_authflavor_t authflavour;	int proto, err = -EIO;	sb->s_blocksize_bits = 0;	sb->s_blocksize = 0;	server = NFS_SB(sb);	if (data->rsize != 0)		server->rsize = nfs_block_size(data->rsize, NULL);	if (data->wsize != 0)		server->wsize = nfs_block_size(data->wsize, NULL);	server->flags = data->flags & NFS_MOUNT_FLAGMASK;	/* NFSv4 doesn't use NLM locking */	server->flags |= NFS_MOUNT_NONLM;	server->acregmin = data->acregmin*HZ;	server->acregmax = data->acregmax*HZ;	server->acdirmin = data->acdirmin*HZ;	server->acdirmax = data->acdirmax*HZ;	server->rpc_ops = &nfs_v4_clientops;	/* Initialize timeout values */	timeparms.to_initval = data->timeo * HZ / 10;	timeparms.to_retries = data->retrans;	timeparms.to_exponential = 1;	if (!timeparms.to_retries)		timeparms.to_retries = 5;	proto = data->proto;	/* Which IP protocol do we use? */	switch (proto) {	case IPPROTO_TCP:		timeparms.to_maxval  = RPC_MAX_TCP_TIMEOUT;		if (!timeparms.to_initval)			timeparms.to_initval = 600 * HZ / 10;		break;	case IPPROTO_UDP:		timeparms.to_maxval  = RPC_MAX_UDP_TIMEOUT;		if (!timeparms.to_initval)			timeparms.to_initval = 11 * HZ / 10;		break;	default:		return -EINVAL;	}	clp = nfs4_get_client(&server->addr.sin_addr);	if (!clp) {		printk(KERN_WARNING "NFS: failed to create NFS4 client.\n");		return -EIO;	}	/* Now create transport and client */	authflavour = RPC_AUTH_UNIX;	if (data->auth_flavourlen != 0) {		if (data->auth_flavourlen > 1)			printk(KERN_INFO "NFS: cannot yet deal with multiple auth flavours.\n");		if (copy_from_user(&authflavour, data->auth_flavours, sizeof(authflavour))) {			err = -EFAULT;			goto out_fail;		}	}	down_write(&clp->cl_sem);	if (clp->cl_rpcclient == NULL) {		xprt = xprt_create_proto(proto, &server->addr, &timeparms);		if (IS_ERR(xprt)) {			up_write(&clp->cl_sem);			printk(KERN_WARNING "NFS: cannot create RPC transport.\n");			err = PTR_ERR(xprt);			goto out_fail;		}		clnt = rpc_create_client(xprt, server->hostname, &nfs_program,				server->rpc_ops->version, authflavour);		if (IS_ERR(clnt)) {			up_write(&clp->cl_sem);			printk(KERN_WARNING "NFS: cannot create RPC client.\n");			xprt_destroy(xprt);			err = PTR_ERR(clnt);			goto out_fail;		}		clnt->cl_chatty   = 1;		clp->cl_rpcclient = clnt;		clp->cl_cred = rpcauth_lookupcred(clnt->cl_auth, 0);		memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr));		nfs_idmap_new(clp);	}	if (list_empty(&clp->cl_superblocks)) {		err = nfs4_init_client(clp);		if (err != 0) {			up_write(&clp->cl_sem);			goto out_fail;		}	}	list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks);	clnt = rpc_clone_client(clp->cl_rpcclient);	if (!IS_ERR(clnt))			server->nfs4_state = clp;	up_write(&clp->cl_sem);	clp = NULL;	if (IS_ERR(clnt)) {		printk(KERN_WARNING "NFS: cannot create RPC client.\n");		return PTR_ERR(clnt);	}	clnt->cl_intr     = (server->flags & NFS4_MOUNT_INTR) ? 1 : 0;	clnt->cl_softrtry = (server->flags & NFS4_MOUNT_SOFT) ? 1 : 0;	server->client    = clnt;	if (server->nfs4_state->cl_idmap == NULL) {		printk(KERN_WARNING "NFS: failed to create idmapper.\n");		return -ENOMEM;	}	if (clnt->cl_auth->au_flavor != authflavour) {		if (rpcauth_create(authflavour, clnt) == NULL) {			printk(KERN_WARNING "NFS: couldn't create credcache!\n");			return -ENOMEM;		}	}	sb->s_op = &nfs4_sops;	err = nfs_sb_init(sb, authflavour);	if (err == 0)		return 0;out_fail:	if (clp)		nfs4_put_client(clp);	return err;}static int nfs4_compare_super(struct super_block *sb, void *data){	struct nfs_server *server = data;	struct nfs_server *old = NFS_SB(sb);	if (strcmp(server->hostname, old->hostname) != 0)		return 0;	if (strcmp(server->mnt_path, old->mnt_path) != 0)		return 0;	return 1;}static void *nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen){	void *p = NULL;	if (!src->len)		return ERR_PTR(-EINVAL);	if (src->len < maxlen)		maxlen = src->len;	if (dst == NULL) {		p = dst = kmalloc(maxlen + 1, GFP_KERNEL);		if (p == NULL)			return ERR_PTR(-ENOMEM);	}	if (copy_from_user(dst, src->data, maxlen)) {		if (p != NULL)			kfree(p);		return ERR_PTR(-EFAULT);	}	dst[maxlen] = '\0';	return dst;}static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,	int flags, const char *dev_name, void *raw_data){	int error;	struct nfs_server *server;	struct super_block *s;	struct nfs4_mount_data *data = raw_data;	void *p;	if (!data) {		printk("nfs_read_super: missing data argument\n");		return ERR_PTR(-EINVAL);	}	server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL);	if (!server)		return ERR_PTR(-ENOMEM);	memset(server, 0, sizeof(struct nfs_server));	/* Zero out the NFS state stuff */	init_nfsv4_state(server);	if (data->version != NFS4_MOUNT_VERSION) {		printk("nfs warning: mount version %s than kernel\n",			data->version < NFS4_MOUNT_VERSION ? "older" : "newer");	}	p = nfs_copy_user_string(NULL, &data->hostname, 256);	if (IS_ERR(p))		goto out_err;	server->hostname = p;	p = nfs_copy_user_string(NULL, &data->mnt_path, 1024);	if (IS_ERR(p))		goto out_err;	server->mnt_path = p;	p = nfs_copy_user_string(server->ip_addr, &data->client_addr,			sizeof(server->ip_addr) - 1);	if (IS_ERR(p))		goto out_err;	/* We now require that the mount process passes the remote address */	if (data->host_addrlen != sizeof(server->addr)) {		s = ERR_PTR(-EINVAL);		goto out_free;	}	if (copy_from_user(&server->addr, data->host_addr, sizeof(server->addr))) {		s = ERR_PTR(-EFAULT);		goto out_free;	}	if (server->addr.sin_family != AF_INET ||	    server->addr.sin_addr.s_addr == INADDR_ANY) {		printk("NFS: mount program didn't pass remote IP address!\n");		s = ERR_PTR(-EINVAL);		goto out_free;	}	s = sget(fs_type, nfs4_compare_super, nfs_set_super, server);	if (IS_ERR(s) || s->s_root)		goto out_free;	s->s_flags = flags;	/* Fire up rpciod if not yet running */	if (rpciod_up() != 0) {		printk(KERN_WARNING "NFS: couldn't start rpciod!\n");		s = ERR_PTR(-EIO);		goto out_free;	}	error = nfs4_fill_super(s, data, flags & MS_VERBOSE ? 1 : 0);	if (error) {		up_write(&s->s_umount);		deactivate_super(s);		return ERR_PTR(error);	}	s->s_flags |= MS_ACTIVE;	return s;out_err:	s = (struct super_block *)p;out_free:	if (server->mnt_path)		kfree(server->mnt_path);	if (server->hostname)		kfree(server->hostname);	kfree(server);	return s;}static void nfs4_kill_super(struct super_block *sb){	nfs_return_all_delegations(sb);	nfs_kill_super(sb);}static struct file_system_type nfs4_fs_type = {	.owner		= THIS_MODULE,	.name		= "nfs4",	.get_sb		= nfs4_get_sb,	.kill_sb	= nfs4_kill_super,	.fs_flags	= FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,};#define nfs4_init_once(nfsi) \	do { \		INIT_LIST_HEAD(&(nfsi)->open_states); \		nfsi->delegation = NULL; \		nfsi->delegation_state = 0; \		init_rwsem(&nfsi->rwsem); \	} while(0)#define register_nfs4fs() register_filesystem(&nfs4_fs_type)#define unregister_nfs4fs() unregister_filesystem(&nfs4_fs_type)#else#define nfs4_init_once(nfsi) \	do { } while (0)#define register_nfs4fs() (0)#define unregister_nfs4fs()#endifextern int nfs_init_nfspagecache(void);extern void nfs_destroy_nfspagecache(void);extern int nfs_init_readpagecache(void);extern int nfs_destroy_readpagecache(void);extern int nfs_init_writepagecache(void);extern int nfs_destroy_writepagecache(void);static kmem_cache_t * nfs_inode_cachep;static struct inode *nfs_alloc_inode(struct super_block *sb){	struct nfs_inode *nfsi;	nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, SLAB_KERNEL);	if (!nfsi)		return NULL;	nfsi->flags = 0;	return &nfsi->vfs_inode;}static void nfs_destroy_inode(struct inode *inode){	kmem_cache_free(nfs_inode_cachep, NFS_I(inode));}static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags){	struct nfs_inode *nfsi = (struct nfs_inode *) foo;	if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==	    SLAB_CTOR_CONSTRUCTOR) {		inode_init_once(&nfsi->vfs_inode);		spin_lock_init(&nfsi->req_lock);		INIT_LIST_HEAD(&nfsi->dirty);		INIT_LIST_HEAD(&nfsi->commit);		INIT_LIST_HEAD(&nfsi->open_files);		INIT_RADIX_TREE(&nfsi->nfs_page_tree, GFP_ATOMIC);		atomic_set(&nfsi->data_updates, 0);		nfsi->ndirty = 0;		nfsi->ncommit = 0;		nfsi->npages = 0;		init_waitqueue_head(&nfsi->nfs_i_wait);		nfs4_init_once(nfsi);	}} int nfs_init_inodecache(void){	nfs_inode_cachep = kmem_cache_create("nfs_inode_cache",					     sizeof(struct nfs_inode),					     0, SLAB_RECLAIM_ACCOUNT,					     init_once, NULL);	if (nfs_inode_cachep == NULL)		return -ENOMEM;	return 0;}void nfs_destroy_inodecache(void){	if (kmem_cache_destroy(nfs_inode_cachep))		printk(KERN_INFO "nfs_inode_cache: not all structures were freed\n");}/* * Initialize NFS */static int __init init_nfs_fs(void){	int err;	err = nfs_init_nfspagecache();	if (err)		goto out4;	err = nfs_init_inodecache();	if (err)		goto out3;	err = nfs_init_readpagecache();	if (err)		goto out2;	err = nfs_init_writepagecache();	if (err)		goto out1;#ifdef CONFIG_PROC_FS	rpc_proc_register(&nfs_rpcstat);#endif        err = register_filesystem(&nfs_fs_type);	if (err)		goto out;	if ((err = register_nfs4fs()) != 0)		goto out;	return 0;out:	rpc_proc_unregister("nfs");	nfs_destroy_writepagecache();out1:	nfs_destroy_readpagecache();out2:	nfs_destroy_inodecache();out3:	nfs_destroy_nfspagecache();out4:	return err;}static void __exit exit_nfs_fs(void){	nfs_destroy_writepagecache();	nfs_destroy_readpagecache();	nfs_destroy_inodecache();	nfs_destroy_nfspagecache();#ifdef CONFIG_PROC_FS	rpc_proc_unregister("nfs");#endif	unregister_filesystem(&nfs_fs_type);	unregister_nfs4fs();}/* Not quite true; I just maintain it */MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>");MODULE_LICENSE("GPL");module_init(init_nfs_fs)module_exit(exit_nfs_fs)

⌨️ 快捷键说明

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