aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2009-03-31 18:23:21 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-01 11:59:14 -0400
commitc2ec175c39f62949438354f603f4aa170846aabb (patch)
treef2c9bf1bec2deabe2d3a5092405b027637b6ead3
parentc2fdf3a9b2d52842808a8e551b53b55dd9b45030 (diff)
mm: page_mkwrite change prototype to match fault
Change the page_mkwrite prototype to take a struct vm_fault, and return VM_FAULT_xxx flags. There should be no functional change. This makes it possible to return much more detailed error information to the VM (and also can provide more information eg. virtual_address to the driver, which might be important in some special cases). This is required for a subsequent fix. And will also make it easier to merge page_mkwrite() with fault() in future. Signed-off-by: Nick Piggin <npiggin@suse.de> Cc: Chris Mason <chris.mason@oracle.com> Cc: Trond Myklebust <trond.myklebust@fys.uio.no> Cc: Miklos Szeredi <miklos@szeredi.hu> Cc: Steven Whitehouse <swhiteho@redhat.com> Cc: Mark Fasheh <mfasheh@suse.com> Cc: Joel Becker <joel.becker@oracle.com> Cc: Artem Bityutskiy <dedekind@infradead.org> Cc: Felix Blyakher <felixb@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/filesystems/Locking2
-rw-r--r--drivers/video/fb_defio.c3
-rw-r--r--fs/btrfs/ctree.h2
-rw-r--r--fs/btrfs/inode.c5
-rw-r--r--fs/buffer.c6
-rw-r--r--fs/ext4/ext4.h2
-rw-r--r--fs/ext4/inode.c5
-rw-r--r--fs/fuse/file.c3
-rw-r--r--fs/gfs2/ops_file.c5
-rw-r--r--fs/nfs/file.c5
-rw-r--r--fs/ocfs2/mmap.c6
-rw-r--r--fs/ubifs/file.c9
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c4
-rw-r--r--include/linux/buffer_head.h2
-rw-r--r--include/linux/mm.h3
-rw-r--r--mm/memory.c26
16 files changed, 65 insertions, 23 deletions
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index 4e78ce677843..76efe5b71d7d 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -505,7 +505,7 @@ prototypes:
505 void (*open)(struct vm_area_struct*); 505 void (*open)(struct vm_area_struct*);
506 void (*close)(struct vm_area_struct*); 506 void (*close)(struct vm_area_struct*);
507 int (*fault)(struct vm_area_struct*, struct vm_fault *); 507 int (*fault)(struct vm_area_struct*, struct vm_fault *);
508 int (*page_mkwrite)(struct vm_area_struct *, struct page *); 508 int (*page_mkwrite)(struct vm_area_struct *, struct vm_fault *);
509 int (*access)(struct vm_area_struct *, unsigned long, void*, int, int); 509 int (*access)(struct vm_area_struct *, unsigned long, void*, int, int);
510 510
511locking rules: 511locking rules:
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 082026546aee..0a7a6679ee6e 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -85,8 +85,9 @@ EXPORT_SYMBOL_GPL(fb_deferred_io_fsync);
85 85
86/* vm_ops->page_mkwrite handler */ 86/* vm_ops->page_mkwrite handler */
87static int fb_deferred_io_mkwrite(struct vm_area_struct *vma, 87static int fb_deferred_io_mkwrite(struct vm_area_struct *vma,
88 struct page *page) 88 struct vm_fault *vmf)
89{ 89{
90 struct page *page = vmf->page;
90 struct fb_info *info = vma->vm_private_data; 91 struct fb_info *info = vma->vm_private_data;
91 struct fb_deferred_io *fbdefio = info->fbdefio; 92 struct fb_deferred_io *fbdefio = info->fbdefio;
92 struct page *cur; 93 struct page *cur;
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 5e1d4e30e9d8..7dd1b6d0bf32 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -2060,7 +2060,7 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
2060unsigned long btrfs_force_ra(struct address_space *mapping, 2060unsigned long btrfs_force_ra(struct address_space *mapping,
2061 struct file_ra_state *ra, struct file *file, 2061 struct file_ra_state *ra, struct file *file,
2062 pgoff_t offset, pgoff_t last_index); 2062 pgoff_t offset, pgoff_t last_index);
2063int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page); 2063int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
2064int btrfs_readpage(struct file *file, struct page *page); 2064int btrfs_readpage(struct file *file, struct page *page);
2065void btrfs_delete_inode(struct inode *inode); 2065void btrfs_delete_inode(struct inode *inode);
2066void btrfs_put_inode(struct inode *inode); 2066void btrfs_put_inode(struct inode *inode);
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 7d4f948bc22a..ec5423790bbb 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -4292,8 +4292,9 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
4292 * beyond EOF, then the page is guaranteed safe against truncation until we 4292 * beyond EOF, then the page is guaranteed safe against truncation until we
4293 * unlock the page. 4293 * unlock the page.
4294 */ 4294 */
4295int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page) 4295int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
4296{ 4296{
4297 struct page *page = vmf->page;
4297 struct inode *inode = fdentry(vma->vm_file)->d_inode; 4298 struct inode *inode = fdentry(vma->vm_file)->d_inode;
4298 struct btrfs_root *root = BTRFS_I(inode)->root; 4299 struct btrfs_root *root = BTRFS_I(inode)->root;
4299 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; 4300 struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
@@ -4362,6 +4363,8 @@ again:
4362out_unlock: 4363out_unlock:
4363 unlock_page(page); 4364 unlock_page(page);
4364out: 4365out:
4366 if (ret)
4367 ret = VM_FAULT_SIGBUS;
4365 return ret; 4368 return ret;
4366} 4369}
4367 4370
diff --git a/fs/buffer.c b/fs/buffer.c
index 73abe6d8218c..6d51a3da362c 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2313,9 +2313,10 @@ int block_commit_write(struct page *page, unsigned from, unsigned to)
2313 * unlock the page. 2313 * unlock the page.
2314 */ 2314 */
2315int 2315int
2316block_page_mkwrite(struct vm_area_struct *vma, struct page *page, 2316block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
2317 get_block_t get_block) 2317 get_block_t get_block)
2318{ 2318{
2319 struct page *page = vmf->page;
2319 struct inode *inode = vma->vm_file->f_path.dentry->d_inode; 2320 struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
2320 unsigned long end; 2321 unsigned long end;
2321 loff_t size; 2322 loff_t size;
@@ -2340,6 +2341,9 @@ block_page_mkwrite(struct vm_area_struct *vma, struct page *page,
2340 ret = block_commit_write(page, 0, end); 2341 ret = block_commit_write(page, 0, end);
2341 2342
2342out_unlock: 2343out_unlock:
2344 if (ret)
2345 ret = VM_FAULT_SIGBUS;
2346
2343 unlock_page(page); 2347 unlock_page(page);
2344 return ret; 2348 return ret;
2345} 2349}
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 6083bb38057b..990c94000924 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1098,7 +1098,7 @@ extern int ext4_meta_trans_blocks(struct inode *, int nrblocks, int idxblocks);
1098extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks); 1098extern int ext4_chunk_trans_blocks(struct inode *, int nrblocks);
1099extern int ext4_block_truncate_page(handle_t *handle, 1099extern int ext4_block_truncate_page(handle_t *handle,
1100 struct address_space *mapping, loff_t from); 1100 struct address_space *mapping, loff_t from);
1101extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page); 1101extern int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf);
1102extern qsize_t ext4_get_reserved_space(struct inode *inode); 1102extern qsize_t ext4_get_reserved_space(struct inode *inode);
1103 1103
1104/* ioctl.c */ 1104/* ioctl.c */
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 71d3ecd5db79..dd82ff390067 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -5146,8 +5146,9 @@ static int ext4_bh_unmapped(handle_t *handle, struct buffer_head *bh)
5146 return !buffer_mapped(bh); 5146 return !buffer_mapped(bh);
5147} 5147}
5148 5148
5149int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page) 5149int ext4_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
5150{ 5150{
5151 struct page *page = vmf->page;
5151 loff_t size; 5152 loff_t size;
5152 unsigned long len; 5153 unsigned long len;
5153 int ret = -EINVAL; 5154 int ret = -EINVAL;
@@ -5199,6 +5200,8 @@ int ext4_page_mkwrite(struct vm_area_struct *vma, struct page *page)
5199 goto out_unlock; 5200 goto out_unlock;
5200 ret = 0; 5201 ret = 0;
5201out_unlock: 5202out_unlock:
5203 if (ret)
5204 ret = VM_FAULT_SIGBUS;
5202 up_read(&inode->i_alloc_sem); 5205 up_read(&inode->i_alloc_sem);
5203 return ret; 5206 return ret;
5204} 5207}
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 821d10f719bd..4e340fedf768 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1234,8 +1234,9 @@ static void fuse_vma_close(struct vm_area_struct *vma)
1234 * - sync(2) 1234 * - sync(2)
1235 * - try_to_free_pages() with order > PAGE_ALLOC_COSTLY_ORDER 1235 * - try_to_free_pages() with order > PAGE_ALLOC_COSTLY_ORDER
1236 */ 1236 */
1237static int fuse_page_mkwrite(struct vm_area_struct *vma, struct page *page) 1237static int fuse_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
1238{ 1238{
1239 struct page *page = vmf->page;
1239 /* 1240 /*
1240 * Don't use page->mapping as it may become NULL from a 1241 * Don't use page->mapping as it may become NULL from a
1241 * concurrent truncate. 1242 * concurrent truncate.
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index 3b9e8de3500b..70b9b8548945 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -337,8 +337,9 @@ static int gfs2_allocate_page_backing(struct page *page)
337 * blocks allocated on disk to back that page. 337 * blocks allocated on disk to back that page.
338 */ 338 */
339 339
340static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) 340static int gfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
341{ 341{
342 struct page *page = vmf->page;
342 struct inode *inode = vma->vm_file->f_path.dentry->d_inode; 343 struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
343 struct gfs2_inode *ip = GFS2_I(inode); 344 struct gfs2_inode *ip = GFS2_I(inode);
344 struct gfs2_sbd *sdp = GFS2_SB(inode); 345 struct gfs2_sbd *sdp = GFS2_SB(inode);
@@ -412,6 +413,8 @@ out_unlock:
412 gfs2_glock_dq(&gh); 413 gfs2_glock_dq(&gh);
413out: 414out:
414 gfs2_holder_uninit(&gh); 415 gfs2_holder_uninit(&gh);
416 if (ret)
417 ret = VM_FAULT_SIGBUS;
415 return ret; 418 return ret;
416} 419}
417 420
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 90f292b520d2..cec79392e4ba 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -451,8 +451,9 @@ const struct address_space_operations nfs_file_aops = {
451 .launder_page = nfs_launder_page, 451 .launder_page = nfs_launder_page,
452}; 452};
453 453
454static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) 454static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
455{ 455{
456 struct page *page = vmf->page;
456 struct file *filp = vma->vm_file; 457 struct file *filp = vma->vm_file;
457 struct dentry *dentry = filp->f_path.dentry; 458 struct dentry *dentry = filp->f_path.dentry;
458 unsigned pagelen; 459 unsigned pagelen;
@@ -483,6 +484,8 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page)
483 ret = pagelen; 484 ret = pagelen;
484out_unlock: 485out_unlock:
485 unlock_page(page); 486 unlock_page(page);
487 if (ret)
488 ret = VM_FAULT_SIGBUS;
486 return ret; 489 return ret;
487} 490}
488 491
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index eea1d24713ea..b606496b72ec 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -154,8 +154,9 @@ out:
154 return ret; 154 return ret;
155} 155}
156 156
157static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct page *page) 157static int ocfs2_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
158{ 158{
159 struct page *page = vmf->page;
159 struct inode *inode = vma->vm_file->f_path.dentry->d_inode; 160 struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
160 struct buffer_head *di_bh = NULL; 161 struct buffer_head *di_bh = NULL;
161 sigset_t blocked, oldset; 162 sigset_t blocked, oldset;
@@ -196,7 +197,8 @@ out:
196 ret2 = ocfs2_vm_op_unblock_sigs(&oldset); 197 ret2 = ocfs2_vm_op_unblock_sigs(&oldset);
197 if (ret2 < 0) 198 if (ret2 < 0)
198 mlog_errno(ret2); 199 mlog_errno(ret2);
199 200 if (ret)
201 ret = VM_FAULT_SIGBUS;
200 return ret; 202 return ret;
201} 203}
202 204
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 93b6de51f261..0ff89fe71e51 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1434,8 +1434,9 @@ static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags)
1434 * mmap()d file has taken write protection fault and is being made 1434 * mmap()d file has taken write protection fault and is being made
1435 * writable. UBIFS must ensure page is budgeted for. 1435 * writable. UBIFS must ensure page is budgeted for.
1436 */ 1436 */
1437static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page) 1437static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
1438{ 1438{
1439 struct page *page = vmf->page;
1439 struct inode *inode = vma->vm_file->f_path.dentry->d_inode; 1440 struct inode *inode = vma->vm_file->f_path.dentry->d_inode;
1440 struct ubifs_info *c = inode->i_sb->s_fs_info; 1441 struct ubifs_info *c = inode->i_sb->s_fs_info;
1441 struct timespec now = ubifs_current_time(inode); 1442 struct timespec now = ubifs_current_time(inode);
@@ -1447,7 +1448,7 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page)
1447 ubifs_assert(!(inode->i_sb->s_flags & MS_RDONLY)); 1448 ubifs_assert(!(inode->i_sb->s_flags & MS_RDONLY));
1448 1449
1449 if (unlikely(c->ro_media)) 1450 if (unlikely(c->ro_media))
1450 return -EROFS; 1451 return VM_FAULT_SIGBUS; /* -EROFS */
1451 1452
1452 /* 1453 /*
1453 * We have not locked @page so far so we may budget for changing the 1454 * We have not locked @page so far so we may budget for changing the
@@ -1480,7 +1481,7 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page)
1480 if (err == -ENOSPC) 1481 if (err == -ENOSPC)
1481 ubifs_warn("out of space for mmapped file " 1482 ubifs_warn("out of space for mmapped file "
1482 "(inode number %lu)", inode->i_ino); 1483 "(inode number %lu)", inode->i_ino);
1483 return err; 1484 return VM_FAULT_SIGBUS;
1484 } 1485 }
1485 1486
1486 lock_page(page); 1487 lock_page(page);
@@ -1520,6 +1521,8 @@ static int ubifs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page)
1520out_unlock: 1521out_unlock:
1521 unlock_page(page); 1522 unlock_page(page);
1522 ubifs_release_budget(c, &req); 1523 ubifs_release_budget(c, &req);
1524 if (err)
1525 err = VM_FAULT_SIGBUS;
1523 return err; 1526 return err;
1524} 1527}
1525 1528
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index e14c4e3aea0c..f4e255441574 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -234,9 +234,9 @@ xfs_file_mmap(
234STATIC int 234STATIC int
235xfs_vm_page_mkwrite( 235xfs_vm_page_mkwrite(
236 struct vm_area_struct *vma, 236 struct vm_area_struct *vma,
237 struct page *page) 237 struct vm_fault *vmf)
238{ 238{
239 return block_page_mkwrite(vma, page, xfs_get_blocks); 239 return block_page_mkwrite(vma, vmf, xfs_get_blocks);
240} 240}
241 241
242const struct file_operations xfs_file_operations = { 242const struct file_operations xfs_file_operations = {
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index f19fd9045ea0..3d7bcde2e332 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -216,7 +216,7 @@ int cont_write_begin(struct file *, struct address_space *, loff_t,
216 get_block_t *, loff_t *); 216 get_block_t *, loff_t *);
217int generic_cont_expand_simple(struct inode *inode, loff_t size); 217int generic_cont_expand_simple(struct inode *inode, loff_t size);
218int block_commit_write(struct page *page, unsigned from, unsigned to); 218int block_commit_write(struct page *page, unsigned from, unsigned to);
219int block_page_mkwrite(struct vm_area_struct *vma, struct page *page, 219int block_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf,
220 get_block_t get_block); 220 get_block_t get_block);
221void block_sync_page(struct page *); 221void block_sync_page(struct page *);
222sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *); 222sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 2223f8dfa568..aeabe953ba4f 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -135,6 +135,7 @@ extern pgprot_t protection_map[16];
135 135
136#define FAULT_FLAG_WRITE 0x01 /* Fault was a write access */ 136#define FAULT_FLAG_WRITE 0x01 /* Fault was a write access */
137#define FAULT_FLAG_NONLINEAR 0x02 /* Fault was via a nonlinear mapping */ 137#define FAULT_FLAG_NONLINEAR 0x02 /* Fault was via a nonlinear mapping */
138#define FAULT_FLAG_MKWRITE 0x04 /* Fault was mkwrite of existing pte */
138 139
139/* 140/*
140 * This interface is used by x86 PAT code to identify a pfn mapping that is 141 * This interface is used by x86 PAT code to identify a pfn mapping that is
@@ -187,7 +188,7 @@ struct vm_operations_struct {
187 188
188 /* notification that a previously read-only page is about to become 189 /* notification that a previously read-only page is about to become
189 * writable, if an error is returned it will cause a SIGBUS */ 190 * writable, if an error is returned it will cause a SIGBUS */
190 int (*page_mkwrite)(struct vm_area_struct *vma, struct page *page); 191 int (*page_mkwrite)(struct vm_area_struct *vma, struct vm_fault *vmf);
191 192
192 /* called by access_process_vm when get_user_pages() fails, typically 193 /* called by access_process_vm when get_user_pages() fails, typically
193 * for use by special VMAs that can switch between memory and hardware 194 * for use by special VMAs that can switch between memory and hardware
diff --git a/mm/memory.c b/mm/memory.c
index 5b4ad5e4f98d..cf6873e91c6a 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1945,6 +1945,15 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
1945 * get_user_pages(.write=1, .force=1). 1945 * get_user_pages(.write=1, .force=1).
1946 */ 1946 */
1947 if (vma->vm_ops && vma->vm_ops->page_mkwrite) { 1947 if (vma->vm_ops && vma->vm_ops->page_mkwrite) {
1948 struct vm_fault vmf;
1949 int tmp;
1950
1951 vmf.virtual_address = (void __user *)(address &
1952 PAGE_MASK);
1953 vmf.pgoff = old_page->index;
1954 vmf.flags = FAULT_FLAG_WRITE|FAULT_FLAG_MKWRITE;
1955 vmf.page = old_page;
1956
1948 /* 1957 /*
1949 * Notify the address space that the page is about to 1958 * Notify the address space that the page is about to
1950 * become writable so that it can prohibit this or wait 1959 * become writable so that it can prohibit this or wait
@@ -1956,8 +1965,12 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
1956 page_cache_get(old_page); 1965 page_cache_get(old_page);
1957 pte_unmap_unlock(page_table, ptl); 1966 pte_unmap_unlock(page_table, ptl);
1958 1967
1959 if (vma->vm_ops->page_mkwrite(vma, old_page) < 0) 1968 tmp = vma->vm_ops->page_mkwrite(vma, &vmf);
1969 if (unlikely(tmp &
1970 (VM_FAULT_ERROR | VM_FAULT_NOPAGE))) {
1971 ret = tmp;
1960 goto unwritable_page; 1972 goto unwritable_page;
1973 }
1961 1974
1962 /* 1975 /*
1963 * Since we dropped the lock we need to revalidate 1976 * Since we dropped the lock we need to revalidate
@@ -2106,7 +2119,7 @@ oom:
2106 2119
2107unwritable_page: 2120unwritable_page:
2108 page_cache_release(old_page); 2121 page_cache_release(old_page);
2109 return VM_FAULT_SIGBUS; 2122 return ret;
2110} 2123}
2111 2124
2112/* 2125/*
@@ -2648,9 +2661,14 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
2648 * to become writable 2661 * to become writable
2649 */ 2662 */
2650 if (vma->vm_ops->page_mkwrite) { 2663 if (vma->vm_ops->page_mkwrite) {
2664 int tmp;
2665
2651 unlock_page(page); 2666 unlock_page(page);
2652 if (vma->vm_ops->page_mkwrite(vma, page) < 0) { 2667 vmf.flags |= FAULT_FLAG_MKWRITE;
2653 ret = VM_FAULT_SIGBUS; 2668 tmp = vma->vm_ops->page_mkwrite(vma, &vmf);
2669 if (unlikely(tmp &
2670 (VM_FAULT_ERROR | VM_FAULT_NOPAGE))) {
2671 ret = tmp;
2654 anon = 1; /* no anon but release vmf.page */ 2672 anon = 1; /* no anon but release vmf.page */
2655 goto out_unlocked; 2673 goto out_unlocked;
2656 } 2674 }