mirror of
https://github.com/torvalds/linux.git
synced 2024-11-23 04:31:50 +00:00
File locking related bugfixes for v3.15 (pile #2)
- fix for a long-standing bug in __break_lease that can cause soft lockups - renaming of file-private locks to "open file description" locks, and the command macros to more visually distinct names. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJTWB/iAAoJEAAOaEEZVoIV2tUP/A1c9YUmgt+LdOJIA2k3Uh9C nNdZss2hj8s91qCRe1Mb7L9UjzTEEiYILYqmXMRW9yUpPI7Oxr5sjqZEqlK5lTso 447QEow93wSE/WIKwwzdbKS+CMRNvIba6EjzQ7h0kU3ExMnFMXwD2QK7eGT2pEko kaQMq5BbxxIaTYmp/tKioacBPbpO3TQpS6ZWv2kZDCk4l1wCdsBNL7h3eqM63L/L A05zA88e3//wxVSPLA5JpQJ5fYkZrz7sqZYd+H80VXn34YQY7/7Kq16fiCprhntq tZb9LWOIJmSruN7r39KJgf43++fpSrv5XPfqsL4TDdwGcYwBAznhItrfOUC0Ja1+ ZY227gHbxBwSeN9jj3zc4peOpzNPdIMnw0CEZVGn/AgssFFh/Ja8PrIQCxjI5djP eLqiiBBznt9HaZWPslWxaKqhdINFyuMp9LbEJ71nXwLQVYY32rOS828FAna982F3 i0A48tPbrGpA1elGnVcsiAmJtAbZA9X6Y5M+gQGU2vWgX5GxiLeXOmEd+kVOaTmu 2WVlwvEc3jTlxg9naGAKsfXwaOKqEIPJDoahWTpSRtNOntNwiPjg0cW80abq+Ybx WaPFhDLyd7290QyOASjyC4TwXMA2XvtQMQ8P+SMWkc2ZscjtuMBfEK9TBalg8tZV vHNrZpqnftIX7u6Y/fuT =rrtj -----END PGP SIGNATURE----- Merge tag 'locks-v3.15-2' of git://git.samba.org/jlayton/linux Pull file locking fixes from Jeff Layton: "File locking related bugfixes for v3.15 (pile #2) - fix for a long-standing bug in __break_lease that can cause soft lockups - renaming of file-private locks to "open file description" locks, and the command macros to more visually distinct names The fix for __break_lease is also in the pile of patches for which Bruce sent a pull request, but I assume that your merge procedure will handle that correctly. For the other patches, I don't like the fact that we need to rename this stuff at this late stage, but it should be settled now (hopefully)" * tag 'locks-v3.15-2' of git://git.samba.org/jlayton/linux: locks: rename FL_FILE_PVT and IS_FILE_PVT to use "*_OFDLCK" instead locks: rename file-private locks to "open file description locks" locks: allow __break_lease to sleep even when break_time is 0
This commit is contained in:
commit
625bba662c
@ -203,9 +203,9 @@ asmlinkage long sys_oabi_fcntl64(unsigned int fd, unsigned int cmd,
|
||||
int ret;
|
||||
|
||||
switch (cmd) {
|
||||
case F_GETLKP:
|
||||
case F_SETLKP:
|
||||
case F_SETLKPW:
|
||||
case F_OFD_GETLK:
|
||||
case F_OFD_SETLK:
|
||||
case F_OFD_SETLKW:
|
||||
case F_GETLK64:
|
||||
case F_SETLK64:
|
||||
case F_SETLKW64:
|
||||
|
14
fs/compat.c
14
fs/compat.c
@ -457,9 +457,9 @@ COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
|
||||
case F_GETLK64:
|
||||
case F_SETLK64:
|
||||
case F_SETLKW64:
|
||||
case F_GETLKP:
|
||||
case F_SETLKP:
|
||||
case F_SETLKPW:
|
||||
case F_OFD_GETLK:
|
||||
case F_OFD_SETLK:
|
||||
case F_OFD_SETLKW:
|
||||
ret = get_compat_flock64(&f, compat_ptr(arg));
|
||||
if (ret != 0)
|
||||
break;
|
||||
@ -468,7 +468,7 @@ COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
|
||||
conv_cmd = convert_fcntl_cmd(cmd);
|
||||
ret = sys_fcntl(fd, conv_cmd, (unsigned long)&f);
|
||||
set_fs(old_fs);
|
||||
if ((conv_cmd == F_GETLK || conv_cmd == F_GETLKP) && ret == 0) {
|
||||
if ((conv_cmd == F_GETLK || conv_cmd == F_OFD_GETLK) && ret == 0) {
|
||||
/* need to return lock information - see above for commentary */
|
||||
if (f.l_start > COMPAT_LOFF_T_MAX)
|
||||
ret = -EOVERFLOW;
|
||||
@ -493,9 +493,9 @@ COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd,
|
||||
case F_GETLK64:
|
||||
case F_SETLK64:
|
||||
case F_SETLKW64:
|
||||
case F_GETLKP:
|
||||
case F_SETLKP:
|
||||
case F_SETLKPW:
|
||||
case F_OFD_GETLK:
|
||||
case F_OFD_SETLK:
|
||||
case F_OFD_SETLKW:
|
||||
return -EINVAL;
|
||||
}
|
||||
return compat_sys_fcntl64(fd, cmd, arg);
|
||||
|
12
fs/fcntl.c
12
fs/fcntl.c
@ -274,15 +274,15 @@ static long do_fcntl(int fd, unsigned int cmd, unsigned long arg,
|
||||
break;
|
||||
#if BITS_PER_LONG != 32
|
||||
/* 32-bit arches must use fcntl64() */
|
||||
case F_GETLKP:
|
||||
case F_OFD_GETLK:
|
||||
#endif
|
||||
case F_GETLK:
|
||||
err = fcntl_getlk(filp, cmd, (struct flock __user *) arg);
|
||||
break;
|
||||
#if BITS_PER_LONG != 32
|
||||
/* 32-bit arches must use fcntl64() */
|
||||
case F_SETLKP:
|
||||
case F_SETLKPW:
|
||||
case F_OFD_SETLK:
|
||||
case F_OFD_SETLKW:
|
||||
#endif
|
||||
/* Fallthrough */
|
||||
case F_SETLK:
|
||||
@ -399,13 +399,13 @@ SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd,
|
||||
|
||||
switch (cmd) {
|
||||
case F_GETLK64:
|
||||
case F_GETLKP:
|
||||
case F_OFD_GETLK:
|
||||
err = fcntl_getlk64(f.file, cmd, (struct flock64 __user *) arg);
|
||||
break;
|
||||
case F_SETLK64:
|
||||
case F_SETLKW64:
|
||||
case F_SETLKP:
|
||||
case F_SETLKPW:
|
||||
case F_OFD_SETLK:
|
||||
case F_OFD_SETLKW:
|
||||
err = fcntl_setlk64(fd, f.file, cmd,
|
||||
(struct flock64 __user *) arg);
|
||||
break;
|
||||
|
48
fs/locks.c
48
fs/locks.c
@ -135,7 +135,7 @@
|
||||
#define IS_POSIX(fl) (fl->fl_flags & FL_POSIX)
|
||||
#define IS_FLOCK(fl) (fl->fl_flags & FL_FLOCK)
|
||||
#define IS_LEASE(fl) (fl->fl_flags & (FL_LEASE|FL_DELEG))
|
||||
#define IS_FILE_PVT(fl) (fl->fl_flags & FL_FILE_PVT)
|
||||
#define IS_OFDLCK(fl) (fl->fl_flags & FL_OFDLCK)
|
||||
|
||||
static bool lease_breaking(struct file_lock *fl)
|
||||
{
|
||||
@ -564,7 +564,7 @@ static void __locks_insert_block(struct file_lock *blocker,
|
||||
BUG_ON(!list_empty(&waiter->fl_block));
|
||||
waiter->fl_next = blocker;
|
||||
list_add_tail(&waiter->fl_block, &blocker->fl_block);
|
||||
if (IS_POSIX(blocker) && !IS_FILE_PVT(blocker))
|
||||
if (IS_POSIX(blocker) && !IS_OFDLCK(blocker))
|
||||
locks_insert_global_blocked(waiter);
|
||||
}
|
||||
|
||||
@ -759,12 +759,12 @@ EXPORT_SYMBOL(posix_test_lock);
|
||||
* of tasks (such as posix threads) sharing the same open file table.
|
||||
* To handle those cases, we just bail out after a few iterations.
|
||||
*
|
||||
* For FL_FILE_PVT locks, the owner is the filp, not the files_struct.
|
||||
* For FL_OFDLCK locks, the owner is the filp, not the files_struct.
|
||||
* Because the owner is not even nominally tied to a thread of
|
||||
* execution, the deadlock detection below can't reasonably work well. Just
|
||||
* skip it for those.
|
||||
*
|
||||
* In principle, we could do a more limited deadlock detection on FL_FILE_PVT
|
||||
* In principle, we could do a more limited deadlock detection on FL_OFDLCK
|
||||
* locks that just checks for the case where two tasks are attempting to
|
||||
* upgrade from read to write locks on the same inode.
|
||||
*/
|
||||
@ -791,9 +791,9 @@ static int posix_locks_deadlock(struct file_lock *caller_fl,
|
||||
|
||||
/*
|
||||
* This deadlock detector can't reasonably detect deadlocks with
|
||||
* FL_FILE_PVT locks, since they aren't owned by a process, per-se.
|
||||
* FL_OFDLCK locks, since they aren't owned by a process, per-se.
|
||||
*/
|
||||
if (IS_FILE_PVT(caller_fl))
|
||||
if (IS_OFDLCK(caller_fl))
|
||||
return 0;
|
||||
|
||||
while ((block_fl = what_owner_is_waiting_for(block_fl))) {
|
||||
@ -1890,7 +1890,7 @@ EXPORT_SYMBOL_GPL(vfs_test_lock);
|
||||
|
||||
static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
|
||||
{
|
||||
flock->l_pid = IS_FILE_PVT(fl) ? -1 : fl->fl_pid;
|
||||
flock->l_pid = IS_OFDLCK(fl) ? -1 : fl->fl_pid;
|
||||
#if BITS_PER_LONG == 32
|
||||
/*
|
||||
* Make sure we can represent the posix lock via
|
||||
@ -1912,7 +1912,7 @@ static int posix_lock_to_flock(struct flock *flock, struct file_lock *fl)
|
||||
#if BITS_PER_LONG == 32
|
||||
static void posix_lock_to_flock64(struct flock64 *flock, struct file_lock *fl)
|
||||
{
|
||||
flock->l_pid = IS_FILE_PVT(fl) ? -1 : fl->fl_pid;
|
||||
flock->l_pid = IS_OFDLCK(fl) ? -1 : fl->fl_pid;
|
||||
flock->l_start = fl->fl_start;
|
||||
flock->l_len = fl->fl_end == OFFSET_MAX ? 0 :
|
||||
fl->fl_end - fl->fl_start + 1;
|
||||
@ -1941,13 +1941,13 @@ int fcntl_getlk(struct file *filp, unsigned int cmd, struct flock __user *l)
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
if (cmd == F_GETLKP) {
|
||||
if (cmd == F_OFD_GETLK) {
|
||||
error = -EINVAL;
|
||||
if (flock.l_pid != 0)
|
||||
goto out;
|
||||
|
||||
cmd = F_GETLK;
|
||||
file_lock.fl_flags |= FL_FILE_PVT;
|
||||
file_lock.fl_flags |= FL_OFDLCK;
|
||||
file_lock.fl_owner = (fl_owner_t)filp;
|
||||
}
|
||||
|
||||
@ -2073,25 +2073,25 @@ again:
|
||||
|
||||
/*
|
||||
* If the cmd is requesting file-private locks, then set the
|
||||
* FL_FILE_PVT flag and override the owner.
|
||||
* FL_OFDLCK flag and override the owner.
|
||||
*/
|
||||
switch (cmd) {
|
||||
case F_SETLKP:
|
||||
case F_OFD_SETLK:
|
||||
error = -EINVAL;
|
||||
if (flock.l_pid != 0)
|
||||
goto out;
|
||||
|
||||
cmd = F_SETLK;
|
||||
file_lock->fl_flags |= FL_FILE_PVT;
|
||||
file_lock->fl_flags |= FL_OFDLCK;
|
||||
file_lock->fl_owner = (fl_owner_t)filp;
|
||||
break;
|
||||
case F_SETLKPW:
|
||||
case F_OFD_SETLKW:
|
||||
error = -EINVAL;
|
||||
if (flock.l_pid != 0)
|
||||
goto out;
|
||||
|
||||
cmd = F_SETLKW;
|
||||
file_lock->fl_flags |= FL_FILE_PVT;
|
||||
file_lock->fl_flags |= FL_OFDLCK;
|
||||
file_lock->fl_owner = (fl_owner_t)filp;
|
||||
/* Fallthrough */
|
||||
case F_SETLKW:
|
||||
@ -2143,13 +2143,13 @@ int fcntl_getlk64(struct file *filp, unsigned int cmd, struct flock64 __user *l)
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
if (cmd == F_GETLKP) {
|
||||
if (cmd == F_OFD_GETLK) {
|
||||
error = -EINVAL;
|
||||
if (flock.l_pid != 0)
|
||||
goto out;
|
||||
|
||||
cmd = F_GETLK64;
|
||||
file_lock.fl_flags |= FL_FILE_PVT;
|
||||
file_lock.fl_flags |= FL_OFDLCK;
|
||||
file_lock.fl_owner = (fl_owner_t)filp;
|
||||
}
|
||||
|
||||
@ -2208,25 +2208,25 @@ again:
|
||||
|
||||
/*
|
||||
* If the cmd is requesting file-private locks, then set the
|
||||
* FL_FILE_PVT flag and override the owner.
|
||||
* FL_OFDLCK flag and override the owner.
|
||||
*/
|
||||
switch (cmd) {
|
||||
case F_SETLKP:
|
||||
case F_OFD_SETLK:
|
||||
error = -EINVAL;
|
||||
if (flock.l_pid != 0)
|
||||
goto out;
|
||||
|
||||
cmd = F_SETLK64;
|
||||
file_lock->fl_flags |= FL_FILE_PVT;
|
||||
file_lock->fl_flags |= FL_OFDLCK;
|
||||
file_lock->fl_owner = (fl_owner_t)filp;
|
||||
break;
|
||||
case F_SETLKPW:
|
||||
case F_OFD_SETLKW:
|
||||
error = -EINVAL;
|
||||
if (flock.l_pid != 0)
|
||||
goto out;
|
||||
|
||||
cmd = F_SETLKW64;
|
||||
file_lock->fl_flags |= FL_FILE_PVT;
|
||||
file_lock->fl_flags |= FL_OFDLCK;
|
||||
file_lock->fl_owner = (fl_owner_t)filp;
|
||||
/* Fallthrough */
|
||||
case F_SETLKW64:
|
||||
@ -2412,8 +2412,8 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
|
||||
if (IS_POSIX(fl)) {
|
||||
if (fl->fl_flags & FL_ACCESS)
|
||||
seq_printf(f, "ACCESS");
|
||||
else if (IS_FILE_PVT(fl))
|
||||
seq_printf(f, "FLPVT ");
|
||||
else if (IS_OFDLCK(fl))
|
||||
seq_printf(f, "OFDLCK");
|
||||
else
|
||||
seq_printf(f, "POSIX ");
|
||||
|
||||
|
@ -815,7 +815,7 @@ static inline struct file *get_file(struct file *f)
|
||||
#define FL_SLEEP 128 /* A blocking lock */
|
||||
#define FL_DOWNGRADE_PENDING 256 /* Lease is being downgraded */
|
||||
#define FL_UNLOCK_PENDING 512 /* Lease is being broken */
|
||||
#define FL_FILE_PVT 1024 /* lock is private to the file */
|
||||
#define FL_OFDLCK 1024 /* lock is "owned" by struct file */
|
||||
|
||||
/*
|
||||
* Special return value from posix_lock_file() and vfs_lock_file() for
|
||||
|
@ -133,20 +133,20 @@
|
||||
#endif
|
||||
|
||||
/*
|
||||
* fd "private" POSIX locks.
|
||||
* Open File Description Locks
|
||||
*
|
||||
* Usually POSIX locks held by a process are released on *any* close and are
|
||||
* Usually record locks held by a process are released on *any* close and are
|
||||
* not inherited across a fork().
|
||||
*
|
||||
* These cmd values will set locks that conflict with normal POSIX locks, but
|
||||
* are "owned" by the opened file, not the process. This means that they are
|
||||
* inherited across fork() like BSD (flock) locks, and they are only released
|
||||
* automatically when the last reference to the the open file against which
|
||||
* they were acquired is put.
|
||||
* These cmd values will set locks that conflict with process-associated
|
||||
* record locks, but are "owned" by the open file description, not the
|
||||
* process. This means that they are inherited across fork() like BSD (flock)
|
||||
* locks, and they are only released automatically when the last reference to
|
||||
* the the open file against which they were acquired is put.
|
||||
*/
|
||||
#define F_GETLKP 36
|
||||
#define F_SETLKP 37
|
||||
#define F_SETLKPW 38
|
||||
#define F_OFD_GETLK 36
|
||||
#define F_OFD_SETLK 37
|
||||
#define F_OFD_SETLKW 38
|
||||
|
||||
#define F_OWNER_TID 0
|
||||
#define F_OWNER_PID 1
|
||||
|
@ -3317,9 +3317,9 @@ static int selinux_file_fcntl(struct file *file, unsigned int cmd,
|
||||
case F_GETLK:
|
||||
case F_SETLK:
|
||||
case F_SETLKW:
|
||||
case F_GETLKP:
|
||||
case F_SETLKP:
|
||||
case F_SETLKPW:
|
||||
case F_OFD_GETLK:
|
||||
case F_OFD_SETLK:
|
||||
case F_OFD_SETLKW:
|
||||
#if BITS_PER_LONG == 32
|
||||
case F_GETLK64:
|
||||
case F_SETLK64:
|
||||
|
Loading…
Reference in New Issue
Block a user