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

📄 inode.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		error = -ENOTSOCK;		sock_inode = server->info_filp->f_path.dentry->d_inode;		if (!S_ISSOCK(sock_inode->i_mode))			goto out_fput2;		info_sock = SOCKET_I(sock_inode);		if (!info_sock)			goto out_fput2;		error = -EBADFD;		if (info_sock->type != SOCK_STREAM)			goto out_fput2;		server->info_sock = info_sock;	}/*	server->lock = 0;	*/	mutex_init(&server->mutex);	server->packet = NULL;/*	server->buffer_size = 0;	*//*	server->conn_status = 0;	*//*	server->root_dentry = NULL;	*//*	server->root_setuped = 0;	*/#ifdef CONFIG_NCPFS_PACKET_SIGNING/*	server->sign_wanted = 0;	*//*	server->sign_active = 0;	*/#endif	server->auth.auth_type = NCP_AUTH_NONE;/*	server->auth.object_name_len = 0;	*//*	server->auth.object_name = NULL;	*//*	server->auth.object_type = 0;		*//*	server->priv.len = 0;			*//*	server->priv.data = NULL;		*/	server->m = data;	/* Althought anything producing this is buggy, it happens	   now because of PATH_MAX changes.. */	if (server->m.time_out < 1) {		server->m.time_out = 10;		printk(KERN_INFO "You need to recompile your ncpfs utils..\n");	}	server->m.time_out = server->m.time_out * HZ / 100;	server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;	server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;#ifdef CONFIG_NCPFS_NLS	/* load the default NLS charsets */	server->nls_vol = load_nls_default();	server->nls_io = load_nls_default();#endif /* CONFIG_NCPFS_NLS */	server->dentry_ttl = 0;	/* no caching */	INIT_LIST_HEAD(&server->tx.requests);	mutex_init(&server->rcv.creq_mutex);	server->tx.creq		= NULL;	server->rcv.creq	= NULL;	server->data_ready	= sock->sk->sk_data_ready;	server->write_space	= sock->sk->sk_write_space;	server->error_report	= sock->sk->sk_error_report;	sock->sk->sk_user_data	= server;	init_timer(&server->timeout_tm);#undef NCP_PACKET_SIZE#define NCP_PACKET_SIZE 131072	error = -ENOMEM;	server->packet_size = NCP_PACKET_SIZE;	server->packet = vmalloc(NCP_PACKET_SIZE);	if (server->packet == NULL)		goto out_nls;	server->txbuf = vmalloc(NCP_PACKET_SIZE);	if (server->txbuf == NULL)		goto out_packet;	server->rxbuf = vmalloc(NCP_PACKET_SIZE);	if (server->rxbuf == NULL)		goto out_txbuf;	sock->sk->sk_data_ready	  = ncp_tcp_data_ready;	sock->sk->sk_error_report = ncp_tcp_error_report;	if (sock->type == SOCK_STREAM) {		server->rcv.ptr = (unsigned char*)&server->rcv.buf;		server->rcv.len = 10;		server->rcv.state = 0;		INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);		INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);		sock->sk->sk_write_space = ncp_tcp_write_space;	} else {		INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);		INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);		server->timeout_tm.data = (unsigned long)server;		server->timeout_tm.function = ncpdgram_timeout_call;	}	ncp_lock_server(server);	error = ncp_connect(server);	ncp_unlock_server(server);	if (error < 0)		goto out_rxbuf;	DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));	error = -EMSGSIZE;	/* -EREMOTESIDEINCOMPATIBLE */#ifdef CONFIG_NCPFS_PACKET_SIGNING	if (ncp_negotiate_size_and_options(server, default_bufsize,		NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)	{		if (options != NCP_DEFAULT_OPTIONS)		{			if (ncp_negotiate_size_and_options(server, 				default_bufsize,				options & 2, 				&(server->buffer_size), &options) != 0)							{				goto out_disconnect;			}		}		if (options & 2)			server->sign_wanted = 1;	}	else #endif	/* CONFIG_NCPFS_PACKET_SIGNING */	if (ncp_negotiate_buffersize(server, default_bufsize,  				     &(server->buffer_size)) != 0)		goto out_disconnect;	DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);	memset(&finfo, 0, sizeof(finfo));	finfo.i.attributes	= aDIR;	finfo.i.dataStreamSize	= 0;	/* ignored */	finfo.i.dirEntNum	= 0;	finfo.i.DosDirNum	= 0;#ifdef CONFIG_NCPFS_SMALLDOS	finfo.i.NSCreator	= NW_NS_DOS;#endif	finfo.volume		= NCP_NUMBER_OF_VOLUMES;	/* set dates of mountpoint to Jan 1, 1986; 00:00 */	finfo.i.creationTime	= finfo.i.modifyTime				= cpu_to_le16(0x0000);	finfo.i.creationDate	= finfo.i.modifyDate				= finfo.i.lastAccessDate				= cpu_to_le16(0x0C21);	finfo.i.nameLen		= 0;	finfo.i.entryName[0]	= '\0';	finfo.opened		= 0;	finfo.ino		= 2;	/* tradition */	server->name_space[finfo.volume] = NW_NS_DOS;	error = -ENOMEM;        root_inode = ncp_iget(sb, &finfo);        if (!root_inode)		goto out_disconnect;	DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);	sb->s_root = d_alloc_root(root_inode);        if (!sb->s_root)		goto out_no_root;	sb->s_root->d_op = &ncp_root_dentry_operations;	return 0;out_no_root:	iput(root_inode);out_disconnect:	ncp_lock_server(server);	ncp_disconnect(server);	ncp_unlock_server(server);out_rxbuf:	ncp_stop_tasks(server);	vfree(server->rxbuf);out_txbuf:	vfree(server->txbuf);out_packet:	vfree(server->packet);out_nls:#ifdef CONFIG_NCPFS_NLS	unload_nls(server->nls_io);	unload_nls(server->nls_vol);#endifout_fput2:	if (server->info_filp)		fput(server->info_filp);out_fput:	/* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:	 * 	 * The previously used put_filp(ncp_filp); was bogous, since	 * it doesn't proper unlocking.	 */	fput(ncp_filp);out:	put_pid(data.wdog_pid);	sb->s_fs_info = NULL;	kfree(server);	return error;}static void ncp_put_super(struct super_block *sb){	struct ncp_server *server = NCP_SBP(sb);	ncp_lock_server(server);	ncp_disconnect(server);	ncp_unlock_server(server);	ncp_stop_tasks(server);#ifdef CONFIG_NCPFS_NLS	/* unload the NLS charsets */	if (server->nls_vol)	{		unload_nls(server->nls_vol);		server->nls_vol = NULL;	}	if (server->nls_io)	{		unload_nls(server->nls_io);		server->nls_io = NULL;	}#endif /* CONFIG_NCPFS_NLS */	if (server->info_filp)		fput(server->info_filp);	fput(server->ncp_filp);	kill_pid(server->m.wdog_pid, SIGTERM, 1);	put_pid(server->m.wdog_pid);	kfree(server->priv.data);	kfree(server->auth.object_name);	vfree(server->rxbuf);	vfree(server->txbuf);	vfree(server->packet);	sb->s_fs_info = NULL;	kfree(server);}static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf){	struct dentry* d;	struct inode* i;	struct ncp_inode_info* ni;	struct ncp_server* s;	struct ncp_volume_info vi;	struct super_block *sb = dentry->d_sb;	int err;	__u8 dh;		d = sb->s_root;	if (!d) {		goto dflt;	}	i = d->d_inode;	if (!i) {		goto dflt;	}	ni = NCP_FINFO(i);	if (!ni) {		goto dflt;	}	s = NCP_SBP(sb);	if (!s) {		goto dflt;	}	if (!s->m.mounted_vol[0]) {		goto dflt;	}	err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);	if (err) {		goto dflt;	}	err = ncp_get_directory_info(s, dh, &vi);	ncp_dirhandle_free(s, dh);	if (err) {		goto dflt;	}	buf->f_type = NCP_SUPER_MAGIC;	buf->f_bsize = vi.sectors_per_block * 512;	buf->f_blocks = vi.total_blocks;	buf->f_bfree = vi.free_blocks;	buf->f_bavail = vi.free_blocks;	buf->f_files = vi.total_dir_entries;	buf->f_ffree = vi.available_dir_entries;	buf->f_namelen = 12;	return 0;	/* We cannot say how much disk space is left on a mounted	   NetWare Server, because free space is distributed over	   volumes, and the current user might have disk quotas. So	   free space is not that simple to determine. Our decision	   here is to err conservatively. */dflt:;	buf->f_type = NCP_SUPER_MAGIC;	buf->f_bsize = NCP_BLOCK_SIZE;	buf->f_blocks = 0;	buf->f_bfree = 0;	buf->f_bavail = 0;	buf->f_namelen = 12;	return 0;}int ncp_notify_change(struct dentry *dentry, struct iattr *attr){	struct inode *inode = dentry->d_inode;	int result = 0;	__le32 info_mask;	struct nw_modify_dos_info info;	struct ncp_server *server;	result = -EIO;	lock_kernel();		server = NCP_SERVER(inode);	if ((!server) || !ncp_conn_valid(server))		goto out;	/* ageing the dentry to force validation */	ncp_age_dentry(server, dentry);	result = inode_change_ok(inode, attr);	if (result < 0)		goto out;	result = -EPERM;	if (((attr->ia_valid & ATTR_UID) &&	     (attr->ia_uid != server->m.uid)))		goto out;	if (((attr->ia_valid & ATTR_GID) &&	     (attr->ia_gid != server->m.gid)))		goto out;	if (((attr->ia_valid & ATTR_MODE) &&	     (attr->ia_mode &	      ~(S_IFREG | S_IFDIR | S_IRWXUGO))))		goto out;	info_mask = 0;	memset(&info, 0, sizeof(info));#if 1         if ((attr->ia_valid & ATTR_MODE) != 0)        {		umode_t newmode = attr->ia_mode;		info_mask |= DM_ATTRIBUTES;                if (S_ISDIR(inode->i_mode)) {                	newmode &= server->m.dir_mode;		} else {#ifdef CONFIG_NCPFS_EXTRAS						if (server->m.flags & NCP_MOUNT_EXTRAS) {				/* any non-default execute bit set */				if (newmode & ~server->m.file_mode & S_IXUGO)					info.attributes |= aSHARED | aSYSTEM;				/* read for group/world and not in default file_mode */				else if (newmode & ~server->m.file_mode & S_IRUGO)					info.attributes |= aSHARED;			} else#endif				newmode &= server->m.file_mode;			                }                if (newmode & S_IWUGO)                	info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);                else			info.attributes |=  (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);#ifdef CONFIG_NCPFS_NFS_NS		if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {			result = ncp_modify_nfs_info(server,						     NCP_FINFO(inode)->volNumber,						     NCP_FINFO(inode)->dirEntNum,						     attr->ia_mode, 0);			if (result != 0)				goto out;			info.attributes &= ~(aSHARED | aSYSTEM);			{				/* mark partial success */				struct iattr tmpattr;								tmpattr.ia_valid = ATTR_MODE;				tmpattr.ia_mode = attr->ia_mode;				result = inode_setattr(inode, &tmpattr);				if (result)					goto out;			}		}#endif        }#endif	/* Do SIZE before attributes, otherwise mtime together with size does not work...	 */	if ((attr->ia_valid & ATTR_SIZE) != 0) {		int written;		DPRINTK("ncpfs: trying to change size to %ld\n",			attr->ia_size);		if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {			result = -EACCES;			goto out;		}		ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,			  attr->ia_size, 0, "", &written);		/* According to ndir, the changes only take effect after		   closing the file */		ncp_inode_close(inode);		result = ncp_make_closed(inode);		if (result)			goto out;		{			struct iattr tmpattr;						tmpattr.ia_valid = ATTR_SIZE;			tmpattr.ia_size = attr->ia_size;						result = inode_setattr(inode, &tmpattr);			if (result)				goto out;		}	}	if ((attr->ia_valid & ATTR_CTIME) != 0) {		info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);		ncp_date_unix2dos(attr->ia_ctime.tv_sec,			     &info.creationTime, &info.creationDate);	}	if ((attr->ia_valid & ATTR_MTIME) != 0) {		info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);		ncp_date_unix2dos(attr->ia_mtime.tv_sec,				  &info.modifyTime, &info.modifyDate);	}	if ((attr->ia_valid & ATTR_ATIME) != 0) {		__le16 dummy;		info_mask |= (DM_LAST_ACCESS_DATE);		ncp_date_unix2dos(attr->ia_atime.tv_sec,				  &dummy, &info.lastAccessDate);	}	if (info_mask != 0) {		result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),				      inode, info_mask, &info);		if (result != 0) {			result = -EACCES;			if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {				/* NetWare seems not to allow this. I				   do not know why. So, just tell the				   user everything went fine. This is				   a terrible hack, but I do not know				   how to do this correctly. */				result = 0;			} else				goto out;		}#ifdef CONFIG_NCPFS_STRONG				if ((!result) && (info_mask & DM_ATTRIBUTES))			NCP_FINFO(inode)->nwattr = info.attributes;#endif	}	if (!result)		result = inode_setattr(inode, attr);out:	unlock_kernel();	return result;}static int ncp_get_sb(struct file_system_type *fs_type,	int flags, const char *dev_name, void *data, struct vfsmount *mnt){	return get_sb_nodev(fs_type, flags, data, ncp_fill_super, mnt);}static struct file_system_type ncp_fs_type = {	.owner		= THIS_MODULE,	.name		= "ncpfs",	.get_sb		= ncp_get_sb,	.kill_sb	= kill_anon_super,};static int __init init_ncp_fs(void){	int err;	DPRINTK("ncpfs: init_module called\n");	err = init_inodecache();	if (err)		goto out1;	err = register_filesystem(&ncp_fs_type);	if (err)		goto out;	return 0;out:	destroy_inodecache();out1:	return err;}static void __exit exit_ncp_fs(void){	DPRINTK("ncpfs: cleanup_module called\n");	unregister_filesystem(&ncp_fs_type);	destroy_inodecache();}module_init(init_ncp_fs)module_exit(exit_ncp_fs)MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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