aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKen Chen <kenchen@google.com>2007-11-14 19:59:44 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-11-14 21:45:40 -0500
commit45c682a68a87251d9a01383ce076ab21ee09812e (patch)
treed9fa6a02263c50ef97e1c525b91b29b6aedf9e40
parent8cde045c7ee97573be6ce495b8f7c918182a2c7a (diff)
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 <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>
-rw-r--r--include/linux/hugetlb.h2
-rw-r--r--mm/hugetlb.c10
2 files changed, 12 insertions, 0 deletions
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 8104e5af75ab..24968790bc3e 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);
168int hugetlb_get_quota(struct address_space *mapping, long delta); 168int hugetlb_get_quota(struct address_space *mapping, long delta);
169void hugetlb_put_quota(struct address_space *mapping, long delta); 169void hugetlb_put_quota(struct address_space *mapping, long delta);
170 170
171#define BLOCKS_PER_HUGEPAGE (HPAGE_SIZE / 512)
172
171static inline int is_file_hugepages(struct file *file) 173static inline int is_file_hugepages(struct file *file)
172{ 174{
173 if (file->f_op == &hugetlbfs_file_operations) 175 if (file->f_op == &hugetlbfs_file_operations)
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index abe1e9f2a942..6121b57bbe96 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -801,6 +801,7 @@ retry:
801 801
802 if (vma->vm_flags & VM_SHARED) { 802 if (vma->vm_flags & VM_SHARED) {
803 int err; 803 int err;
804 struct inode *inode = mapping->host;
804 805
805 err = add_to_page_cache(page, mapping, idx, GFP_KERNEL); 806 err = add_to_page_cache(page, mapping, idx, GFP_KERNEL);
806 if (err) { 807 if (err) {
@@ -809,6 +810,10 @@ retry:
809 goto retry; 810 goto retry;
810 goto out; 811 goto out;
811 } 812 }
813
814 spin_lock(&inode->i_lock);
815 inode->i_blocks += BLOCKS_PER_HUGEPAGE;
816 spin_unlock(&inode->i_lock);
812 } else 817 } else
813 lock_page(page); 818 lock_page(page);
814 } 819 }
@@ -1160,6 +1165,11 @@ int hugetlb_reserve_pages(struct inode *inode, long from, long to)
1160void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed) 1165void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed)
1161{ 1166{
1162 long chg = region_truncate(&inode->i_mapping->private_list, offset); 1167 long chg = region_truncate(&inode->i_mapping->private_list, offset);
1168
1169 spin_lock(&inode->i_lock);
1170 inode->i_blocks -= BLOCKS_PER_HUGEPAGE * freed;
1171 spin_unlock(&inode->i_lock);
1172
1163 hugetlb_put_quota(inode->i_mapping, (chg - freed)); 1173 hugetlb_put_quota(inode->i_mapping, (chg - freed));
1164 hugetlb_acct_memory(-(chg - freed)); 1174 hugetlb_acct_memory(-(chg - freed));
1165} 1175}