From 6b0e42771795334bd24d089402d04d93bac048d3 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Sun, 21 Jul 2019 19:01:34 -0400 Subject: locks: revise generic_add_lease tracepoint Now that check_conflicting_open uses inode->i_readcount instead of the dentry->d_count to detect opens for read, revise the tracepoint to display that value instead. Also, fl is never NULL, so no need to check for that in the fast assign section. Cc: Amir Goldstein Reported-by: Al Viro Signed-off-by: Jeff Layton --- include/trace/events/filelock.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) 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)) -- cgit v1.2.3 From 43e4cb942e88e756b41ea4d30249a47973880508 Mon Sep 17 00:00:00 2001 From: Pavel Begunkov Date: Wed, 24 Jul 2019 20:16:31 +0300 Subject: locks: Fix procfs output for file leases Since commit 778fc546f749c588aa2f ("locks: fix tracking of inprogress lease breaks"), leases break don't change @fl_type but modifies @fl_flags. However, procfs's part haven't been updated. Previously, for a breaking lease the target type was printed (see target_leasetype()), as returns fcntl(F_GETLEASE). But now it's always "READ", as F_UNLCK no longer means "breaking". Unlike the previous one, this behaviour don't provide a complete description of the lease. There are /proc/pid/fdinfo/ outputs for a lease (the same for READ and WRITE) breaked by O_WRONLY. -- before: lock: 1: LEASE BREAKING READ 2558 08:03:815793 0 EOF -- after: lock: 1: LEASE BREAKING UNLCK 2558 08:03:815793 0 EOF Signed-off-by: Pavel Begunkov Signed-off-by: Jeff Layton --- fs/locks.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/locks.c b/fs/locks.c index 686eae21daf6..24d1db632f6c 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -2784,10 +2784,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 */ -- cgit v1.2.3 From df2474a22c42ce419b67067c52d71da06c385501 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Thu, 15 Aug 2019 15:21:17 -0400 Subject: locks: print a warning when mount fails due to lack of "mand" support Since 9e8925b67a ("locks: Allow disabling mandatory locking at compile time"), attempts to mount filesystems with "-o mand" will fail. Unfortunately, there is no other indiciation of the reason for the failure. Change how the function is defined for better readability. When CONFIG_MANDATORY_FILE_LOCKING is disabled, printk a warning when someone attempts to mount with -o mand. Also, add a blurb to the mandatory-locking.txt file to explain about the "mand" option, and the behavior one should expect when it is disabled. Reported-by: Jan Kara Reviewed-by: Jan Kara Signed-off-by: Jeff Layton --- Documentation/filesystems/mandatory-locking.txt | 10 ++++++++++ fs/namespace.c | 11 ++++++++--- 2 files changed, 18 insertions(+), 3 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/namespace.c b/fs/namespace.c index 6464ea4acba9..602bd78ba572 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. -- cgit v1.2.3 From cfddf9f4c9f038c91c6c61d5cf3a161731b5c418 Mon Sep 17 00:00:00 2001 From: Wenwen Wang Date: Mon, 19 Aug 2019 18:47:34 -0500 Subject: locks: fix a memory leak bug in __break_lease() In __break_lease(), the file lock 'new_fl' is allocated in lease_alloc(). However, it is not deallocated in the following execution if smp_load_acquire() fails, leading to a memory leak bug. To fix this issue, free 'new_fl' before returning the error. Signed-off-by: Wenwen Wang Signed-off-by: Jeff Layton --- fs/locks.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fs/locks.c b/fs/locks.c index 24d1db632f6c..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; } -- cgit v1.2.3