kernels/linux-2.6.24/mm/filemap.c
/*
 * Called under i_mutex for writes to S_ISREG files.   Returns -EIO if something
 * went wrong during pagecache shootdown.
 */
Called under i_mutex for writes to S_ISREG files.   Returns -EIO if something
went wrong during pagecache shootdown.
Called under i_mutex for writes to S_ISREG files . Returns - EIO if something went wrong during pagecache shootdown .
static ssize_t
generic_file_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
	loff_t offset, unsigned long nr_segs)
{
	struct file *file = iocb->ki_filp;
	struct address_space *mapping = file->f_mapping;
	ssize_t retval;
	size_t write_len;
	pgoff_t end = 0; 
	if (rw == WRITE) {
		write_len = iov_length(iov, nr_segs);
		end = (offset + write_len - 1) >> PAGE_CACHE_SHIFT;
	       	if (mapping_mapped(mapping))
			unmap_mapping_range(mapping, offset, write_len, 0);
	}
	retval = filemap_write_and_wait(mapping);
	if (retval)
		goto out;
	if (rw == WRITE && mapping->nrpages) {
		retval = invalidate_inode_pages2_range(mapping,
					offset >> PAGE_CACHE_SHIFT, end);
		if (retval)
			goto out;
	}
	retval = mapping->a_ops->direct_IO(rw, iocb, iov, offset, nr_segs);
	if (rw == WRITE && mapping->nrpages) {
		invalidate_inode_pages2_range(mapping, offset >> PAGE_CACHE_SHIFT, end);
	}
out:
	return retval;
}
static ssize_t generic_file_direct_IO ( int rw , struct kiocb * iocb , const struct iovec * iov , loff_t offset , unsigned long nr_segs ) { struct file * file = iocb -> ki_filp ; struct address_space * mapping = file -> f_mapping ; ssize_t retval ; size_t write_len ; pgoff_t end = 0 ; if ( rw == WRITE ) { write_len = iov_length ( iov , nr_segs ) ; end = ( offset + write_len - 1 ) >> PAGE_CACHE_SHIFT ; if ( mapping_mapped ( mapping ) ) unmap_mapping_range ( mapping , offset , write_len , 0 ) ; } retval = filemap_write_and_wait ( mapping ) ; if ( retval ) goto out ; if ( rw == WRITE && mapping -> nrpages ) { retval = invalidate_inode_pages2_range ( mapping , offset >> PAGE_CACHE_SHIFT , end ) ; if ( retval ) goto out ; } retval = mapping -> a_ops -> direct_IO ( rw , iocb , iov , offset , nr_segs ) ; if ( rw == WRITE && mapping -> nrpages ) { invalidate_inode_pages2_range ( mapping , offset >> PAGE_CACHE_SHIFT , end ) ; } out : return retval ; }
Called under i_mutex for writes to S_ISREG files.
Called under i_mutex for writes to S_ISREG files .
/* silence gcc */ /*
	 * If it's a write, unmap all mmappings of the file up-front.  This
	 * will cause any pte dirty bits to be propagated into the pageframes
	 * for the subsequent filemap_write_and_wait().
	 */ /*
	 * After a write we want buffered reads to be sure to go to disk to get
	 * the new data.  We invalidate clean cached page from the region we're
	 * about to write.  We do this *before* the write so that we can return
	 * -EIO without clobbering -EIOCBQUEUED from ->direct_IO().
	 */ /*
	 * Finally, try again to invalidate clean pages which might have been
	 * cached by non-direct readahead, or faulted in by get_user_pages()
	 * if the source of the write was an mmap'ed region of the file
	 * we're writing.  Either one is a pretty crazy thing to do,
	 * so we don't support it 100%.  If this invalidation
	 * fails, tough, the write still worked...
	 */