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); | |||
2306 | * beyond EOF, then the page is guaranteed safe against truncation until we | 2306 | * beyond EOF, then the page is guaranteed safe against truncation until we |
2307 | * unlock the page. | 2307 | * unlock the page. |
2308 | * | 2308 | * |
2309 | * Direct callers of this function should call vfs_check_frozen() so that page | 2309 | * Direct callers of this function should protect against filesystem freezing |
2310 | * fault does not busyloop until the fs is thawed. | 2310 | * using sb_start_write() - sb_end_write() functions. |
2311 | */ | 2311 | */ |
2312 | int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | 2312 | int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, |
2313 | get_block_t get_block) | 2313 | get_block_t get_block) |
@@ -2318,6 +2318,12 @@ int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | |||
2318 | loff_t size; | 2318 | loff_t size; |
2319 | int ret; | 2319 | int ret; |
2320 | 2320 | ||
2321 | /* | ||
2322 | * Update file times before taking page lock. We may end up failing the | ||
2323 | * fault so this update may be superfluous but who really cares... | ||
2324 | */ | ||
2325 | file_update_time(vma->vm_file); | ||
2326 | |||
2321 | lock_page(page); | 2327 | lock_page(page); |
2322 | size = i_size_read(inode); | 2328 | size = i_size_read(inode); |
2323 | if ((page->mapping != inode->i_mapping) || | 2329 | if ((page->mapping != inode->i_mapping) || |
@@ -2339,18 +2345,7 @@ int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | |||
2339 | 2345 | ||
2340 | if (unlikely(ret < 0)) | 2346 | if (unlikely(ret < 0)) |
2341 | goto out_unlock; | 2347 | goto out_unlock; |
2342 | /* | ||
2343 | * Freezing in progress? We check after the page is marked dirty and | ||
2344 | * with page lock held so if the test here fails, we are sure freezing | ||
2345 | * code will wait during syncing until the page fault is done - at that | ||
2346 | * point page will be dirty and unlocked so freezing code will write it | ||
2347 | * and writeprotect it again. | ||
2348 | */ | ||
2349 | set_page_dirty(page); | 2348 | set_page_dirty(page); |
2350 | if (inode->i_sb->s_frozen != SB_UNFROZEN) { | ||
2351 | ret = -EAGAIN; | ||
2352 | goto out_unlock; | ||
2353 | } | ||
2354 | wait_on_page_writeback(page); | 2349 | wait_on_page_writeback(page); |
2355 | return 0; | 2350 | return 0; |
2356 | out_unlock: | 2351 | out_unlock: |
@@ -2365,12 +2360,9 @@ int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, | |||
2365 | int ret; | 2360 | int ret; |
2366 | struct super_block *sb = vma->vm_file->f_path.dentry->d_inode->i_sb; | 2361 | struct super_block *sb = vma->vm_file->f_path.dentry->d_inode->i_sb; |
2367 | 2362 | ||
2368 | /* | 2363 | sb_start_pagefault(sb); |
2369 | * This check is racy but catches the common case. The check in | ||
2370 | * __block_page_mkwrite() is reliable. | ||
2371 | */ | ||
2372 | vfs_check_frozen(sb, SB_FREEZE_WRITE); | ||
2373 | ret = __block_page_mkwrite(vma, vmf, get_block); | 2364 | ret = __block_page_mkwrite(vma, vmf, get_block); |
2365 | sb_end_pagefault(sb); | ||
2374 | return block_page_mkwrite_return(ret); | 2366 | return block_page_mkwrite_return(ret); |
2375 | } | 2367 | } |
2376 | EXPORT_SYMBOL(block_page_mkwrite); | 2368 | EXPORT_SYMBOL(block_page_mkwrite); |