Received: by 2002:a05:6a10:f347:0:0:0:0 with SMTP id d7csp4354236pxu; Tue, 1 Dec 2020 02:52:53 -0800 (PST) X-Google-Smtp-Source: ABdhPJycZwwZ7U6dFKW1CiP5K0CqUsFqh8zaBvWH8I5/yMOqnCjAEiGL+AMNLJUrqA/y+O476Ipw X-Received: by 2002:a50:99cb:: with SMTP id n11mr2389030edb.362.1606819972892; Tue, 01 Dec 2020 02:52:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1606819972; cv=none; d=google.com; s=arc-20160816; b=YtVxA7481bRPBWBX8uoyLVo5k/7cmNu6wBoPwVzEkae26e6qP5aYpa/38WoAvW9SUq j42mMoewHLALjA7RqBD30GpgK4R8EVucVK8U+JTwpNsq8ANjQFI7UndCw8L1AhS1h9Vu 41E6nnmySasp+H2TYGI4SugxUmupVEmpPb9+d0/PG72EX2ChD8Eg5LAbQSQ2mKKa+FkY Um5ncN/zELQ0Bu3IRnu6vQ50vT92aCT8BYogx5xIJysm08KX1yyRXamrM0KPhzhF/CXx DmrWMlM8LQN58yQrOA8eDqWqKWSy7GBZnhma04oX0HGrB5Vyqh/IwnBWi+rm7VBEYa78 v+0g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:user-agent:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date; bh=1utdZYn6/W4d4q5QVV9OmQs/tsE22LizqW8fXfTLzlo=; b=MJi+3BACWyjlPsbbjG15kkkSTErXG8LDBOoG+hOe9sEwRaZpw08yRTbjSrfScT2nnh 0c0UWbOyhFH2JYlAY+LetCAC33NwZFNjhJA342ON4/QkuEJK/PjAyfPVtExz6BWgbrHX dvT2m3a4mtlJaXulG5lIKXvZ4STNi0aHucPHjcMjSJX2r99dugqOEoU+NqLcMCPRSXGB ZF1wQu/gSWNSuOzhahK8yA9oiGDPdm8duHKybnX2ZdwKxxPRkIhZU0MwoI38wbV7pVKg Wth6WmMnrYnsLaq59mYYKnimVnyO7zupz+9gczjigJilD9v2nrEeTnWbDPw+MHXJLKWu NJIw== ARC-Authentication-Results: i=1; mx.google.com; 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 Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id z4si678347ejw.380.2020.12.01.02.52.29; Tue, 01 Dec 2020 02:52:52 -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; 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 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730013AbgLAKty (ORCPT + 99 others); Tue, 1 Dec 2020 05:49:54 -0500 Received: from verein.lst.de ([213.95.11.211]:48950 "EHLO verein.lst.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726810AbgLAKty (ORCPT ); Tue, 1 Dec 2020 05:49:54 -0500 Received: by verein.lst.de (Postfix, from userid 2407) id 71BEF6736F; Tue, 1 Dec 2020 11:49:07 +0100 (CET) Date: Tue, 1 Dec 2020 11:49:07 +0100 From: Christoph Hellwig To: Christian Brauner Cc: Alexander Viro , Christoph Hellwig , linux-fsdevel@vger.kernel.org, John Johansen , James Morris , Mimi Zohar , Dmitry Kasatkin , Stephen Smalley , Casey Schaufler , Arnd Bergmann , Andreas Dilger , OGAWA Hirofumi , Geoffrey Thomas , Mrunal Patel , Josh Triplett , Andy Lutomirski , Theodore Tso , Alban Crequy , Tycho Andersen , David Howells , James Bottomley , Seth Forshee , =?iso-8859-1?Q?St=E9phane?= Graber , Aleksa Sarai , Lennart Poettering , "Eric W. Biederman" , smbarber@chromium.org, Phil Estes , Serge Hallyn , Kees Cook , Todd Kjos , Paul Moore , Jonathan Corbet , containers@lists.linux-foundation.org, fstests@vger.kernel.org, linux-security-module@vger.kernel.org, linux-api@vger.kernel.org, linux-ext4@vger.kernel.org, linux-integrity@vger.kernel.org, selinux@vger.kernel.org, Christoph Hellwig Subject: Re: [PATCH v3 04/38] fs: add mount_setattr() Message-ID: <20201201104907.GD27730@lst.de> References: <20201128213527.2669807-1-christian.brauner@ubuntu.com> <20201128213527.2669807-5-christian.brauner@ubuntu.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20201128213527.2669807-5-christian.brauner@ubuntu.com> User-Agent: Mutt/1.5.17 (2007-11-01) Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Lots of crazy long lines in the patch. Remember that you should only go past 80 lines if it clearly improves readability, and I don't think it does anywhere in here. > index a7cd0f64faa4..a5a6c470dc07 100644 > --- a/fs/internal.h > +++ b/fs/internal.h > @@ -82,6 +82,14 @@ int may_linkat(struct path *link); > /* > * namespace.c > */ > +struct mount_kattr { > + unsigned int attr_set; > + unsigned int attr_clr; > + unsigned int propagation; > + unsigned int lookup_flags; > + bool recurse; > +}; Even with the whole series applied this structure is only used in namespace.c, so it might be worth moving there. > +static inline int mnt_hold_writers(struct mount *mnt) > { > - int ret = 0; > - > mnt->mnt.mnt_flags |= MNT_WRITE_HOLD; > /* > * After storing MNT_WRITE_HOLD, we'll read the counters. This store > @@ -497,15 +495,29 @@ static int mnt_make_readonly(struct mount *mnt) > * we're counting up here. > */ > if (mnt_get_writers(mnt) > 0) > - ret = -EBUSY; > - else > - mnt->mnt.mnt_flags |= MNT_READONLY; > + return -EBUSY; > + > + return 0; > +} > + > +static inline void mnt_unhold_writers(struct mount *mnt) > +{ > /* > * MNT_READONLY must become visible before ~MNT_WRITE_HOLD, so writers > * that become unheld will see MNT_READONLY. > */ > smp_wmb(); > mnt->mnt.mnt_flags &= ~MNT_WRITE_HOLD; > +} > + > +static int mnt_make_readonly(struct mount *mnt) > +{ > + int ret; > + > + ret = mnt_hold_writers(mnt); > + if (!ret) > + mnt->mnt.mnt_flags |= MNT_READONLY; > + mnt_unhold_writers(mnt); > return ret; > } > > @@ -3438,6 +3450,33 @@ SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, > return ret; > } This refactoring seems worth a little prep patch. > > +static int build_attr_flags(unsigned int attr_flags, unsigned int *flags) > +{ > + unsigned int aflags = 0; > + > + if (attr_flags & ~(MOUNT_ATTR_RDONLY | > + MOUNT_ATTR_NOSUID | > + MOUNT_ATTR_NODEV | > + MOUNT_ATTR_NOEXEC | > + MOUNT_ATTR__ATIME | > + MOUNT_ATTR_NODIRATIME)) > + return -EINVAL; > + > + if (attr_flags & MOUNT_ATTR_RDONLY) > + aflags |= MNT_READONLY; > + if (attr_flags & MOUNT_ATTR_NOSUID) > + aflags |= MNT_NOSUID; > + if (attr_flags & MOUNT_ATTR_NODEV) > + aflags |= MNT_NODEV; > + if (attr_flags & MOUNT_ATTR_NOEXEC) > + aflags |= MNT_NOEXEC; > + if (attr_flags & MOUNT_ATTR_NODIRATIME) > + aflags |= MNT_NODIRATIME; > + > + *flags = aflags; > + return 0; > +} Same for adding this helper. > + *kattr = (struct mount_kattr){ Missing whitespace before the {. > + switch (attr->propagation) { > + case MAKE_PROPAGATION_UNCHANGED: > + kattr->propagation = 0; > + break; > + case MAKE_PROPAGATION_UNBINDABLE: > + kattr->propagation = MS_UNBINDABLE; > + break; > + case MAKE_PROPAGATION_PRIVATE: > + kattr->propagation = MS_PRIVATE; > + break; > + case MAKE_PROPAGATION_DEPENDENT: > + kattr->propagation = MS_SLAVE; > + break; > + case MAKE_PROPAGATION_SHARED: > + kattr->propagation = MS_SHARED; > + break; > + default: Any reason to not just reuse the MS_* flags in the new API? Yes, your new names are more descriptive, but having different names for the same thing is also rather confusing. > + if (upper_32_bits(attr->attr_set)) > + return -EINVAL; > + if (build_attr_flags(lower_32_bits(attr->attr_set), &kattr->attr_set)) > + return -EINVAL; > + > + if (upper_32_bits(attr->attr_clr)) > + return -EINVAL; > + if (build_attr_flags(lower_32_bits(attr->attr_clr), &kattr->attr_clr)) > + return -EINVAL; What is so magic about the upper and lower 32 bits? > + return -EINVAL; > + else if ((attr->attr_clr & MOUNT_ATTR__ATIME) && > + ((attr->attr_clr & MOUNT_ATTR__ATIME) != MOUNT_ATTR__ATIME)) > + return -EINVAL; No need for the else here. That being said I'd reword the thing to be a little more obvious: if (attr->attr_clr & MOUNT_ATTR__ATIME) { if ((attr->attr_clr & MOUNT_ATTR__ATIME) != MOUNT_ATTR__ATIME) return -EINVAL; ... code doing the update of the atime flags here } else { if (attr->attr_set & MOUNT_ATTR__ATIME) return -EINVAL; } > +/* Change propagation through mount_setattr(). */ > +enum propagation_type { > + MAKE_PROPAGATION_UNCHANGED = 0, /* Don't change mount propagation (default). */ > + MAKE_PROPAGATION_UNBINDABLE = 1, /* Make unbindable. */ > + MAKE_PROPAGATION_PRIVATE = 2, /* Do not receive or send mount events. */ > + MAKE_PROPAGATION_DEPENDENT = 3, /* Only receive mount events. */ > + MAKE_PROPAGATION_SHARED = 4, /* Send and receive mount events. */ > +}; FYI, in uapis using defines instead of enums is usually the better choice, as that allows userspace to probe for later added defines. But if we use MS_* here that would be void anyway. > +/* List of all mount_attr versions. */ > +#define MOUNT_ATTR_SIZE_VER0 24 /* sizeof first published struct */ > +#define MOUNT_ATTR_SIZE_LATEST MOUNT_ATTR_SIZE_VER0 The _LATEST things is pretty dangerous as there basically is no safe and correct way for userspace to use it.