Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 223046
b: refs/heads/master
c: 6072d13
h: refs/heads/master
v: v3
  • Loading branch information
Linus Torvalds authored and Trond Myklebust committed Dec 2, 2010
1 parent 8d503eb commit 92d5f6f
Show file tree
Hide file tree
Showing 7 changed files with 31 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: 0aded708d125a3ff7e5abaea9c2d9c6d7ebbfdcd
refs/heads/master: 6072d13c429373c5d63b69dadbbef40a9b035552
7 changes: 6 additions & 1 deletion trunk/Documentation/filesystems/Locking
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,13 @@ prototypes:
sector_t (*bmap)(struct address_space *, sector_t);
int (*invalidatepage) (struct page *, unsigned long);
int (*releasepage) (struct page *, int);
void (*freepage)(struct page *);
int (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
loff_t offset, unsigned long nr_segs);
int (*launder_page) (struct page *);

locking rules:
All except set_page_dirty may block
All except set_page_dirty and freepage may block

BKL PageLocked(page) i_mutex
writepage: no yes, unlocks (see below)
Expand All @@ -193,6 +194,7 @@ perform_write: no n/a yes
bmap: no
invalidatepage: no yes
releasepage: no yes
freepage: no yes
direct_IO: no
launder_page: no yes

Expand Down Expand Up @@ -288,6 +290,9 @@ buffers from the page in preparation for freeing it. It returns zero to
indicate that the buffers are (or may be) freeable. If ->releasepage is zero,
the kernel assumes that the fs has no private interest in the buffers.

->freepage() is called when the kernel is done dropping the page
from the page cache.

->launder_page() may be called prior to releasing a page if
it is still found to be dirty. It returns zero if the page was successfully
cleaned, or an error value if not. Note that in order to prevent the page
Expand Down
7 changes: 7 additions & 0 deletions trunk/Documentation/filesystems/vfs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ struct address_space_operations {
sector_t (*bmap)(struct address_space *, sector_t);
int (*invalidatepage) (struct page *, unsigned long);
int (*releasepage) (struct page *, int);
void (*freepage)(struct page *);
ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
loff_t offset, unsigned long nr_segs);
struct page* (*get_xip_page)(struct address_space *, sector_t,
Expand Down Expand Up @@ -679,6 +680,12 @@ struct address_space_operations {
need to ensure this. Possibly it can clear the PageUptodate
bit if it cannot free private data yet.

freepage: freepage is called once the page is no longer visible in
the page cache in order to allow the cleanup of any private
data. Since it may be called by the memory reclaimer, it
should not assume that the original address_space mapping still
exists, and it should not block.

direct_IO: called by the generic read/write routines to perform
direct_IO - that is IO requests which bypass the page cache
and transfer data directly between the storage and the
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,7 @@ struct address_space_operations {
sector_t (*bmap)(struct address_space *, sector_t);
void (*invalidatepage) (struct page *, unsigned long);
int (*releasepage) (struct page *, gfp_t);
void (*freepage)(struct page *);
ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov,
loff_t offset, unsigned long nr_segs);
int (*get_xip_mem)(struct address_space *, pgoff_t, int,
Expand Down
5 changes: 5 additions & 0 deletions trunk/mm/filemap.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,18 @@ void __remove_from_page_cache(struct page *page)
void remove_from_page_cache(struct page *page)
{
struct address_space *mapping = page->mapping;
void (*freepage)(struct page *);

BUG_ON(!PageLocked(page));

freepage = mapping->a_ops->freepage;
spin_lock_irq(&mapping->tree_lock);
__remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
mem_cgroup_uncharge_cache_page(page);

if (freepage)
freepage(page);
}
EXPORT_SYMBOL(remove_from_page_cache);

Expand Down
4 changes: 4 additions & 0 deletions trunk/mm/truncate.c
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,10 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page)
__remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
mem_cgroup_uncharge_cache_page(page);

if (mapping->a_ops->freepage)
mapping->a_ops->freepage(page);

page_cache_release(page); /* pagecache ref */
return 1;
failed:
Expand Down
7 changes: 7 additions & 0 deletions trunk/mm/vmscan.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,9 +494,16 @@ static int __remove_mapping(struct address_space *mapping, struct page *page)
spin_unlock_irq(&mapping->tree_lock);
swapcache_free(swap, page);
} else {
void (*freepage)(struct page *);

freepage = mapping->a_ops->freepage;

__remove_from_page_cache(page);
spin_unlock_irq(&mapping->tree_lock);
mem_cgroup_uncharge_cache_page(page);

if (freepage != NULL)
freepage(page);
}

return 1;
Expand Down

0 comments on commit 92d5f6f

Please sign in to comment.