diff --git a/fs/ceph/addr.c b/fs/ceph/addr.c index 63ca1732570b..149b10063be8 100644 --- a/fs/ceph/addr.c +++ b/fs/ceph/addr.c @@ -779,10 +779,8 @@ static int ceph_writepages_start(struct address_space *mapping, mapping_set_error(mapping, -EIO); return -EIO; /* we're in a forced umount, don't write! */ } - if (fsc->mount_options->wsize && fsc->mount_options->wsize < wsize) + if (fsc->mount_options->wsize < wsize) wsize = fsc->mount_options->wsize; - if (wsize < PAGE_SIZE) - wsize = PAGE_SIZE; max_pages_ever = wsize >> PAGE_SHIFT; pagevec_init(&pvec, 0); diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 85f0dba394a2..a39ff54cb372 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -887,7 +887,9 @@ ceph_direct_read_write(struct kiocb *iocb, struct iov_iter *iter, break; } - if (!write) + if (write) + size = min_t(u64, size, fsc->mount_options->wsize); + else size = min_t(u64, size, fsc->mount_options->rsize); len = size; diff --git a/fs/ceph/super.c b/fs/ceph/super.c index 2b2a260acb24..caf9801712ca 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -233,7 +233,9 @@ static int parse_fsopt_token(char *c, void *private) break; /* misc */ case Opt_wsize: - fsopt->wsize = intval; + if (intval < PAGE_SIZE || intval > CEPH_MAX_WRITE_SIZE) + return -EINVAL; + fsopt->wsize = ALIGN(intval, PAGE_SIZE); break; case Opt_rsize: if (intval < PAGE_SIZE || intval > CEPH_MAX_READ_SIZE) @@ -392,6 +394,7 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt, fsopt->sb_flags = flags; fsopt->flags = CEPH_MOUNT_OPT_DEFAULT; + fsopt->wsize = CEPH_MAX_WRITE_SIZE; fsopt->rsize = CEPH_MAX_READ_SIZE; fsopt->rasize = CEPH_RASIZE_DEFAULT; fsopt->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL); diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 2b1b021ad6b8..eed2a67d8e52 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h @@ -48,6 +48,9 @@ /* max size of osd read request, limited by libceph */ #define CEPH_MAX_READ_SIZE CEPH_MSG_MAX_DATA_LEN +/* osd has a configurable limitaion of max write size. + * CEPH_MSG_MAX_DATA_LEN should be small enough. */ +#define CEPH_MAX_WRITE_SIZE CEPH_MSG_MAX_DATA_LEN #define CEPH_RASIZE_DEFAULT (8192*1024) /* max readahead */ #define CEPH_MAX_READDIR_DEFAULT 1024 #define CEPH_MAX_READDIR_BYTES_DEFAULT (512*1024)