Commit 90f7d7a0 authored by Jeff Layton's avatar Jeff Layton
Browse files

locks: remove LOCK_MAND flock lock support



As best I can tell, the logic for these has been broken for a long time
(at least before the move to git), such that they never conflict with
anything. Also, nothing checks for these flags and prevented opens or
read/write behavior on the files. They don't seem to do anything.

Given that, we can rip these symbols out of the kernel, and just make
flock(2) return 0 when LOCK_MAND is set in order to preserve existing
behavior.

Cc: Matthew Wilcox <willy@infradead.org>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
Signed-off-by: default avatarJeff Layton <jlayton@kernel.org>
parent bf9f243f
Loading
Loading
Loading
Loading
+0 −3
Original line number Diff line number Diff line
@@ -302,9 +302,6 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)

	if (!(fl->fl_flags & FL_FLOCK))
		return -ENOLCK;
	/* No mandatory locks */
	if (fl->fl_type & LOCK_MAND)
		return -EOPNOTSUPP;

	dout("ceph_flock, fl_file: %p\n", fl->fl_file);

+0 −2
Original line number Diff line number Diff line
@@ -1338,8 +1338,6 @@ static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl)
{
	if (!(fl->fl_flags & FL_FLOCK))
		return -ENOLCK;
	if (fl->fl_type & LOCK_MAND)
		return -EOPNOTSUPP;

	if (fl->fl_type == F_UNLCK) {
		do_unflock(file, fl);
+22 −25
Original line number Diff line number Diff line
@@ -461,8 +461,6 @@ static void locks_move_blocks(struct file_lock *new, struct file_lock *fl)
}

static inline int flock_translate_cmd(int cmd) {
	if (cmd & LOCK_MAND)
		return cmd & (LOCK_MAND | LOCK_RW);
	switch (cmd) {
	case LOCK_SH:
		return F_RDLCK;
@@ -942,8 +940,6 @@ static bool flock_locks_conflict(struct file_lock *caller_fl,
	 */
	if (caller_fl->fl_file == sys_fl->fl_file)
		return false;
	if ((caller_fl->fl_type & LOCK_MAND) || (sys_fl->fl_type & LOCK_MAND))
		return false;

	return locks_conflict(caller_fl, sys_fl);
}
@@ -2116,11 +2112,9 @@ EXPORT_SYMBOL(locks_lock_inode_wait);
 *	- %LOCK_SH -- a shared lock.
 *	- %LOCK_EX -- an exclusive lock.
 *	- %LOCK_UN -- remove an existing lock.
 *	- %LOCK_MAND -- a 'mandatory' flock.
 *	  This exists to emulate Windows Share Modes.
 *	- %LOCK_MAND -- a 'mandatory' flock. (DEPRECATED)
 *
 *	%LOCK_MAND can be combined with %LOCK_READ or %LOCK_WRITE to allow other
 *	processes read and write access respectively.
 *	%LOCK_MAND support has been removed from the kernel.
 */
SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
{
@@ -2137,10 +2131,23 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
	cmd &= ~LOCK_NB;
	unlock = (cmd == LOCK_UN);

	if (!unlock && !(cmd & LOCK_MAND) &&
	    !(f.file->f_mode & (FMODE_READ|FMODE_WRITE)))
	if (!unlock && !(f.file->f_mode & (FMODE_READ|FMODE_WRITE)))
		goto out_putf;

	/*
	 * LOCK_MAND locks were broken for a long time in that they never
	 * conflicted with one another and didn't prevent any sort of open,
	 * read or write activity.
	 *
	 * Just ignore these requests now, to preserve legacy behavior, but
	 * throw a warning to let people know that they don't actually work.
	 */
	if (cmd & LOCK_MAND) {
		pr_warn_once("Attempt to set a LOCK_MAND lock via flock(2). This support has been removed and the request ignored.\n");
		error = 0;
		goto out_putf;
	}

	lock = flock_make_lock(f.file, cmd, NULL);
	if (IS_ERR(lock)) {
		error = PTR_ERR(lock);
@@ -2718,6 +2725,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
	struct inode *inode = NULL;
	unsigned int fl_pid;
	struct pid_namespace *proc_pidns = proc_pid_ns(file_inode(f->file)->i_sb);
	int type;

	fl_pid = locks_translate_pid(fl, proc_pidns);
	/*
@@ -2745,11 +2753,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
		seq_printf(f, " %s ",
			     (inode == NULL) ? "*NOINODE*" : "ADVISORY ");
	} else if (IS_FLOCK(fl)) {
		if (fl->fl_type & LOCK_MAND) {
			seq_puts(f, "FLOCK  MSNFS     ");
		} else {
		seq_puts(f, "FLOCK  ADVISORY  ");
		}
	} else if (IS_LEASE(fl)) {
		if (fl->fl_flags & FL_DELEG)
			seq_puts(f, "DELEG  ");
@@ -2765,17 +2769,10 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
	} else {
		seq_puts(f, "UNKNOWN UNKNOWN  ");
	}
	if (fl->fl_type & LOCK_MAND) {
		seq_printf(f, "%s ",
			       (fl->fl_type & LOCK_READ)
			       ? (fl->fl_type & LOCK_WRITE) ? "RW   " : "READ "
			       : (fl->fl_type & LOCK_WRITE) ? "WRITE" : "NONE ");
	} else {
		int type = IS_LEASE(fl) ? target_leasetype(fl) : fl->fl_type;
	type = IS_LEASE(fl) ? target_leasetype(fl) : fl->fl_type;

	seq_printf(f, "%s ", (type == F_WRLCK) ? "WRITE" :
			     (type == F_RDLCK) ? "READ" : "UNLCK");
	}
	if (inode) {
		/* userspace relies on this representation of dev_t */
		seq_printf(f, "%d %02x:%02x:%lu ", fl_pid,
+0 −9
Original line number Diff line number Diff line
@@ -843,15 +843,6 @@ int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
	if (!(fl->fl_flags & FL_FLOCK))
		return -ENOLCK;

	/*
	 * The NFSv4 protocol doesn't support LOCK_MAND, which is not part of
	 * any standard. In principle we might be able to support LOCK_MAND
	 * on NFSv2/3 since NLMv3/4 support DOS share modes, but for now the
	 * NFS code is not set up for it.
	 */
	if (fl->fl_type & LOCK_MAND)
		return -EINVAL;

	if (NFS_SERVER(inode)->flags & NFS_MOUNT_LOCAL_FLOCK)
		is_local = 1;

+4 −0
Original line number Diff line number Diff line
@@ -181,6 +181,10 @@ struct f_owner_ex {
				   blocking */
#define LOCK_UN		8	/* remove lock */

/*
 * LOCK_MAND support has been removed from the kernel. We leave the symbols
 * here to not break legacy builds, but these should not be used in new code.
 */
#define LOCK_MAND	32	/* This is a mandatory flock ... */
#define LOCK_READ	64	/* which allows concurrent read operations */
#define LOCK_WRITE	128	/* which allows concurrent write operations */