From: Ken Chen Date: Thu, 15 Nov 2007 00:59:44 +0000 (-0800) Subject: hugetlb: fix i_blocks accounting X-Git-Tag: v2.6.24-rc3~88 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=45c682a68a87251d9a01383ce076ab21ee09812e;p=linux-2.6 hugetlb: fix i_blocks accounting 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 Acked-by: Adam Litke Cc: Badari Pulavarty Cc: David Gibson Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 8104e5af75..24968790bc 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -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) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index abe1e9f2a9..6121b57bbe 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -801,6 +801,7 @@ retry: 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) { @@ -809,6 +810,10 @@ retry: goto retry; goto out; } + + spin_lock(&inode->i_lock); + inode->i_blocks += BLOCKS_PER_HUGEPAGE; + spin_unlock(&inode->i_lock); } else lock_page(page); } @@ -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)); }