locks: remove LOCK_MAND flock lock support
authorJeff Layton <jlayton@kernel.org>
Fri, 10 Sep 2021 19:36:29 +0000 (15:36 -0400)
committerJeff Layton <jlayton@kernel.org>
Fri, 10 Sep 2021 20:21:44 +0000 (16:21 -0400)
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: Jeff Layton <jlayton@kernel.org>
fs/ceph/locks.c
fs/gfs2/file.c
fs/locks.c
fs/nfs/file.c
include/uapi/asm-generic/fcntl.h

index bdeb271f47d9526263dbf8d2089246212ad0bc2c..d8c31069fbf2b9eed2ec3e8825f7f4dae9ac4856 100644 (file)
@@ -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);
 
index c559827cb6f915a505fa225fa9a84bea71901923..078ef29e31bce478359eb45ff31fdd247bc7b0ec 100644 (file)
@@ -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);
index 3d6fb4ae847b4c6084c4f9745f2effce71ea6d78..d397394633be329088e3b71852afd000a197e6e9 100644 (file)
@@ -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,9 +2131,22 @@ 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)) {
@@ -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  ");
-               }
+               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");
-       }
+       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,
index aa353fd5824041f59b158c87db13251aca5815e5..24e7dccce3559f9b7d399fecea8109d88d1e8e41 100644 (file)
@@ -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;
 
index 9dc0bf0c5a6ee895edd0f9862923bbd86e4be808..ecd0f5bdfc1d617aede5900454f86076b924baf0 100644 (file)
@@ -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 */