keep iocb_flags() result cached in struct file
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 22 May 2022 15:38:11 +0000 (11:38 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Fri, 10 Jun 2022 20:10:23 +0000 (16:10 -0400)
* calculate at the time we set FMODE_OPENED (do_dentry_open() for normal
opens, alloc_file() for pipe()/socket()/etc.)
* update when handling F_SETFL
* keep in a new field - file->f_iocb_flags; since that thing is needed only
before the refcount reaches zero, we can put it into the same anon union
where ->f_rcuhead and ->f_llist live - those are used only after refcount
reaches zero.

Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
drivers/nvme/target/io-cmd-file.c
fs/aio.c
fs/fcntl.c
fs/file_table.c
fs/io_uring.c
fs/open.c
include/linux/fs.h

index f3d58ab..64b47e2 100644 (file)
@@ -112,7 +112,7 @@ static ssize_t nvmet_file_submit_bvec(struct nvmet_req *req, loff_t pos,
 
        iocb->ki_pos = pos;
        iocb->ki_filp = req->ns->file;
-       iocb->ki_flags = ki_flags | iocb_flags(req->ns->file);
+       iocb->ki_flags = ki_flags | iocb->ki_filp->f_iocb_flags;
 
        return call_iter(iocb, &iter);
 }
index 3c249b9..2bdd444 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1475,7 +1475,7 @@ static int aio_prep_rw(struct kiocb *req, const struct iocb *iocb)
        req->ki_complete = aio_complete_rw;
        req->private = NULL;
        req->ki_pos = iocb->aio_offset;
-       req->ki_flags = iocb_flags(req->ki_filp);
+       req->ki_flags = req->ki_filp->f_iocb_flags;
        if (iocb->aio_flags & IOCB_FLAG_RESFD)
                req->ki_flags |= IOCB_EVENTFD;
        if (iocb->aio_flags & IOCB_FLAG_IOPRIO) {
index 34a3faa..146c9ab 100644 (file)
@@ -78,6 +78,7 @@ static int setfl(int fd, struct file * filp, unsigned long arg)
        }
        spin_lock(&filp->f_lock);
        filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK);
+       filp->f_iocb_flags = iocb_flags(filp);
        spin_unlock(&filp->f_lock);
 
  out:
index b989e33..905792b 100644 (file)
@@ -241,6 +241,7 @@ static struct file *alloc_file(const struct path *path, int flags,
        if ((file->f_mode & FMODE_WRITE) &&
             likely(fop->write || fop->write_iter))
                file->f_mode |= FMODE_CAN_WRITE;
+       file->f_iocb_flags = iocb_flags(file);
        file->f_mode |= FMODE_OPENED;
        file->f_op = fop;
        if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
index 3aab418..53424b1 100644 (file)
@@ -4330,7 +4330,7 @@ static int io_rw_init_file(struct io_kiocb *req, fmode_t mode)
        if (!io_req_ffs_set(req))
                req->flags |= io_file_get_flags(file) << REQ_F_SUPPORT_NOWAIT_BIT;
 
-       kiocb->ki_flags = iocb_flags(file);
+       kiocb->ki_flags = file->f_iocb_flags;
        ret = kiocb_set_rw_flags(kiocb, req->rw.flags);
        if (unlikely(ret))
                return ret;
index 1d57fbd..d80441a 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -862,6 +862,7 @@ static int do_dentry_open(struct file *f,
                f->f_mode |= FMODE_CAN_ODIRECT;
 
        f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);
+       f->f_iocb_flags = iocb_flags(f);
 
        file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping);
 
index 380a129..c82b9d4 100644 (file)
@@ -926,6 +926,7 @@ struct file {
        union {
                struct llist_node       f_llist;
                struct rcu_head         f_rcuhead;
+               unsigned int            f_iocb_flags;
        };
        struct path             f_path;
        struct inode            *f_inode;       /* cached value */
@@ -2199,13 +2200,11 @@ static inline bool HAS_UNMAPPED_ID(struct user_namespace *mnt_userns,
               !gid_valid(i_gid_into_mnt(mnt_userns, inode));
 }
 
-static inline int iocb_flags(struct file *file);
-
 static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
 {
        *kiocb = (struct kiocb) {
                .ki_filp = filp,
-               .ki_flags = iocb_flags(filp),
+               .ki_flags = filp->f_iocb_flags,
                .ki_ioprio = get_current_ioprio(),
        };
 }