From patchwork Tue May 29 14:46:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 10435777 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 8BED7602BF for ; Tue, 29 May 2018 14:50:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7BCCD2864E for ; Tue, 29 May 2018 14:50:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 77927286B1; Tue, 29 May 2018 14:50:27 +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.9 required=2.0 tests=BAYES_00, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI autolearn=unavailable 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 E40AC286B1 for ; Tue, 29 May 2018 14:50:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935516AbeE2OuL (ORCPT ); Tue, 29 May 2018 10:50:11 -0400 Received: from mail-wm0-f48.google.com ([74.125.82.48]:35776 "EHLO mail-wm0-f48.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S936649AbeE2Oqn (ORCPT ); Tue, 29 May 2018 10:46:43 -0400 Received: by mail-wm0-f48.google.com with SMTP id o78-v6so41498633wmg.0 for ; Tue, 29 May 2018 07:46:42 -0700 (PDT) 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=3meUC00+tdqe9TH85IGKLU0R8Hhb2qbKlnzpKjuxUlg=; b=ALOCrzoUA+y4PxXSwbFff8ixLVYxskCiDUBsqrybGGChgVyqGH45uu7D40XJkDX2YP bZ3SLXLBs0q8Ggn92GhwJq4Z5D/IUtYLdoKI8by2Emmg8ltBuLsD0j60FJ+KuxJDzsOq O6wRNrguXax03oP18hg1N8BH9fyflbN+M8yyAd7mOAuiashx/Jgn1sEOJunrJ4N138xM 5E8pCRj8tx11LRHhraleI+6+9dvpLJ9z1wjO+DX+wm/I+H1gbehF/RComyh5CjjrB64e 1JpCpuhvoISCn0K7AF0Ftyi+d+BA8e+SnfkknME0I+ULHYgr2Ehl9PNyf/w55Guo+e0e pkyw== X-Gm-Message-State: ALKqPweVwRIXXBsk1flLF4JqZGRYu0KFlV4F1vKQcMEyym8x6pXXofqL /hEcjlk961uBtjRdKRkvCU1sYw== X-Google-Smtp-Source: ADUXVKJ9Zvyh5Rp7ONzSTIyjEvfF3E0Kd14Ery/TSY4WtW4IeNFIgoOls4Tl0myYqqFFD+fnDiTHTg== X-Received: by 2002:a1c:64d7:: with SMTP id y206-v6mr5178574wmb.43.1527605202147; Tue, 29 May 2018 07:46:42 -0700 (PDT) Received: from veci.piliscsaba.redhat.com (catv-176-63-54-97.catv.broadband.hu. [176.63.54.97]) by smtp.gmail.com with ESMTPSA id n71-v6sm20942227wmi.14.2018.05.29.07.46.41 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 29 May 2018 07:46:41 -0700 (PDT) From: Miklos Szeredi To: linux-unionfs@vger.kernel.org Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 22/28] ovl: Set redirect on metacopy files upon rename Date: Tue, 29 May 2018 16:46:06 +0200 Message-Id: <20180529144612.16675-23-mszeredi@redhat.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180529144612.16675-1-mszeredi@redhat.com> References: <20180529144612.16675-1-mszeredi@redhat.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 From: Vivek Goyal Set redirect on metacopy files upon rename. This will help find data dentry in lower dirs. Signed-off-by: Vivek Goyal Reviewed-by: Amir Goldstein Signed-off-by: Miklos Szeredi --- fs/overlayfs/dir.c | 66 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 8d8e063e4706..1658961a9762 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -873,13 +873,13 @@ static bool ovl_can_move(struct dentry *dentry) !d_is_dir(dentry) || !ovl_type_merge_or_lower(dentry); } -static char *ovl_get_redirect(struct dentry *dentry, bool samedir) +static char *ovl_get_redirect(struct dentry *dentry, bool abs_redirect) { char *buf, *ret; struct dentry *d, *tmp; int buflen = ovl_redirect_max + 1; - if (samedir) { + if (!abs_redirect) { ret = kstrndup(dentry->d_name.name, dentry->d_name.len, GFP_KERNEL); goto out; @@ -933,15 +933,43 @@ static char *ovl_get_redirect(struct dentry *dentry, bool samedir) return ret ? ret : ERR_PTR(-ENOMEM); } +static bool ovl_need_absolute_redirect(struct dentry *dentry, bool samedir) +{ + struct dentry *lowerdentry; + + if (!samedir) + return true; + + if (d_is_dir(dentry)) + return false; + + /* + * For non-dir hardlinked files, we need absolute redirects + * in general as two upper hardlinks could be in different + * dirs. We could put a relative redirect now and convert + * it to absolute redirect later. But when nlink > 1 and + * indexing is on, that means relative redirect needs to be + * converted to absolute during copy up of another lower + * hardllink as well. + * + * So without optimizing too much, just check if lower is + * a hard link or not. If lower is hard link, put absolute + * redirect. + */ + lowerdentry = ovl_dentry_lower(dentry); + return (d_inode(lowerdentry)->i_nlink > 1); +} + static int ovl_set_redirect(struct dentry *dentry, bool samedir) { int err; const char *redirect = ovl_dentry_get_redirect(dentry); + bool absolute_redirect = ovl_need_absolute_redirect(dentry, samedir); - if (redirect && (samedir || redirect[0] == '/')) + if (redirect && (!absolute_redirect || redirect[0] == '/')) return 0; - redirect = ovl_get_redirect(dentry, samedir); + redirect = ovl_get_redirect(dentry, absolute_redirect); if (IS_ERR(redirect)) return PTR_ERR(redirect); @@ -1117,22 +1145,20 @@ static int ovl_rename(struct inode *olddir, struct dentry *old, goto out_dput; err = 0; - if (is_dir) { - if (ovl_type_merge_or_lower(old)) - err = ovl_set_redirect(old, samedir); - else if (!old_opaque && ovl_type_merge(new->d_parent)) - err = ovl_set_opaque_xerr(old, olddentry, -EXDEV); - if (err) - goto out_dput; - } - if (!overwrite && new_is_dir) { - if (ovl_type_merge_or_lower(new)) - err = ovl_set_redirect(new, samedir); - else if (!new_opaque && ovl_type_merge(old->d_parent)) - err = ovl_set_opaque_xerr(new, newdentry, -EXDEV); - if (err) - goto out_dput; - } + if (ovl_type_merge_or_lower(old)) + err = ovl_set_redirect(old, samedir); + else if (is_dir && !old_opaque && ovl_type_merge(new->d_parent)) + err = ovl_set_opaque_xerr(old, olddentry, -EXDEV); + if (err) + goto out_dput; + + if (!overwrite && ovl_type_merge_or_lower(new)) + err = ovl_set_redirect(new, samedir); + else if (!overwrite && new_is_dir && !new_opaque && + ovl_type_merge(old->d_parent)) + err = ovl_set_opaque_xerr(new, newdentry, -EXDEV); + if (err) + goto out_dput; err = ovl_do_rename(old_upperdir->d_inode, olddentry, new_upperdir->d_inode, newdentry, flags);