Received: by 2002:a6b:fb09:0:0:0:0:0 with SMTP id h9csp21837iog; Tue, 28 Jun 2022 14:00:21 -0700 (PDT) X-Google-Smtp-Source: AGRyM1s0APo8uu0WNwISKJffNkJlPfypQJRV8cEfpHuZOg2C3sBk5N8XUFrhBkwlL1fw7G9L9f3v X-Received: by 2002:a17:907:7211:b0:722:e200:5410 with SMTP id dr17-20020a170907721100b00722e2005410mr18033ejc.614.1656450020880; Tue, 28 Jun 2022 14:00:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1656450020; cv=none; d=google.com; s=arc-20160816; b=uWRbSVe+bMwQggKRUV87ixbpGStJa6vGxjNvqi/fq5j9gZ8NVx4UoBEFmlhPWI9tcX tx0ggxhaRgltf4XMqoNDpeV6P4p3jmJudcXgzGUmo4XtueYIFxT76/Bly1nrstc5Tr4M lwOo9l9MykGqMtcYFS1u4MC5uF6Dvt+o1JTd/M/M2QEEjaADz1lxnLsMUKx55ZywGgf/ 1vM/FVmIOJaQTcWZ2Sf2kr2m8VTbt5tTPpYvtLPpOCyANUxATmBq4GupVh6T6dd7lUmF qHQLcbawM+6PJlkFcHh0/zwyEP0pyNne18FXgJ2Jz7h3QZ0EuCKC174CCgn+gz4QZ1FN tRmw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=3UnwOLd+3RtI858ogHbbAwRvYSEQdRCv3KJ1ACMKljA=; b=CEG0VrikJwhILPIz+wtBjlK3ZWqptP5PnacLnsGm1CXymMmjQU3pcirY+nWQmQm4SP 9ekb0haXtpIqlN01CT4eaPtle734tLEmvYgLwnwT0zQ6qQWdpD57k6mXxVchKT91s96E LAAZBb8BzO6n9jyDD6X5li0/aOO/a4up9gp/k8iywf/VkhB930yTFIjXvNxdGPlMAvp+ B5GtHUi9krnjVPCqsj0J9jbqEmDWh3ArNkULerlC3tcRVlB5IAXThLmRHmvQcpXStAJm V/QvxIly73KnlZDQ2gqs+EJWcE7bFyakcDK8Dy89ikhM0lxQRWhV2BmGwVHL+EsP50Gt skkA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Bd7KEVq7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id s3-20020a17090699c300b00712ae69fac3si20120085ejn.878.2022.06.28.13.59.51; Tue, 28 Jun 2022 14:00:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Bd7KEVq7; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231142AbiF1Uq2 (ORCPT + 99 others); Tue, 28 Jun 2022 16:46:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33014 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229626AbiF1UqV (ORCPT ); Tue, 28 Jun 2022 16:46:21 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id D79CE2A275 for ; Tue, 28 Jun 2022 13:46:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1656449179; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=3UnwOLd+3RtI858ogHbbAwRvYSEQdRCv3KJ1ACMKljA=; b=Bd7KEVq7dBHToUrVcIJKRhjf1WDj3RT0pjyEz0neSfPRzswxap5UKtZyiY/2ADxbmST0He ZWSMcVS4O++D2MK3LgNzrQvLyCde2UPPsYtOggMEIYvC0QF0z+HDUva+Vchg6mykTluAz1 2iUAEllWBPELNceeP3kddvSApghiTlk= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-665-KDy9fWrnP-m8W5GnpFIHkQ-1; Tue, 28 Jun 2022 16:46:14 -0400 X-MC-Unique: KDy9fWrnP-m8W5GnpFIHkQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 7EABC85A581; Tue, 28 Jun 2022 20:46:14 +0000 (UTC) Received: from max.localdomain (unknown [10.40.193.19]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8EC9540D282F; Tue, 28 Jun 2022 20:46:13 +0000 (UTC) From: Andreas Gruenbacher To: cluster-devel@redhat.com Cc: Andreas Gruenbacher , linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, "Eric W. Biederman" Subject: [PATCH 1/5] gfs2: Add glockfd debugfs file Date: Tue, 28 Jun 2022 22:46:07 +0200 Message-Id: <20220628204611.651126-2-agruenba@redhat.com> In-Reply-To: <20220628204611.651126-1-agruenba@redhat.com> References: <20220628204611.651126-1-agruenba@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Scanned-By: MIMEDefang 2.84 on 10.11.54.2 X-Spam-Status: No, score=-3.2 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_LOW, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org When a process has a gfs2 file open, the file is keeping a reference on the underlying gfs2 inode, and the inode is keeping the inode's iopen glock held in shared mode. In other words, the process depends on the iopen glock of each open gfs2 file. Expose those dependencies in a new "glockfd" debugfs file. The new debugfs file contains one line for each gfs2 file descriptor, specifying the tgid, file descriptor number, and glock name, e.g., 1601 6 5/816d This list is compiled by iterating all tasks on the system using find_ge_pid(), and all file descriptors of each task using task_lookup_next_fd_rcu(). To make that work from gfs2, export those two functions. Signed-off-by: Andreas Gruenbacher Cc: Eric W. Biederman Cc: cluster-devel@redhat.com Cc: linux-kernel@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org --- fs/file.c | 1 + fs/gfs2/glock.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++ kernel/pid.c | 1 + 3 files changed, 149 insertions(+) diff --git a/fs/file.c b/fs/file.c index 3bcc1ecc314a..5f9c802a5d8d 100644 --- a/fs/file.c +++ b/fs/file.c @@ -980,6 +980,7 @@ struct file *task_lookup_next_fd_rcu(struct task_struct *task, unsigned int *ret *ret_fd = fd; return file; } +EXPORT_SYMBOL(task_lookup_next_fd_rcu); /* * Lightweight file lookup - no refcnt increment if fd table isn't shared. diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index c992d53013d3..63dbab6fa242 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "gfs2.h" #include "incore.h" @@ -2745,6 +2746,149 @@ static const struct file_operations gfs2_glstats_fops = { .release = gfs2_glocks_release, }; +struct gfs2_glockfd_iter { + struct super_block *sb; + unsigned int tgid; + struct task_struct *task; + unsigned int fd; + struct file *file; +}; + +static struct task_struct *gfs2_glockfd_next_task(struct gfs2_glockfd_iter *i) +{ + struct pid_namespace *ns = task_active_pid_ns(current); + struct pid *pid; + + if (i->task) + put_task_struct(i->task); + + rcu_read_lock(); +retry: + i->task = NULL; + pid = find_ge_pid(i->tgid, ns); + if (pid) { + i->tgid = pid_nr_ns(pid, ns); + i->task = pid_task(pid, PIDTYPE_TGID); + if (!i->task) { + i->tgid++; + goto retry; + } + get_task_struct(i->task); + } + rcu_read_unlock(); + return i->task; +} + +static struct file *gfs2_glockfd_next_file(struct gfs2_glockfd_iter *i) +{ + if (i->file) { + fput(i->file); + i->file = NULL; + } + + rcu_read_lock(); + for(;; i->fd++) { + struct inode *inode; + + i->file = task_lookup_next_fd_rcu(i->task, &i->fd); + if (!i->file) { + i->fd = 0; + break; + } + inode = file_inode(i->file); + if (inode->i_sb != i->sb) + continue; + if (get_file_rcu(i->file)) + break; + } + rcu_read_unlock(); + return i->file; +} + +static void *gfs2_glockfd_seq_start(struct seq_file *seq, loff_t *pos) +{ + struct gfs2_glockfd_iter *i = seq->private; + + if (*pos) + return NULL; + while (gfs2_glockfd_next_task(i)) { + if (gfs2_glockfd_next_file(i)) + return i; + i->tgid++; + } + return NULL; +} + +static void *gfs2_glockfd_seq_next(struct seq_file *seq, void *iter_ptr, + loff_t *pos) +{ + struct gfs2_glockfd_iter *i = seq->private; + + (*pos)++; + i->fd++; + do { + if (gfs2_glockfd_next_file(i)) + return i; + i->tgid++; + } while (gfs2_glockfd_next_task(i)); + return NULL; +} + +static void gfs2_glockfd_seq_stop(struct seq_file *seq, void *iter_ptr) +{ + struct gfs2_glockfd_iter *i = seq->private; + + if (i->file) + fput(i->file); + if (i->task) + put_task_struct(i->task); +} + +static int gfs2_glockfd_seq_show(struct seq_file *seq, void *iter_ptr) +{ + struct gfs2_glockfd_iter *i = seq->private; + struct inode *inode = file_inode(i->file); + struct gfs2_glock *gl; + + inode_lock_shared(inode); + gl = GFS2_I(inode)->i_iopen_gh.gh_gl; + if (gl) { + seq_printf(seq, "%d %u %u/%llx\n", + i->tgid, i->fd, gl->gl_name.ln_type, + (unsigned long long)gl->gl_name.ln_number); + } + inode_unlock_shared(inode); + return 0; +} + +static const struct seq_operations gfs2_glockfd_seq_ops = { + .start = gfs2_glockfd_seq_start, + .next = gfs2_glockfd_seq_next, + .stop = gfs2_glockfd_seq_stop, + .show = gfs2_glockfd_seq_show, +}; + +static int gfs2_glockfd_open(struct inode *inode, struct file *file) +{ + struct gfs2_glockfd_iter *i; + struct gfs2_sbd *sdp = inode->i_private; + + i = __seq_open_private(file, &gfs2_glockfd_seq_ops, + sizeof(struct gfs2_glockfd_iter)); + if (!i) + return -ENOMEM; + i->sb = sdp->sd_vfs; + return 0; +} + +static const struct file_operations gfs2_glockfd_fops = { + .owner = THIS_MODULE, + .open = gfs2_glockfd_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release_private, +}; + DEFINE_SEQ_ATTRIBUTE(gfs2_sbstats); void gfs2_create_debugfs_file(struct gfs2_sbd *sdp) @@ -2754,6 +2898,9 @@ void gfs2_create_debugfs_file(struct gfs2_sbd *sdp) debugfs_create_file("glocks", S_IFREG | S_IRUGO, sdp->debugfs_dir, sdp, &gfs2_glocks_fops); + debugfs_create_file("glockfd", S_IFREG | S_IRUGO, sdp->debugfs_dir, sdp, + &gfs2_glockfd_fops); + debugfs_create_file("glstats", S_IFREG | S_IRUGO, sdp->debugfs_dir, sdp, &gfs2_glstats_fops); diff --git a/kernel/pid.c b/kernel/pid.c index 2fc0a16ec77b..3fbc5e46b721 100644 --- a/kernel/pid.c +++ b/kernel/pid.c @@ -519,6 +519,7 @@ struct pid *find_ge_pid(int nr, struct pid_namespace *ns) { return idr_get_next(&ns->idr, &nr); } +EXPORT_SYMBOL_GPL(find_ge_pid); struct pid *pidfd_get_pid(unsigned int fd, unsigned int *flags) { -- 2.35.1