diff --git a/config/kernel-bdev-logical-size.m4 b/config/kernel-bdev-logical-size.m4 new file mode 100644 index 0000000000..1e199663b1 --- /dev/null +++ b/config/kernel-bdev-logical-size.m4 @@ -0,0 +1,22 @@ +dnl # +dnl # 2.6.30 API change +dnl # bdev_hardsect_size() replaced with bdev_logical_block_size(). While +dnl # it has been true for a while that there was no strict 1:1 mapping +dnl # between physical sector size and logical block size this change makes +dnl # it explicit. +dnl # +AC_DEFUN([ZFS_AC_KERNEL_BDEV_LOGICAL_BLOCK_SIZE], [ + AC_MSG_CHECKING([whether bdev_logical_block_size() is available]) + ZFS_LINUX_TRY_COMPILE([ + #include + ],[ + struct block_device *bdev = NULL; + bdev_logical_block_size(bdev); + ],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_BDEV_LOGICAL_BLOCK_SIZE, 1, + [bdev_logical_block_size() is available]) + ],[ + AC_MSG_RESULT(no) + ]) +]) diff --git a/config/kernel.m4 b/config/kernel.m4 index 6124f0fddb..916a6be73d 100644 --- a/config/kernel.m4 +++ b/config/kernel.m4 @@ -6,6 +6,7 @@ AC_DEFUN([ZFS_AC_CONFIG_KERNEL], [ ZFS_AC_SPL ZFS_AC_KERNEL_OPEN_BDEV_EXCLUSIVE ZFS_AC_KERNEL_INVALIDATE_BDEV_ARGS + ZFS_AC_KERNEL_BDEV_LOGICAL_BLOCK_SIZE ZFS_AC_KERNEL_BIO_END_IO_T_ARGS ZFS_AC_KERNEL_BIO_RW_SYNCIO ZFS_AC_KERNEL_BIO_EMPTY_BARRIER diff --git a/module/zfs/arc.c b/module/zfs/arc.c index 33984e79b2..880d737114 100644 --- a/module/zfs/arc.c +++ b/module/zfs/arc.c @@ -517,7 +517,7 @@ static void arc_evict_ghost(arc_state_t *state, uint64_t spa, int64_t bytes); * Hash table routines */ -#define HT_LOCK_PAD 64 +#define HT_LOCK_PAD 256 struct ht_lock { kmutex_t ht_lock; diff --git a/module/zfs/include/sys/vdev_disk.h b/module/zfs/include/sys/vdev_disk.h index 06063d2c3d..544036bbc0 100644 --- a/module/zfs/include/sys/vdev_disk.h +++ b/module/zfs/include/sys/vdev_disk.h @@ -55,6 +55,13 @@ extern int vdev_disk_read_rootlabel(char *, char *, nvlist_t **); # define vdev_bdev_invalidate(bdev) invalidate_bdev(bdev, 1) #endif /* HAVE_1ARG_INVALIDATE_BDEV */ +/* 2.6.30 API change */ +#ifdef HAVE_BDEV_LOGICAL_BLOCK_SIZE +# define vdev_bdev_block_size(bdev) bdev_logical_block_size(bdev) +#else +# define vdev_bdev_block_size(bdev) bdev_hardsect_size(bdev) +#endif + #endif /* _KERNEL */ #ifdef __cplusplus diff --git a/module/zfs/vdev_disk.c b/module/zfs/vdev_disk.c index 656e62edf7..c1e0aa7794 100644 --- a/module/zfs/vdev_disk.c +++ b/module/zfs/vdev_disk.c @@ -94,7 +94,7 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *ashift) { struct block_device *bdev; vdev_disk_t *vd; - int mode; + int mode, block_size; /* Must have a pathname and it must be absolute. */ if (v->vdev_path == NULL || v->vdev_path[0] != '/') { @@ -129,6 +129,7 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *ashift) v->vdev_tsd = vd; vd->vd_bdev = bdev; + block_size = vdev_bdev_block_size(bdev); /* Check if this is a whole device. When bdev->bd_contains == * bdev we have a whole device and not simply a partition. */ @@ -138,10 +139,10 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *ashift) v->vdev_nowritecache = B_FALSE; /* Physical volume size in bytes */ - *psize = bdev_capacity(bdev) * bdev_hardsect_size(bdev); + *psize = bdev_capacity(bdev) * block_size; /* Based on the minimum sector size set the block size */ - *ashift = highbit(MAX(bdev_hardsect_size(bdev), SPA_MINBLOCKSIZE)) - 1; + *ashift = highbit(MAX(block_size, SPA_MINBLOCKSIZE)) - 1; return 0; } @@ -310,7 +311,7 @@ __vdev_disk_physio(struct block_device *bdev, zio_t *zio, caddr_t kbuf_ptr, caddr_t bio_ptr; uint64_t bio_offset; int bio_size, bio_count = 16; - int i = 0, error = 0; + int i = 0, error = 0, block_size; retry: dr = vdev_disk_dio_alloc(bio_count); @@ -319,6 +320,7 @@ retry: dr->dr_zio = zio; dr->dr_rw = flags; + block_size = vdev_bdev_block_size(bdev); #ifdef BIO_RW_FAILFAST if (flags & (1 << BIO_RW_FAILFAST)) @@ -364,7 +366,7 @@ retry: vdev_disk_dio_get(dr); dr->dr_bio[i]->bi_bdev = bdev; - dr->dr_bio[i]->bi_sector = bio_offset/bdev_hardsect_size(bdev); + dr->dr_bio[i]->bi_sector = bio_offset / block_size; dr->dr_bio[i]->bi_rw = dr->dr_rw; dr->dr_bio[i]->bi_end_io = vdev_disk_physio_completion; dr->dr_bio[i]->bi_private = dr; @@ -573,7 +575,7 @@ vdev_disk_read_rootlabel(char *devpath, char *devid, nvlist_t **config) if (IS_ERR(bdev)) return -PTR_ERR(bdev); - s = bdev_capacity(bdev) * bdev_hardsect_size(bdev); + s = bdev_capacity(bdev) * vdev_bdev_block_size(bdev); if (s == 0) { vdev_bdev_close(bdev, vdev_bdev_mode(FREAD)); return EIO;