aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hugetlbfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2005-10-29 21:16:42 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-30 00:40:43 -0400
commit96527980d4cb8f65fe49efdbc4ab92c0837d42f6 (patch)
tree93b6b438cee41d62e562ae277e67c9b6cad288a7 /fs/hugetlbfs
parentb8072f099b7829a6ff3eba618e1d079a81f753f8 (diff)
[PATCH] hugetlbfs: move free_inodes accounting
Move hugetlbfs accounting into ->alloc_inode / ->destroy_inode. This keeps the code simpler, fixes a loeak where a failing inode allocation wouldn't decrement the counter and moves hugetlbfs_delete_inode and hugetlbfs_forget_inode closer to their generic counterparts. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/hugetlbfs')
-rw-r--r--fs/hugetlbfs/inode.c78
1 files changed, 42 insertions, 36 deletions
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index a826a8add5e3..8e9d43633365 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -224,8 +224,6 @@ static void truncate_hugepages(struct address_space *mapping, loff_t lstart)
224 224
225static void hugetlbfs_delete_inode(struct inode *inode) 225static void hugetlbfs_delete_inode(struct inode *inode)
226{ 226{
227 struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(inode->i_sb);
228
229 hlist_del_init(&inode->i_hash); 227 hlist_del_init(&inode->i_hash);
230 list_del_init(&inode->i_list); 228 list_del_init(&inode->i_list);
231 list_del_init(&inode->i_sb_list); 229 list_del_init(&inode->i_sb_list);
@@ -238,12 +236,6 @@ static void hugetlbfs_delete_inode(struct inode *inode)
238 236
239 security_inode_delete(inode); 237 security_inode_delete(inode);
240 238
241 if (sbinfo->free_inodes >= 0) {
242 spin_lock(&sbinfo->stat_lock);
243 sbinfo->free_inodes++;
244 spin_unlock(&sbinfo->stat_lock);
245 }
246
247 clear_inode(inode); 239 clear_inode(inode);
248 destroy_inode(inode); 240 destroy_inode(inode);
249} 241}
@@ -251,7 +243,6 @@ static void hugetlbfs_delete_inode(struct inode *inode)
251static void hugetlbfs_forget_inode(struct inode *inode) 243static void hugetlbfs_forget_inode(struct inode *inode)
252{ 244{
253 struct super_block *super_block = inode->i_sb; 245 struct super_block *super_block = inode->i_sb;
254 struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(super_block);
255 246
256 if (hlist_unhashed(&inode->i_hash)) 247 if (hlist_unhashed(&inode->i_hash))
257 goto out_truncate; 248 goto out_truncate;
@@ -278,12 +269,6 @@ out_truncate:
278 if (inode->i_data.nrpages) 269 if (inode->i_data.nrpages)
279 truncate_hugepages(&inode->i_data, 0); 270 truncate_hugepages(&inode->i_data, 0);
280 271
281 if (sbinfo->free_inodes >= 0) {
282 spin_lock(&sbinfo->stat_lock);
283 sbinfo->free_inodes++;
284 spin_unlock(&sbinfo->stat_lock);
285 }
286
287 clear_inode(inode); 272 clear_inode(inode);
288 destroy_inode(inode); 273 destroy_inode(inode);
289} 274}
@@ -375,17 +360,6 @@ static struct inode *hugetlbfs_get_inode(struct super_block *sb, uid_t uid,
375 gid_t gid, int mode, dev_t dev) 360 gid_t gid, int mode, dev_t dev)
376{ 361{
377 struct inode *inode; 362 struct inode *inode;
378 struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
379
380 if (sbinfo->free_inodes >= 0) {
381 spin_lock(&sbinfo->stat_lock);
382 if (!sbinfo->free_inodes) {
383 spin_unlock(&sbinfo->stat_lock);
384 return NULL;
385 }
386 sbinfo->free_inodes--;
387 spin_unlock(&sbinfo->stat_lock);
388 }
389 363
390 inode = new_inode(sb); 364 inode = new_inode(sb);
391 if (inode) { 365 if (inode) {
@@ -527,29 +501,51 @@ static void hugetlbfs_put_super(struct super_block *sb)
527 } 501 }
528} 502}
529 503
504static inline int hugetlbfs_dec_free_inodes(struct hugetlbfs_sb_info *sbinfo)
505{
506 if (sbinfo->free_inodes >= 0) {
507 spin_lock(&sbinfo->stat_lock);
508 if (unlikely(!sbinfo->free_inodes)) {
509 spin_unlock(&sbinfo->stat_lock);
510 return 0;
511 }
512 sbinfo->free_inodes--;
513 spin_unlock(&sbinfo->stat_lock);
514 }
515
516 return 1;
517}
518
519static void hugetlbfs_inc_free_inodes(struct hugetlbfs_sb_info *sbinfo)
520{
521 if (sbinfo->free_inodes >= 0) {
522 spin_lock(&sbinfo->stat_lock);
523 sbinfo->free_inodes++;
524 spin_unlock(&sbinfo->stat_lock);
525 }
526}
527
528
530static kmem_cache_t *hugetlbfs_inode_cachep; 529static kmem_cache_t *hugetlbfs_inode_cachep;
531 530
532static struct inode *hugetlbfs_alloc_inode(struct super_block *sb) 531static struct inode *hugetlbfs_alloc_inode(struct super_block *sb)
533{ 532{
533 struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
534 struct hugetlbfs_inode_info *p; 534 struct hugetlbfs_inode_info *p;
535 535
536 if (unlikely(!hugetlbfs_dec_free_inodes(sbinfo)))
537 return NULL;
536 p = kmem_cache_alloc(hugetlbfs_inode_cachep, SLAB_KERNEL); 538 p = kmem_cache_alloc(hugetlbfs_inode_cachep, SLAB_KERNEL);
537 if (!p) 539 if (unlikely(!p)) {
540 hugetlbfs_inc_free_inodes(sbinfo);
538 return NULL; 541 return NULL;
542 }
539 return &p->vfs_inode; 543 return &p->vfs_inode;
540} 544}
541 545
542static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
543{
544 struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo;
545
546 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
547 SLAB_CTOR_CONSTRUCTOR)
548 inode_init_once(&ei->vfs_inode);
549}
550
551static void hugetlbfs_destroy_inode(struct inode *inode) 546static void hugetlbfs_destroy_inode(struct inode *inode)
552{ 547{
548 hugetlbfs_inc_free_inodes(HUGETLBFS_SB(inode->i_sb));
553 mpol_free_shared_policy(&HUGETLBFS_I(inode)->policy); 549 mpol_free_shared_policy(&HUGETLBFS_I(inode)->policy);
554 kmem_cache_free(hugetlbfs_inode_cachep, HUGETLBFS_I(inode)); 550 kmem_cache_free(hugetlbfs_inode_cachep, HUGETLBFS_I(inode));
555} 551}
@@ -561,6 +557,16 @@ static struct address_space_operations hugetlbfs_aops = {
561 .set_page_dirty = hugetlbfs_set_page_dirty, 557 .set_page_dirty = hugetlbfs_set_page_dirty,
562}; 558};
563 559
560
561static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
562{
563 struct hugetlbfs_inode_info *ei = (struct hugetlbfs_inode_info *)foo;
564
565 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
566 SLAB_CTOR_CONSTRUCTOR)
567 inode_init_once(&ei->vfs_inode);
568}
569
564struct file_operations hugetlbfs_file_operations = { 570struct file_operations hugetlbfs_file_operations = {
565 .mmap = hugetlbfs_file_mmap, 571 .mmap = hugetlbfs_file_mmap,
566 .fsync = simple_sync_file, 572 .fsync = simple_sync_file,