Commit 96527980d4cb8f65fe49efdbc4ab92c0837d42f6

Authored by Christoph Hellwig
Committed by Linus Torvalds
1 parent b8072f099b

[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>

Showing 1 changed file with 42 additions and 36 deletions Side-by-side Diff

fs/hugetlbfs/inode.c
... ... @@ -224,8 +224,6 @@
224 224  
225 225 static void hugetlbfs_delete_inode(struct inode *inode)
226 226 {
227   - struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(inode->i_sb);
228   -
229 227 hlist_del_init(&inode->i_hash);
230 228 list_del_init(&inode->i_list);
231 229 list_del_init(&inode->i_sb_list);
... ... @@ -238,12 +236,6 @@
238 236  
239 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 239 clear_inode(inode);
248 240 destroy_inode(inode);
249 241 }
... ... @@ -251,7 +243,6 @@
251 243 static void hugetlbfs_forget_inode(struct inode *inode)
252 244 {
253 245 struct super_block *super_block = inode->i_sb;
254   - struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(super_block);
255 246  
256 247 if (hlist_unhashed(&inode->i_hash))
257 248 goto out_truncate;
... ... @@ -278,12 +269,6 @@
278 269 if (inode->i_data.nrpages)
279 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 272 clear_inode(inode);
288 273 destroy_inode(inode);
289 274 }
290 275  
... ... @@ -375,18 +360,7 @@
375 360 gid_t gid, int mode, dev_t dev)
376 361 {
377 362 struct inode *inode;
378   - struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
379 363  
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   -
390 364 inode = new_inode(sb);
391 365 if (inode) {
392 366 struct hugetlbfs_inode_info *info;
393 367  
394 368  
395 369  
396 370  
397 371  
398 372  
... ... @@ -527,29 +501,51 @@
527 501 }
528 502 }
529 503  
  504 +static 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 +
  519 +static 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 +
530 529 static kmem_cache_t *hugetlbfs_inode_cachep;
531 530  
532 531 static struct inode *hugetlbfs_alloc_inode(struct super_block *sb)
533 532 {
  533 + struct hugetlbfs_sb_info *sbinfo = HUGETLBFS_SB(sb);
534 534 struct hugetlbfs_inode_info *p;
535 535  
  536 + if (unlikely(!hugetlbfs_dec_free_inodes(sbinfo)))
  537 + return NULL;
536 538 p = kmem_cache_alloc(hugetlbfs_inode_cachep, SLAB_KERNEL);
537   - if (!p)
  539 + if (unlikely(!p)) {
  540 + hugetlbfs_inc_free_inodes(sbinfo);
538 541 return NULL;
  542 + }
539 543 return &p->vfs_inode;
540 544 }
541 545  
542   -static 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   -
551 546 static void hugetlbfs_destroy_inode(struct inode *inode)
552 547 {
  548 + hugetlbfs_inc_free_inodes(HUGETLBFS_SB(inode->i_sb));
553 549 mpol_free_shared_policy(&HUGETLBFS_I(inode)->policy);
554 550 kmem_cache_free(hugetlbfs_inode_cachep, HUGETLBFS_I(inode));
555 551 }
... ... @@ -560,6 +556,16 @@
560 556 .commit_write = hugetlbfs_commit_write,
561 557 .set_page_dirty = hugetlbfs_set_page_dirty,
562 558 };
  559 +
  560 +
  561 +static 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 +}
563 569  
564 570 struct file_operations hugetlbfs_file_operations = {
565 571 .mmap = hugetlbfs_file_mmap,