proc: show locks in /proc/pid/fdinfo/X
Let's show locks which are associated with a file descriptor in its fdinfo file. Currently we don't have a reliable way to determine who holds a lock. We can find some information in /proc/locks, but PID which is reported there can be wrong. For example, a process takes a lock, then forks a child and dies. In this case /proc/locks contains the parent pid, which can be reused by another process. $ cat /proc/locks ... 6: FLOCK ADVISORY WRITE 324 00:13:13431 0 EOF ... $ ps -C rpcbind PID TTY TIME CMD 332 ? 00:00:00 rpcbind $ cat /proc/332/fdinfo/4 pos: 0 flags: 0100000 mnt_id: 22 lock: 1: FLOCK ADVISORY WRITE 324 00:13:13431 0 EOF $ ls -l /proc/332/fd/4 lr-x------ 1 root root 64 Mar 5 14:43 /proc/332/fd/4 -> /run/rpcbind.lock $ ls -l /proc/324/fd/ total 0 lrwx------ 1 root root 64 Feb 27 14:50 0 -> /dev/pts/0 lrwx------ 1 root root 64 Feb 27 14:50 1 -> /dev/pts/0 lrwx------ 1 root root 64 Feb 27 14:49 2 -> /dev/pts/0 You can see that the process with the 324 pid doesn't hold the lock. This information is required for proper dumping and restoring file locks. Signed-off-by: Andrey Vagin <avagin@openvz.org> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Acked-by: Jeff Layton <jlayton@poochiereds.net> Acked-by: "J. Bruce Fields" <bfields@fieldses.org> Acked-by: Cyrill Gorcunov <gorcunov@openvz.org> Cc: Pavel Emelyanov <xemul@parallels.com> Cc: Joe Perches <joe@perches.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:

committed by
Linus Torvalds

parent
15eb42d674
commit
6c8c90319c
38
fs/locks.c
38
fs/locks.c
@@ -2590,6 +2590,44 @@ static int locks_show(struct seq_file *f, void *v)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __show_fd_locks(struct seq_file *f,
|
||||
struct list_head *head, int *id,
|
||||
struct file *filp, struct files_struct *files)
|
||||
{
|
||||
struct file_lock *fl;
|
||||
|
||||
list_for_each_entry(fl, head, fl_list) {
|
||||
|
||||
if (filp != fl->fl_file)
|
||||
continue;
|
||||
if (fl->fl_owner != files &&
|
||||
fl->fl_owner != filp)
|
||||
continue;
|
||||
|
||||
(*id)++;
|
||||
seq_puts(f, "lock:\t");
|
||||
lock_get_status(f, fl, *id, "");
|
||||
}
|
||||
}
|
||||
|
||||
void show_fd_locks(struct seq_file *f,
|
||||
struct file *filp, struct files_struct *files)
|
||||
{
|
||||
struct inode *inode = file_inode(filp);
|
||||
struct file_lock_context *ctx;
|
||||
int id = 0;
|
||||
|
||||
ctx = inode->i_flctx;
|
||||
if (!ctx)
|
||||
return;
|
||||
|
||||
spin_lock(&ctx->flc_lock);
|
||||
__show_fd_locks(f, &ctx->flc_flock, &id, filp, files);
|
||||
__show_fd_locks(f, &ctx->flc_posix, &id, filp, files);
|
||||
__show_fd_locks(f, &ctx->flc_lease, &id, filp, files);
|
||||
spin_unlock(&ctx->flc_lock);
|
||||
}
|
||||
|
||||
static void *locks_start(struct seq_file *f, loff_t *pos)
|
||||
__acquires(&blocked_lock_lock)
|
||||
{
|
||||
|
Reference in New Issue
Block a user