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

📄 file.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
		rc = CIFSFindFirst(xid, pTcon, full_path, pfindData,				&findParms, cifs_sb->local_nls,				&Unicode, &UnixSearch);		cFYI(1, ("Count: %d  End: %d ",			le16_to_cpu(findParms.SearchCount),			le16_to_cpu(findParms.EndofSearch))); 		if (rc == 0) {			__u16 count = le16_to_cpu(findParms.SearchCount);			searchHandle = findParms.SearchHandle;			if(file->private_data == NULL)				file->private_data =					kmalloc(sizeof(struct cifsFileInfo),GFP_KERNEL);			if (file->private_data) {				memset(file->private_data, 0,				       sizeof (struct cifsFileInfo));				cifsFile =				    (struct cifsFileInfo *) file->private_data;				cifsFile->netfid = searchHandle;				cifsFile->invalidHandle = FALSE;				init_MUTEX(&cifsFile->fh_sem);			} else {				rc = -ENOMEM;				break;			}			renew_parental_timestamps(file->f_dentry);			lastFindData = 				(FILE_DIRECTORY_INFO *) ((char *) pfindData + 					le16_to_cpu(findParms.LastNameOffset));			if((char *)lastFindData > (char *)pfindData + bufsize) {				cFYI(1,("last search entry past end of packet"));				rc = -EIO;				break;			}			/* Offset of resume key same for levels 257 and 514 */			cifsFile->resume_key = lastFindData->FileIndex;			if(UnixSearch == FALSE) {				cifsFile->resume_name_length = 					le32_to_cpu(lastFindData->FileNameLength);				if(cifsFile->resume_name_length > bufsize - 64) {					cFYI(1,("Illegal resume file name length %d",						cifsFile->resume_name_length));					rc = -ENOMEM;					break;				}				cifsFile->search_resume_name = 					kmalloc(cifsFile->resume_name_length, GFP_KERNEL);				cFYI(1,("Last file: %s with name %d bytes long",					lastFindData->FileName,					cifsFile->resume_name_length));				if(cifsFile->search_resume_name == NULL) {					rc = -ENOMEM;					break;				}				memcpy(cifsFile->search_resume_name,					lastFindData->FileName, 					cifsFile->resume_name_length);			} else {				pfindDataUnix = (FILE_UNIX_INFO *)lastFindData;				if (Unicode == TRUE) {					for(i=0;(pfindDataUnix->FileName[i] 						    | pfindDataUnix->FileName[i+1]);						i+=2) {						if(i > bufsize-64)							break;					}					cifsFile->resume_name_length = i + 2;				} else {					cifsFile->resume_name_length = 						strnlen(pfindDataUnix->FileName,							bufsize-63);				}				if(cifsFile->resume_name_length > bufsize - 64) {					cFYI(1,("Illegal resume file name length %d",						cifsFile->resume_name_length));					rc = -ENOMEM;					break;				}				cifsFile->search_resume_name = 					kmalloc(cifsFile->resume_name_length, GFP_KERNEL);				cFYI(1,("Last file: %s with name %d bytes long",					pfindDataUnix->FileName,					cifsFile->resume_name_length));				if(cifsFile->search_resume_name == NULL) {					rc = -ENOMEM;					break;				}				memcpy(cifsFile->search_resume_name,					pfindDataUnix->FileName, 					cifsFile->resume_name_length);			}			for (i = 2; i < count + 2; i++) {				if (UnixSearch == FALSE) {					__u32 len = le32_to_cpu(pfindData->FileNameLength);					if (Unicode == TRUE)						len =						    cifs_strfromUCS_le						    (pfindData->FileName,						     (wchar_t *)						     pfindData->FileName,						     len / 2,						     cifs_sb->local_nls);					qstring.len = len;					if (((len != 1)					     || (pfindData->FileName[0] != '.'))					    && ((len != 2)						|| (pfindData->						    FileName[0] != '.')						|| (pfindData->						    FileName[1] != '.'))) {						if(cifs_filldir(&qstring,							     pfindData,							     file, filldir,							     direntry)) {							/* do not end search if								kernel not ready to take								remaining entries yet */							reset_resume_key(file, pfindData->FileName,qstring.len,								Unicode, cifs_sb->local_nls);							findParms.EndofSearch = 0;							break;						}						file->f_pos++;					}				} else {	/* UnixSearch */					pfindDataUnix =					    (FILE_UNIX_INFO *) pfindData;					if (Unicode == TRUE)						qstring.len =							cifs_strfromUCS_le							(pfindDataUnix->FileName,							(wchar_t *)							pfindDataUnix->FileName,							MAX_PATHCONF,							cifs_sb->local_nls);					else						qstring.len =							strnlen(pfindDataUnix->							  FileName,							  MAX_PATHCONF);					if (((qstring.len != 1)					     || (pfindDataUnix->						 FileName[0] != '.'))					    && ((qstring.len != 2)						|| (pfindDataUnix->						    FileName[0] != '.')						|| (pfindDataUnix->						    FileName[1] != '.'))) {						if(cifs_filldir_unix(&qstring,								  pfindDataUnix,								  file,								  filldir,								  direntry)) {							/* do not end search if								kernel not ready to take								remaining entries yet */							findParms.EndofSearch = 0;							reset_resume_key(file, pfindDataUnix->FileName,								qstring.len,Unicode,cifs_sb->local_nls);							break;						}						file->f_pos++;					}				}				/* works also for Unix ff struct since first field of both */				pfindData = 					(FILE_DIRECTORY_INFO *) ((char *) pfindData						 + le32_to_cpu(pfindData->NextEntryOffset));				/* BB also should check to make sure that pointer is not beyond the end of the SMB */				/* if(pfindData > lastFindData) rc = -EIO; break; */			}	/* end for loop */			if ((findParms.EndofSearch != 0) && cifsFile) {				cifsFile->endOfSearch = TRUE;				if(findParms.SearchCount == cpu_to_le16(2))					cifsFile->emptyDir = TRUE;			}		} else {			if (cifsFile)				cifsFile->endOfSearch = TRUE;			/* unless parent directory gone do not return error */			rc = 0;		}		break;	default:		if (file->private_data == NULL) {			rc = -EBADF;			cFYI(1,			     ("Readdir on closed srch, pos = %lld",			      file->f_pos));		} else {			cifsFile = (struct cifsFileInfo *) file->private_data;			if (cifsFile->endOfSearch) {				rc = 0;				cFYI(1, ("End of search "));				break;			}			searchHandle = cifsFile->netfid;			rc = CIFSFindNext(xid, pTcon, pfindData,				&findNextParms, searchHandle, 				cifsFile->search_resume_name,				cifsFile->resume_name_length,				cifsFile->resume_key,				&Unicode, &UnixSearch);			cFYI(1,("Count: %d  End: %d ",			      le16_to_cpu(findNextParms.SearchCount),			      le16_to_cpu(findNextParms.EndofSearch)));			if ((rc == 0) && (findNextParms.SearchCount != 0)) {			/* BB save off resume key, key name and name length  */				__u16 count = le16_to_cpu(findNextParms.SearchCount);				lastFindData = 					(FILE_DIRECTORY_INFO *) ((char *) pfindData 					+ le16_to_cpu(findNextParms.LastNameOffset));				if((char *)lastFindData > (char *)pfindData + bufsize) {					cFYI(1,("last search entry past end of packet"));					rc = -EIO;					break;				}				/* Offset of resume key same for levels 257 and 514 */				cifsFile->resume_key = lastFindData->FileIndex;				if(UnixSearch == FALSE) {					cifsFile->resume_name_length = 						le32_to_cpu(lastFindData->FileNameLength);					if(cifsFile->resume_name_length > bufsize - 64) {						cFYI(1,("Illegal resume file name length %d",							cifsFile->resume_name_length));						rc = -ENOMEM;						break;					}					/* Free the memory allocated by previous findfirst 					or findnext call - we can not reuse the memory since					the resume name may not be same string length */					if(cifsFile->search_resume_name)						kfree(cifsFile->search_resume_name);					cifsFile->search_resume_name = 						kmalloc(cifsFile->resume_name_length, GFP_KERNEL);					cFYI(1,("Last file: %s with name %d bytes long",						lastFindData->FileName,						cifsFile->resume_name_length));					if(cifsFile->search_resume_name == NULL) {						rc = -ENOMEM;						break;					}										memcpy(cifsFile->search_resume_name,						lastFindData->FileName, 						cifsFile->resume_name_length);				} else {					pfindDataUnix = (FILE_UNIX_INFO *)lastFindData;					if (Unicode == TRUE) {						for(i=0;(pfindDataUnix->FileName[i] 								| pfindDataUnix->FileName[i+1]);							i+=2) {							if(i > bufsize-64)								break;						}						cifsFile->resume_name_length = i + 2;					} else {						cifsFile->resume_name_length = 							strnlen(pfindDataUnix->							 FileName,							 MAX_PATHCONF);					}					if(cifsFile->resume_name_length > bufsize - 64) {						cFYI(1,("Illegal resume file name length %d",								cifsFile->resume_name_length));						rc = -ENOMEM;						break;					}					/* Free the memory allocated by previous findfirst 					or findnext call - we can not reuse the memory since					the resume name may not be same string length */					if(cifsFile->search_resume_name)						kfree(cifsFile->search_resume_name);					cifsFile->search_resume_name = 						kmalloc(cifsFile->resume_name_length, GFP_KERNEL);					cFYI(1,("fnext last file: %s with name %d bytes long",						pfindDataUnix->FileName,						cifsFile->resume_name_length));					if(cifsFile->search_resume_name == NULL) {						rc = -ENOMEM;						break;					}					memcpy(cifsFile->search_resume_name,						pfindDataUnix->FileName, 						cifsFile->resume_name_length);				}				for (i = 0; i < count; i++) {					__u32 len = le32_to_cpu(pfindData->							FileNameLength);					if (UnixSearch == FALSE) {						if (Unicode == TRUE)							len =							  cifs_strfromUCS_le							  (pfindData->FileName,							  (wchar_t *)							  pfindData->FileName,							  len / 2,							  cifs_sb->local_nls);						qstring.len = len;						if (((len != 1)						    || (pfindData->FileName[0] != '.'))						    && ((len != 2)							|| (pfindData->FileName[0] != '.')							|| (pfindData->FileName[1] !=							    '.'))) {							if(cifs_filldir							    (&qstring,							     pfindData,							     file, filldir,							     direntry)) {							/* do not end search if								kernel not ready to take								remaining entries yet */								findNextParms.EndofSearch = 0;								reset_resume_key(file, pfindData->FileName,qstring.len,									Unicode,cifs_sb->local_nls);								break;							}							file->f_pos++;						}					} else {	/* UnixSearch */						pfindDataUnix =						    (FILE_UNIX_INFO *)						    pfindData;						if (Unicode == TRUE)							qstring.len =							  cifs_strfromUCS_le							  (pfindDataUnix->FileName,							  (wchar_t *)							  pfindDataUnix->FileName,							  MAX_PATHCONF,							  cifs_sb->local_nls);						else							qstring.len =							  strnlen							  (pfindDataUnix->							  FileName,							  MAX_PATHCONF);						if (((qstring.len != 1)						     || (pfindDataUnix->							 FileName[0] != '.'))						    && ((qstring.len != 2)							|| (pfindDataUnix->							    FileName[0] != '.')							|| (pfindDataUnix->							    FileName[1] !=							    '.'))) {							if(cifs_filldir_unix							    (&qstring,							     pfindDataUnix,							     file, filldir,							     direntry)) {								/* do not end search if								kernel not ready to take								remaining entries yet */								findNextParms.EndofSearch = 0;								reset_resume_key(file, pfindDataUnix->FileName,qstring.len,									Unicode,cifs_sb->local_nls);								break;							}							file->f_pos++;						}					}					pfindData = (FILE_DIRECTORY_INFO *) ((char *) pfindData + 						le32_to_cpu(pfindData->NextEntryOffset));	/* works also for Unix find struct since first field of both */	/* BB also should check to ensure pointer not beyond end of SMB */				} /* end for loop */				if (findNextParms.EndofSearch != 0) {					cifsFile->endOfSearch = TRUE;				}			} else {				cifsFile->endOfSearch = TRUE;				rc = 0;	/* unless parent directory disappeared - do not				return error here (eg Access Denied or no more files) */			}		}	} /* end switch */	if (data)		kfree(data);	if (full_path)		kfree(full_path);	FreeXid(xid);	return rc;}int cifs_prepare_write(struct file *file, struct page *page,			unsigned from, unsigned to){	int rc = 0;        loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;	cFYI(1,("prepare write for page %p from %d to %d",page,from,to));	if (!PageUptodate(page)) {	/*	if (to - from != PAGE_CACHE_SIZE) {			void *kaddr = kmap_atomic(page, KM_USER0);			memset(kaddr, 0, from);			memset(kaddr + to, 0, PAGE_CACHE_SIZE - to);			flush_dcache_page(page);			kunmap_atomic(kaddr, KM_USER0);		} */		/* If we are writing a full page it will be up to date,		no need to read from the server */		if((to==PAGE_CACHE_SIZE) && (from == 0))			SetPageUptodate(page);		/* might as well read a page, it is fast enough */		if((file->f_flags & O_ACCMODE) != O_WRONLY) {			rc = cifs_readpage_worker(file,page,&offset);		} else {		/* should we try using another		file handle if there is one - how would we lock it		to prevent close of that handle racing with this read? */		/* In any case this will be written out by commit_write */		}	}	/* BB should we pass any errors back? e.g. if we do not have read access to the file */	return 0;}struct address_space_operations cifs_addr_ops = {	.readpage = cifs_readpage,	.readpages = cifs_readpages,	.writepage = cifs_writepage,	.prepare_write = cifs_prepare_write, 	.commit_write = cifs_commit_write,	.set_page_dirty = __set_page_dirty_nobuffers,   /* .sync_page = cifs_sync_page, */	/*.direct_IO = */};

⌨️ 快捷键说明

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