From 1f36cd05e0081f2c75769a551d584c4ffb2a5660 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Sun, 22 Oct 2023 19:34:28 -0400 Subject: [PATCH 1/3] sparc32: fix a braino in fault handling in csum_and_copy_..._user() Fault handler used to make non-trivial calls, so it needed to set a stack frame up. Used to be save ... - grab a stack frame, old %o... become %i... .... ret - go back to address originally in %o7, currently %i7 restore - switch to previous stack frame, in delay slot Non-trivial calls had been gone since ab5e8b331244 and that code should have become retl - go back to address in %o7 clr %o0 - have return value set to 0 What it had become instead was ret - go back to address in %i7 - return address of *caller* clr %o0 - have return value set to 0 which is not good, to put it mildly - we forcibly return 0 from csum_and_copy_{from,to}_iter() (which is what the call of that thing had been inlined into) and do that without dropping the stack frame of said csum_and_copy_..._iter(). Confuses the hell out of the caller of csum_and_copy_..._iter(), obviously... Reviewed-by: Sam Ravnborg Fixes: ab5e8b331244 "sparc32: propagate the calling conventions change down to __csum_partial_copy_sparc_generic()" Signed-off-by: Al Viro --- arch/sparc/lib/checksum_32.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/sparc/lib/checksum_32.S b/arch/sparc/lib/checksum_32.S index 84ad709cbecb..66eda40fce36 100644 --- a/arch/sparc/lib/checksum_32.S +++ b/arch/sparc/lib/checksum_32.S @@ -453,5 +453,5 @@ ccslow: cmp %g1, 0 * we only bother with faults on loads... */ cc_fault: - ret + retl clr %o0 From 1939316bf988f3e49a07d9c4dd6f660bf4daa53d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 28 Aug 2023 18:47:31 -0400 Subject: [PATCH 2/3] io_uring: kiocb_done() should *not* trust ->ki_pos if ->{read,write}_iter() failed ->ki_pos value is unreliable in such cases. For an obvious example, consider O_DSYNC write - we feed the data to page cache and start IO, then we make sure it's completed. Update of ->ki_pos is dealt with by the first part; failure in the second ends up with negative value returned _and_ ->ki_pos left advanced as if sync had been successful. In the same situation write(2) does not advance the file position at all. Reviewed-by: Christian Brauner Reviewed-by: Jens Axboe Signed-off-by: Al Viro --- io_uring/rw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/io_uring/rw.c b/io_uring/rw.c index c8c822fa7980..08d94fb972f0 100644 --- a/io_uring/rw.c +++ b/io_uring/rw.c @@ -339,7 +339,7 @@ static int kiocb_done(struct io_kiocb *req, ssize_t ret, struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw); unsigned final_ret = io_fixup_rw_res(req, ret); - if (req->flags & REQ_F_CUR_POS) + if (ret >= 0 && req->flags & REQ_F_CUR_POS) req->file->f_pos = rw->kiocb.ki_pos; if (ret >= 0 && (rw->kiocb.ki_complete == io_complete_rw)) { if (!__io_complete_rw_common(req, ret)) { From dc32464a5fe4946fe1a4d8f8e29961dc411933c5 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 14 Sep 2023 21:55:29 -0400 Subject: [PATCH 3/3] ceph_wait_on_conflict_unlink(): grab reference before dropping ->d_lock Use of dget() after we'd dropped ->d_lock is too late - dentry might be gone by that point. Reviewed-by: Jeff Layton Signed-off-by: Al Viro --- fs/ceph/mds_client.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 615db141b6c4..293b93182955 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -861,8 +861,8 @@ int ceph_wait_on_conflict_unlink(struct dentry *dentry) if (!d_same_name(udentry, pdentry, &dname)) goto next; + found = dget_dlock(udentry); spin_unlock(&udentry->d_lock); - found = dget(udentry); break; next: spin_unlock(&udentry->d_lock);