Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 251683
b: refs/heads/master
c: ea13a86
h: refs/heads/master
i:
  251681: 5f76d44
  251679: a1a2e63
v: v3
  • Loading branch information
Jan Kara authored and Al Viro committed May 26, 2011
1 parent 407d9ef commit b03e3cc
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 24da4fab5a617ecbf0f0c64e7ba7703383faa411
refs/heads/master: ea13a86463fd0c26c2c209c53dc46b8eff81bad4
24 changes: 23 additions & 1 deletion trunk/fs/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -2331,6 +2331,9 @@ EXPORT_SYMBOL(block_commit_write);
* page lock we can determine safely if the page is beyond EOF. If it is not
* 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.
*/
int __block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
get_block_t get_block)
Expand Down Expand Up @@ -2362,6 +2365,18 @@ 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;
}
return 0;
out_unlock:
unlock_page(page);
Expand All @@ -2372,8 +2387,15 @@ EXPORT_SYMBOL(__block_page_mkwrite);
int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
get_block_t get_block)
{
int ret = __block_page_mkwrite(vma, vmf, get_block);
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);
ret = __block_page_mkwrite(vma, vmf, get_block);
return block_page_mkwrite_return(ret);
}
EXPORT_SYMBOL(block_page_mkwrite);
Expand Down
2 changes: 2 additions & 0 deletions trunk/include/linux/buffer_head.h
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ static inline int block_page_mkwrite_return(int err)
return VM_FAULT_NOPAGE;
if (err == -ENOMEM)
return VM_FAULT_OOM;
if (err == -EAGAIN)
return VM_FAULT_RETRY;
/* -ENOSPC, -EDQUOT, -EIO ... */
return VM_FAULT_SIGBUS;
}
Expand Down

0 comments on commit b03e3cc

Please sign in to comment.