Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 625bba66 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents b8e6dece cff2fce5
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -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:
+7 −7
Original line number Diff line number Diff line
@@ -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);
+6 −6
Original line number Diff line number Diff line
@@ -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;
+24 −24
Original line number Diff line number Diff line
@@ -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 @@ int fcntl_setlk(unsigned int fd, struct file *filp, unsigned int cmd,

	/*
	 * 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 @@ int fcntl_setlk64(unsigned int fd, struct file *filp, unsigned int cmd,

	/*
	 * 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 ");

+1 −1
Original line number Diff line number Diff line
@@ -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
Loading