diff options
| -rw-r--r-- | fs/hugetlbfs/inode.c | 78 |
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 | ||
| 225 | static void hugetlbfs_delete_inode(struct inode *inode) | 225 | static 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) | |||
| 251 | static void hugetlbfs_forget_inode(struct inode *inode) | 243 | static 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 | ||
| 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 | static kmem_cache_t *hugetlbfs_inode_cachep; | 529 | static kmem_cache_t *hugetlbfs_inode_cachep; |
| 531 | 530 | ||
| 532 | static struct inode *hugetlbfs_alloc_inode(struct super_block *sb) | 531 | static 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 | ||
| 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 | static void hugetlbfs_destroy_inode(struct inode *inode) | 546 | static 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 | |||
| 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 | } | ||
| 569 | |||
| 564 | struct file_operations hugetlbfs_file_operations = { | 570 | struct 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, |
