diff options
Diffstat (limited to 'fs/inode.c')
| -rw-r--r-- | fs/inode.c | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/fs/inode.c b/fs/inode.c index 4bcdad3c9361..f96d2a6f88cc 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); |
| @@ -1899,3 +1898,34 @@ void inode_dio_done(struct inode *inode) | |||
| 1899 | wake_up_bit(&inode->i_state, __I_DIO_WAKEUP); | 1898 | wake_up_bit(&inode->i_state, __I_DIO_WAKEUP); |
| 1900 | } | 1899 | } |
| 1901 | EXPORT_SYMBOL(inode_dio_done); | 1900 | EXPORT_SYMBOL(inode_dio_done); |
| 1901 | |||
| 1902 | /* | ||
| 1903 | * inode_set_flags - atomically set some inode flags | ||
| 1904 | * | ||
| 1905 | * Note: the caller should be holding i_mutex, or else be sure that | ||
| 1906 | * they have exclusive access to the inode structure (i.e., while the | ||
| 1907 | * inode is being instantiated). The reason for the cmpxchg() loop | ||
| 1908 | * --- which wouldn't be necessary if all code paths which modify | ||
| 1909 | * i_flags actually followed this rule, is that there is at least one | ||
| 1910 | * code path which doesn't today --- for example, | ||
| 1911 | * __generic_file_aio_write() calls file_remove_suid() without holding | ||
| 1912 | * i_mutex --- so we use cmpxchg() out of an abundance of caution. | ||
| 1913 | * | ||
| 1914 | * In the long run, i_mutex is overkill, and we should probably look | ||
| 1915 | * at using the i_lock spinlock to protect i_flags, and then make sure | ||
| 1916 | * it is so documented in include/linux/fs.h and that all code follows | ||
| 1917 | * the locking convention!! | ||
| 1918 | */ | ||
| 1919 | void inode_set_flags(struct inode *inode, unsigned int flags, | ||
| 1920 | unsigned int mask) | ||
| 1921 | { | ||
| 1922 | unsigned int old_flags, new_flags; | ||
| 1923 | |||
| 1924 | WARN_ON_ONCE(flags & ~mask); | ||
| 1925 | do { | ||
| 1926 | old_flags = ACCESS_ONCE(inode->i_flags); | ||
| 1927 | new_flags = (old_flags & ~mask) | flags; | ||
| 1928 | } while (unlikely(cmpxchg(&inode->i_flags, old_flags, | ||
| 1929 | new_flags) != old_flags)); | ||
| 1930 | } | ||
| 1931 | EXPORT_SYMBOL(inode_set_flags); | ||
