Merge tag 'filelock-v5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 18 Sep 2019 20:41:01 +0000 (13:41 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 18 Sep 2019 20:41:01 +0000 (13:41 -0700)
Pull file locking updates from Jeff Layton:
 "Just a couple of minor bugfixes, a revision to a tracepoint to account
  for some earlier changes to the internals, and a patch to add a
  pr_warn message when someone tries to mount a filesystem with '-o
  mand' on a kernel that has that support disabled"

* tag 'filelock-v5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux:
  locks: fix a memory leak bug in __break_lease()
  locks: print a warning when mount fails due to lack of "mand" support
  locks: Fix procfs output for file leases
  locks: revise generic_add_lease tracepoint

Documentation/filesystems/mandatory-locking.txt
fs/locks.c
fs/namespace.c
include/trace/events/filelock.h

index 0979d1d2ca8bb94b21d15f7a0c193ac7ce9f4f9f..a251ca33164ae9d2e8902f94aeb680e7038faeae 100644 (file)
@@ -169,3 +169,13 @@ havoc if they lock crucial files. The way around it is to change the file
 permissions (remove the setgid bit) before trying to read or write to it.
 Of course, that might be a bit tricky if the system is hung :-(
 
+7. The "mand" mount option
+--------------------------
+Mandatory locking is disabled on all filesystems by default, and must be
+administratively enabled by mounting with "-o mand". That mount option
+is only allowed if the mounting task has the CAP_SYS_ADMIN capability.
+
+Since kernel v4.5, it is possible to disable mandatory locking
+altogether by setting CONFIG_MANDATORY_FILE_LOCKING to "n". A kernel
+with this disabled will reject attempts to mount filesystems with the
+"mand" mount option with the error status EPERM.
index 686eae21daf6aeeac4d13a492009f224f678a096..a364ebc5cec3b1b974da670c72e9af0a42e07c2a 100644 (file)
@@ -1592,7 +1592,7 @@ int __break_lease(struct inode *inode, unsigned int mode, unsigned int type)
        ctx = smp_load_acquire(&inode->i_flctx);
        if (!ctx) {
                WARN_ON_ONCE(1);
-               return error;
+               goto free_lock;
        }
 
        percpu_down_read(&file_rwsem);
@@ -1672,6 +1672,7 @@ out:
        spin_unlock(&ctx->flc_lock);
        percpu_up_read(&file_rwsem);
        locks_dispose_list(&dispose);
+free_lock:
        locks_free_lock(new_fl);
        return error;
 }
@@ -2784,10 +2785,10 @@ static void lock_get_status(struct seq_file *f, struct file_lock *fl,
                               ? (fl->fl_type & LOCK_WRITE) ? "RW   " : "READ "
                               : (fl->fl_type & LOCK_WRITE) ? "WRITE" : "NONE ");
        } else {
-               seq_printf(f, "%s ",
-                              (lease_breaking(fl))
-                              ? (fl->fl_type == F_UNLCK) ? "UNLCK" : "READ "
-                              : (fl->fl_type == F_WRLCK) ? "WRITE" : "READ ");
+               int 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 */
index 81edb7e7ddfda8840e233fd2ead048b3d35377d0..227f7b34303465a2621497524dece91038267b23 100644 (file)
@@ -1643,13 +1643,18 @@ static inline bool may_mount(void)
        return ns_capable(current->nsproxy->mnt_ns->user_ns, CAP_SYS_ADMIN);
 }
 
+#ifdef CONFIG_MANDATORY_FILE_LOCKING
 static inline bool may_mandlock(void)
 {
-#ifndef        CONFIG_MANDATORY_FILE_LOCKING
-       return false;
-#endif
        return capable(CAP_SYS_ADMIN);
 }
+#else
+static inline bool may_mandlock(void)
+{
+       pr_warn("VFS: \"mand\" mount option not supported");
+       return false;
+}
+#endif
 
 /*
  * Now umount can handle mount points as well as block devices.
index 4b735923f2ffc3b49806347f6cb0c18eae41f940..c705e4944a5037434b964ef68b078d7c2bb797c0 100644 (file)
@@ -176,7 +176,7 @@ TRACE_EVENT(generic_add_lease,
        TP_STRUCT__entry(
                __field(unsigned long, i_ino)
                __field(int, wcount)
-               __field(int, dcount)
+               __field(int, rcount)
                __field(int, icount)
                __field(dev_t, s_dev)
                __field(fl_owner_t, fl_owner)
@@ -188,16 +188,16 @@ TRACE_EVENT(generic_add_lease,
                __entry->s_dev = inode->i_sb->s_dev;
                __entry->i_ino = inode->i_ino;
                __entry->wcount = atomic_read(&inode->i_writecount);
-               __entry->dcount = d_count(fl->fl_file->f_path.dentry);
+               __entry->rcount = atomic_read(&inode->i_readcount);
                __entry->icount = atomic_read(&inode->i_count);
-               __entry->fl_owner = fl ? fl->fl_owner : NULL;
-               __entry->fl_flags = fl ? fl->fl_flags : 0;
-               __entry->fl_type = fl ? fl->fl_type : 0;
+               __entry->fl_owner = fl->fl_owner;
+               __entry->fl_flags = fl->fl_flags;
+               __entry->fl_type = fl->fl_type;
        ),
 
-       TP_printk("dev=0x%x:0x%x ino=0x%lx wcount=%d dcount=%d icount=%d fl_owner=0x%p fl_flags=%s fl_type=%s",
+       TP_printk("dev=0x%x:0x%x ino=0x%lx wcount=%d rcount=%d icount=%d fl_owner=0x%p fl_flags=%s fl_type=%s",
                MAJOR(__entry->s_dev), MINOR(__entry->s_dev),
-               __entry->i_ino, __entry->wcount, __entry->dcount,
+               __entry->i_ino, __entry->wcount, __entry->rcount,
                __entry->icount, __entry->fl_owner,
                show_fl_flags(__entry->fl_flags),
                show_fl_type(__entry->fl_type))