From f1512ee61e2f22186ac16481a09d86112b2d6788 Mon Sep 17 00:00:00 2001 From: Matthew Ahrens Date: Mon, 3 Nov 2014 12:15:08 -0800 Subject: Illumos 5027 - zfs large block support 5027 zfs large block support Reviewed by: Alek Pinchuk Reviewed by: George Wilson Reviewed by: Josef 'Jeff' Sipek Reviewed by: Richard Elling Reviewed by: Saso Kiselkov Reviewed by: Brian Behlendorf Approved by: Dan McDonald References: https://www.illumos.org/issues/5027 https://github.com/illumos/illumos-gate/commit/b515258 Porting Notes: * Included in this patch is a tiny ISP2() cleanup in zio_init() from Illumos 5255. * Unlike the upstream Illumos commit this patch does not impose an arbitrary 128K block size limit on volumes. Volumes, like filesystems, are limited by the zfs_max_recordsize=1M module option. * By default the maximum record size is limited to 1M by the module option zfs_max_recordsize. This value may be safely increased up to 16M which is the largest block size supported by the on-disk format. At the moment, 1M blocks clearly offer a significant performance improvement but the benefits of going beyond this for the majority of workloads are less clear. * The illumos version of this patch increased DMU_MAX_ACCESS to 32M. This was determined not to be large enough when using 16M blocks because the zfs_make_xattrdir() function will fail (EFBIG) when assigning a TX. This was immediately observed under Linux because all newly created files must have a security xattr created and that was failing. Therefore, we've set DMU_MAX_ACCESS to 64M. * On 32-bit platforms a hard limit of 1M is set for blocks due to the limited virtual address space. We should be able to relax this one the ABD patches are merged. Ported-by: Brian Behlendorf Closes #354 --- module/zfs/zio.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'module/zfs/zio.c') diff --git a/module/zfs/zio.c b/module/zfs/zio.c index 9204df2b2..2b338f2a7 100644 --- a/module/zfs/zio.c +++ b/module/zfs/zio.c @@ -24,6 +24,7 @@ * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved. */ +#include #include #include #include @@ -107,9 +108,8 @@ zio_init(void) /* * For small buffers, we want a cache for each multiple of - * SPA_MINBLOCKSIZE. For medium-size buffers, we want a cache - * for each quarter-power of 2. For large buffers, we want - * a cache for each multiple of PAGESIZE. + * SPA_MINBLOCKSIZE. For larger buffers, we want a cache + * for each quarter-power of 2. */ for (c = 0; c < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; c++) { size_t size = (c + 1) << SPA_MINBLOCKSHIFT; @@ -117,7 +117,16 @@ zio_init(void) size_t align = 0; size_t cflags = (size > zio_buf_debug_limit) ? KMC_NODEBUG : 0; - while (p2 & (p2 - 1)) +#ifdef _ILP32 + /* + * Cache size limited to 1M on 32-bit platforms until ARC + * buffers no longer require virtual address space. + */ + if (size > zfs_max_recordsize) + break; +#endif + + while (!ISP2(p2)) p2 &= p2 - 1; #ifndef _KERNEL @@ -132,10 +141,8 @@ zio_init(void) #endif if (size <= 4 * SPA_MINBLOCKSIZE) { align = SPA_MINBLOCKSIZE; - } else if (IS_P2ALIGNED(size, PAGESIZE)) { - align = PAGESIZE; } else if (IS_P2ALIGNED(size, p2 >> 2)) { - align = p2 >> 2; + align = MIN(p2 >> 2, PAGESIZE); } if (align != 0) { @@ -174,6 +181,14 @@ zio_fini(void) kmem_cache_t *last_data_cache = NULL; for (c = 0; c < SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT; c++) { +#ifdef _ILP32 + /* + * Cache size limited to 1M on 32-bit platforms until ARC + * buffers no longer require virtual address space. + */ + if (((c + 1) << SPA_MINBLOCKSHIFT) > zfs_max_recordsize) + break; +#endif if (zio_buf_cache[c] != last_cache) { last_cache = zio_buf_cache[c]; kmem_cache_destroy(zio_buf_cache[c]); -- cgit v1.2.3