fs: use mount types in iattr
authorChristian Brauner <brauner@kernel.org>
Tue, 21 Jun 2022 14:14:49 +0000 (16:14 +0200)
committerChristian Brauner (Microsoft) <brauner@kernel.org>
Sun, 26 Jun 2022 16:18:55 +0000 (18:18 +0200)
Add ia_vfs{g,u}id members of type vfs{g,u}id_t to struct iattr. We use
an anonymous union (similar to what we do in struct file) around
ia_{g,u}id and ia_vfs{g,u}id.

At the end of this series ia_{g,u}id and ia_vfs{g,u}id will always
contain the same value independent of whether struct iattr is
initialized from an idmapped mount. This is a change from how this is
done today.

Wrapping this in a anonymous unions has a few advantages. It allows us
to avoid needlessly increasing struct iattr. Since the types for
ia_{g,u}id and ia_vfs{g,u}id are structures with overlapping/identical
members they are covered by 6.5.2.3/6 of the C standard and it is safe
to initialize and access them.

Filesystems that raise FS_ALLOW_IDMAP and thus support idmapped mounts
will have to use ia_vfs{g,u}id and the associated helpers. And will be
ported at the end of this series. They will immediately benefit from the
type safe new helpers.

Filesystems that do not support FS_ALLOW_IDMAP can continue to use
ia_{g,u}id for now. The aim is to convert every filesystem to always use
ia_vfs{g,u}id and thus ultimately remove the ia_{g,u}id members.

Link: https://lore.kernel.org/r/20220621141454.2914719-4-brauner@kernel.org
Cc: Seth Forshee <sforshee@digitalocean.com>
Cc: Christoph Hellwig <hch@lst.de>
Cc: Aleksa Sarai <cyphar@cyphar.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
CC: linux-fsdevel@vger.kernel.org
Reviewed-by: Seth Forshee <sforshee@digitalocean.com>
Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org>
include/linux/fs.h
include/linux/mnt_idmapping.h

index afcffa251cb9cdc81714fcfbd8d7d61700166796..54ffcdce3ccb733720abdf0d1c8c9d945eb3f830 100644 (file)
@@ -221,8 +221,22 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 struct iattr {
        unsigned int    ia_valid;
        umode_t         ia_mode;
-       kuid_t          ia_uid;
-       kgid_t          ia_gid;
+       /*
+        * The two anonymous unions wrap structures with the same member.
+        *
+        * Filesystems raising FS_ALLOW_IDMAP need to use ia_vfs{g,u}id which
+        * are a dedicated type requiring the filesystem to use the dedicated
+        * helpers. Other filesystem can continue to use ia_{g,u}id until they
+        * have been ported.
+        */
+       union {
+               kuid_t          ia_uid;
+               vfsuid_t        ia_vfsuid;
+       };
+       union {
+               kgid_t          ia_gid;
+               vfsgid_t        ia_vfsgid;
+       };
        loff_t          ia_size;
        struct timespec64 ia_atime;
        struct timespec64 ia_mtime;
index 71b4cd5a7466ea6899cfd9016440740027bb28a6..6a752b61088b6314f0c868367b5999e31427819a 100644 (file)
@@ -21,6 +21,11 @@ typedef struct {
        gid_t val;
 } vfsgid_t;
 
+static_assert(sizeof(vfsuid_t) == sizeof(kuid_t));
+static_assert(sizeof(vfsgid_t) == sizeof(kgid_t));
+static_assert(offsetof(vfsuid_t, val) == offsetof(kuid_t, val));
+static_assert(offsetof(vfsgid_t, val) == offsetof(kgid_t, val));
+
 #ifdef CONFIG_MULTIUSER
 static inline uid_t __vfsuid_val(vfsuid_t uid)
 {