From patchwork Tue Oct 17 16:44:23 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amir Goldstein X-Patchwork-Id: 10012457 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 63A73600CC for ; Tue, 17 Oct 2017 16:44:15 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 56FE127F94 for ; Tue, 17 Oct 2017 16:44:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4B45727FB7; Tue, 17 Oct 2017 16:44:15 +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=-6.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM 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 E256F27F94 for ; Tue, 17 Oct 2017 16:44:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S937049AbdJQQoN (ORCPT ); Tue, 17 Oct 2017 12:44:13 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:46938 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S937042AbdJQQoG (ORCPT ); Tue, 17 Oct 2017 12:44:06 -0400 Received: by mail-wm0-f65.google.com with SMTP id m72so5114902wmc.1; Tue, 17 Oct 2017 09:44:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Koqs3J9hCNvMs7cSy6ZCEpvgIhU1yHP0qQXQXdkjRl0=; b=CArR7ZtNYshpW9QBdY9spt1effOd41r01c94cxSSrLK1jFJA6MzO129T4MWHbZ65Zy QL/3M+n22g5iKzZ22SNeCh0DCPmvt7+O9pA4jZFAisx3yEtUzNF1/t0L4razF9CUlsDU 0t34rGiRvFwnRteIPNHLE29kABl2MBLWsVdZE0S1D1Wdbj4s0lndOw9dKxwOH3Yi6CLH 08w0Kew1PdlyT+SAp/jA+4HJ0xOpTlAtL/v1xUIHppw4hiP5SQu+vIwWCXSORL+hf//w VY8DdDOzs0GIHmoRlokXWRH5p5g54o1wCZ3vpAKnE5GWhNQTZWOQJlgPzfyR2gkLnKNK y6Fw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Koqs3J9hCNvMs7cSy6ZCEpvgIhU1yHP0qQXQXdkjRl0=; b=JlswBuPuM6N389OxEq6TLagfnwI1SY1HdKFeh0/48yxB09iWWIXgmE7/xzg0eB1DLi 1KQjV0Jte6HGV6db/stRmWBvTtE6orBAi2XucUI7BBr4PRNtz40SEM113aXc75y6TiTk NZaaz3yQ4cf8eRSNIHlb+AkXh6mlz4dWD9oMv4X2F4m3r1PqabfB3lM82mBfhBwFIrSP m91lmq9TKk1QzJAYcN623IOvC+jBEzBAfeu9DZh4xtSmlH6g9rj1N7o9Mz7TrPSxvSDO T8+9MXTAh2C1LrYETJu3T73dYJY5v8E3ILZysgv8CvvPQKVnKFeuoOsD4HpzoEZXeuC/ mqVA== X-Gm-Message-State: AMCzsaWnzesyHvvEpHbvmx6w8p5oWC7Y5ux36Ib1cOki6S1tP8JnZbmn 0ztLt9B0tOBrJtj8qUfPeS0= X-Google-Smtp-Source: AOwi7QBLG3rTIqYyYIdvTFSjUHV+QwmaybhVaNTGsa8lMNl/gXFAo+PkGJvfWKkTA9VQAjFRTe/JDw== X-Received: by 10.80.169.193 with SMTP id n59mr18181632edc.282.1508258644552; Tue, 17 Oct 2017 09:44:04 -0700 (PDT) Received: from localhost.localdomain (bzq-166-168-31-246.red.bezeqint.net. [31.168.166.246]) by smtp.gmail.com with ESMTPSA id c25sm8439979edb.28.2017.10.17.09.44.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 17 Oct 2017 09:44:04 -0700 (PDT) From: Amir Goldstein To: Miklos Szeredi Cc: Jeff Layton , "J . Bruce Fields" , linux-unionfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH 06/14] ovl: encode pure-upper connectable file handles Date: Tue, 17 Oct 2017 19:44:23 +0300 Message-Id: <1508258671-10800-7-git-send-email-amir73il@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1508258671-10800-1-git-send-email-amir73il@gmail.com> References: <1508258671-10800-1-git-send-email-amir73il@gmail.com> 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 To allow reconnecting of pure upper overlay dentry based on its real parent, we restrict the implementation to encoding of overlay dentries with pure upper ancestry up to overlay root. Signed-off-by: Amir Goldstein --- fs/overlayfs/export.c | 70 ++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 9 deletions(-) diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c index 33914f23530e..263415dd929b 100644 --- a/fs/overlayfs/export.c +++ b/fs/overlayfs/export.c @@ -17,15 +17,40 @@ #include "overlayfs.h" #include "ovl_entry.h" +/* Check if dentry is pure upper ancestry up to root */ +static bool ovl_is_pure_upper_or_root(struct dentry *dentry, int connectable) +{ + struct dentry *parent = NULL; + + /* For non-connectable non-dir we don't need to check ancestry */ + if (!d_is_dir(dentry) && !connectable) + return !ovl_dentry_lower(dentry); + + dget(dentry); + while (!IS_ROOT(dentry) && !ovl_dentry_lower(dentry)) { + parent = dget_parent(dentry); + dput(dentry); + dentry = parent; + } + dput(dentry); + + return dentry == dentry->d_sb->s_root; +} + /* TODO: add export_operations method dentry_to_fh() ??? */ static int ovl_dentry_to_fh(struct dentry *dentry, struct fid *fid, int *max_len, int connectable) { - struct dentry *lower = ovl_dentry_lower(dentry); int type; - /* TODO: handle encoding of non pure upper */ - if (lower) + /* + * Overlay root dir inode is hashed and encoded as pure upper, because + * root dir dentry is born upper and not indexed. It is not a problem + * that root dir is not indexed, because root dentry is pinned to cache. + * + * TODO: handle encoding of non pure upper. + */ + if (!ovl_is_pure_upper_or_root(dentry, connectable)) return FILEID_INVALID; /* @@ -40,20 +65,47 @@ static int ovl_dentry_to_fh(struct dentry *dentry, struct fid *fid, return type; } +/* Find an alias of inode. If @dir is non NULL, find a child alias */ +static struct dentry *ovl_find_alias(struct inode *inode, struct inode *dir) +{ + struct dentry *parent, *child; + struct dentry *alias = NULL; + + /* Parent inode is never provided when encoding a directory */ + if (!dir || WARN_ON(!S_ISDIR(dir->i_mode) || S_ISDIR(inode->i_mode))) + return d_find_alias(inode); + + /* + * Run all of the dentries associated with this parent. Since this is + * a directory, there damn well better only be one item on this list. + */ + spin_lock(&dir->i_lock); + hlist_for_each_entry(parent, &dir->i_dentry, d_u.d_alias) { + /* Find an alias of inode who is a child of parent */ + spin_lock(&parent->d_lock); + list_for_each_entry(child, &parent->d_subdirs, d_child) { + if (child->d_inode == inode) { + alias = dget(child); + break; + } + } + spin_unlock(&parent->d_lock); + } + spin_unlock(&dir->i_lock); + + return alias; +} + static int ovl_encode_inode_fh(struct inode *inode, u32 *fh, int *max_len, struct inode *parent) { - struct dentry *dentry = d_find_alias(inode); + struct dentry *dentry = ovl_find_alias(inode, parent); int type; if (!dentry) return FILEID_INVALID; - /* TODO: handle encoding of non-dir connectable file handle */ - if (parent) - return FILEID_INVALID; - - type = ovl_dentry_to_fh(dentry, (struct fid *)fh, max_len, 0); + type = ovl_dentry_to_fh(dentry, (struct fid *)fh, max_len, !!parent); dput(dentry); return type;