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

📄 file.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 5 页
字号:
	if(list_empty(&(CIFS_I(inode)->openFileList))) {		cFYI(1,("closing last open instance for inode %p",inode));		/* if the file is not open we do not know if we can cache		info on this inode, much less write behind and read ahead */		CIFS_I(inode)->clientCanCacheRead = FALSE;		CIFS_I(inode)->clientCanCacheAll  = FALSE;	}	if((rc ==0) && CIFS_I(inode)->write_behind_rc)		rc = CIFS_I(inode)->write_behind_rc;	FreeXid(xid);	return rc;}intcifs_closedir(struct inode *inode, struct file *file){	int rc = 0;	int xid;	struct cifsFileInfo *pSMBFileStruct =	    (struct cifsFileInfo *) file->private_data;	cFYI(1, ("Closedir inode = 0x%p with ", inode));	xid = GetXid();	if (pSMBFileStruct) {		cFYI(1, ("Freeing private data in close dir"));		kfree(file->private_data);		file->private_data = NULL;	}	FreeXid(xid);	return rc;}intcifs_lock(struct file *file, int cmd, struct file_lock *pfLock){	int rc, xid;	__u32 lockType = LOCKING_ANDX_LARGE_FILES;	__u32 numLock = 0;	__u32 numUnlock = 0;	__u64 length;	int wait_flag = FALSE;	struct cifs_sb_info *cifs_sb;	struct cifsTconInfo *pTcon;	length = 1 + pfLock->fl_end - pfLock->fl_start;	rc = -EACCES;	xid = GetXid();	cFYI(1,	     ("Lock parm: 0x%x flockflags: 0x%x flocktype: 0x%x start: %lld end: %lld",	      cmd, pfLock->fl_flags, pfLock->fl_type, pfLock->fl_start,	      pfLock->fl_end));	if (pfLock->fl_flags & FL_POSIX)		cFYI(1, ("Posix "));	if (pfLock->fl_flags & FL_FLOCK)		cFYI(1, ("Flock "));	if (pfLock->fl_flags & FL_SLEEP) {		cFYI(1, ("Blocking lock "));		wait_flag = TRUE;	}	if (pfLock->fl_flags & FL_ACCESS)		cFYI(1, ("Process suspended by mandatory locking - not implemented yet "));	if (pfLock->fl_flags & FL_LEASE)		cFYI(1, ("Lease on file - not implemented yet"));	if (pfLock->fl_flags & (~(FL_POSIX | FL_FLOCK | FL_SLEEP | FL_ACCESS | FL_LEASE)))		cFYI(1, ("Unknown lock flags 0x%x",pfLock->fl_flags));	if (pfLock->fl_type == F_WRLCK) {		cFYI(1, ("F_WRLCK "));		numLock = 1;	} else if (pfLock->fl_type == F_UNLCK) {		cFYI(1, ("F_UNLCK "));		numUnlock = 1;	} else if (pfLock->fl_type == F_RDLCK) {		cFYI(1, ("F_RDLCK "));		lockType |= LOCKING_ANDX_SHARED_LOCK;		numLock = 1;	} else if (pfLock->fl_type == F_EXLCK) {		cFYI(1, ("F_EXLCK "));		numLock = 1;	} else if (pfLock->fl_type == F_SHLCK) {		cFYI(1, ("F_SHLCK "));		lockType |= LOCKING_ANDX_SHARED_LOCK;		numLock = 1;	} else		cFYI(1, ("Unknown type of lock "));	cifs_sb = CIFS_SB(file->f_dentry->d_sb);	pTcon = cifs_sb->tcon;	if (file->private_data == NULL) {		FreeXid(xid);		return -EBADF;	}	if (IS_GETLK(cmd)) {		rc = CIFSSMBLock(xid, pTcon,				 ((struct cifsFileInfo *) file->				  private_data)->netfid,				 length,				 pfLock->fl_start, 0, 1, lockType,				 0 /* wait flag */ );		if (rc == 0) {			rc = CIFSSMBLock(xid, pTcon,					 ((struct cifsFileInfo *) file->					  private_data)->netfid,					 length,					 pfLock->fl_start, 1 /* numUnlock */ ,					 0 /* numLock */ , lockType,					 0 /* wait flag */ );			pfLock->fl_type = F_UNLCK;			if (rc != 0)				cERROR(1,					("Error unlocking previously locked range %d during test of lock ",					rc));			rc = 0;		} else {			/* if rc == ERR_SHARING_VIOLATION ? */			rc = 0;	/* do not change lock type to unlock since range in use */		}		FreeXid(xid);		return rc;	}	rc = CIFSSMBLock(xid, pTcon,			 ((struct cifsFileInfo *) file->private_data)->			 netfid, length,			 pfLock->fl_start, numUnlock, numLock, lockType,			 wait_flag);	if (rc == 0 && (pfLock->fl_flags & FL_POSIX))		posix_lock_file(file, pfLock);	FreeXid(xid);	return rc;}ssize_tcifs_write(struct file * file, const char *write_data,	   size_t write_size, loff_t * poffset){	int rc = 0;	unsigned int bytes_written = 0;	unsigned int total_written;	struct cifs_sb_info *cifs_sb;	struct cifsTconInfo *pTcon;	int xid, long_op;	struct cifsFileInfo * open_file;	if(file->f_dentry == NULL)		return -EBADF;	cifs_sb = CIFS_SB(file->f_dentry->d_sb);	if(cifs_sb == NULL) {		return -EBADF;	}	pTcon = cifs_sb->tcon;	/*cFYI(1,	   (" write %d bytes to offset %lld of %s", write_size,	   *poffset, file->f_dentry->d_name.name)); */	if (file->private_data == NULL) {		return -EBADF;	} else {		open_file = (struct cifsFileInfo *) file->private_data;	}		xid = GetXid();	if(file->f_dentry->d_inode == NULL) {		FreeXid(xid);		return -EBADF;	}	if (*poffset > file->f_dentry->d_inode->i_size)		long_op = 2;  /* writes past end of file can take a long time */	else		long_op = 1;	for (total_written = 0; write_size > total_written;	     total_written += bytes_written) {		rc = -EAGAIN;		while(rc == -EAGAIN) {			if(file->private_data == NULL) {				/* file has been closed on us */				FreeXid(xid);			/* if we have gotten here we have written some data			and blocked, and the file has been freed on us			while we blocked so return what we managed to write */				return total_written;			} 			if(open_file->closePend) {				FreeXid(xid);				if(total_written)					return total_written;				else					return -EBADF;			}			if (open_file->invalidHandle) {				if((file->f_dentry == NULL) ||				   (file->f_dentry->d_inode == NULL)) {					FreeXid(xid);					return total_written;				}				/* we could deadlock if we called				 filemap_fdatawait from here so tell				reopen_file not to flush data to server now */				rc = cifs_reopen_file(file->f_dentry->d_inode,					file,FALSE);				if(rc != 0)					break;			}			rc = CIFSSMBWrite(xid, pTcon,				   open_file->netfid,				  write_size - total_written, *poffset,				  &bytes_written,				  write_data + total_written, long_op);		}		if (rc || (bytes_written == 0)) {			if (total_written)				break;			else {				FreeXid(xid);				return rc;			}		} else			*poffset += bytes_written;		long_op = FALSE; /* subsequent writes fast - 15 seconds is plenty */	}#ifdef CONFIG_CIFS_STATS	if(total_written > 0) {		atomic_inc(&pTcon->num_writes);		spin_lock(&pTcon->stat_lock);		pTcon->bytes_written += total_written;		spin_unlock(&pTcon->stat_lock);	}#endif			/* since the write may have blocked check these pointers again */	if(file->f_dentry) {		if(file->f_dentry->d_inode) {			file->f_dentry->d_inode->i_ctime = file->f_dentry->d_inode->i_mtime =				CURRENT_TIME;			if (total_written > 0) {				if (*poffset > file->f_dentry->d_inode->i_size)					i_size_write(file->f_dentry->d_inode, *poffset);			}			mark_inode_dirty_sync(file->f_dentry->d_inode);		}	}	FreeXid(xid);	return total_written;}static intcifs_partialpagewrite(struct page *page,unsigned from, unsigned to){	struct address_space *mapping = page->mapping;	loff_t offset = (loff_t)page->index << PAGE_CACHE_SHIFT;	char * write_data;	int rc = -EFAULT;	int bytes_written = 0;	struct cifs_sb_info *cifs_sb;	struct cifsTconInfo *pTcon;	struct inode *inode;	struct cifsInodeInfo *cifsInode;	struct cifsFileInfo *open_file = NULL;	struct list_head *tmp;	struct list_head *tmp1;	if (!mapping) {		return -EFAULT;	} else if(!mapping->host) {		return -EFAULT;	}	inode = page->mapping->host;	cifs_sb = CIFS_SB(inode->i_sb);	pTcon = cifs_sb->tcon;	offset += (loff_t)from;	write_data = kmap(page);	write_data += from;	if((to > PAGE_CACHE_SIZE) || (from > to)) {		kunmap(page);		return -EIO;	}	/* racing with truncate? */	if(offset > mapping->host->i_size) {		kunmap(page);		return 0; /* don't care */	}	/* check to make sure that we are not extending the file */	if(mapping->host->i_size - offset < (loff_t)to)		to = (unsigned)(mapping->host->i_size - offset); 			cifsInode = CIFS_I(mapping->host);	read_lock(&GlobalSMBSeslock); 	/* BB we should start at the end */	list_for_each_safe(tmp, tmp1, &cifsInode->openFileList) {            		open_file = list_entry(tmp,struct cifsFileInfo, flist);		if(open_file->closePend)			continue;		/* We check if file is open for writing first */		if((open_file->pfile) && 		   ((open_file->pfile->f_flags & O_RDWR) || 			(open_file->pfile->f_flags & O_WRONLY))) {			read_unlock(&GlobalSMBSeslock);			bytes_written = cifs_write(open_file->pfile, write_data,					to-from, &offset);			read_lock(&GlobalSMBSeslock);		/* Does mm or vfs already set times? */			inode->i_atime = inode->i_mtime = CURRENT_TIME;			if ((bytes_written > 0) && (offset)) {				rc = 0;			} else if(bytes_written < 0) {				if(rc == -EBADF) {				/* have seen a case in which				kernel seemed to have closed/freed a file				even with writes active so we might as well				see if there are other file structs to try				for the same inode before giving up */					continue;				} else					rc = bytes_written;			}			break;  /* now that we found a valid file handle				and tried to write to it we are done, no				sense continuing to loop looking for another */		}		if(tmp->next == NULL) {			cFYI(1,("File instance %p removed",tmp));			break;		}	}	read_unlock(&GlobalSMBSeslock);	if(open_file == NULL) {		cFYI(1,("No writeable filehandles for inode"));		rc = -EIO;	}	kunmap(page);	return rc;}#if 0static intcifs_writepages(struct address_space *mapping, struct writeback_control *wbc){	int rc = -EFAULT;	int xid;	xid = GetXid();/* call 16K write then Setpageuptodate */	FreeXid(xid);	return rc;}#endifstatic intcifs_writepage(struct page* page, struct writeback_control *wbc){	int rc = -EFAULT;	int xid;	xid = GetXid();/* BB add check for wbc flags */	page_cache_get(page);        if (!PageUptodate(page)) {		cFYI(1,("ppw - page not up to date"));	}		rc = cifs_partialpagewrite(page,0,PAGE_CACHE_SIZE);	SetPageUptodate(page); /* BB add check for error and Clearuptodate? */	unlock_page(page);	page_cache_release(page);		FreeXid(xid);	return rc;}static intcifs_commit_write(struct file *file, struct page *page, unsigned offset,		  unsigned to){	int xid;	int rc = 0;	struct inode *inode = page->mapping->host;	loff_t position = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;	char * page_data;	xid = GetXid();	cFYI(1,("commit write for page %p up to position %lld for %d",page,position,to));	if (position > inode->i_size){		i_size_write(inode, position);		/*if (file->private_data == NULL) {			rc = -EBADF;		} else {			open_file = (struct cifsFileInfo *)file->private_data;			cifs_sb = CIFS_SB(inode->i_sb);			rc = -EAGAIN;			while(rc == -EAGAIN) {				if((open_file->invalidHandle) && 				  (!open_file->closePend)) {					rc = cifs_reopen_file(file->f_dentry->d_inode,file);					if(rc != 0)						break;				}				if(!open_file->closePend) {					rc = CIFSSMBSetFileSize(xid, cifs_sb->tcon, 						position, open_file->netfid,						open_file->pid,FALSE);				} else {					rc = -EBADF;					break;				}			}			cFYI(1,(" SetEOF (commit write) rc = %d",rc));		}*/	}	if (!PageUptodate(page)) {		position =  ((loff_t)page->index << PAGE_CACHE_SHIFT) + offset;		/* can not rely on (or let) writepage write this data */		if(to < offset) {			cFYI(1,("Illegal offsets, can not copy from %d to %d",				offset,to));			FreeXid(xid);

⌨️ 快捷键说明

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