diff options
Diffstat (limited to 'fs/inode.c')
| -rw-r--r-- | fs/inode.c | 63 |
1 files changed, 37 insertions, 26 deletions
diff --git a/fs/inode.c b/fs/inode.c index da85e56378f..9910c039f02 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
| @@ -84,16 +84,13 @@ static struct hlist_head *inode_hashtable __read_mostly; | |||
| 84 | DEFINE_SPINLOCK(inode_lock); | 84 | DEFINE_SPINLOCK(inode_lock); |
| 85 | 85 | ||
| 86 | /* | 86 | /* |
| 87 | * iprune_sem provides exclusion between the kswapd or try_to_free_pages | 87 | * iprune_sem provides exclusion between the icache shrinking and the |
| 88 | * icache shrinking path, and the umount path. Without this exclusion, | 88 | * umount path. |
| 89 | * by the time prune_icache calls iput for the inode whose pages it has | ||
| 90 | * been invalidating, or by the time it calls clear_inode & destroy_inode | ||
| 91 | * from its final dispose_list, the struct super_block they refer to | ||
| 92 | * (for inode->i_sb->s_op) may already have been freed and reused. | ||
| 93 | * | 89 | * |
| 94 | * We make this an rwsem because the fastpath is icache shrinking. In | 90 | * We don't actually need it to protect anything in the umount path, |
| 95 | * some cases a filesystem may be doing a significant amount of work in | 91 | * but only need to cycle through it to make sure any inode that |
| 96 | * its inode reclaim code, so this should improve parallelism. | 92 | * prune_icache took off the LRU list has been fully torn down by the |
| 93 | * time we are past evict_inodes. | ||
| 97 | */ | 94 | */ |
| 98 | static DECLARE_RWSEM(iprune_sem); | 95 | static DECLARE_RWSEM(iprune_sem); |
| 99 | 96 | ||
| @@ -295,6 +292,20 @@ static void destroy_inode(struct inode *inode) | |||
| 295 | call_rcu(&inode->i_rcu, i_callback); | 292 | call_rcu(&inode->i_rcu, i_callback); |
| 296 | } | 293 | } |
| 297 | 294 | ||
| 295 | void address_space_init_once(struct address_space *mapping) | ||
| 296 | { | ||
| 297 | memset(mapping, 0, sizeof(*mapping)); | ||
| 298 | INIT_RADIX_TREE(&mapping->page_tree, GFP_ATOMIC); | ||
| 299 | spin_lock_init(&mapping->tree_lock); | ||
| 300 | spin_lock_init(&mapping->i_mmap_lock); | ||
| 301 | INIT_LIST_HEAD(&mapping->private_list); | ||
| 302 | spin_lock_init(&mapping->private_lock); | ||
| 303 | INIT_RAW_PRIO_TREE_ROOT(&mapping->i_mmap); | ||
| 304 | INIT_LIST_HEAD(&mapping->i_mmap_nonlinear); | ||
| 305 | mutex_init(&mapping->unmap_mutex); | ||
| 306 | } | ||
| 307 | EXPORT_SYMBOL(address_space_init_once); | ||
| 308 | |||
| 298 | /* | 309 | /* |
| 299 | * These are initializations that only need to be done | 310 | * These are initializations that only need to be done |
| 300 | * once, because the fields are idempotent across use | 311 | * once, because the fields are idempotent across use |
| @@ -308,13 +319,7 @@ void inode_init_once(struct inode *inode) | |||
| 308 | INIT_LIST_HEAD(&inode->i_devices); | 319 | INIT_LIST_HEAD(&inode->i_devices); |
| 309 | INIT_LIST_HEAD(&inode->i_wb_list); | 320 | INIT_LIST_HEAD(&inode->i_wb_list); |
| 310 | INIT_LIST_HEAD(&inode->i_lru); | 321 | INIT_LIST_HEAD(&inode->i_lru); |
| 311 | INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC); | 322 | address_space_init_once(&inode->i_data); |
| 312 | spin_lock_init(&inode->i_data.tree_lock); | ||
| 313 | spin_lock_init(&inode->i_data.i_mmap_lock); | ||
| 314 | INIT_LIST_HEAD(&inode->i_data.private_list); | ||
| 315 | spin_lock_init(&inode->i_data.private_lock); | ||
| 316 | INIT_RAW_PRIO_TREE_ROOT(&inode->i_data.i_mmap); | ||
| 317 | INIT_LIST_HEAD(&inode->i_data.i_mmap_nonlinear); | ||
| 318 | i_size_ordered_init(inode); | 323 | i_size_ordered_init(inode); |
| 319 | #ifdef CONFIG_FSNOTIFY | 324 | #ifdef CONFIG_FSNOTIFY |
| 320 | INIT_HLIST_HEAD(&inode->i_fsnotify_marks); | 325 | INIT_HLIST_HEAD(&inode->i_fsnotify_marks); |
| @@ -508,17 +513,12 @@ void evict_inodes(struct super_block *sb) | |||
| 508 | struct inode *inode, *next; | 513 | struct inode *inode, *next; |
| 509 | LIST_HEAD(dispose); | 514 | LIST_HEAD(dispose); |
| 510 | 515 | ||
| 511 | down_write(&iprune_sem); | ||
| 512 | |||
| 513 | spin_lock(&inode_lock); | 516 | spin_lock(&inode_lock); |
| 514 | list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) { | 517 | list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) { |
| 515 | if (atomic_read(&inode->i_count)) | 518 | if (atomic_read(&inode->i_count)) |
| 516 | continue; | 519 | continue; |
| 517 | 520 | if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE)) | |
| 518 | if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE)) { | ||
| 519 | WARN_ON(1); | ||
| 520 | continue; | 521 | continue; |
| 521 | } | ||
| 522 | 522 | ||
| 523 | inode->i_state |= I_FREEING; | 523 | inode->i_state |= I_FREEING; |
| 524 | 524 | ||
| @@ -534,28 +534,40 @@ void evict_inodes(struct super_block *sb) | |||
| 534 | spin_unlock(&inode_lock); | 534 | spin_unlock(&inode_lock); |
| 535 | 535 | ||
| 536 | dispose_list(&dispose); | 536 | dispose_list(&dispose); |
| 537 | |||
| 538 | /* | ||
| 539 | * Cycle through iprune_sem to make sure any inode that prune_icache | ||
| 540 | * moved off the list before we took the lock has been fully torn | ||
| 541 | * down. | ||
| 542 | */ | ||
| 543 | down_write(&iprune_sem); | ||
| 537 | up_write(&iprune_sem); | 544 | up_write(&iprune_sem); |
| 538 | } | 545 | } |
| 539 | 546 | ||
| 540 | /** | 547 | /** |
| 541 | * invalidate_inodes - attempt to free all inodes on a superblock | 548 | * invalidate_inodes - attempt to free all inodes on a superblock |
| 542 | * @sb: superblock to operate on | 549 | * @sb: superblock to operate on |
| 550 | * @kill_dirty: flag to guide handling of dirty inodes | ||
| 543 | * | 551 | * |
| 544 | * Attempts to free all inodes for a given superblock. If there were any | 552 | * Attempts to free all inodes for a given superblock. If there were any |
| 545 | * busy inodes return a non-zero value, else zero. | 553 | * busy inodes return a non-zero value, else zero. |
| 554 | * If @kill_dirty is set, discard dirty inodes too, otherwise treat | ||
| 555 | * them as busy. | ||
| 546 | */ | 556 | */ |
| 547 | int invalidate_inodes(struct super_block *sb) | 557 | int invalidate_inodes(struct super_block *sb, bool kill_dirty) |
| 548 | { | 558 | { |
| 549 | int busy = 0; | 559 | int busy = 0; |
| 550 | struct inode *inode, *next; | 560 | struct inode *inode, *next; |
| 551 | LIST_HEAD(dispose); | 561 | LIST_HEAD(dispose); |
| 552 | 562 | ||
| 553 | down_write(&iprune_sem); | ||
| 554 | |||
| 555 | spin_lock(&inode_lock); | 563 | spin_lock(&inode_lock); |
| 556 | list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) { | 564 | list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) { |
| 557 | if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE)) | 565 | if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE)) |
| 558 | continue; | 566 | continue; |
| 567 | if (inode->i_state & I_DIRTY && !kill_dirty) { | ||
| 568 | busy = 1; | ||
| 569 | continue; | ||
| 570 | } | ||
| 559 | if (atomic_read(&inode->i_count)) { | 571 | if (atomic_read(&inode->i_count)) { |
| 560 | busy = 1; | 572 | busy = 1; |
| 561 | continue; | 573 | continue; |
| @@ -575,7 +587,6 @@ int invalidate_inodes(struct super_block *sb) | |||
| 575 | spin_unlock(&inode_lock); | 587 | spin_unlock(&inode_lock); |
| 576 | 588 | ||
| 577 | dispose_list(&dispose); | 589 | dispose_list(&dispose); |
| 578 | up_write(&iprune_sem); | ||
| 579 | 590 | ||
| 580 | return busy; | 591 | return busy; |
| 581 | } | 592 | } |
