From patchwork Thu May 17 08:53:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 10405955 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 50C10602C2 for ; Thu, 17 May 2018 08:53:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3FA4D284F5 for ; Thu, 17 May 2018 08:53:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 32D66285CB; Thu, 17 May 2018 08:53:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 79E62284F5 for ; Thu, 17 May 2018 08:53:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1750924AbeEQIxR (ORCPT ); Thu, 17 May 2018 04:53:17 -0400 Received: from mail-wm0-f68.google.com ([74.125.82.68]:54647 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750826AbeEQIxN (ORCPT ); Thu, 17 May 2018 04:53:13 -0400 Received: by mail-wm0-f68.google.com with SMTP id f6-v6so6982767wmc.4 for ; Thu, 17 May 2018 01:53:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=szeredi.hu; s=google; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=FkV+zcENTVI/X+PntvHm6Bb7u0t3r10shYjDNAZI8a4=; b=kR8Ud1JXdq9xo1eDVfm6XhbaGxxqsiyWJn8Q012UyaTE3InhBD521gYK4fOnkbDPvV WAliItNi8aktCcv+t5eQOhYIdbQo6lbtI7IqWrzIF2h/ztuWtK0H8QgLPQGuems6BlaB Rbn0oeeza5BEVMOs3VAeGV5PYOYEIFjtJoSCU= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=FkV+zcENTVI/X+PntvHm6Bb7u0t3r10shYjDNAZI8a4=; b=FbZJVx/JL1eB4o+E5geMf+0K6HFnF7p/zE03MGyyfL2g0F0bDorZx6UShlJ0aP7kkB 8/izZDFhmphYAm3oD64y3DoBAFnXwkk9h/+oPq0ZScAP4SOX7AnllVEgNkb75dMiMF1v DfPbGZaICa370zftxZzww3tGzMhQToZjMDZ9HfGKSwR5Hxdg/uXcOEahgQXrAZY1FZSi //xYBkllDuykwTGgIWfRGs5Lo4Hsumj/izzuxJtgWG/fQLGW3wkgtQ38OERiDjFAPYlr Rk0CERDDHj7Fx5pkMCSq0p8cWkO2J6CGwsOWIYRIhxRfvGF0i8VO1wZAv+/5uzgDan2b fzyA== X-Gm-Message-State: ALKqPwe9hKAv6VM3IRfchxGSp2BbCkLXN6c3fVFf4i8fEuC2SWDGF9ka zdJ2kZ09VuOVOezevj/lD1K9Bg== X-Google-Smtp-Source: AB8JxZoTsyvXuZc/fm5dLZyyWWLP1isqSnFh3hkHAM9YcQJLTNK6+M6ishrSeoiIrKIQoIsCJCLT9w== X-Received: by 2002:a1c:8611:: with SMTP id i17-v6mr1052604wmd.107.1526547192480; Thu, 17 May 2018 01:53:12 -0700 (PDT) Received: from veci.piliscsaba.redhat.com (C2B0E321.catv.pool.telekom.hu. [194.176.227.33]) by smtp.gmail.com with ESMTPSA id 2-v6sm9850580wrb.22.2018.05.17.01.53.11 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 17 May 2018 01:53:11 -0700 (PDT) Date: Thu, 17 May 2018 10:53:05 +0200 From: Miklos Szeredi To: Amir Goldstein Cc: Vivek Goyal , Al Viro , overlayfs , linux-fsdevel Subject: Re: [PATCH v3 1/4] ovl: use insert_inode_locked4() to hash a newly created inode Message-ID: <20180517085305.GA23785@veci.piliscsaba.redhat.com> References: <1526379972-20923-1-git-send-email-amir73il@gmail.com> <1526379972-20923-2-git-send-email-amir73il@gmail.com> <20180515132328.GA11678@redhat.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.9.2 (2017-12-15) Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP On Thu, May 17, 2018 at 10:10:58AM +0200, Miklos Szeredi wrote: > > Not the only reason: we don't want inode allocation to fail after > successful creation. Solution: add a preallocated inode argument to > ovl_get_inode() and deal with allocation failure there. Here's a patch to split a helper out of iget5_locked() that takes a preallocated inode. It makes the whole thing more readable, IMO, regardless of overlayfs's needs. Thanks, Miklos diff --git a/fs/inode.c b/fs/inode.c index 13ceb98c3bd3..bb79e3f96147 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -1002,6 +1002,52 @@ void unlock_two_nondirectories(struct inode *inode1, struct inode *inode2) } EXPORT_SYMBOL(unlock_two_nondirectories); +struct inode *iget5_prealloc(struct inode *inode, + struct super_block *sb, unsigned long hashval, + int (*test)(struct inode *, void *), + int (*set)(struct inode *, void *), void *data) +{ + struct hlist_head *head = inode_hashtable + hash(sb, hashval); + struct inode *old; + +again: + spin_lock(&inode_hash_lock); + old = find_inode(sb, head, test, data); + if (unlikely(old)) { + /* + * Uhhuh, somebody else created the same inode under us. + * Use the old inode instead of the preallocated one. + */ + spin_unlock(&inode_hash_lock); + wait_on_inode(old); + if (unlikely(inode_unhashed(old))) { + iput(old); + goto again; + } + return old; + } + + if (unlikely(set(inode, data))) { + inode = NULL; + goto unlock; + } + + /* + * Return the locked inode with I_NEW set, the + * caller is responsible for filling in the contents + */ + spin_lock(&inode->i_lock); + inode->i_state = I_NEW; + hlist_add_head(&inode->i_hash, head); + spin_unlock(&inode->i_lock); + inode_sb_list_add(inode); +unlock: + spin_unlock(&inode_hash_lock); + + return inode; +} +EXPORT_SYMBOL(iget5_prealloc); + /** * iget5_locked - obtain an inode from a mounted file system * @sb: super block of file system @@ -1026,66 +1072,18 @@ struct inode *iget5_locked(struct super_block *sb, unsigned long hashval, int (*test)(struct inode *, void *), int (*set)(struct inode *, void *), void *data) { - struct hlist_head *head = inode_hashtable + hash(sb, hashval); - struct inode *inode; -again: - spin_lock(&inode_hash_lock); - inode = find_inode(sb, head, test, data); - spin_unlock(&inode_hash_lock); + struct inode *inode = ilookup5(sb, hashval, test, data); - if (inode) { - wait_on_inode(inode); - if (unlikely(inode_unhashed(inode))) { - iput(inode); - goto again; - } - return inode; - } - - inode = alloc_inode(sb); - if (inode) { - struct inode *old; - - spin_lock(&inode_hash_lock); - /* We released the lock, so.. */ - old = find_inode(sb, head, test, data); - if (!old) { - if (set(inode, data)) - goto set_failed; - - spin_lock(&inode->i_lock); - inode->i_state = I_NEW; - hlist_add_head(&inode->i_hash, head); - spin_unlock(&inode->i_lock); - inode_sb_list_add(inode); - spin_unlock(&inode_hash_lock); - - /* Return the locked inode with I_NEW set, the - * caller is responsible for filling in the contents - */ - return inode; - } + if (!inode) { + struct inode *new = alloc_inode(sb); - /* - * Uhhuh, somebody else created the same inode under - * us. Use the old inode instead of the one we just - * allocated. - */ - spin_unlock(&inode_hash_lock); - destroy_inode(inode); - inode = old; - wait_on_inode(inode); - if (unlikely(inode_unhashed(inode))) { - iput(inode); - goto again; + if (new) { + inode = iget5_prealloc(new, sb, hashval, test, set, data); + if (inode != new) + destroy_inode(new); } } return inode; - -set_failed: - spin_unlock(&inode_hash_lock); - destroy_inode(inode); - return NULL; } EXPORT_SYMBOL(iget5_locked);