diff options
Diffstat (limited to 'fs/inode.c')
| -rw-r--r-- | fs/inode.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/fs/inode.c b/fs/inode.c index da85e56378f3..0647d80accf6 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
| @@ -295,6 +295,20 @@ static void destroy_inode(struct inode *inode) | |||
| 295 | call_rcu(&inode->i_rcu, i_callback); | 295 | call_rcu(&inode->i_rcu, i_callback); |
| 296 | } | 296 | } |
| 297 | 297 | ||
| 298 | void address_space_init_once(struct address_space *mapping) | ||
| 299 | { | ||
| 300 | memset(mapping, 0, sizeof(*mapping)); | ||
| 301 | INIT_RADIX_TREE(&mapping->page_tree, GFP_ATOMIC); | ||
| 302 | spin_lock_init(&mapping->tree_lock); | ||
| 303 | spin_lock_init(&mapping->i_mmap_lock); | ||
| 304 | INIT_LIST_HEAD(&mapping->private_list); | ||
| 305 | spin_lock_init(&mapping->private_lock); | ||
| 306 | INIT_RAW_PRIO_TREE_ROOT(&mapping->i_mmap); | ||
| 307 | INIT_LIST_HEAD(&mapping->i_mmap_nonlinear); | ||
| 308 | mutex_init(&mapping->unmap_mutex); | ||
| 309 | } | ||
| 310 | EXPORT_SYMBOL(address_space_init_once); | ||
| 311 | |||
| 298 | /* | 312 | /* |
| 299 | * These are initializations that only need to be done | 313 | * These are initializations that only need to be done |
| 300 | * once, because the fields are idempotent across use | 314 | * once, because the fields are idempotent across use |
| @@ -308,13 +322,7 @@ void inode_init_once(struct inode *inode) | |||
| 308 | INIT_LIST_HEAD(&inode->i_devices); | 322 | INIT_LIST_HEAD(&inode->i_devices); |
| 309 | INIT_LIST_HEAD(&inode->i_wb_list); | 323 | INIT_LIST_HEAD(&inode->i_wb_list); |
| 310 | INIT_LIST_HEAD(&inode->i_lru); | 324 | INIT_LIST_HEAD(&inode->i_lru); |
| 311 | INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC); | 325 | 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); | 326 | i_size_ordered_init(inode); |
| 319 | #ifdef CONFIG_FSNOTIFY | 327 | #ifdef CONFIG_FSNOTIFY |
| 320 | INIT_HLIST_HEAD(&inode->i_fsnotify_marks); | 328 | INIT_HLIST_HEAD(&inode->i_fsnotify_marks); |
| @@ -540,11 +548,14 @@ void evict_inodes(struct super_block *sb) | |||
| 540 | /** | 548 | /** |
| 541 | * invalidate_inodes - attempt to free all inodes on a superblock | 549 | * invalidate_inodes - attempt to free all inodes on a superblock |
| 542 | * @sb: superblock to operate on | 550 | * @sb: superblock to operate on |
| 551 | * @kill_dirty: flag to guide handling of dirty inodes | ||
| 543 | * | 552 | * |
| 544 | * Attempts to free all inodes for a given superblock. If there were any | 553 | * Attempts to free all inodes for a given superblock. If there were any |
| 545 | * busy inodes return a non-zero value, else zero. | 554 | * busy inodes return a non-zero value, else zero. |
| 555 | * If @kill_dirty is set, discard dirty inodes too, otherwise treat | ||
| 556 | * them as busy. | ||
| 546 | */ | 557 | */ |
| 547 | int invalidate_inodes(struct super_block *sb) | 558 | int invalidate_inodes(struct super_block *sb, bool kill_dirty) |
| 548 | { | 559 | { |
| 549 | int busy = 0; | 560 | int busy = 0; |
| 550 | struct inode *inode, *next; | 561 | struct inode *inode, *next; |
| @@ -556,6 +567,10 @@ int invalidate_inodes(struct super_block *sb) | |||
| 556 | list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) { | 567 | 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)) | 568 | if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE)) |
| 558 | continue; | 569 | continue; |
| 570 | if (inode->i_state & I_DIRTY && !kill_dirty) { | ||
| 571 | busy = 1; | ||
| 572 | continue; | ||
| 573 | } | ||
| 559 | if (atomic_read(&inode->i_count)) { | 574 | if (atomic_read(&inode->i_count)) { |
| 560 | busy = 1; | 575 | busy = 1; |
| 561 | continue; | 576 | continue; |
