One more thing on this one... > +int io_truncate_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) > +{ > + struct io_trunc *tr = io_kiocb_to_cmd(req, struct io_trunc); > + > + if (sqe->off || sqe->rw_flags || sqe->buf_index || sqe->splice_fd_in) > + return -EINVAL; > + if (unlikely(req->flags & REQ_F_FIXED_FILE)) > + return -EBADF; > + > + tr->pathname = u64_to_user_ptr(READ_ONCE(sqe->addr)); io_uring generally guarantees that any data passed in is stable past submit returns, but that's not the case here. Imagine you had code ala: prep_truncate(ring, dir, filename) { char path[PATH_MAX]; sprintf(path, "%s/%s", dir, filename); sqe = io_uring_get_seq(ring); io_uring_prep_truncate(sqe, path, -1, 0); /* your io_truncate_prep() will be run here */ io_uring_submit(ring); } io_loop() { ... prep_truncate(ring, dir, filename); /* path was on stack and now out-of-scope, and there's nothing preventing io_truncate() from running post that. */ } which implies you'd want some refactoring done here as well, so you can pass in a path for do_sys_truncate(). And then you would certainly need the cleanup flag set, but also provide a ->cleanup() helper. See some of the other fs handling code, like xattr, for how that should be done. This problem obviously doesn't exist for the fd ftruncate variant, as there's no path resolution to do there. -- Jens Axboe