Skip to content

Commit f2ffc48

Browse files
committed
Merge patch series "pipe: don't update {a,c,m}time for anonymous pipes"
Oleg Nesterov <oleg@redhat.com> says: Don't update {a,c,m}time for anonymous pipes for performance reasons. * patches from https://lore.kernel.org/r/20250205181716.GA13817@redhat.com: pipe: don't update {a,c,m}time for anonymous pipes pipe: introduce struct file_operations pipeanon_fops Link: https://lore.kernel.org/r/20250205181716.GA13817@redhat.com Signed-off-by: Christian Brauner <brauner@kernel.org>
2 parents 2014c95 + f017b0a commit f2ffc48

1 file changed

Lines changed: 47 additions & 15 deletions

File tree

fs/pipe.c

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ static inline unsigned int pipe_update_tail(struct pipe_inode_info *pipe,
248248
}
249249

250250
static ssize_t
251-
pipe_read(struct kiocb *iocb, struct iov_iter *to)
251+
anon_pipe_read(struct kiocb *iocb, struct iov_iter *to)
252252
{
253253
size_t total_len = iov_iter_count(to);
254254
struct file *filp = iocb->ki_filp;
@@ -404,8 +404,15 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
404404
if (wake_next_reader)
405405
wake_up_interruptible_sync_poll(&pipe->rd_wait, EPOLLIN | EPOLLRDNORM);
406406
kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
407+
return ret;
408+
}
409+
410+
static ssize_t
411+
fifo_pipe_read(struct kiocb *iocb, struct iov_iter *to)
412+
{
413+
int ret = anon_pipe_read(iocb, to);
407414
if (ret > 0)
408-
file_accessed(filp);
415+
file_accessed(iocb->ki_filp);
409416
return ret;
410417
}
411418

@@ -426,7 +433,7 @@ static inline bool pipe_writable(const struct pipe_inode_info *pipe)
426433
}
427434

428435
static ssize_t
429-
pipe_write(struct kiocb *iocb, struct iov_iter *from)
436+
anon_pipe_write(struct kiocb *iocb, struct iov_iter *from)
430437
{
431438
struct file *filp = iocb->ki_filp;
432439
struct pipe_inode_info *pipe = filp->private_data;
@@ -604,11 +611,21 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
604611
kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
605612
if (wake_next_writer)
606613
wake_up_interruptible_sync_poll(&pipe->wr_wait, EPOLLOUT | EPOLLWRNORM);
607-
if (ret > 0 && sb_start_write_trylock(file_inode(filp)->i_sb)) {
608-
int err = file_update_time(filp);
609-
if (err)
610-
ret = err;
611-
sb_end_write(file_inode(filp)->i_sb);
614+
return ret;
615+
}
616+
617+
static ssize_t
618+
fifo_pipe_write(struct kiocb *iocb, struct iov_iter *from)
619+
{
620+
int ret = anon_pipe_write(iocb, from);
621+
if (ret > 0) {
622+
struct file *filp = iocb->ki_filp;
623+
if (sb_start_write_trylock(file_inode(filp)->i_sb)) {
624+
int err = file_update_time(filp);
625+
if (err)
626+
ret = err;
627+
sb_end_write(file_inode(filp)->i_sb);
628+
}
612629
}
613630
return ret;
614631
}
@@ -878,6 +895,8 @@ static const struct dentry_operations pipefs_dentry_operations = {
878895
.d_dname = pipefs_dname,
879896
};
880897

898+
static const struct file_operations pipeanon_fops;
899+
881900
static struct inode * get_pipe_inode(void)
882901
{
883902
struct inode *inode = new_inode_pseudo(pipe_mnt->mnt_sb);
@@ -895,7 +914,7 @@ static struct inode * get_pipe_inode(void)
895914
inode->i_pipe = pipe;
896915
pipe->files = 2;
897916
pipe->readers = pipe->writers = 1;
898-
inode->i_fop = &pipefifo_fops;
917+
inode->i_fop = &pipeanon_fops;
899918

900919
/*
901920
* Mark the inode dirty from the very beginning,
@@ -938,7 +957,7 @@ int create_pipe_files(struct file **res, int flags)
938957

939958
f = alloc_file_pseudo(inode, pipe_mnt, "",
940959
O_WRONLY | (flags & (O_NONBLOCK | O_DIRECT)),
941-
&pipefifo_fops);
960+
&pipeanon_fops);
942961
if (IS_ERR(f)) {
943962
free_pipe_info(inode->i_pipe);
944963
iput(inode);
@@ -949,7 +968,7 @@ int create_pipe_files(struct file **res, int flags)
949968
f->f_pipe = 0;
950969

951970
res[0] = alloc_file_clone(f, O_RDONLY | (flags & O_NONBLOCK),
952-
&pipefifo_fops);
971+
&pipeanon_fops);
953972
if (IS_ERR(res[0])) {
954973
put_pipe_info(inode, inode->i_pipe);
955974
fput(f);
@@ -1107,8 +1126,8 @@ static void wake_up_partner(struct pipe_inode_info *pipe)
11071126

11081127
static int fifo_open(struct inode *inode, struct file *filp)
11091128
{
1129+
bool is_pipe = inode->i_fop == &pipeanon_fops;
11101130
struct pipe_inode_info *pipe;
1111-
bool is_pipe = inode->i_sb->s_magic == PIPEFS_MAGIC;
11121131
int ret;
11131132

11141133
filp->f_pipe = 0;
@@ -1232,8 +1251,19 @@ static int fifo_open(struct inode *inode, struct file *filp)
12321251

12331252
const struct file_operations pipefifo_fops = {
12341253
.open = fifo_open,
1235-
.read_iter = pipe_read,
1236-
.write_iter = pipe_write,
1254+
.read_iter = fifo_pipe_read,
1255+
.write_iter = fifo_pipe_write,
1256+
.poll = pipe_poll,
1257+
.unlocked_ioctl = pipe_ioctl,
1258+
.release = pipe_release,
1259+
.fasync = pipe_fasync,
1260+
.splice_write = iter_file_splice_write,
1261+
};
1262+
1263+
static const struct file_operations pipeanon_fops = {
1264+
.open = fifo_open,
1265+
.read_iter = anon_pipe_read,
1266+
.write_iter = anon_pipe_write,
12371267
.poll = pipe_poll,
12381268
.unlocked_ioctl = pipe_ioctl,
12391269
.release = pipe_release,
@@ -1388,7 +1418,9 @@ struct pipe_inode_info *get_pipe_info(struct file *file, bool for_splice)
13881418
{
13891419
struct pipe_inode_info *pipe = file->private_data;
13901420

1391-
if (file->f_op != &pipefifo_fops || !pipe)
1421+
if (!pipe)
1422+
return NULL;
1423+
if (file->f_op != &pipefifo_fops && file->f_op != &pipeanon_fops)
13921424
return NULL;
13931425
if (for_splice && pipe_has_watch_queue(pipe))
13941426
return NULL;

0 commit comments

Comments
 (0)