Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 61528
b: refs/heads/master
c: d00806b
h: refs/heads/master
v: v3
  • Loading branch information
Nick Piggin authored and Linus Torvalds committed Jul 19, 2007
1 parent 9754efa commit d51f55e
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 117 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: 589f1e81bde732dd0b1bc5d01b6bddd4bcb4527b
refs/heads/master: d00806b183152af6d24f46f0c33f14162ca1262a
2 changes: 2 additions & 0 deletions trunk/fs/gfs2/ops_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,8 @@ static int gfs2_mmap(struct file *file, struct vm_area_struct *vma)
else
vma->vm_ops = &gfs2_vm_ops_private;

vma->vm_flags |= VM_CAN_INVALIDATE;

gfs2_glock_dq_uninit(&i_gh);

return error;
Expand Down
2 changes: 2 additions & 0 deletions trunk/fs/gfs2/ops_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ static struct page *gfs2_sharewrite_nopage(struct vm_area_struct *area,
if (alloc_required) {
error = alloc_page_backing(ip, result);
if (error) {
if (area->vm_flags & VM_CAN_INVALIDATE)
unlock_page(result);
page_cache_release(result);
result = NULL;
goto out;
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/ncpfs/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ int ncp_mmap(struct file *file, struct vm_area_struct *vma)
return -EFBIG;

vma->vm_ops = &ncp_file_mmap;
vma->vm_flags |= VM_CAN_INVALIDATE;
file_accessed(file);
return 0;
}
1 change: 1 addition & 0 deletions trunk/fs/ocfs2/mmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ int ocfs2_mmap(struct file *file, struct vm_area_struct *vma)
ocfs2_meta_unlock(file->f_dentry->d_inode, lock_level);
out:
vma->vm_ops = &ocfs2_file_vm_ops;
vma->vm_flags |= VM_CAN_INVALIDATE;
return 0;
}

1 change: 1 addition & 0 deletions trunk/fs/xfs/linux-2.6/xfs_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,6 +310,7 @@ xfs_file_mmap(
struct vm_area_struct *vma)
{
vma->vm_ops = &xfs_file_vm_ops;
vma->vm_flags |= VM_CAN_INVALIDATE;

#ifdef CONFIG_XFS_DMAPI
if (vn_from_inode(filp->f_path.dentry->d_inode)->v_vfsp->vfs_flag & VFS_DMI)
Expand Down
6 changes: 6 additions & 0 deletions trunk/include/linux/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,12 @@ extern unsigned int kobjsize(const void *objp);
#define VM_INSERTPAGE 0x02000000 /* The vma has had "vm_insert_page()" done on it */
#define VM_ALWAYSDUMP 0x04000000 /* Always include in core dumps */

#define VM_CAN_INVALIDATE 0x08000000 /* The mapping may be invalidated,
* eg. truncate or invalidate_inode_*.
* In this case, do_no_page must
* return with the page locked.
*/

#ifndef VM_STACK_DEFAULT_FLAGS /* arch can override this */
#define VM_STACK_DEFAULT_FLAGS VM_DATA_DEFAULT_FLAGS
#endif
Expand Down
53 changes: 20 additions & 33 deletions trunk/mm/filemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1325,9 +1325,10 @@ struct page *filemap_nopage(struct vm_area_struct *area,
unsigned long size, pgoff;
int did_readaround = 0, majmin = VM_FAULT_MINOR;

BUG_ON(!(area->vm_flags & VM_CAN_INVALIDATE));

pgoff = ((address-area->vm_start) >> PAGE_CACHE_SHIFT) + area->vm_pgoff;

retry_all:
size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
if (pgoff >= size)
goto outside_data_content;
Expand All @@ -1349,7 +1350,7 @@ struct page *filemap_nopage(struct vm_area_struct *area,
* Do we have something in the page cache already?
*/
retry_find:
page = find_get_page(mapping, pgoff);
page = find_lock_page(mapping, pgoff);
if (!page) {
unsigned long ra_pages;

Expand Down Expand Up @@ -1383,7 +1384,7 @@ struct page *filemap_nopage(struct vm_area_struct *area,
start = pgoff - ra_pages / 2;
do_page_cache_readahead(mapping, file, start, ra_pages);
}
page = find_get_page(mapping, pgoff);
page = find_lock_page(mapping, pgoff);
if (!page)
goto no_cached_page;
}
Expand All @@ -1392,13 +1393,19 @@ struct page *filemap_nopage(struct vm_area_struct *area,
ra->mmap_hit++;

/*
* Ok, found a page in the page cache, now we need to check
* that it's up-to-date.
* We have a locked page in the page cache, now we need to check
* that it's up-to-date. If not, it is going to be due to an error.
*/
if (!PageUptodate(page))
if (unlikely(!PageUptodate(page)))
goto page_not_uptodate;

success:
/* Must recheck i_size under page lock */
size = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
if (unlikely(pgoff >= size)) {
unlock_page(page);
goto outside_data_content;
}

/*
* Found the page and have a reference on it.
*/
Expand Down Expand Up @@ -1440,6 +1447,7 @@ struct page *filemap_nopage(struct vm_area_struct *area,
return NOPAGE_SIGBUS;

page_not_uptodate:
/* IO error path */
if (!did_readaround) {
majmin = VM_FAULT_MAJOR;
count_vm_event(PGMAJFAULT);
Expand All @@ -1451,37 +1459,15 @@ struct page *filemap_nopage(struct vm_area_struct *area,
* because there really aren't any performance issues here
* and we need to check for errors.
*/
lock_page(page);

/* Somebody truncated the page on us? */
if (!page->mapping) {
unlock_page(page);
page_cache_release(page);
goto retry_all;
}

/* Somebody else successfully read it in? */
if (PageUptodate(page)) {
unlock_page(page);
goto success;
}
ClearPageError(page);
error = mapping->a_ops->readpage(file, page);
if (!error) {
wait_on_page_locked(page);
if (PageUptodate(page))
goto success;
} else if (error == AOP_TRUNCATED_PAGE) {
page_cache_release(page);
page_cache_release(page);

if (!error || error == AOP_TRUNCATED_PAGE)
goto retry_find;
}

/*
* Things didn't work out. Return zero to tell the
* mm layer so, possibly freeing the page cache page first.
*/
/* Things didn't work out. Return zero to tell the mm layer so. */
shrink_readahead_size_eio(file, ra);
page_cache_release(page);
return NOPAGE_SIGBUS;
}
EXPORT_SYMBOL(filemap_nopage);
Expand Down Expand Up @@ -1674,6 +1660,7 @@ int generic_file_mmap(struct file * file, struct vm_area_struct * vma)
return -ENOEXEC;
file_accessed(file);
vma->vm_ops = &generic_file_vm_ops;
vma->vm_flags |= VM_CAN_INVALIDATE;
return 0;
}

Expand Down
Loading

0 comments on commit d51f55e

Please sign in to comment.