aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/buffer.c24
-rw-r--r--include/linux/buffer_head.h2
2 files changed, 25 insertions, 1 deletions
diff --git a/fs/buffer.c b/fs/buffer.c
index f6ad8f9b8fa5..b0675bfe8207 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2331,6 +2331,9 @@ EXPORT_SYMBOL(block_commit_write);
2331 * page lock we can determine safely if the page is beyond EOF. If it is not 2331 * page lock we can determine safely if the page is beyond EOF. If it is not
2332 * beyond EOF, then the page is guaranteed safe against truncation until we 2332 * beyond EOF, then the page is guaranteed safe against truncation until we
2333 * unlock the page. 2333 * unlock the page.
2334 *
2335 * Direct callers of this function should call vfs_check_frozen() so that page
2336 * fault does not busyloop until the fs is thawed.
2334 */ 2337 */
2335int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, 2338int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
2336 get_block_t get_block) 2339 get_block_t get_block)
@@ -2362,6 +2365,18 @@ int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
2362 2365
2363 if (unlikely(ret < 0)) 2366 if (unlikely(ret < 0))
2364 goto out_unlock; 2367 goto out_unlock;
2368 /*
2369 * Freezing in progress? We check after the page is marked dirty and
2370 * with page lock held so if the test here fails, we are sure freezing
2371 * code will wait during syncing until the page fault is done - at that
2372 * point page will be dirty and unlocked so freezing code will write it
2373 * and writeprotect it again.
2374 */
2375 set_page_dirty(page);
2376 if (inode->i_sb->s_frozen != SB_UNFROZEN) {
2377 ret = -EAGAIN;
2378 goto out_unlock;
2379 }
2365 return 0; 2380 return 0;
2366out_unlock: 2381out_unlock:
2367 unlock_page(page); 2382 unlock_page(page);
@@ -2372,8 +2387,15 @@ EXPORT_SYMBOL(__block_page_mkwrite);
2372int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf, 2387int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
2373 get_block_t get_block) 2388 get_block_t get_block)
2374{ 2389{
2375 int ret = __block_page_mkwrite(vma, vmf, get_block); 2390 int ret;
2391 struct super_block *sb = vma->vm_file->f_path.dentry->d_inode->i_sb;
2376 2392
2393 /*
2394 * This check is racy but catches the common case. The check in
2395 * __block_page_mkwrite() is reliable.
2396 */
2397 vfs_check_frozen(sb, SB_FREEZE_WRITE);
2398 ret = __block_page_mkwrite(vma, vmf, get_block);
2377 return block_page_mkwrite_return(ret); 2399 return block_page_mkwrite_return(ret);
2378} 2400}
2379EXPORT_SYMBOL(block_page_mkwrite); 2401EXPORT_SYMBOL(block_page_mkwrite);
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 2bf6a9136a94..503c8a6b3079 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -230,6 +230,8 @@ static inline int block_page_mkwrite_return(int err)
230 return VM_FAULT_NOPAGE; 230 return VM_FAULT_NOPAGE;
231 if (err == -ENOMEM) 231 if (err == -ENOMEM)
232 return VM_FAULT_OOM; 232 return VM_FAULT_OOM;
233 if (err == -EAGAIN)
234 return VM_FAULT_RETRY;
233 /* -ENOSPC, -EDQUOT, -EIO ... */ 235 /* -ENOSPC, -EDQUOT, -EIO ... */
234 return VM_FAULT_SIGBUS; 236 return VM_FAULT_SIGBUS;
235} 237}