diff options
Diffstat (limited to 'fs/inode.c')
-rw-r--r-- | fs/inode.c | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/fs/inode.c b/fs/inode.c index 4bcdad3c9361..fb59ba7967f1 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -503,6 +503,7 @@ void clear_inode(struct inode *inode) | |||
503 | */ | 503 | */ |
504 | spin_lock_irq(&inode->i_data.tree_lock); | 504 | spin_lock_irq(&inode->i_data.tree_lock); |
505 | BUG_ON(inode->i_data.nrpages); | 505 | BUG_ON(inode->i_data.nrpages); |
506 | BUG_ON(inode->i_data.nrshadows); | ||
506 | spin_unlock_irq(&inode->i_data.tree_lock); | 507 | spin_unlock_irq(&inode->i_data.tree_lock); |
507 | BUG_ON(!list_empty(&inode->i_data.private_list)); | 508 | BUG_ON(!list_empty(&inode->i_data.private_list)); |
508 | BUG_ON(!(inode->i_state & I_FREEING)); | 509 | BUG_ON(!(inode->i_state & I_FREEING)); |
@@ -548,8 +549,7 @@ static void evict(struct inode *inode) | |||
548 | if (op->evict_inode) { | 549 | if (op->evict_inode) { |
549 | op->evict_inode(inode); | 550 | op->evict_inode(inode); |
550 | } else { | 551 | } else { |
551 | if (inode->i_data.nrpages) | 552 | truncate_inode_pages_final(&inode->i_data); |
552 | truncate_inode_pages(&inode->i_data, 0); | ||
553 | clear_inode(inode); | 553 | clear_inode(inode); |
554 | } | 554 | } |
555 | if (S_ISBLK(inode->i_mode) && inode->i_bdev) | 555 | if (S_ISBLK(inode->i_mode) && inode->i_bdev) |
@@ -944,24 +944,22 @@ EXPORT_SYMBOL(unlock_new_inode); | |||
944 | 944 | ||
945 | /** | 945 | /** |
946 | * lock_two_nondirectories - take two i_mutexes on non-directory objects | 946 | * lock_two_nondirectories - take two i_mutexes on non-directory objects |
947 | * | ||
948 | * Lock any non-NULL argument that is not a directory. | ||
949 | * Zero, one or two objects may be locked by this function. | ||
950 | * | ||
947 | * @inode1: first inode to lock | 951 | * @inode1: first inode to lock |
948 | * @inode2: second inode to lock | 952 | * @inode2: second inode to lock |
949 | */ | 953 | */ |
950 | void lock_two_nondirectories(struct inode *inode1, struct inode *inode2) | 954 | void lock_two_nondirectories(struct inode *inode1, struct inode *inode2) |
951 | { | 955 | { |
952 | WARN_ON_ONCE(S_ISDIR(inode1->i_mode)); | 956 | if (inode1 > inode2) |
953 | if (inode1 == inode2 || !inode2) { | 957 | swap(inode1, inode2); |
954 | mutex_lock(&inode1->i_mutex); | 958 | |
955 | return; | 959 | if (inode1 && !S_ISDIR(inode1->i_mode)) |
956 | } | ||
957 | WARN_ON_ONCE(S_ISDIR(inode2->i_mode)); | ||
958 | if (inode1 < inode2) { | ||
959 | mutex_lock(&inode1->i_mutex); | 960 | mutex_lock(&inode1->i_mutex); |
961 | if (inode2 && !S_ISDIR(inode2->i_mode) && inode2 != inode1) | ||
960 | mutex_lock_nested(&inode2->i_mutex, I_MUTEX_NONDIR2); | 962 | mutex_lock_nested(&inode2->i_mutex, I_MUTEX_NONDIR2); |
961 | } else { | ||
962 | mutex_lock(&inode2->i_mutex); | ||
963 | mutex_lock_nested(&inode1->i_mutex, I_MUTEX_NONDIR2); | ||
964 | } | ||
965 | } | 963 | } |
966 | EXPORT_SYMBOL(lock_two_nondirectories); | 964 | EXPORT_SYMBOL(lock_two_nondirectories); |
967 | 965 | ||
@@ -972,8 +970,9 @@ EXPORT_SYMBOL(lock_two_nondirectories); | |||
972 | */ | 970 | */ |
973 | void unlock_two_nondirectories(struct inode *inode1, struct inode *inode2) | 971 | void unlock_two_nondirectories(struct inode *inode1, struct inode *inode2) |
974 | { | 972 | { |
975 | mutex_unlock(&inode1->i_mutex); | 973 | if (inode1 && !S_ISDIR(inode1->i_mode)) |
976 | if (inode2 && inode2 != inode1) | 974 | mutex_unlock(&inode1->i_mutex); |
975 | if (inode2 && !S_ISDIR(inode2->i_mode) && inode2 != inode1) | ||
977 | mutex_unlock(&inode2->i_mutex); | 976 | mutex_unlock(&inode2->i_mutex); |
978 | } | 977 | } |
979 | EXPORT_SYMBOL(unlock_two_nondirectories); | 978 | EXPORT_SYMBOL(unlock_two_nondirectories); |