mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-09 22:50:41 +00:00
ceph: add additional offset check in ceph_write_iter()
If the offset is larger or equal to both real file size and max file size, then return -EFBIG. Signed-off-by: Chengguang Xu <cgxu519@gmx.com> Reviewed-by: "Yan, Zheng" <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
This commit is contained in:
parent
0671e9968d
commit
8687a3e2c7
@ -1384,12 +1384,12 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
|
||||
struct ceph_file_info *fi = file->private_data;
|
||||
struct inode *inode = file_inode(file);
|
||||
struct ceph_inode_info *ci = ceph_inode(inode);
|
||||
struct ceph_osd_client *osdc =
|
||||
&ceph_sb_to_client(inode->i_sb)->client->osdc;
|
||||
struct ceph_fs_client *fsc = ceph_inode_to_client(inode);
|
||||
struct ceph_cap_flush *prealloc_cf;
|
||||
ssize_t count, written = 0;
|
||||
int err, want, got;
|
||||
loff_t pos;
|
||||
loff_t limit = max(i_size_read(inode), fsc->max_file_size);
|
||||
|
||||
if (ceph_snap(inode) != CEPH_NOSNAP)
|
||||
return -EROFS;
|
||||
@ -1415,6 +1415,13 @@ retry_snap:
|
||||
goto out;
|
||||
|
||||
pos = iocb->ki_pos;
|
||||
if (unlikely(pos >= limit)) {
|
||||
err = -EFBIG;
|
||||
goto out;
|
||||
} else {
|
||||
iov_iter_truncate(from, limit - pos);
|
||||
}
|
||||
|
||||
count = iov_iter_count(from);
|
||||
if (ceph_quota_is_max_bytes_exceeded(inode, pos + count)) {
|
||||
err = -EDQUOT;
|
||||
@ -1436,7 +1443,7 @@ retry_snap:
|
||||
}
|
||||
|
||||
/* FIXME: not complete since it doesn't account for being at quota */
|
||||
if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_FULL)) {
|
||||
if (ceph_osdmap_flag(&fsc->client->osdc, CEPH_OSDMAP_FULL)) {
|
||||
err = -ENOSPC;
|
||||
goto out;
|
||||
}
|
||||
@ -1526,7 +1533,7 @@ retry_snap:
|
||||
}
|
||||
|
||||
if (written >= 0) {
|
||||
if (ceph_osdmap_flag(osdc, CEPH_OSDMAP_NEARFULL))
|
||||
if (ceph_osdmap_flag(&fsc->client->osdc, CEPH_OSDMAP_NEARFULL))
|
||||
iocb->ki_flags |= IOCB_DSYNC;
|
||||
written = generic_write_sync(iocb, written);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user