diff options
author | David Howells <dhowells@redhat.com> | 2013-09-04 17:10:39 +0000 |
---|---|---|
committer | Steve French <smfrench@gmail.com> | 2013-09-18 10:17:03 -0500 |
commit | 54afa99057ee2ffd3df0f5e891298bbbb65ea63c (patch) | |
tree | bbe235d0310023e4c4eace892b1de10faee13c3f /fs/cifs/file.c | |
parent | 62d228b8c676232eca579f91cc0782b060a59097 (diff) | |
download | linux-stable-54afa99057ee2ffd3df0f5e891298bbbb65ea63c.tar.gz linux-stable-54afa99057ee2ffd3df0f5e891298bbbb65ea63c.tar.bz2 linux-stable-54afa99057ee2ffd3df0f5e891298bbbb65ea63c.zip |
CIFS: FS-Cache: Uncache unread pages in cifs_readpages() before freeing them
In cifs_readpages(), we may decide we don't want to read a page after all -
but the page may already have passed through fscache_read_or_alloc_pages() and
thus have marks and reservations set. Thus we have to call
fscache_readpages_cancel() or fscache_uncache_page() on the pages we're
returning to clear the marks.
NFS, AFS and 9P should be unaffected by this as they call read_cache_pages()
which does the cleanup for you.
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Jeff Layton <jlayton@redhat.com>
Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs/cifs/file.c')
-rw-r--r-- | fs/cifs/file.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index eb955b525e55..7ddddf2e2504 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -3254,6 +3254,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, /* * Reads as many pages as possible from fscache. Returns -ENOBUFS * immediately if the cookie is negative + * + * After this point, every page in the list might have PG_fscache set, + * so we will need to clean that up off of every page we don't use. */ rc = cifs_readpages_from_fscache(mapping->host, mapping, page_list, &num_pages); @@ -3376,6 +3379,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, kref_put(&rdata->refcount, cifs_readdata_release); } + /* Any pages that have been shown to fscache but didn't get added to + * the pagecache must be uncached before they get returned to the + * allocator. + */ + cifs_fscache_readpages_cancel(mapping->host, page_list); return rc; } |