Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

keep iocb_flags() result cached in struct file

* 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>

Al Viro 164f4064 91b94c5d

+8 -6
+1 -1
drivers/nvme/target/io-cmd-file.c
··· 112 112 113 113 iocb->ki_pos = pos; 114 114 iocb->ki_filp = req->ns->file; 115 - iocb->ki_flags = ki_flags | iocb_flags(req->ns->file); 115 + iocb->ki_flags = ki_flags | iocb->ki_filp->f_iocb_flags; 116 116 117 117 return call_iter(iocb, &iter); 118 118 }
+1 -1
fs/aio.c
··· 1475 1475 req->ki_complete = aio_complete_rw; 1476 1476 req->private = NULL; 1477 1477 req->ki_pos = iocb->aio_offset; 1478 - req->ki_flags = iocb_flags(req->ki_filp); 1478 + req->ki_flags = req->ki_filp->f_iocb_flags; 1479 1479 if (iocb->aio_flags & IOCB_FLAG_RESFD) 1480 1480 req->ki_flags |= IOCB_EVENTFD; 1481 1481 if (iocb->aio_flags & IOCB_FLAG_IOPRIO) {
+1
fs/fcntl.c
··· 78 78 } 79 79 spin_lock(&filp->f_lock); 80 80 filp->f_flags = (arg & SETFL_MASK) | (filp->f_flags & ~SETFL_MASK); 81 + filp->f_iocb_flags = iocb_flags(filp); 81 82 spin_unlock(&filp->f_lock); 82 83 83 84 out:
+1
fs/file_table.c
··· 241 241 if ((file->f_mode & FMODE_WRITE) && 242 242 likely(fop->write || fop->write_iter)) 243 243 file->f_mode |= FMODE_CAN_WRITE; 244 + file->f_iocb_flags = iocb_flags(file); 244 245 file->f_mode |= FMODE_OPENED; 245 246 file->f_op = fop; 246 247 if ((file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
+1 -1
fs/io_uring.c
··· 4330 4330 if (!io_req_ffs_set(req)) 4331 4331 req->flags |= io_file_get_flags(file) << REQ_F_SUPPORT_NOWAIT_BIT; 4332 4332 4333 - kiocb->ki_flags = iocb_flags(file); 4333 + kiocb->ki_flags = file->f_iocb_flags; 4334 4334 ret = kiocb_set_rw_flags(kiocb, req->rw.flags); 4335 4335 if (unlikely(ret)) 4336 4336 return ret;
+1
fs/open.c
··· 862 862 f->f_mode |= FMODE_CAN_ODIRECT; 863 863 864 864 f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); 865 + f->f_iocb_flags = iocb_flags(f); 865 866 866 867 file_ra_state_init(&f->f_ra, f->f_mapping->host->i_mapping); 867 868
+2 -3
include/linux/fs.h
··· 926 926 union { 927 927 struct llist_node f_llist; 928 928 struct rcu_head f_rcuhead; 929 + unsigned int f_iocb_flags; 929 930 }; 930 931 struct path f_path; 931 932 struct inode *f_inode; /* cached value */ ··· 2200 2199 !gid_valid(i_gid_into_mnt(mnt_userns, inode)); 2201 2200 } 2202 2201 2203 - static inline int iocb_flags(struct file *file); 2204 - 2205 2202 static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp) 2206 2203 { 2207 2204 *kiocb = (struct kiocb) { 2208 2205 .ki_filp = filp, 2209 - .ki_flags = iocb_flags(filp), 2206 + .ki_flags = filp->f_iocb_flags, 2210 2207 .ki_ioprio = get_current_ioprio(), 2211 2208 }; 2212 2209 }