Merge tag 'pull-work.iov_iter-base' of git://git.kernel.org/pub/scm/linux/kernel...
[platform/kernel/linux-starfive.git] / include / linux / fs.h
index c82b9d4..cc64873 100644 (file)
@@ -180,6 +180,9 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
 /* File supports async buffered reads */
 #define FMODE_BUF_RASYNC       ((__force fmode_t)0x40000000)
 
+/* File supports async nowait buffered writes */
+#define FMODE_BUF_WASYNC       ((__force fmode_t)0x80000000)
+
 /*
  * Attribute flags.  These should be or-ed together to figure out what
  * has been changed!
@@ -221,8 +224,26 @@ 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.
+        *
+        * They always contain the same value. In other words FS_ALLOW_IDMAP
+        * pass down the same value on idmapped mounts as they would on regular
+        * mounts.
+        */
+       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;
@@ -362,13 +383,11 @@ struct address_space_operations {
        void (*free_folio)(struct folio *folio);
        ssize_t (*direct_IO)(struct kiocb *, struct iov_iter *iter);
        /*
-        * migrate the contents of a page to the specified target. If
+        * migrate the contents of a folio to the specified target. If
         * migrate_mode is MIGRATE_ASYNC, it must not block.
         */
-       int (*migratepage) (struct address_space *,
-                       struct page *, struct page *, enum migrate_mode);
-       bool (*isolate_page)(struct page *, isolate_mode_t);
-       void (*putback_page)(struct page *);
+       int (*migrate_folio)(struct address_space *, struct folio *dst,
+                       struct folio *src, enum migrate_mode);
        int (*launder_folio)(struct folio *);
        bool (*is_partially_uptodate) (struct folio *, size_t from,
                        size_t count);
@@ -1601,13 +1620,68 @@ static inline void i_gid_write(struct inode *inode, gid_t gid)
  * @mnt_userns: user namespace of the mount the inode was found from
  * @inode: inode to map
  *
+ * Note, this will eventually be removed completely in favor of the type-safe
+ * i_uid_into_vfsuid().
+ *
  * Return: the inode's i_uid mapped down according to @mnt_userns.
  * If the inode's i_uid has no mapping INVALID_UID is returned.
  */
 static inline kuid_t i_uid_into_mnt(struct user_namespace *mnt_userns,
                                    const struct inode *inode)
 {
-       return mapped_kuid_fs(mnt_userns, i_user_ns(inode), inode->i_uid);
+       return AS_KUIDT(make_vfsuid(mnt_userns, i_user_ns(inode), inode->i_uid));
+}
+
+/**
+ * i_uid_into_vfsuid - map an inode's i_uid down into a mnt_userns
+ * @mnt_userns: user namespace of the mount the inode was found from
+ * @inode: inode to map
+ *
+ * Return: whe inode's i_uid mapped down according to @mnt_userns.
+ * If the inode's i_uid has no mapping INVALID_VFSUID is returned.
+ */
+static inline vfsuid_t i_uid_into_vfsuid(struct user_namespace *mnt_userns,
+                                        const struct inode *inode)
+{
+       return make_vfsuid(mnt_userns, i_user_ns(inode), inode->i_uid);
+}
+
+/**
+ * i_uid_needs_update - check whether inode's i_uid needs to be updated
+ * @mnt_userns: user namespace of the mount the inode was found from
+ * @attr: the new attributes of @inode
+ * @inode: the inode to update
+ *
+ * Check whether the $inode's i_uid field needs to be updated taking idmapped
+ * mounts into account if the filesystem supports it.
+ *
+ * Return: true if @inode's i_uid field needs to be updated, false if not.
+ */
+static inline bool i_uid_needs_update(struct user_namespace *mnt_userns,
+                                     const struct iattr *attr,
+                                     const struct inode *inode)
+{
+       return ((attr->ia_valid & ATTR_UID) &&
+               !vfsuid_eq(attr->ia_vfsuid,
+                          i_uid_into_vfsuid(mnt_userns, inode)));
+}
+
+/**
+ * i_uid_update - update @inode's i_uid field
+ * @mnt_userns: user namespace of the mount the inode was found from
+ * @attr: the new attributes of @inode
+ * @inode: the inode to update
+ *
+ * Safely update @inode's i_uid field translating the vfsuid of any idmapped
+ * mount into the filesystem kuid.
+ */
+static inline void i_uid_update(struct user_namespace *mnt_userns,
+                               const struct iattr *attr,
+                               struct inode *inode)
+{
+       if (attr->ia_valid & ATTR_UID)
+               inode->i_uid = from_vfsuid(mnt_userns, i_user_ns(inode),
+                                          attr->ia_vfsuid);
 }
 
 /**
@@ -1615,13 +1689,68 @@ static inline kuid_t i_uid_into_mnt(struct user_namespace *mnt_userns,
  * @mnt_userns: user namespace of the mount the inode was found from
  * @inode: inode to map
  *
+ * Note, this will eventually be removed completely in favor of the type-safe
+ * i_gid_into_vfsgid().
+ *
  * Return: the inode's i_gid mapped down according to @mnt_userns.
  * If the inode's i_gid has no mapping INVALID_GID is returned.
  */
 static inline kgid_t i_gid_into_mnt(struct user_namespace *mnt_userns,
                                    const struct inode *inode)
 {
-       return mapped_kgid_fs(mnt_userns, i_user_ns(inode), inode->i_gid);
+       return AS_KGIDT(make_vfsgid(mnt_userns, i_user_ns(inode), inode->i_gid));
+}
+
+/**
+ * i_gid_into_vfsgid - map an inode's i_gid down into a mnt_userns
+ * @mnt_userns: user namespace of the mount the inode was found from
+ * @inode: inode to map
+ *
+ * Return: the inode's i_gid mapped down according to @mnt_userns.
+ * If the inode's i_gid has no mapping INVALID_VFSGID is returned.
+ */
+static inline vfsgid_t i_gid_into_vfsgid(struct user_namespace *mnt_userns,
+                                        const struct inode *inode)
+{
+       return make_vfsgid(mnt_userns, i_user_ns(inode), inode->i_gid);
+}
+
+/**
+ * i_gid_needs_update - check whether inode's i_gid needs to be updated
+ * @mnt_userns: user namespace of the mount the inode was found from
+ * @attr: the new attributes of @inode
+ * @inode: the inode to update
+ *
+ * Check whether the $inode's i_gid field needs to be updated taking idmapped
+ * mounts into account if the filesystem supports it.
+ *
+ * Return: true if @inode's i_gid field needs to be updated, false if not.
+ */
+static inline bool i_gid_needs_update(struct user_namespace *mnt_userns,
+                                     const struct iattr *attr,
+                                     const struct inode *inode)
+{
+       return ((attr->ia_valid & ATTR_GID) &&
+               !vfsgid_eq(attr->ia_vfsgid,
+                          i_gid_into_vfsgid(mnt_userns, inode)));
+}
+
+/**
+ * i_gid_update - update @inode's i_gid field
+ * @mnt_userns: user namespace of the mount the inode was found from
+ * @attr: the new attributes of @inode
+ * @inode: the inode to update
+ *
+ * Safely update @inode's i_gid field translating the vfsgid of any idmapped
+ * mount into the filesystem kgid.
+ */
+static inline void i_gid_update(struct user_namespace *mnt_userns,
+                               const struct iattr *attr,
+                               struct inode *inode)
+{
+       if (attr->ia_valid & ATTR_GID)
+               inode->i_gid = from_vfsgid(mnt_userns, i_user_ns(inode),
+                                          attr->ia_vfsgid);
 }
 
 /**
@@ -2196,8 +2325,8 @@ static inline bool sb_rdonly(const struct super_block *sb) { return sb->s_flags
 static inline bool HAS_UNMAPPED_ID(struct user_namespace *mnt_userns,
                                   struct inode *inode)
 {
-       return !uid_valid(i_uid_into_mnt(mnt_userns, inode)) ||
-              !gid_valid(i_gid_into_mnt(mnt_userns, inode));
+       return !vfsuid_valid(i_uid_into_vfsuid(mnt_userns, inode)) ||
+              !vfsgid_valid(i_gid_into_vfsgid(mnt_userns, inode));
 }
 
 static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
@@ -2386,6 +2515,7 @@ static inline void file_accessed(struct file *file)
 }
 
 extern int file_modified(struct file *file);
+int kiocb_modified(struct kiocb *iocb);
 
 int sync_inode_metadata(struct inode *inode, int wait);
 
@@ -3027,7 +3157,7 @@ extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out,
 extern void
 file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping);
 extern loff_t noop_llseek(struct file *file, loff_t offset, int whence);
-extern loff_t no_llseek(struct file *file, loff_t offset, int whence);
+#define no_llseek NULL
 extern loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize);
 extern loff_t generic_file_llseek(struct file *file, loff_t offset, int whence);
 extern loff_t generic_file_llseek_size(struct file *file, loff_t offset,
@@ -3220,18 +3350,6 @@ extern int generic_check_addressable(unsigned, u64);
 
 extern void generic_set_encrypted_ci_d_ops(struct dentry *dentry);
 
-#ifdef CONFIG_MIGRATION
-extern int buffer_migrate_page(struct address_space *,
-                               struct page *, struct page *,
-                               enum migrate_mode);
-extern int buffer_migrate_page_norefs(struct address_space *,
-                               struct page *, struct page *,
-                               enum migrate_mode);
-#else
-#define buffer_migrate_page NULL
-#define buffer_migrate_page_norefs NULL
-#endif
-
 int may_setattr(struct user_namespace *mnt_userns, struct inode *inode,
                unsigned int ia_valid);
 int setattr_prepare(struct user_namespace *, struct dentry *, struct iattr *);