summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-09-18 13:41:01 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2019-09-18 13:41:01 -0700
commitd013cc800a2a41b0496f99a11f3cff724cf65941 (patch)
tree43dfaac956d04461b8fcf24e7d4cf2582beb68b7
parente170eb27715fc9253ae031297d0638a3ef51b5da (diff)
parentcfddf9f4c9f038c91c6c61d5cf3a161731b5c418 (diff)
downloadlinux-d013cc800a2a41b0496f99a11f3cff724cf65941.tar.bz2
Merge tag 'filelock-v5.4-1' of git://git.kernel.org/pub/scm/linux/kernel/git/jlayton/linux
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
-rw-r--r--Documentation/filesystems/mandatory-locking.txt10
-rw-r--r--fs/locks.c11
-rw-r--r--fs/namespace.c11
-rw-r--r--include/trace/events/filelock.h14
4 files changed, 31 insertions, 15 deletions
diff --git a/Documentation/filesystems/mandatory-locking.txt b/Documentation/filesystems/mandatory-locking.txt
index 0979d1d2ca8b..a251ca33164a 100644
--- a/Documentation/filesystems/mandatory-locking.txt
+++ b/Documentation/filesystems/mandatory-locking.txt
@@ -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.
diff --git a/fs/locks.c b/fs/locks.c
index 686eae21daf6..a364ebc5cec3 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -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 */
diff --git a/fs/namespace.c b/fs/namespace.c
index 81edb7e7ddfd..227f7b343034 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -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.
diff --git a/include/trace/events/filelock.h b/include/trace/events/filelock.h
index 4b735923f2ff..c705e4944a50 100644
--- a/include/trace/events/filelock.h
+++ b/include/trace/events/filelock.h
@@ -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))