Skip to content

Commit aa18792

Browse files
ukernelidryomov
authored andcommitted
ceph: limit osd read size to CEPH_MSG_MAX_DATA_LEN
libceph returns -EIO when read size > CEPH_MSG_MAX_DATA_LEN. Link: http://tracker.ceph.com/issues/20528 Signed-off-by: "Yan, Zheng" <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
1 parent 2ae409d commit aa18792

File tree

4 files changed

+15
-18
lines changed

4 files changed

+15
-18
lines changed

fs/ceph/addr.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -455,13 +455,9 @@ static int ceph_readpages(struct file *file, struct address_space *mapping,
455455
if (rc == 0)
456456
goto out;
457457

458-
if (fsc->mount_options->rsize >= PAGE_SIZE)
459-
max = (fsc->mount_options->rsize + PAGE_SIZE - 1)
460-
>> PAGE_SHIFT;
461-
462-
dout("readpages %p file %p nr_pages %d max %d\n", inode,
463-
file, nr_pages,
464-
max);
458+
max = fsc->mount_options->rsize >> PAGE_SHIFT;
459+
dout("readpages %p file %p nr_pages %d max %d\n",
460+
inode, file, nr_pages, max);
465461
while (!list_empty(page_list)) {
466462
rc = start_read(inode, page_list, max);
467463
if (rc < 0)

fs/ceph/file.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,6 +887,9 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter,
887887
break;
888888
}
889889

890+
if (!write)
891+
size = min_t(u64, size, fsc->mount_options->rsize);
892+
890893
len = size;
891894
pages = dio_get_pages_alloc(iter, len, &start, &num_pages);
892895
if (IS_ERR(pages)) {

fs/ceph/super.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,9 @@ static int parse_fsopt_token(char *c, void *private)
236236
fsopt->wsize = intval;
237237
break;
238238
case Opt_rsize:
239-
fsopt->rsize = intval;
239+
if (intval < PAGE_SIZE || intval > CEPH_MAX_READ_SIZE)
240+
return -EINVAL;
241+
fsopt->rsize = ALIGN(intval, PAGE_SIZE);
240242
break;
241243
case Opt_rasize:
242244
fsopt->rasize = intval;
@@ -390,7 +392,7 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt,
390392
fsopt->sb_flags = flags;
391393
fsopt->flags = CEPH_MOUNT_OPT_DEFAULT;
392394

393-
fsopt->rsize = CEPH_RSIZE_DEFAULT;
395+
fsopt->rsize = CEPH_MAX_READ_SIZE;
394396
fsopt->rasize = CEPH_RASIZE_DEFAULT;
395397
fsopt->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL);
396398
if (!fsopt->snapdir_name) {
@@ -505,7 +507,7 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root)
505507
seq_printf(m, ",mds_namespace=%s", fsopt->mds_namespace);
506508
if (fsopt->wsize)
507509
seq_printf(m, ",wsize=%d", fsopt->wsize);
508-
if (fsopt->rsize != CEPH_RSIZE_DEFAULT)
510+
if (fsopt->rsize != CEPH_MAX_READ_SIZE)
509511
seq_printf(m, ",rsize=%d", fsopt->rsize);
510512
if (fsopt->rasize != CEPH_RASIZE_DEFAULT)
511513
seq_printf(m, ",rasize=%d", fsopt->rasize);
@@ -948,13 +950,8 @@ static int ceph_setup_bdi(struct super_block *sb, struct ceph_fs_client *fsc)
948950
else
949951
sb->s_bdi->ra_pages = VM_MAX_READAHEAD * 1024 / PAGE_SIZE;
950952

951-
if (fsc->mount_options->rsize > fsc->mount_options->rasize &&
952-
fsc->mount_options->rsize >= PAGE_SIZE)
953-
sb->s_bdi->io_pages =
954-
(fsc->mount_options->rsize + PAGE_SIZE - 1)
955-
>> PAGE_SHIFT;
956-
else if (fsc->mount_options->rsize == 0)
957-
sb->s_bdi->io_pages = ULONG_MAX;
953+
/* set io_pages based on max osd read size */
954+
sb->s_bdi->io_pages = fsc->mount_options->rsize >> PAGE_SHIFT;
958955

959956
return 0;
960957
}

fs/ceph/super.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
#define ceph_test_mount_opt(fsc, opt) \
4747
(!!((fsc)->mount_options->flags & CEPH_MOUNT_OPT_##opt))
4848

49-
#define CEPH_RSIZE_DEFAULT (64*1024*1024) /* max read size */
49+
/* max size of osd read request, limited by libceph */
50+
#define CEPH_MAX_READ_SIZE CEPH_MSG_MAX_DATA_LEN
5051
#define CEPH_RASIZE_DEFAULT (8192*1024) /* max readahead */
5152
#define CEPH_MAX_READDIR_DEFAULT 1024
5253
#define CEPH_MAX_READDIR_BYTES_DEFAULT (512*1024)

0 commit comments

Comments
 (0)