diff options
author | David Howells <dhowells@redhat.com> | 2009-01-08 12:04:46 +0000 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2009-01-08 12:04:46 +0000 |
commit | 0e8f989a253b1bf85ea1c8d7987d67c054f4af91 (patch) | |
tree | 0b8b2c1e5c09c5cd46851680d8de2a0ad3c0fa9b | |
parent | 9e42d0cf5020aaf217433cad1a224745241d212a (diff) | |
download | linux-0e8f989a253b1bf85ea1c8d7987d67c054f4af91.tar.gz linux-0e8f989a253b1bf85ea1c8d7987d67c054f4af91.tar.bz2 linux-0e8f989a253b1bf85ea1c8d7987d67c054f4af91.zip |
NOMMU: Fix cleanup handling in ramfs_nommu_get_umapped_area()
Fix cleanup handling in ramfs_nommu_get_umapped_area() by only freeing the
number of pages that find_get_pages() said it had returned (nr) rather than
attempting to free the number of pages we asked for (lpages) - thus avoiding
the situation whereby put_page() may be handed NULL pointers if
find_get_pages() returned fewer pages that were requested.
Also avoid a warning about nr being uninitialised and the need for an
if-statement in the cleanup path by using appropriate gotos.
Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r-- | fs/ramfs/file-nommu.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c index 76acdbc34611..b9b567a28376 100644 --- a/fs/ramfs/file-nommu.c +++ b/fs/ramfs/file-nommu.c @@ -262,11 +262,11 @@ unsigned long ramfs_nommu_get_unmapped_area(struct file *file, ret = -ENOMEM; pages = kzalloc(lpages * sizeof(struct page *), GFP_KERNEL); if (!pages) - goto out; + goto out_free; nr = find_get_pages(inode->i_mapping, pgoff, lpages, pages); if (nr != lpages) - goto out; /* leave if some pages were missing */ + goto out_free_pages; /* leave if some pages were missing */ /* check the pages for physical adjacency */ ptr = pages; @@ -274,19 +274,18 @@ unsigned long ramfs_nommu_get_unmapped_area(struct file *file, page++; for (loop = lpages; loop > 1; loop--) if (*ptr++ != page++) - goto out; + goto out_free_pages; /* okay - all conditions fulfilled */ ret = (unsigned long) page_address(pages[0]); - out: - if (pages) { - ptr = pages; - for (loop = lpages; loop > 0; loop--) - put_page(*ptr++); - kfree(pages); - } - +out_free_pages: + ptr = pages; + for (loop = nr; loop > 0; loop--) + put_page(*ptr++); +out_free: + kfree(pages); +out: return ret; } |