With cache=never, we fall back to direct IO. pjdfstest chmod test 12.t was failing because if a file has setuid bit, it should be cleared if an unpriviledged user opens it for write and writes to it. Call fuse_remove_privs() even for direct I/O path. Signed-off-by: Vivek Goyal <vgoyal@xxxxxxxxxx> --- fs/fuse/file.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index cb28cf26a6e7..0be5a7380b3c 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1679,13 +1679,25 @@ static ssize_t fuse_direct_write_iter(struct kiocb *iocb, struct iov_iter *from) /* Don't allow parallel writes to the same file */ inode_lock(inode); res = generic_write_checks(iocb, from); - if (res > 0) - res = fuse_direct_io(&io, from, &iocb->ki_pos, FUSE_DIO_WRITE); + if (res < 0) + goto out_invalidate; + + res = file_remove_privs(iocb->ki_filp); + if (res) + goto out_invalidate; + + res = fuse_direct_io(&io, from, &iocb->ki_pos, FUSE_DIO_WRITE); + if (res < 0) + goto out_invalidate; + fuse_invalidate_attr(inode); - if (res > 0) - fuse_write_update_size(inode, iocb->ki_pos); + fuse_write_update_size(inode, iocb->ki_pos); inode_unlock(inode); + return res; +out_invalidate: + fuse_invalidate_attr(inode); + inode_unlock(inode); return res; } -- 2.13.6