diff options
Diffstat (limited to 'fs/locks.c')
| -rw-r--r-- | fs/locks.c | 91 | 
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 @@  #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)  { @@ -389,18 +389,6 @@ static int flock64_to_posix_lock(struct file *filp, struct file_lock *fl,  	fl->fl_ops = NULL;  	fl->fl_lmops = NULL; -	/* Ensure that fl->fl_filp has compatible f_mode */ -	switch (l->l_type) { -	case F_RDLCK: -		if (!(filp->f_mode & FMODE_READ)) -			return -EBADF; -		break; -	case F_WRLCK: -		if (!(filp->f_mode & FMODE_WRITE)) -			return -EBADF; -		break; -	} -  	return assign_type(fl, l->l_type);  } @@ -564,7 +552,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 +747,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 +779,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))) { @@ -1391,11 +1379,10 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)  restart:  	break_time = flock->fl_break_time; -	if (break_time != 0) { +	if (break_time != 0)  		break_time -= jiffies; -		if (break_time == 0) -			break_time++; -	} +	if (break_time == 0) +		break_time++;  	locks_insert_block(flock, new_fl);  	spin_unlock(&inode->i_lock);  	error = wait_event_interruptible_timeout(new_fl->fl_wait, @@ -1891,7 +1878,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 @@ -1913,7 +1900,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; @@ -1942,13 +1929,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;  	} @@ -2035,6 +2022,22 @@ static int do_lock_file_wait(struct file *filp, unsigned int cmd,  	return error;  } +/* Ensure that fl->fl_filp has compatible f_mode for F_SETLK calls */ +static int +check_fmode_for_setlk(struct file_lock *fl) +{ +	switch (fl->fl_type) { +	case F_RDLCK: +		if (!(fl->fl_file->f_mode & FMODE_READ)) +			return -EBADF; +		break; +	case F_WRLCK: +		if (!(fl->fl_file->f_mode & FMODE_WRITE)) +			return -EBADF; +	} +	return 0; +} +  /* Apply the lock described by l to an open file descriptor.   * This implements both the F_SETLK and F_SETLKW commands of fcntl().   */ @@ -2072,27 +2075,31 @@ again:  	if (error)  		goto out; +	error = check_fmode_for_setlk(file_lock); +	if (error) +		goto out; +  	/*  	 * 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: @@ -2144,13 +2151,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;  	} @@ -2207,27 +2214,31 @@ again:  	if (error)  		goto out; +	error = check_fmode_for_setlk(file_lock); +	if (error) +		goto out; +  	/*  	 * 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: @@ -2413,8 +2424,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 "); | 

