aboutsummaryrefslogtreecommitdiffstats
path: root/fs/locks.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/locks.c')
-rw-r--r--fs/locks.c91
1 files changed, 51 insertions, 40 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 13fc7a6d380a..e390bd9ae068 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -135,7 +135,7 @@
135#define IS_POSIX(fl) (fl->fl_flags & FL_POSIX) 135#define IS_POSIX(fl) (fl->fl_flags & FL_POSIX)
136#define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK) 136#define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK)
137#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG)) 137#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG))
138#define IS_FILE_PVT(fl) (fl->fl_flags & FL_FILE_PVT) 138#define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK)
139 139
140static bool lease_breaking(struct file_lock *fl) 140static bool lease_breaking(struct file_lock *fl)
141{ 141{
@@ -389,18 +389,6 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,
389 fl->fl_ops = NULL; 389 fl->fl_ops = NULL;
390 fl->fl_lmops = NULL; 390 fl->fl_lmops = NULL;
391 391
392 /* Ensure that fl->fl_filp has compatible f_mode */
393 switch (l->l_type) {
394 case F_RDLCK:
395 if (!(filp->f_mode & FMODE_READ))
396 return -EBADF;
397 break;
398 case F_WRLCK:
399 if (!(filp->f_mode & FMODE_WRITE))
400 return -EBADF;
401 break;
402 }
403
404 return assign_type(fl, l->l_type); 392 return assign_type(fl, l->l_type);
405} 393}
406 394
@@ -564,7 +552,7 @@ static void __locks_insert_block(struct file_lock *blocker,
564 BUG_ON(!list_empty(&waiter->fl_block)); 552 BUG_ON(!list_empty(&waiter->fl_block));
565 waiter->fl_next = blocker; 553 waiter->fl_next = blocker;
566 list_add_tail(&waiter->fl_block, &blocker->fl_block); 554 list_add_tail(&waiter->fl_block, &blocker->fl_block);
567 if (IS_POSIX(blocker) && !IS_FILE_PVT(blocker)) 555 if (IS_POSIX(blocker) && !IS_OFDLCK(blocker))
568 locks_insert_global_blocked(waiter); 556 locks_insert_global_blocked(waiter);
569} 557}
570 558
@@ -759,12 +747,12 @@ EXPORT_SYMBOL(posix_test_lock);
759 * of tasks (such as posix threads) sharing the same open file table. 747 * of tasks (such as posix threads) sharing the same open file table.
760 * To handle those cases, we just bail out after a few iterations. 748 * To handle those cases, we just bail out after a few iterations.
761 * 749 *
762 * For FL_FILE_PVT locks, the owner is the filp, not the files_struct. 750 * For FL_OFDLCK locks, the owner is the filp, not the files_struct.
763 * Because the owner is not even nominally tied to a thread of 751 * Because the owner is not even nominally tied to a thread of
764 * execution, the deadlock detection below can't reasonably work well. Just 752 * execution, the deadlock detection below can't reasonably work well. Just
765 * skip it for those. 753 * skip it for those.
766 * 754 *
767 * In principle, we could do a more limited deadlock detection on FL_FILE_PVT 755 * In principle, we could do a more limited deadlock detection on FL_OFDLCK
768 * locks that just checks for the case where two tasks are attempting to 756 * locks that just checks for the case where two tasks are attempting to
769 * upgrade from read to write locks on the same inode. 757 * upgrade from read to write locks on the same inode.
770 */ 758 */
@@ -791,9 +779,9 @@ static int posix_locks_deadlock(struct file_lock *caller_fl,
791 779
792 /* 780 /*
793 * This deadlock detector can't reasonably detect deadlocks with 781 * This deadlock detector can't reasonably detect deadlocks with
794 * FL_FILE_PVT locks, since they aren't owned by a process, per-se. 782 * FL_OFDLCK locks, since they aren't owned by a process, per-se.
795 */ 783 */
796 if (IS_FILE_PVT(caller_fl)) 784 if (IS_OFDLCK(caller_fl))
797 return 0; 785 return 0;
798 786
799 while ((block_fl = what_owner_is_waiting_for(block_fl))) { 787 while ((block_fl = what_owner_is_waiting_for(block_fl))) {
@@ -1391,11 +1379,10 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
1391 1379
1392restart: 1380restart:
1393 break_time = flock->fl_break_time; 1381 break_time = flock->fl_break_time;
1394 if (break_time != 0) { 1382 if (break_time != 0)
1395 break_time -= jiffies; 1383 break_time -= jiffies;
1396 if (break_time == 0) 1384 if (break_time == 0)
1397 break_time++; 1385 break_time++;
1398 }
1399 locks_insert_block(flock, new_fl); 1386 locks_insert_block(flock, new_fl);
1400 spin_unlock(&inode->i_lock); 1387 spin_unlock(&inode->i_lock);
1401 error = wait_event_interruptible_timeout(new_fl->fl_wait, 1388 error = wait_event_interruptible_timeout(new_fl->fl_wait,
@@ -1891,7 +1878,7 @@ EXPORT_SYMBOL_GPL(vfs_test_lock);
1891 1878
1892static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl) 1879static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
1893{ 1880{
1894 flock->l_pid = IS_FILE_PVT(fl) ? -1 : fl->fl_pid; 1881 flock->l_pid = IS_OFDLCK(fl) ? -1 : fl->fl_pid;
1895#if BITS_PER_LONG == 32 1882#if BITS_PER_LONG == 32
1896 /* 1883 /*
1897 * Make sure we can represent the posix lock via 1884 * Make sure we can represent the posix lock via
@@ -1913,7 +1900,7 @@ static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
1913#if BITS_PER_LONG == 32 1900#if BITS_PER_LONG == 32
1914static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl) 1901static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
1915{ 1902{
1916 flock->l_pid = IS_FILE_PVT(fl) ? -1 : fl->fl_pid; 1903 flock->l_pid = IS_OFDLCK(fl) ? -1 : fl->fl_pid;
1917 flock->l_start = fl->fl_start; 1904 flock->l_start = fl->fl_start;
1918 flock->l_len = fl->fl_end == OFFSET_MAX ? 0 : 1905 flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
1919 fl->fl_end - fl->fl_start + 1; 1906 fl->fl_end - fl->fl_start + 1;
@@ -1942,13 +1929,13 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l)
1942 if (error) 1929 if (error)
1943 goto out; 1930 goto out;
1944 1931
1945 if (cmd == F_GETLKP) { 1932 if (cmd == F_OFD_GETLK) {
1946 error = -EINVAL; 1933 error = -EINVAL;
1947 if (flock.l_pid != 0) 1934 if (flock.l_pid != 0)
1948 goto out; 1935 goto out;
1949 1936
1950 cmd = F_GETLK; 1937 cmd = F_GETLK;
1951 file_lock.fl_flags |= FL_FILE_PVT; 1938 file_lock.fl_flags |= FL_OFDLCK;
1952 file_lock.fl_owner = (fl_owner_t)filp; 1939 file_lock.fl_owner = (fl_owner_t)filp;
1953 } 1940 }
1954 1941
@@ -2035,6 +2022,22 @@ static int do_lock_file_wait(struct file *filp, unsigned int cmd,
2035 return error; 2022 return error;
2036} 2023}
2037 2024
2025/* Ensure that fl->fl_filp has compatible f_mode for F_SETLK calls */
2026static int
2027check_fmode_for_setlk(struct file_lock *fl)
2028{
2029 switch (fl->fl_type) {
2030 case F_RDLCK:
2031 if (!(fl->fl_file->f_mode & FMODE_READ))
2032 return -EBADF;
2033 break;
2034 case F_WRLCK:
2035 if (!(fl->fl_file->f_mode & FMODE_WRITE))
2036 return -EBADF;
2037 }
2038 return 0;
2039}
2040
2038/* Apply the lock described by l to an open file descriptor. 2041/* Apply the lock described by l to an open file descriptor.
2039 * This implements both the F_SETLK and F_SETLKW commands of fcntl(). 2042 * This implements both the F_SETLK and F_SETLKW commands of fcntl().
2040 */ 2043 */
@@ -2072,27 +2075,31 @@ again:
2072 if (error) 2075 if (error)
2073 goto out; 2076 goto out;
2074 2077
2078 error = check_fmode_for_setlk(file_lock);
2079 if (error)
2080 goto out;
2081
2075 /* 2082 /*
2076 * If the cmd is requesting file-private locks, then set the 2083 * If the cmd is requesting file-private locks, then set the
2077 * FL_FILE_PVT flag and override the owner. 2084 * FL_OFDLCK flag and override the owner.
2078 */ 2085 */
2079 switch (cmd) { 2086 switch (cmd) {
2080 case F_SETLKP: 2087 case F_OFD_SETLK:
2081 error = -EINVAL; 2088 error = -EINVAL;
2082 if (flock.l_pid != 0) 2089 if (flock.l_pid != 0)
2083 goto out; 2090 goto out;
2084 2091
2085 cmd = F_SETLK; 2092 cmd = F_SETLK;
2086 file_lock->fl_flags |= FL_FILE_PVT; 2093 file_lock->fl_flags |= FL_OFDLCK;
2087 file_lock->fl_owner = (fl_owner_t)filp; 2094 file_lock->fl_owner = (fl_owner_t)filp;
2088 break; 2095 break;
2089 case F_SETLKPW: 2096 case F_OFD_SETLKW:
2090 error = -EINVAL; 2097 error = -EINVAL;
2091 if (flock.l_pid != 0) 2098 if (flock.l_pid != 0)
2092 goto out; 2099 goto out;
2093 2100
2094 cmd = F_SETLKW; 2101 cmd = F_SETLKW;
2095 file_lock->fl_flags |= FL_FILE_PVT; 2102 file_lock->fl_flags |= FL_OFDLCK;
2096 file_lock->fl_owner = (fl_owner_t)filp; 2103 file_lock->fl_owner = (fl_owner_t)filp;
2097 /* Fallthrough */ 2104 /* Fallthrough */
2098 case F_SETLKW: 2105 case F_SETLKW:
@@ -2144,13 +2151,13 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l)
2144 if (error) 2151 if (error)
2145 goto out; 2152 goto out;
2146 2153
2147 if (cmd == F_GETLKP) { 2154 if (cmd == F_OFD_GETLK) {
2148 error = -EINVAL; 2155 error = -EINVAL;
2149 if (flock.l_pid != 0) 2156 if (flock.l_pid != 0)
2150 goto out; 2157 goto out;
2151 2158
2152 cmd = F_GETLK64; 2159 cmd = F_GETLK64;
2153 file_lock.fl_flags |= FL_FILE_PVT; 2160 file_lock.fl_flags |= FL_OFDLCK;
2154 file_lock.fl_owner = (fl_owner_t)filp; 2161 file_lock.fl_owner = (fl_owner_t)filp;
2155 } 2162 }
2156 2163
@@ -2207,27 +2214,31 @@ again:
2207 if (error) 2214 if (error)
2208 goto out; 2215 goto out;
2209 2216
2217 error = check_fmode_for_setlk(file_lock);
2218 if (error)
2219 goto out;
2220
2210 /* 2221 /*
2211 * If the cmd is requesting file-private locks, then set the 2222 * If the cmd is requesting file-private locks, then set the
2212 * FL_FILE_PVT flag and override the owner. 2223 * FL_OFDLCK flag and override the owner.
2213 */ 2224 */
2214 switch (cmd) { 2225 switch (cmd) {
2215 case F_SETLKP: 2226 case F_OFD_SETLK:
2216 error = -EINVAL; 2227 error = -EINVAL;
2217 if (flock.l_pid != 0) 2228 if (flock.l_pid != 0)
2218 goto out; 2229 goto out;
2219 2230
2220 cmd = F_SETLK64; 2231 cmd = F_SETLK64;
2221 file_lock->fl_flags |= FL_FILE_PVT; 2232 file_lock->fl_flags |= FL_OFDLCK;
2222 file_lock->fl_owner = (fl_owner_t)filp; 2233 file_lock->fl_owner = (fl_owner_t)filp;
2223 break; 2234 break;
2224 case F_SETLKPW: 2235 case F_OFD_SETLKW:
2225 error = -EINVAL; 2236 error = -EINVAL;
2226 if (flock.l_pid != 0) 2237 if (flock.l_pid != 0)
2227 goto out; 2238 goto out;
2228 2239
2229 cmd = F_SETLKW64; 2240 cmd = F_SETLKW64;
2230 file_lock->fl_flags |= FL_FILE_PVT; 2241 file_lock->fl_flags |= FL_OFDLCK;
2231 file_lock->fl_owner = (fl_owner_t)filp; 2242 file_lock->fl_owner = (fl_owner_t)filp;
2232 /* Fallthrough */ 2243 /* Fallthrough */
2233 case F_SETLKW64: 2244 case F_SETLKW64:
@@ -2413,8 +2424,8 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
2413 if (IS_POSIX(fl)) { 2424 if (IS_POSIX(fl)) {
2414 if (fl->fl_flags & FL_ACCESS) 2425 if (fl->fl_flags & FL_ACCESS)
2415 seq_printf(f, "ACCESS"); 2426 seq_printf(f, "ACCESS");
2416 else if (IS_FILE_PVT(fl)) 2427 else if (IS_OFDLCK(fl))
2417 seq_printf(f, "FLPVT "); 2428 seq_printf(f, "OFDLCK");
2418 else 2429 else
2419 seq_printf(f, "POSIX "); 2430 seq_printf(f, "POSIX ");
2420 2431