From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from digeo-nav01.digeo.com (digeo-nav01.digeo.com [192.168.1.233]) by packet.digeo.com (8.9.3+Sun/8.9.3) with SMTP id CAA09914 for ; Sun, 2 Feb 2003 02:55:51 -0800 (PST) Date: Sun, 2 Feb 2003 02:55:58 -0800 From: Andrew Morton Subject: Re: hugepage patches Message-Id: <20030202025558.7bae8546.akpm@digeo.com> In-Reply-To: <20030131151501.7273a9bf.akpm@digeo.com> References: <20030131151501.7273a9bf.akpm@digeo.com> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-linux-mm@kvack.org Return-Path: To: davem@redhat.com, rohit.seth@intel.com, davidm@napali.hpl.hp.com, anton@samba.org, wli@holomorphy.com, linux-mm@kvack.org List-ID: 7/4 hugetlbfs i_size fixes We're expanding hugetlbfs i_size in the wrong place. If someone attempts to mmap more pages than are available, i_size is updated to reflect the attempted mapping size. So set i_size only when pages are successfully added to the mapping. i_size handling at truncate time is still a bit wrong - if the mapping has pages at (say) page offset 100-200 and the mappng is truncated to (say_ page offset 50, i_size should be set to zero. But it is instead set to 50*HPAGE_SIZE. That's harmless. i386/mm/hugetlbpage.c | 5 +++++ ia64/mm/hugetlbpage.c | 0 sparc64/mm/hugetlbpage.c | 0 x86_64/mm/hugetlbpage.c | 6 ++++++ hugetlbfs/inode.c | 5 ----- 5 files changed, 11 insertions(+), 5 deletions(-) diff -puN fs/hugetlbfs/inode.c~hugetlbfs-i_size-fix fs/hugetlbfs/inode.c --- 25/fs/hugetlbfs/inode.c~hugetlbfs-i_size-fix 2003-02-01 02:07:22.000000000 -0800 +++ 25-akpm/fs/hugetlbfs/inode.c 2003-02-01 02:07:22.000000000 -0800 @@ -45,7 +45,6 @@ static int hugetlbfs_file_mmap(struct fi { struct inode *inode =file->f_dentry->d_inode; struct address_space *mapping = inode->i_mapping; - size_t len; int ret; if (!capable(CAP_IPC_LOCK)) @@ -66,10 +65,6 @@ 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 = (vma->vm_end - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); - if (inode->i_size < len) - inode->i_size = len; - up(&inode->i_sem); return ret; } 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 2003-02-01 02:07:22.000000000 -0800 +++ 25-akpm/arch/i386/mm/hugetlbpage.c 2003-02-01 02:07:22.000000000 -0800 @@ -284,6 +284,7 @@ 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 *inode = mapping->host; unsigned long addr; int ret = 0; @@ -307,6 +308,7 @@ 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; @@ -318,6 +320,9 @@ 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/ia64/mm/hugetlbpage.c~hugetlbfs-i_size-fix arch/ia64/mm/hugetlbpage.c diff -puN arch/sparc64/mm/hugetlbpage.c~hugetlbfs-i_size-fix arch/sparc64/mm/hugetlbpage.c 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 2003-02-01 02:07:22.000000000 -0800 +++ 25-akpm/arch/x86_64/mm/hugetlbpage.c 2003-02-01 02:07:22.000000000 -0800 @@ -205,6 +205,7 @@ 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; @@ -228,6 +229,8 @@ 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; @@ -239,6 +242,9 @@ 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); } _ -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/