diff options
author | J. Bruce Fields <bfields@redhat.com> | 2014-04-01 11:08:43 -0400 |
---|---|---|
committer | Miklos Szeredi <mszeredi@suse.cz> | 2014-04-01 11:08:43 -0400 |
commit | 4fd699ae3fbca2ac760137e1d26f98a105f59f05 (patch) | |
tree | de9f5b2d915d2a30fd1841a9fa7098de84a9c0ec | |
parent | 0b3974eb04c4874e85fa1d4fc70450d12f28611d (diff) |
vfs: lock_two_nondirectories: allow directory args
lock_two_nondirectories warned if either of its args was a directory.
Instead just ignore the directory args. This is needed for locking in
cross rename.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
-rw-r--r-- | fs/inode.c | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/fs/inode.c b/fs/inode.c index 4bcdad3c9361..73779c090f0d 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -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); |