Received: by 2002:ac0:a5b6:0:0:0:0:0 with SMTP id m51-v6csp375708imm; Fri, 1 Jun 2018 02:26:54 -0700 (PDT) X-Google-Smtp-Source: ADUXVKLaKyWy2L5FpXewYIyLJf5d0HcvEBGmekM8ERWwEhwTs4ixJH7KBRTGPAF0rE9/lk16DlJu X-Received: by 2002:a17:902:5a3:: with SMTP id f32-v6mr6770567plf.109.1527845214783; Fri, 01 Jun 2018 02:26:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1527845214; cv=none; d=google.com; s=arc-20160816; b=QvgIB/uSwyJ0HG/kzuYYhfPy8GNg6/odXluxKFOHsufBqyQR1ibdtG6lXUdL6QxGwv xZ9m9MJQBw6LiwuC3UvhNap3dmhCdraCTFS5mgDPZP/GSm2eGDZYOG7B2vwDiE4EzSS3 ntjQmOrUtEfOozqj2cWa6G/24NY2vZPyKqpnnhR1RTgmvXh3frnruEmoQ8B3OwTkbQV0 mg521l4/rvKZ+EnxjnEaKwWFWbYcwr4J7OOmSZ3c5p3HBDVr2fOitWtAd5NJxaq27nJn fmXA1uij1gn8OscptZQNt/wjHD0gCq0QO9QgE/Kb1iuH5cEGHRqHh+r8QQ4Lr3QvY0HQ gezA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:content-language :accept-language:in-reply-to:references:message-id:date:thread-index :thread-topic:subject:cc:to:from:arc-authentication-results; bh=5yKP9fkrW1aql5JEQR0VjO49jDZVOZuOWfi7S6Zl5so=; b=DeJGqmUUXtQepT+gv0puldFL2aRK13rPU/UTbJHMbtv9wKJMJaTYrEcnbxcDDhH9qd gTK24ZfOrRONPR0xH6S68tmRXfonX6LZseXEywTx300xlEt8A/pGIfgP1tyUmrhzzIho PdPdBVH3KsPJKHpAufdRI1p9HeBh9UxOunzpHXvjeQIiBa53NYliJg30CeDch55mUfkQ VH8id/vZ1ueoHEbftN+MRwYQQ/QZTzf7StnyFCsoTguf0XY6pZgvG+Zdp15iauVIxXvm lB+zfFPVMTZqMDJfgH0s6Fl9KbiVNbYRWIbH4yZdQzoAIhQrEAPn7VMxElaTu/7acecP XfRw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id bj5-v6si37675626plb.67.2018.06.01.02.26.38; Fri, 01 Jun 2018 02:26:54 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751482AbeFAJZn (ORCPT + 99 others); Fri, 1 Jun 2018 05:25:43 -0400 Received: from mgwym04.jp.fujitsu.com ([211.128.242.43]:10269 "EHLO mgwym04.jp.fujitsu.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751417AbeFAJZk (ORCPT ); Fri, 1 Jun 2018 05:25:40 -0400 Received: from yt-mxauth.gw.nic.fujitsu.com (unknown [192.168.229.68]) by mgwym04.jp.fujitsu.com with smtp id 7f2b_3856_9b06e5c0_0abf_457f_8d88_1e3016153e16; Fri, 01 Jun 2018 18:25:33 +0900 Received: from g01jpfmpwyt02.exch.g01.fujitsu.local (g01jpfmpwyt02.exch.g01.fujitsu.local [10.128.193.56]) by yt-mxauth.gw.nic.fujitsu.com (Postfix) with ESMTP id AD0B3AC04EE for ; Fri, 1 Jun 2018 18:25:33 +0900 (JST) Received: from G01JPEXCHYT13.g01.fujitsu.local (G01JPEXCHYT13.g01.fujitsu.local [10.128.194.52]) by g01jpfmpwyt02.exch.g01.fujitsu.local (Postfix) with ESMTP id 9E294584380; Fri, 1 Jun 2018 18:25:32 +0900 (JST) Received: from G01JPEXMBYT03.g01.fujitsu.local ([10.128.194.67]) by G01JPEXCHYT13 ([10.128.194.52]) with mapi id 14.03.0352.000; Fri, 1 Jun 2018 18:25:32 +0900 From: "Hatayama, Daisuke" To: "'tj@kernel.org'" CC: "'gregkh@linuxfoundation.org'" , "Okajima, Toshiyuki" , "linux-kernel@vger.kernel.org" , "'ebiederm@aristanetworks.com'" Subject: RE: [RESEND PATCH v2] kernfs: fix dentry unexpected skip Thread-Topic: [RESEND PATCH v2] kernfs: fix dentry unexpected skip Thread-Index: AdP2gtQcFftKX6rKRguW2o+iRXsAXgAm4bKAAJr88AA= Date: Fri, 1 Jun 2018 09:25:32 +0000 Message-ID: <33710E6CAA200E4583255F4FB666C4E21B65779C@G01JPEXMBYT03> References: <33710E6CAA200E4583255F4FB666C4E21B63D491@G01JPEXMBYT03> <20180529162627.GH1351649@devbig577.frc2.facebook.com> In-Reply-To: <20180529162627.GH1351649@devbig577.frc2.facebook.com> Accept-Language: ja-JP, en-US Content-Language: ja-JP X-MS-Has-Attach: X-MS-TNEF-Correlator: x-securitypolicycheck: OK by SHieldMailChecker v2.5.2 x-shieldmailcheckerpolicyversion: FJ-ISEC-20170217-enc x-shieldmailcheckermailid: 9b3207184fab408395c5922b35759b0d x-originating-ip: [10.124.89.120] Content-Type: text/plain; charset="iso-2022-jp" MIME-Version: 1.0 X-SecurityPolicyCheck-GC: OK by FENCE-Mail X-TM-AS-MML: disable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org > -----Original Message----- > From: Tejun Heo [mailto:htejun@gmail.com] On Behalf Of 'tj@kernel.org' > Sent: Wednesday, May 30, 2018 1:26 AM > To: Hatayama, Daisuke > Cc: 'gregkh@linuxfoundation.org' ; Okajima, > Toshiyuki ; > linux-kernel@vger.kernel.org; 'ebiederm@aristanetworks.com' > > Subject: Re: [RESEND PATCH v2] kernfs: fix dentry unexpected skip > > Hello, > > On Mon, May 28, 2018 at 12:54:03PM +0000, Hatayama, Daisuke wrote: > > diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c > > index 89d1dc1..3aeeb7a 100644 > > --- a/fs/kernfs/dir.c > > +++ b/fs/kernfs/dir.c > > @@ -1621,8 +1621,10 @@ static int kernfs_dir_fop_release(struct inode *inode, > struct file *filp) > > static struct kernfs_node *kernfs_dir_next_pos(const void *ns, > > struct kernfs_node *parent, ino_t ino, struct kernfs_node *pos) > > { > > + struct kernfs_node *orig = pos; > > + > > pos = kernfs_dir_pos(ns, parent, ino, pos); > > - if (pos) { > > + if (pos && kernfs_sd_compare(pos, orig) <= 0) { > > Hmm... the code seems a bit unintuitive to me and I wonder whether > it's because there are two identical skipping loops in > kernfs_dir_pos() and kernfs_dir_next_pos() and we're now trying to > selectively disable one of them. Wouldn't it make more sense to get > rid of it from kernfs_dir_pos() and skip explicitly only when > necessary? > kernfs_dir_pos() checks if a kernfs_node object given as one of its arguments is still active and if so returns it, or returns a kernfs_node object that is most equal (possibly smaller and larger) to the given object. kernfs_dir_next_pos() returns a kernfs_node object that is next to the object given by kernfs_dir_pos(). Two functions does different things and both need to skip inactive nodes. I don't think it natural to remove the skip only from kernfs_dir_pos(). OTOH, throughout getdents(), there is no case that the kernfs_node object given to kernfs_dir_pos() is used afterwards in the processing. So, is it enough to provide kernfs_dir_next_pos() only? Then, the skip code is now not duplicated. The patch below is my thought. How do you think? But note that this patch has some bug so that system boot get hang without detecting root filesystem disk :) I'm debugging this now. diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 89d1dc1..140706f 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c @@ -1584,9 +1584,11 @@ static int kernfs_dir_fop_release(struct inode *inode, struct file *filp) return 0; } -static struct kernfs_node *kernfs_dir_pos(const void *ns, +static struct kernfs_node *kernfs_dir_next_pos(const void *ns, struct kernfs_node *parent, loff_t hash, struct kernfs_node *pos) { + struct kernfs_node *orig = pos; + if (pos) { int valid = kernfs_active(pos) && pos->parent == parent && hash == pos->hash; @@ -1608,7 +1610,9 @@ static struct kernfs_node *kernfs_dir_pos(const void *ns, } } /* Skip over entries which are dying/dead or in the wrong namespace */ - while (pos && (!kernfs_active(pos) || pos->ns != ns)) { + while (pos && (!kernfs_active(pos) || + (!orig || kernfs_sd_compare(pos, orig) <= 0) || + pos->ns != ns)) { struct rb_node *node = rb_next(&pos->rb); if (!node) pos = NULL; @@ -1618,22 +1622,6 @@ static struct kernfs_node *kernfs_dir_pos(const void *ns, return pos; } -static struct kernfs_node *kernfs_dir_next_pos(const void *ns, - struct kernfs_node *parent, ino_t ino, struct kernfs_node *pos) -{ - pos = kernfs_dir_pos(ns, parent, ino, pos); - if (pos) { - do { - struct rb_node *node = rb_next(&pos->rb); - if (!node) - pos = NULL; - else - pos = rb_to_kn(node); - } while (pos && (!kernfs_active(pos) || pos->ns != ns)); - } - return pos; -} - static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx) { struct dentry *dentry = file->f_path.dentry; @@ -1648,7 +1636,7 @@ static int kernfs_fop_readdir(struct file *file, struct dir_context *ctx) if (kernfs_ns_enabled(parent)) ns = kernfs_info(dentry->d_sb)->ns; - for (pos = kernfs_dir_pos(ns, parent, ctx->pos, pos); + for (pos = kernfs_dir_next_pos(ns, parent, ctx->pos, pos); pos; pos = kernfs_dir_next_pos(ns, parent, ctx->pos, pos)) { const char *name = pos->name; Thanks. HATAYAMA, Daisuke