summaryrefslogtreecommitdiff
path: root/fs/ceph
diff options
context:
space:
mode:
authorXiubo Li <xiubli@redhat.com>2023-02-13 13:56:20 +0800
committerIlya Dryomov <idryomov@gmail.com>2023-02-26 20:03:14 +0100
commite027253c4b77d395798600a90b6a96fe4adf4d5e (patch)
tree2a6177521c2185023fb3ad104324548b17830f13 /fs/ceph
parentc9c3395d5e3dcc6daee66c6908354d47bf98cb0c (diff)
ceph: update the time stamps and try to drop the suid/sgid
The fallocate will try to clear the suid/sgid if a unprevileged user changed the file. There is no POSIX item requires that we should clear the suid/sgid in fallocate code path but this is the default behaviour for most of the filesystems and the VFS layer. And also the same for the write code path, which have already support it. And also we need to update the time stamps since the fallocate will change the file contents. Cc: stable@vger.kernel.org Link: https://tracker.ceph.com/issues/58054 Signed-off-by: Xiubo Li <xiubli@redhat.com> Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'fs/ceph')
-rw-r--r--fs/ceph/file.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index b5cff85925a1..dc39a4b0ec8e 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -2102,6 +2102,9 @@ static long ceph_fallocate(struct file *file, int mode,
loff_t endoff = 0;
loff_t size;
+ dout("%s %p %llx.%llx mode %x, offset %llu length %llu\n", __func__,
+ inode, ceph_vinop(inode), mode, offset, length);
+
if (mode != (FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE))
return -EOPNOTSUPP;
@@ -2136,6 +2139,10 @@ static long ceph_fallocate(struct file *file, int mode,
if (ret < 0)
goto unlock;
+ ret = file_modified(file);
+ if (ret)
+ goto put_caps;
+
filemap_invalidate_lock(inode->i_mapping);
ceph_fscache_invalidate(inode, false);
ceph_zero_pagecache_range(inode, offset, length);
@@ -2151,6 +2158,7 @@ static long ceph_fallocate(struct file *file, int mode,
}
filemap_invalidate_unlock(inode->i_mapping);
+put_caps:
ceph_put_cap_refs(ci, got);
unlock:
inode_unlock(inode);