summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYan, Zheng <zyan@redhat.com>2017-07-11 12:34:46 +0300
committerIlya Dryomov <idryomov@gmail.com>2017-09-06 20:56:41 +0300
commit95cca2b44e54b00a3ed6ed7dc869717cd6807e81 (patch)
tree944f555f63a1b9641f2598703a562777437b0456
parentaa187926b739fb391f153335c7552c7a10d60e82 (diff)
downloadlinux-95cca2b44e54b00a3ed6ed7dc869717cd6807e81.tar.xz
ceph: limit osd write size
OSD has a configurable limitation of max write size. OSD return error if write request size is larger than the limitation. For now, set max write size to CEPH_MSG_MAX_DATA_LEN. It should be small enough. Signed-off-by: "Yan, Zheng" <zyan@redhat.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
-rw-r--r--fs/ceph/addr.c4
-rw-r--r--fs/ceph/file.c4
-rw-r--r--fs/ceph/super.c5
-rw-r--r--fs/ceph/super.h3
4 files changed, 11 insertions, 5 deletions
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)