Growing i_size in hugetlbfs_prefault() isn't right - if we run out of pages,
do_mmap_pgoff() will chop the partially-instantiated pages off again.

So update i_size in hugetlbfs_file_mmap() if the whole mmap attempt was
successful.


 arch/i386/mm/hugetlbpage.c   |    5 -----
 arch/x86_64/mm/hugetlbpage.c |    5 -----
 fs/hugetlbfs/inode.c         |    5 +++++
 3 files changed, 5 insertions(+), 10 deletions(-)

diff -puN arch/i386/mm/hugetlbpage.c~hugetlbfs-i_size-fix arch/i386/mm/hugetlbpage.c
--- 25/arch/i386/mm/hugetlbpage.c~hugetlbfs-i_size-fix	Mon Feb 10 16:55:34 2003
+++ 25-akpm/arch/i386/mm/hugetlbpage.c	Mon Feb 10 16:55:34 2003
@@ -296,7 +296,6 @@ zap_hugepage_range(struct vm_area_struct
 int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
 {
 	struct mm_struct *mm = current->mm;
-	struct inode *inode = mapping->host;
 	unsigned long addr;
 	int ret = 0;
 
@@ -320,7 +319,6 @@ int hugetlb_prefault(struct address_spac
 			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
 		page = find_get_page(mapping, idx);
 		if (!page) {
-			loff_t i_size;
 			page = alloc_hugetlb_page();
 			if (!page) {
 				ret = -ENOMEM;
@@ -332,9 +330,6 @@ int hugetlb_prefault(struct address_spac
 				free_huge_page(page);
 				goto out;
 			}
-			i_size = (loff_t)(idx + 1) * HPAGE_SIZE;
-			if (i_size > inode->i_size)
-				inode->i_size = i_size;
 		}
 		set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
 	}
diff -puN arch/x86_64/mm/hugetlbpage.c~hugetlbfs-i_size-fix arch/x86_64/mm/hugetlbpage.c
--- 25/arch/x86_64/mm/hugetlbpage.c~hugetlbfs-i_size-fix	Mon Feb 10 16:55:34 2003
+++ 25-akpm/arch/x86_64/mm/hugetlbpage.c	Mon Feb 10 16:55:34 2003
@@ -216,7 +216,6 @@ void zap_hugepage_range(struct vm_area_s
 int hugetlb_prefault(struct address_space *mapping, struct vm_area_struct *vma)
 {
 	struct mm_struct *mm = current->mm;
-	struct inode = mapping->host;
 	unsigned long addr;
 	int ret = 0;
 
@@ -240,7 +239,6 @@ int hugetlb_prefault(struct address_spac
 			+ (vma->vm_pgoff >> (HPAGE_SHIFT - PAGE_SHIFT));
 		page = find_get_page(mapping, idx);
 		if (!page) {
-			loff_t i_size;
 
 			page = alloc_hugetlb_page();
 			if (!page) {
@@ -253,9 +251,6 @@ int hugetlb_prefault(struct address_spac
 				free_huge_page(page);
 				goto out;
 			}
-			i_size = (loff_t)(idx + 1) * HPAGE_SIZE;
-			if (i_size > inode->i_size)
-				inode->i_size = i_size;
 		}
 		set_huge_pte(mm, vma, page, pte, vma->vm_flags & VM_WRITE);
 	}
diff -puN fs/hugetlbfs/inode.c~hugetlbfs-i_size-fix fs/hugetlbfs/inode.c
--- 25/fs/hugetlbfs/inode.c~hugetlbfs-i_size-fix	Mon Feb 10 16:55:34 2003
+++ 25-akpm/fs/hugetlbfs/inode.c	Mon Feb 10 16:55:34 2003
@@ -45,6 +45,7 @@ static int hugetlbfs_file_mmap(struct fi
 {
 	struct inode *inode =file->f_dentry->d_inode;
 	struct address_space *mapping = inode->i_mapping;
+	loff_t len;
 	int ret;
 
 	if (!capable(CAP_IPC_LOCK))
@@ -65,6 +66,10 @@ static int hugetlbfs_file_mmap(struct fi
 	vma->vm_flags |= VM_HUGETLB | VM_RESERVED;
 	vma->vm_ops = &hugetlb_vm_ops;
 	ret = hugetlb_prefault(mapping, vma);
+	len = (loff_t)(vma->vm_end - vma->vm_start) +
+			((loff_t)vma->vm_pgoff << PAGE_SHIFT);
+	if (ret == 0 && inode->i_size < len)
+		inode->i_size = len;
 	up(&inode->i_sem);
 	return ret;
 }

_