Received: by 2002:a05:6a10:16a7:0:0:0:0 with SMTP id gp39csp4066353pxb; Tue, 17 Nov 2020 10:20:01 -0800 (PST) X-Google-Smtp-Source: ABdhPJwu8y+cJbOxoPbmpFDmsVDjQUH6mpEuwyHcoEEzc4ZwHVUFeTzCAjZmnmQ0aKnsh++slxFD X-Received: by 2002:a50:9ee4:: with SMTP id a91mr4079732edf.121.1605637201630; Tue, 17 Nov 2020 10:20:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1605637201; cv=none; d=google.com; s=arc-20160816; b=ieMaaPyS7m/bjgX34h7pt7hq546W1Q5530jPu/4xCKLbpZK17pzRDLRjG702Pw3doJ 5Ay+EmD3i29fZblVpUxurX0eE2cCV4PDUkkfTxsaJZwD6RlmCwngoldnqOpuQbaVLhFS PFjsESWLaJYXJ2FRWWUTtdLqaIV4MVWu3upMvHOedsF1ohycLMKtzrJjPCczI1X9xt+c 90ZULfmDLWkvD5xlzaY1BPZsTWa9xAtr8yfCCm+aMzQvHDM3ZP0ezq3zqqvVTPoCavY8 MuNhddX+muKULUXy8EJHFZQozYoZ3BfRV+QOgQ/tYWjqqYuznTpzSUTD07MbEVWWSzeR MwGg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:in-reply-to:content-disposition:mime-version :references:message-id:subject:cc:to:from:date:dkim-signature; bh=xo2hoVo6kjy9rNjJoWda4Xi/zFTJxlZl40M0wZmhrWQ=; b=iwVwplvv1sn4avlQGJHaUdATek4l+lnGZc/vypa1AC3/3W+Hq3yghTJxC/dbq6PEGL uqRHbrhu6uh1nOnirDuLFoE/LPaRVwteIIMiVQj2ZITzroI4upQOrQ7FaMlpcOhwzRFe dZ1mz248vV0Lr64Wql/x4oMYHFuK5vnb+FEgMcVxmYYcorz/6uSjacJi4Wrh/l3QiW4w Of/dewV5Rg17khYs/4y7V2y1feTQLvdqDEbGCKEV3a2fn1j4RZZBiE3i6L+wC3H+fB7W gA4sT3TtqqPbesj5cuHPrlrbkVDHzlIsI2FLA6H8xBFC2+UX8De9rSYEioAim0AN40Px uulg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=BIyHtChu; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id op9si13737522ejb.447.2020.11.17.10.19.29; Tue, 17 Nov 2020 10:20:01 -0800 (PST) Received-SPF: pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=BIyHtChu; spf=pass (google.com: domain of linux-ext4-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-ext4-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731214AbgKQSRu (ORCPT + 99 others); Tue, 17 Nov 2020 13:17:50 -0500 Received: from mail.kernel.org ([198.145.29.99]:56364 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730914AbgKQSQw (ORCPT ); Tue, 17 Nov 2020 13:16:52 -0500 Received: from sol.localdomain (172-10-235-113.lightspeed.sntcca.sbcglobal.net [172.10.235.113]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E8B352222E; Tue, 17 Nov 2020 18:16:50 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1605637011; bh=LYmQa3sjmY4vGoc9PzmWfJg6D+u8panQLU6mw2v2bU0=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=BIyHtChuKC/1Z2hfN01FJL2lQedY2Jopd9Xk6ljOb8WSU5039BmyYLu1lS/JerWeZ P+zilHNPhlrTLNiM1v44Y5EagbQsJhPY2JHB3h9CWIqeujkTkuhcWx5hjeDSPcyMf4 ccWF5nBSvvcF0BXkSIJq0FUknVkLg8jyR9SxjF2Y= Date: Tue, 17 Nov 2020 10:16:49 -0800 From: Eric Biggers To: Daniel Rosenberg Cc: "Theodore Y . Ts'o" , Jaegeuk Kim , Andreas Dilger , Chao Yu , Alexander Viro , Richard Weinberger , linux-fscrypt@vger.kernel.org, linux-ext4@vger.kernel.org, linux-f2fs-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mtd@lists.infradead.org, Gabriel Krisman Bertazi , kernel-team@android.com Subject: Re: [PATCH v2 1/3] libfs: Add generic function for setting dentry_ops Message-ID: References: <20201117040315.28548-1-drosen@google.com> <20201117040315.28548-2-drosen@google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20201117040315.28548-2-drosen@google.com> Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org On Tue, Nov 17, 2020 at 04:03:13AM +0000, Daniel Rosenberg wrote: > > Currently the casefolding dentry operation are always set if the > filesystem defines an encoding because the features is toggleable on > empty directories. Since we don't know what set of functions we'll > eventually need, and cannot change them later, we add just add them. This isn't a very useful explanation, since encryption can be toggled on empty directories too (at least from off to on --- not the other way). Why is casefolding different? > +static const struct dentry_operations generic_ci_dentry_ops = { > + .d_hash = generic_ci_d_hash, > + .d_compare = generic_ci_d_compare, > +}; > #endif > + > +#ifdef CONFIG_FS_ENCRYPTION > +static const struct dentry_operations generic_encrypted_dentry_ops = { > + .d_revalidate = fscrypt_d_revalidate, > +}; > +#endif > + > +#if IS_ENABLED(CONFIG_UNICODE) && IS_ENABLED(CONFIG_FS_ENCRYPTION) > +static const struct dentry_operations generic_encrypted_ci_dentry_ops = { > + .d_hash = generic_ci_d_hash, > + .d_compare = generic_ci_d_compare, > + .d_revalidate = fscrypt_d_revalidate, > +}; > +#endif > + > +/** > + * generic_set_encrypted_ci_d_ops - helper for setting d_ops for given dentry > + * @dentry: dentry to set ops on > + * > + * This function sets the dentry ops for the given dentry to handle both > + * casefolded and encrypted dentry names. > + * > + * Encryption requires d_revalidate to remove nokey names once the key is present. > + * Casefolding is toggleable on an empty directory. Since we can't change the > + * operations later on, we just add the casefolding ops if the filesystem defines an > + * encoding. > + */ There are some overly long lines here (> 80 columns). But more importantly this still isn't a good explanation. Encryption can also be enabled on empty directories; what makes casefolding different? It's also not obvious why so many different copies of the dentry operations needed, instead of just using generic_encrypted_ci_dentry_ops on all. If I'm still struggling to understand this after following these patches for a long time, I expect everyone else will have trouble too... Here's a suggestion which I think explains it a lot better. It's still possible I'm misunderstanding something, though, so please check it carefully: /** * generic_set_encrypted_ci_d_ops - helper for setting d_ops for given dentry * @dentry: dentry to set ops on * * Casefolded directories need d_hash and d_compare set, so that the dentries * contained in them are handled case-insensitively. Note that these operations * are needed on the parent directory rather than on the dentries in it, and the * casefolding flag can be enabled on an empty directory later but the * dentry_operations can't be changed later. As a result, if the filesystem has * casefolding support enabled at all, we have to give all dentries the * casefolding operations even if their inode doesn't have the casefolding flag * currently (and thus the casefolding ops would be no-ops for now). * * Encryption works differently in that the only dentry operation it needs is * d_revalidate, which it only needs on dentries that have the no-key name flag. * The no-key flag can't be set "later", so we don't have to worry about that. * * Finally, to maximize compatibility with overlayfs (which isn't compatible * with certain dentry operations) and to avoid taking an unnecessary * performance hit, we use custom dentry_operations for each possible * combination rather always installing all operations. */ > +void generic_set_encrypted_ci_d_ops(struct dentry *dentry) > +{ > +#ifdef CONFIG_FS_ENCRYPTION > + bool needs_encrypt_ops = dentry->d_flags & DCACHE_NOKEY_NAME; > +#endif > +#ifdef CONFIG_UNICODE > + bool needs_ci_ops = dentry->d_sb->s_encoding; > +#endif > +#if defined(CONFIG_FS_ENCRYPTION) && defined(CONFIG_UNICODE) > + if (needs_encrypt_ops && needs_ci_ops) { > + d_set_d_op(dentry, &generic_encrypted_ci_dentry_ops); > + return; > + } The return statement above has the wrong indentation level. > +#endif > +#ifdef CONFIG_FS_ENCRYPTION > + if (needs_encrypt_ops) { > + d_set_d_op(dentry, &generic_encrypted_dentry_ops); > + return; > + } > +#endif > +#ifdef CONFIG_UNICODE > + if (needs_ci_ops) { > + d_set_d_op(dentry, &generic_ci_dentry_ops); > + return; > + } > +#endif > +} > +EXPORT_SYMBOL(generic_set_encrypted_ci_d_ops); > diff --git a/include/linux/fs.h b/include/linux/fs.h > index 8667d0cdc71e..11345e66353b 100644 > --- a/include/linux/fs.h > +++ b/include/linux/fs.h > @@ -3202,6 +3202,7 @@ extern int generic_ci_d_hash(const struct dentry *dentry, struct qstr *str); > extern int generic_ci_d_compare(const struct dentry *dentry, unsigned int len, > const char *str, const struct qstr *name); > #endif > +extern void generic_set_encrypted_ci_d_ops(struct dentry *dentry); > > #ifdef CONFIG_MIGRATION > extern int buffer_migrate_page(struct address_space *,