diff options
Diffstat (limited to 'mm/filemap.c')
| -rw-r--r-- | mm/filemap.c | 38 | 
1 files changed, 29 insertions, 9 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index a4a5260b027..384344575c3 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -1412,12 +1412,8 @@ generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,  			retval = filemap_write_and_wait_range(mapping, pos,  					pos + iov_length(iov, nr_segs) - 1);  			if (!retval) { -				struct blk_plug plug; - -				blk_start_plug(&plug);  				retval = mapping->a_ops->direct_IO(READ, iocb,  							iov, pos, nr_segs); -				blk_finish_plug(&plug);  			}  			if (retval > 0) {  				*ppos = pos + retval; @@ -1712,8 +1708,35 @@ page_not_uptodate:  }  EXPORT_SYMBOL(filemap_fault); +int filemap_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf) +{ +	struct page *page = vmf->page; +	struct inode *inode = vma->vm_file->f_path.dentry->d_inode; +	int ret = VM_FAULT_LOCKED; + +	sb_start_pagefault(inode->i_sb); +	file_update_time(vma->vm_file); +	lock_page(page); +	if (page->mapping != inode->i_mapping) { +		unlock_page(page); +		ret = VM_FAULT_NOPAGE; +		goto out; +	} +	/* +	 * We mark the page dirty already here so that when freeze is in +	 * progress, we are guaranteed that writeback during freezing will +	 * see the dirty page and writeprotect it again. +	 */ +	set_page_dirty(page); +out: +	sb_end_pagefault(inode->i_sb); +	return ret; +} +EXPORT_SYMBOL(filemap_page_mkwrite); +  const struct vm_operations_struct generic_file_vm_ops = {  	.fault		= filemap_fault, +	.page_mkwrite	= filemap_page_mkwrite,  };  /* This is used for a general mmap of a disk file */ @@ -2407,8 +2430,6 @@ ssize_t __generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,  	count = ocount;  	pos = *ppos; -	vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); -  	/* We can write back this queue in page reclaim */  	current->backing_dev_info = mapping->backing_dev_info;  	written = 0; @@ -2502,13 +2523,12 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,  {  	struct file *file = iocb->ki_filp;  	struct inode *inode = file->f_mapping->host; -	struct blk_plug plug;  	ssize_t ret;  	BUG_ON(iocb->ki_pos != pos); +	sb_start_write(inode->i_sb);  	mutex_lock(&inode->i_mutex); -	blk_start_plug(&plug);  	ret = __generic_file_aio_write(iocb, iov, nr_segs, &iocb->ki_pos);  	mutex_unlock(&inode->i_mutex); @@ -2519,7 +2539,7 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const struct iovec *iov,  		if (err < 0 && ret > 0)  			ret = err;  	} -	blk_finish_plug(&plug); +	sb_end_write(inode->i_sb);  	return ret;  }  EXPORT_SYMBOL(generic_file_aio_write);  |