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

📄 cifsfs.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 2 页
字号:
	cFYI(1, ("Devname: %s flags: %d ", dev_name, flags));	if (IS_ERR(sb))		return sb;	sb->s_flags = flags;	rc = cifs_read_super(sb, data, dev_name, flags & MS_VERBOSE ? 1 : 0);	if (rc) {		up_write(&sb->s_umount);		deactivate_super(sb);		return ERR_PTR(rc);	}	sb->s_flags |= MS_ACTIVE;	return sb;}static ssize_tcifs_read_wrapper(struct file * file, char __user *read_data, size_t read_size,          loff_t * poffset){	if(file == NULL)		return -EIO;	else if(file->f_dentry == NULL)		return -EIO;	else if(file->f_dentry->d_inode == NULL)		return -EIO;	cFYI(1,("In read_wrapper size %zd at %lld",read_size,*poffset));	if(CIFS_I(file->f_dentry->d_inode)->clientCanCacheRead) {		return generic_file_read(file,read_data,read_size,poffset);	} else {		/* BB do we need to lock inode from here until after invalidate? *//*		if(file->f_dentry->d_inode->i_mapping) {			filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);			filemap_fdatawait(file->f_dentry->d_inode->i_mapping);		}*//*		cifs_revalidate(file->f_dentry);*/ /* BB fixme */		/* BB we should make timer configurable - perhaps 		   by simply calling cifs_revalidate here */		/* invalidate_remote_inode(file->f_dentry->d_inode);*/		return generic_file_read(file,read_data,read_size,poffset);	}}static ssize_tcifs_write_wrapper(struct file * file, const char __user *write_data,           size_t write_size, loff_t * poffset) {	ssize_t written;	if(file == NULL)		return -EIO;	else if(file->f_dentry == NULL)		return -EIO;	else if(file->f_dentry->d_inode == NULL)		return -EIO;	cFYI(1,("In write_wrapper size %zd at %lld",write_size,*poffset));	/* check whether we can cache writes locally */	written = generic_file_write(file,write_data,write_size,poffset);	if(!CIFS_I(file->f_dentry->d_inode)->clientCanCacheAll)  {		if(file->f_dentry->d_inode->i_mapping) {			filemap_fdatawrite(file->f_dentry->d_inode->i_mapping);		}	}	return written;}static struct file_system_type cifs_fs_type = {	.owner = THIS_MODULE,	.name = "cifs",	.get_sb = cifs_get_sb,	.kill_sb = kill_anon_super,	/*  .fs_flags */};struct inode_operations cifs_dir_inode_ops = {	.create = cifs_create,	.lookup = cifs_lookup,	.getattr = cifs_getattr,	.unlink = cifs_unlink,	.link = cifs_hardlink,	.mkdir = cifs_mkdir,	.rmdir = cifs_rmdir,	.rename = cifs_rename,	.permission = cifs_permission,/*	revalidate:cifs_revalidate,   */	.setattr = cifs_setattr,	.symlink = cifs_symlink,	.mknod   = cifs_mknod,};struct inode_operations cifs_file_inode_ops = {/*	revalidate:cifs_revalidate, */	.setattr = cifs_setattr,	.getattr = cifs_getattr, /* do we need this anymore? */	.rename = cifs_rename,	.permission = cifs_permission,#ifdef CONFIG_CIFS_XATTR	.setxattr = cifs_setxattr,	.getxattr = cifs_getxattr,	.listxattr = cifs_listxattr,	.removexattr = cifs_removexattr,#endif };struct inode_operations cifs_symlink_inode_ops = {	.readlink = generic_readlink, 	.follow_link = cifs_follow_link,	.put_link = cifs_put_link,	.permission = cifs_permission,	/* BB add the following two eventually */	/* revalidate: cifs_revalidate,	   setattr:    cifs_notify_change, *//* BB do we need notify change */#ifdef CONFIG_CIFS_XATTR	.setxattr = cifs_setxattr,	.getxattr = cifs_getxattr,	.listxattr = cifs_listxattr,	.removexattr = cifs_removexattr,#endif };struct file_operations cifs_file_ops = {	.read = cifs_read_wrapper,	.write = cifs_write_wrapper, 	.open = cifs_open,	.release = cifs_close,	.lock = cifs_lock,	.fsync = cifs_fsync,	.flush = cifs_flush,	.mmap  = cifs_file_mmap,	.sendfile = generic_file_sendfile,	.dir_notify = cifs_dir_notify,};struct file_operations cifs_dir_ops = {	.readdir = cifs_readdir,	.release = cifs_closedir,	.read    = generic_read_dir,	.dir_notify = cifs_dir_notify,};static voidcifs_init_once(void *inode, kmem_cache_t * cachep, unsigned long flags){	struct cifsInodeInfo *cifsi = (struct cifsInodeInfo *) inode;	if ((flags & (SLAB_CTOR_VERIFY | SLAB_CTOR_CONSTRUCTOR)) ==	    SLAB_CTOR_CONSTRUCTOR) {		inode_init_once(&cifsi->vfs_inode);		INIT_LIST_HEAD(&cifsi->lockList);	}}static intcifs_init_inodecache(void){	cifs_inode_cachep = kmem_cache_create("cifs_inode_cache",					      sizeof (struct cifsInodeInfo),					      0, SLAB_RECLAIM_ACCOUNT,					      cifs_init_once, NULL);	if (cifs_inode_cachep == NULL)		return -ENOMEM;	return 0;}static voidcifs_destroy_inodecache(void){	if (kmem_cache_destroy(cifs_inode_cachep))		printk(KERN_WARNING "cifs_inode_cache: error freeing\n");}static intcifs_init_request_bufs(void){	cifs_req_cachep = kmem_cache_create("cifs_request",					    CIFS_MAX_MSGSIZE +					    MAX_CIFS_HDR_SIZE, 0,					    SLAB_HWCACHE_ALIGN, NULL, NULL);	if (cifs_req_cachep == NULL)		return -ENOMEM;	cifs_req_poolp = mempool_create(CIFS_MIN_RCV_POOL,					mempool_alloc_slab,					mempool_free_slab,					cifs_req_cachep);	if(cifs_req_poolp == NULL) {		kmem_cache_destroy(cifs_req_cachep);		return -ENOMEM;	}	return 0;}static voidcifs_destroy_request_bufs(void){	mempool_destroy(cifs_req_poolp);	if (kmem_cache_destroy(cifs_req_cachep))		printk(KERN_WARNING		       "cifs_destroy_request_cache: error not all structures were freed\n");}static intcifs_init_mids(void){	cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids",				sizeof (struct mid_q_entry), 0,				SLAB_HWCACHE_ALIGN, NULL, NULL);	if (cifs_mid_cachep == NULL)		return -ENOMEM;	cifs_mid_poolp = mempool_create(3 /* a reasonable min simultan opers */,					mempool_alloc_slab,					mempool_free_slab,					cifs_mid_cachep);	if(cifs_mid_poolp == NULL) {		kmem_cache_destroy(cifs_mid_cachep);		return -ENOMEM;	}	cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs",				sizeof (struct oplock_q_entry), 0,				SLAB_HWCACHE_ALIGN, NULL, NULL);	if (cifs_oplock_cachep == NULL) {		kmem_cache_destroy(cifs_mid_cachep);		mempool_destroy(cifs_mid_poolp);		return -ENOMEM;	}	return 0;}static voidcifs_destroy_mids(void){	mempool_destroy(cifs_mid_poolp);	if (kmem_cache_destroy(cifs_mid_cachep))		printk(KERN_WARNING		       "cifs_destroy_mids: error not all structures were freed\n");	if (kmem_cache_destroy(cifs_oplock_cachep))		printk(KERN_WARNING		       "error not all oplock structures were freed\n");}static int cifs_oplock_thread(void * dummyarg){	struct oplock_q_entry * oplock_item;	struct cifsTconInfo *pTcon;	struct inode * inode;	__u16  netfid;	int rc;	daemonize("cifsoplockd");	allow_signal(SIGTERM);	oplockThread = current;	do {		set_current_state(TASK_INTERRUPTIBLE);				schedule_timeout(1*HZ);  		spin_lock(&GlobalMid_Lock);		if(list_empty(&GlobalOplock_Q)) {			spin_unlock(&GlobalMid_Lock);			set_current_state(TASK_INTERRUPTIBLE);			schedule_timeout(39*HZ);		} else {			oplock_item = list_entry(GlobalOplock_Q.next, 				struct oplock_q_entry, qhead);			if(oplock_item) {				cFYI(1,("found oplock item to write out")); 				pTcon = oplock_item->tcon;				inode = oplock_item->pinode;				netfid = oplock_item->netfid;				spin_unlock(&GlobalMid_Lock);				DeleteOplockQEntry(oplock_item);				/* can not grab inode sem here since it would				deadlock when oplock received on delete 				since vfs_unlink holds the i_sem across				the call */				/* down(&inode->i_sem);*/				if (S_ISREG(inode->i_mode)) {					rc = filemap_fdatawrite(inode->i_mapping);					if(CIFS_I(inode)->clientCanCacheRead == 0) {						filemap_fdatawait(inode->i_mapping);						invalidate_remote_inode(inode);					}				} else					rc = 0;				/* up(&inode->i_sem);*/				if (rc)					CIFS_I(inode)->write_behind_rc = rc;				cFYI(1,("Oplock flush inode %p rc %d",inode,rc));				/* releasing a stale oplock after recent reconnection 				of smb session using a now incorrect file 				handle is not a data integrity issue but do  				not bother sending an oplock release if session 				to server still is disconnected since oplock 				already released by the server in that case */				if(pTcon->tidStatus != CifsNeedReconnect) {				    rc = CIFSSMBLock(0, pTcon, netfid,					    0 /* len */ , 0 /* offset */, 0, 					    0, LOCKING_ANDX_OPLOCK_RELEASE,					    0 /* wait flag */);					cFYI(1,("Oplock release rc = %d ",rc));				}			} else				spin_unlock(&GlobalMid_Lock);		}	} while(!signal_pending(current));	complete_and_exit (&cifs_oplock_exited, 0);}static int __initinit_cifs(void){	int rc = 0;#ifdef CONFIG_PROC_FS	cifs_proc_init();#endif	INIT_LIST_HEAD(&GlobalServerList);	/* BB not implemented yet */	INIT_LIST_HEAD(&GlobalSMBSessionList);	INIT_LIST_HEAD(&GlobalTreeConnectionList);	INIT_LIST_HEAD(&GlobalOplock_Q);/* *  Initialize Global counters */	atomic_set(&sesInfoAllocCount, 0);	atomic_set(&tconInfoAllocCount, 0);	atomic_set(&tcpSesAllocCount,0);	atomic_set(&tcpSesReconnectCount, 0);	atomic_set(&tconInfoReconnectCount, 0);	atomic_set(&bufAllocCount, 0);	atomic_set(&midCount, 0);	GlobalCurrentXid = 0;	GlobalTotalActiveXid = 0;	GlobalMaxActiveXid = 0;	GlobalSMBSeslock = RW_LOCK_UNLOCKED;	GlobalMid_Lock = SPIN_LOCK_UNLOCKED;	rc = cifs_init_inodecache();	if (!rc) {		rc = cifs_init_mids();		if (!rc) {			rc = cifs_init_request_bufs();			if (!rc) {				rc = register_filesystem(&cifs_fs_type);				if (!rc) {                					rc = (int)kernel_thread(cifs_oplock_thread, NULL, 						CLONE_FS | CLONE_FILES | CLONE_VM);					if(rc > 0)						return 0;					else 						cERROR(1,("error %d create oplock thread",rc));				}				cifs_destroy_request_bufs();			}			cifs_destroy_mids();		}		cifs_destroy_inodecache();	}#ifdef CONFIG_PROC_FS	cifs_proc_clean();#endif	return rc;}static void __exitexit_cifs(void){	cFYI(0, ("In unregister ie exit_cifs"));#ifdef CONFIG_PROC_FS	cifs_proc_clean();#endif	unregister_filesystem(&cifs_fs_type);	cifs_destroy_inodecache();	cifs_destroy_mids();	cifs_destroy_request_bufs();	if(oplockThread) {		send_sig(SIGTERM, oplockThread, 1);		wait_for_completion(&cifs_oplock_exited);	}}MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");MODULE_LICENSE("GPL");		/* combination of LGPL + GPL source behaves as GPL */MODULE_DESCRIPTION    ("VFS to access servers complying with the SNIA CIFS Specification e.g. Samba and Windows");MODULE_VERSION(CIFS_VERSION);module_init(init_cifs)module_exit(exit_cifs)

⌨️ 快捷键说明

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