diff options
Diffstat (limited to 'fs/buffer.c')
| -rw-r--r-- | fs/buffer.c | 28 | 
1 files changed, 10 insertions, 18 deletions
diff --git a/fs/buffer.c b/fs/buffer.c index c7062c896d7c..9f6d2e41281d 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2306,8 +2306,8 @@ EXPORT_SYMBOL(block_commit_write);   * beyond EOF, then the page is guaranteed safe against truncation until we   * unlock the page.   * - * Direct callers of this function should call vfs_check_frozen() so that page - * fault does not busyloop until the fs is thawed. + * Direct callers of this function should protect against filesystem freezing + * using sb_start_write() - sb_end_write() functions.   */  int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,  			 get_block_t get_block) @@ -2318,6 +2318,12 @@ int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,  	loff_t size;  	int ret; +	/* +	 * Update file times before taking page lock. We may end up failing the +	 * fault so this update may be superfluous but who really cares... +	 */ +	file_update_time(vma->vm_file); +  	lock_page(page);  	size = i_size_read(inode);  	if ((page->mapping != inode->i_mapping) || @@ -2339,18 +2345,7 @@ int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,  	if (unlikely(ret < 0))  		goto out_unlock; -	/* -	 * Freezing in progress? We check after the page is marked dirty and -	 * with page lock held so if the test here fails, we are sure freezing -	 * code will wait during syncing until the page fault is done - at that -	 * point page will be dirty and unlocked so freezing code will write it -	 * and writeprotect it again. -	 */  	set_page_dirty(page); -	if (inode->i_sb->s_frozen != SB_UNFROZEN) { -		ret = -EAGAIN; -		goto out_unlock; -	}  	wait_on_page_writeback(page);  	return 0;  out_unlock: @@ -2365,12 +2360,9 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,  	int ret;  	struct super_block *sb = vma->vm_file->f_path.dentry->d_inode->i_sb; -	/* -	 * This check is racy but catches the common case. The check in -	 * __block_page_mkwrite() is reliable. -	 */ -	vfs_check_frozen(sb, SB_FREEZE_WRITE); +	sb_start_pagefault(sb);  	ret = __block_page_mkwrite(vma, vmf, get_block); +	sb_end_pagefault(sb);  	return block_page_mkwrite_return(ret);  }  EXPORT_SYMBOL(block_page_mkwrite);  |