提交 90f7d7a0 编写于 作者: J Jeff Layton

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: NJeff Layton <jlayton@kernel.org>
上级 bf9f243f
...@@ -302,9 +302,6 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) ...@@ -302,9 +302,6 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl)
if (!(fl->fl_flags & FL_FLOCK)) if (!(fl->fl_flags & FL_FLOCK))
return -ENOLCK; return -ENOLCK;
/* No mandatory locks */
if (fl->fl_type & LOCK_MAND)
return -EOPNOTSUPP;
dout("ceph_flock, fl_file: %p\n", fl->fl_file); dout("ceph_flock, fl_file: %p\n", fl->fl_file);
......
...@@ -1338,8 +1338,6 @@ static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl) ...@@ -1338,8 +1338,6 @@ static int gfs2_flock(struct file *file, int cmd, struct file_lock *fl)
{ {
if (!(fl->fl_flags & FL_FLOCK)) if (!(fl->fl_flags & FL_FLOCK))
return -ENOLCK; return -ENOLCK;
if (fl->fl_type & LOCK_MAND)
return -EOPNOTSUPP;
if (fl->fl_type == F_UNLCK) { if (fl->fl_type == F_UNLCK) {
do_unflock(file, fl); do_unflock(file, fl);
......
...@@ -461,8 +461,6 @@ static void locks_move_blocks(struct file_lock *new, struct file_lock *fl) ...@@ -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) { static inline int flock_translate_cmd(int cmd) {
if (cmd & LOCK_MAND)
return cmd & (LOCK_MAND | LOCK_RW);
switch (cmd) { switch (cmd) {
case LOCK_SH: case LOCK_SH:
return F_RDLCK; return F_RDLCK;
...@@ -942,8 +940,6 @@ static bool flock_locks_conflict(struct file_lock *caller_fl, ...@@ -942,8 +940,6 @@ static bool flock_locks_conflict(struct file_lock *caller_fl,
*/ */
if (caller_fl->fl_file == sys_fl->fl_file) if (caller_fl->fl_file == sys_fl->fl_file)
return false; return false;
if ((caller_fl->fl_type & LOCK_MAND) || (sys_fl->fl_type & LOCK_MAND))
return false;
return locks_conflict(caller_fl, sys_fl); return locks_conflict(caller_fl, sys_fl);
} }
...@@ -2116,11 +2112,9 @@ EXPORT_SYMBOL(locks_lock_inode_wait); ...@@ -2116,11 +2112,9 @@ EXPORT_SYMBOL(locks_lock_inode_wait);
* - %LOCK_SH -- a shared lock. * - %LOCK_SH -- a shared lock.
* - %LOCK_EX -- an exclusive lock. * - %LOCK_EX -- an exclusive lock.
* - %LOCK_UN -- remove an existing lock. * - %LOCK_UN -- remove an existing lock.
* - %LOCK_MAND -- a 'mandatory' flock. * - %LOCK_MAND -- a 'mandatory' flock. (DEPRECATED)
* This exists to emulate Windows Share Modes.
* *
* %LOCK_MAND can be combined with %LOCK_READ or %LOCK_WRITE to allow other * %LOCK_MAND support has been removed from the kernel.
* processes read and write access respectively.
*/ */
SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
{ {
...@@ -2137,9 +2131,22 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd) ...@@ -2137,9 +2131,22 @@ SYSCALL_DEFINE2(flock, unsigned int, fd, unsigned int, cmd)
cmd &= ~LOCK_NB; cmd &= ~LOCK_NB;
unlock = (cmd == LOCK_UN); unlock = (cmd == LOCK_UN);
if (!unlock && !(cmd & LOCK_MAND) && if (!unlock && !(f.file->f_mode & (FMODE_READ|FMODE_WRITE)))
!(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; goto out_putf;
}
lock = flock_make_lock(f.file, cmd, NULL); lock = flock_make_lock(f.file, cmd, NULL);
if (IS_ERR(lock)) { if (IS_ERR(lock)) {
...@@ -2718,6 +2725,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl, ...@@ -2718,6 +2725,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
struct inode *inode = NULL; struct inode *inode = NULL;
unsigned int fl_pid; unsigned int fl_pid;
struct pid_namespace *proc_pidns = proc_pid_ns(file_inode(f->file)->i_sb); struct pid_namespace *proc_pidns = proc_pid_ns(file_inode(f->file)->i_sb);
int type;
fl_pid = locks_translate_pid(fl, proc_pidns); 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, ...@@ -2745,11 +2753,7 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
seq_printf(f, " %s ", seq_printf(f, " %s ",
(inode == NULL) ? "*NOINODE*" : "ADVISORY "); (inode == NULL) ? "*NOINODE*" : "ADVISORY ");
} else if (IS_FLOCK(fl)) { } else if (IS_FLOCK(fl)) {
if (fl->fl_type & LOCK_MAND) { seq_puts(f, "FLOCK ADVISORY ");
seq_puts(f, "FLOCK MSNFS ");
} else {
seq_puts(f, "FLOCK ADVISORY ");
}
} else if (IS_LEASE(fl)) { } else if (IS_LEASE(fl)) {
if (fl->fl_flags & FL_DELEG) if (fl->fl_flags & FL_DELEG)
seq_puts(f, "DELEG "); seq_puts(f, "DELEG ");
...@@ -2765,17 +2769,10 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl, ...@@ -2765,17 +2769,10 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
} else { } else {
seq_puts(f, "UNKNOWN UNKNOWN "); seq_puts(f, "UNKNOWN UNKNOWN ");
} }
if (fl->fl_type & LOCK_MAND) { type = IS_LEASE(fl) ? target_leasetype(fl) : fl->fl_type;
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;
seq_printf(f, "%s ", (type == F_WRLCK) ? "WRITE" : seq_printf(f, "%s ", (type == F_WRLCK) ? "WRITE" :
(type == F_RDLCK) ? "READ" : "UNLCK"); (type == F_RDLCK) ? "READ" : "UNLCK");
}
if (inode) { if (inode) {
/* userspace relies on this representation of dev_t */ /* userspace relies on this representation of dev_t */
seq_printf(f, "%d %02x:%02x:%lu ", fl_pid, seq_printf(f, "%d %02x:%02x:%lu ", fl_pid,
......
...@@ -843,15 +843,6 @@ int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) ...@@ -843,15 +843,6 @@ int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
if (!(fl->fl_flags & FL_FLOCK)) if (!(fl->fl_flags & FL_FLOCK))
return -ENOLCK; 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) if (NFS_SERVER(inode)->flags & NFS_MOUNT_LOCAL_FLOCK)
is_local = 1; is_local = 1;
......
...@@ -181,6 +181,10 @@ struct f_owner_ex { ...@@ -181,6 +181,10 @@ struct f_owner_ex {
blocking */ blocking */
#define LOCK_UN 8 /* remove lock */ #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_MAND 32 /* This is a mandatory flock ... */
#define LOCK_READ 64 /* which allows concurrent read operations */ #define LOCK_READ 64 /* which allows concurrent read operations */
#define LOCK_WRITE 128 /* which allows concurrent write operations */ #define LOCK_WRITE 128 /* which allows concurrent write operations */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册