Skip to content

Commit

Permalink
hugetlb: fix i_blocks accounting
Browse files Browse the repository at this point in the history
For administrative purpose, we want to query actual block usage for
hugetlbfs file via fstat.  Currently, hugetlbfs always return 0.  Fix that
up since kernel already has all the information to track it properly.

Signed-off-by: Ken Chen <kenchen@google.com>
Acked-by: Adam Litke <agl@us.ibm.com>
Cc: Badari Pulavarty <pbadari@us.ibm.com>
Cc: David Gibson <david@gibson.dropbear.id.au>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Ken Chen authored and Linus Torvalds committed Nov 15, 2007
1 parent 8cde045 commit 45c682a
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 0 deletions.
2 changes: 2 additions & 0 deletions include/linux/hugetlb.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ struct file *hugetlb_file_setup(const char *name, size_t);
int hugetlb_get_quota(struct address_space *mapping, long delta);
void hugetlb_put_quota(struct address_space *mapping, long delta);

#define BLOCKS_PER_HUGEPAGE (HPAGE_SIZE / 512)

static inline int is_file_hugepages(struct file *file)
{
if (file->f_op == &hugetlbfs_file_operations)
Expand Down
10 changes: 10 additions & 0 deletions mm/hugetlb.c
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,7 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,

if (vma->vm_flags & VM_SHARED) {
int err;
struct inode *inode = mapping->host;

err = add_to_page_cache(page, mapping, idx, GFP_KERNEL);
if (err) {
Expand All @@ -809,6 +810,10 @@ static int hugetlb_no_page(struct mm_struct *mm, struct vm_area_struct *vma,
goto retry;
goto out;
}

spin_lock(&inode->i_lock);
inode->i_blocks += BLOCKS_PER_HUGEPAGE;
spin_unlock(&inode->i_lock);
} else
lock_page(page);
}
Expand Down Expand Up @@ -1160,6 +1165,11 @@ int hugetlb_reserve_pages(struct inode *inode, long from, long to)
void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed)
{
long chg = region_truncate(&inode->i_mapping->private_list, offset);

spin_lock(&inode->i_lock);
inode->i_blocks -= BLOCKS_PER_HUGEPAGE * freed;
spin_unlock(&inode->i_lock);

hugetlb_put_quota(inode->i_mapping, (chg - freed));
hugetlb_acct_memory(-(chg - freed));
}

0 comments on commit 45c682a

Please sign in to comment.