mirror of
				https://git.proxmox.com/git/mirror_zfs.git
				synced 2025-10-26 18:05:04 +03:00 
			
		
		
		
	Linux 6.5 compat: blkdev changes
Multiple changes to the blkdev API were introduced in Linux 6.5. This includes passing (void* holder) to blkdev_put, adding a new blk_holder_ops* arg to blkdev_get_by_path, adding a new blk_mode_t type that replaces uses of fmode_t, and removing an argument from the release handler on block_device_operations that we weren't using. The open function definition has also changed to take gendisk* and blk_mode_t, so update it accordingly, too. Implement local wrappers for blkdev_get_by_path() and vdev_blkdev_put() so that the in-line calls are cleaner, and place the conditionally-compiled implementation details inside of both of these local wrappers. Both calls are exclusively used within vdev_disk.c, at this time. Add blk_mode_is_open_write() to test FMODE_WRITE / BLK_OPEN_WRITE The wrapper function is now used for testing using the appropriate method for the kernel, whether the open mode is writable or not. Emphasize fmode_t arg in zvol_release is not used Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Coleman Kane <ckane@colemankane.org> Closes #15099
This commit is contained in:
		
							parent
							
								
									3ff9e4f8ac
								
							
						
					
					
						commit
						7c0618bdb7
					
				| @ -16,14 +16,65 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH], [ | |||||||
| 	]) | 	]) | ||||||
| ]) | ]) | ||||||
| 
 | 
 | ||||||
|  | dnl # | ||||||
|  | dnl # 6.5.x API change, | ||||||
|  | dnl # blkdev_get_by_path() takes 4 args | ||||||
|  | dnl # | ||||||
|  | AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG], [ | ||||||
|  | 	ZFS_LINUX_TEST_SRC([blkdev_get_by_path_4arg], [ | ||||||
|  | 		#include <linux/fs.h> | ||||||
|  | 		#include <linux/blkdev.h> | ||||||
|  | 	], [ | ||||||
|  | 		struct block_device *bdev __attribute__ ((unused)) = NULL; | ||||||
|  | 		const char *path = "path"; | ||||||
|  | 		fmode_t mode = 0; | ||||||
|  | 		void *holder = NULL; | ||||||
|  | 		struct blk_holder_ops h; | ||||||
|  | 
 | ||||||
|  | 		bdev = blkdev_get_by_path(path, mode, holder, &h); | ||||||
|  | 	]) | ||||||
|  | ]) | ||||||
|  | 
 | ||||||
| AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [ | AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [ | ||||||
| 	AC_MSG_CHECKING([whether blkdev_get_by_path() exists]) | 	AC_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 3 args]) | ||||||
| 	ZFS_LINUX_TEST_RESULT([blkdev_get_by_path], [ | 	ZFS_LINUX_TEST_RESULT([blkdev_get_by_path], [ | ||||||
| 		AC_MSG_RESULT(yes) | 		AC_MSG_RESULT(yes) | ||||||
|  | 	], [ | ||||||
|  | 		AC_MSG_RESULT(no) | ||||||
|  | 		AC_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 4 args]) | ||||||
|  | 		ZFS_LINUX_TEST_RESULT([blkdev_get_by_path_4arg], [ | ||||||
|  | 			AC_DEFINE(HAVE_BLKDEV_GET_BY_PATH_4ARG, 1, | ||||||
|  | 				[blkdev_get_by_path() exists and takes 4 args]) | ||||||
|  | 			AC_MSG_RESULT(yes) | ||||||
| 		], [ | 		], [ | ||||||
| 			ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()]) | 			ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()]) | ||||||
| 		]) | 		]) | ||||||
| 	]) | 	]) | ||||||
|  | ]) | ||||||
|  | 
 | ||||||
|  | dnl # | ||||||
|  | dnl # 6.5.x API change | ||||||
|  | dnl # blk_mode_t was added as a type to supercede some places where fmode_t | ||||||
|  | dnl # is used | ||||||
|  | dnl # | ||||||
|  | AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BLK_MODE_T], [ | ||||||
|  | 	ZFS_LINUX_TEST_SRC([blk_mode_t], [ | ||||||
|  | 		#include <linux/fs.h> | ||||||
|  | 		#include <linux/blkdev.h> | ||||||
|  | 	], [ | ||||||
|  | 		blk_mode_t m __attribute((unused)) = (blk_mode_t)0; | ||||||
|  | 	]) | ||||||
|  | ]) | ||||||
|  | 
 | ||||||
|  | AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BLK_MODE_T], [ | ||||||
|  | 	AC_MSG_CHECKING([whether blk_mode_t is defined]) | ||||||
|  | 	ZFS_LINUX_TEST_RESULT([blk_mode_t], [ | ||||||
|  | 		AC_MSG_RESULT(yes) | ||||||
|  | 		AC_DEFINE(HAVE_BLK_MODE_T, 1, [blk_mode_t is defined]) | ||||||
|  | 	], [ | ||||||
|  | 		AC_MSG_RESULT(no) | ||||||
|  | 	]) | ||||||
|  | ]) | ||||||
| 
 | 
 | ||||||
| dnl # | dnl # | ||||||
| dnl # 2.6.38 API change, | dnl # 2.6.38 API change, | ||||||
| @ -41,14 +92,37 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_PUT], [ | |||||||
| 	]) | 	]) | ||||||
| ]) | ]) | ||||||
| 
 | 
 | ||||||
|  | dnl # | ||||||
|  | dnl # 6.5.x API change. | ||||||
|  | dnl # blkdev_put() takes (void* holder) as arg 2 | ||||||
|  | dnl # | ||||||
|  | AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER], [ | ||||||
|  | 	ZFS_LINUX_TEST_SRC([blkdev_put_holder], [ | ||||||
|  | 		#include <linux/fs.h> | ||||||
|  | 		#include <linux/blkdev.h> | ||||||
|  | 	], [ | ||||||
|  | 		struct block_device *bdev = NULL; | ||||||
|  | 		void *holder = NULL; | ||||||
|  | 
 | ||||||
|  | 		blkdev_put(bdev, holder); | ||||||
|  | 	]) | ||||||
|  | ]) | ||||||
|  | 
 | ||||||
| AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [ | AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [ | ||||||
| 	AC_MSG_CHECKING([whether blkdev_put() exists]) | 	AC_MSG_CHECKING([whether blkdev_put() exists]) | ||||||
| 	ZFS_LINUX_TEST_RESULT([blkdev_put], [ | 	ZFS_LINUX_TEST_RESULT([blkdev_put], [ | ||||||
| 		AC_MSG_RESULT(yes) | 		AC_MSG_RESULT(yes) | ||||||
|  | 	], [ | ||||||
|  | 		AC_MSG_CHECKING([whether blkdev_put() accepts void* as arg 2]) | ||||||
|  | 		ZFS_LINUX_TEST_RESULT([blkdev_put_holder], [ | ||||||
|  | 			AC_MSG_RESULT(yes) | ||||||
|  | 			AC_DEFINE(HAVE_BLKDEV_PUT_HOLDER, 1, | ||||||
|  | 				[blkdev_put() accepts void* as arg 2]) | ||||||
| 		], [ | 		], [ | ||||||
| 			ZFS_LINUX_TEST_ERROR([blkdev_put()]) | 			ZFS_LINUX_TEST_ERROR([blkdev_put()]) | ||||||
| 		]) | 		]) | ||||||
| 	]) | 	]) | ||||||
|  | ]) | ||||||
| 
 | 
 | ||||||
| dnl # | dnl # | ||||||
| dnl # 4.1 API, exported blkdev_reread_part() symbol, back ported to the | dnl # 4.1 API, exported blkdev_reread_part() symbol, back ported to the | ||||||
| @ -495,7 +569,9 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_BLK_STS_RESV_CONFLICT], [ | |||||||
| 
 | 
 | ||||||
| AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [ | AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [ | ||||||
| 	ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH | 	ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH | ||||||
|  | 	ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG | ||||||
| 	ZFS_AC_KERNEL_SRC_BLKDEV_PUT | 	ZFS_AC_KERNEL_SRC_BLKDEV_PUT | ||||||
|  | 	ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER | ||||||
| 	ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART | 	ZFS_AC_KERNEL_SRC_BLKDEV_REREAD_PART | ||||||
| 	ZFS_AC_KERNEL_SRC_BLKDEV_INVALIDATE_BDEV | 	ZFS_AC_KERNEL_SRC_BLKDEV_INVALIDATE_BDEV | ||||||
| 	ZFS_AC_KERNEL_SRC_BLKDEV_LOOKUP_BDEV | 	ZFS_AC_KERNEL_SRC_BLKDEV_LOOKUP_BDEV | ||||||
| @ -510,6 +586,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [ | |||||||
| 	ZFS_AC_KERNEL_SRC_BLKDEV_PART_TO_DEV | 	ZFS_AC_KERNEL_SRC_BLKDEV_PART_TO_DEV | ||||||
| 	ZFS_AC_KERNEL_SRC_BLKDEV_DISK_CHECK_MEDIA_CHANGE | 	ZFS_AC_KERNEL_SRC_BLKDEV_DISK_CHECK_MEDIA_CHANGE | ||||||
| 	ZFS_AC_KERNEL_SRC_BLKDEV_BLK_STS_RESV_CONFLICT | 	ZFS_AC_KERNEL_SRC_BLKDEV_BLK_STS_RESV_CONFLICT | ||||||
|  | 	ZFS_AC_KERNEL_SRC_BLKDEV_BLK_MODE_T | ||||||
| ]) | ]) | ||||||
| 
 | 
 | ||||||
| AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [ | AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [ | ||||||
| @ -530,4 +607,5 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV], [ | |||||||
| 	ZFS_AC_KERNEL_BLKDEV_PART_TO_DEV | 	ZFS_AC_KERNEL_BLKDEV_PART_TO_DEV | ||||||
| 	ZFS_AC_KERNEL_BLKDEV_DISK_CHECK_MEDIA_CHANGE | 	ZFS_AC_KERNEL_BLKDEV_DISK_CHECK_MEDIA_CHANGE | ||||||
| 	ZFS_AC_KERNEL_BLKDEV_BLK_STS_RESV_CONFLICT | 	ZFS_AC_KERNEL_BLKDEV_BLK_STS_RESV_CONFLICT | ||||||
|  | 	ZFS_AC_KERNEL_BLKDEV_BLK_MODE_T | ||||||
| ]) | ]) | ||||||
|  | |||||||
| @ -49,14 +49,44 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [ | |||||||
| 	], [], []) | 	], [], []) | ||||||
| ]) | ]) | ||||||
| 
 | 
 | ||||||
|  | dnl # | ||||||
|  | dnl # 5.9.x API change | ||||||
|  | dnl # | ||||||
|  | AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG], [ | ||||||
|  | 	ZFS_LINUX_TEST_SRC([block_device_operations_release_void_1arg], [ | ||||||
|  | 		#include <linux/blkdev.h> | ||||||
|  | 
 | ||||||
|  | 		void blk_release(struct gendisk *g) { | ||||||
|  | 			(void) g; | ||||||
|  | 			return; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		static const struct block_device_operations | ||||||
|  | 		    bops __attribute__ ((unused)) = { | ||||||
|  | 			.open		= NULL, | ||||||
|  | 			.release	= blk_release, | ||||||
|  | 			.ioctl		= NULL, | ||||||
|  | 			.compat_ioctl	= NULL, | ||||||
|  | 		}; | ||||||
|  | 	], [], []) | ||||||
|  | ]) | ||||||
|  | 
 | ||||||
| AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [ | AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID], [ | ||||||
| 	AC_MSG_CHECKING([whether bops->release() is void]) | 	AC_MSG_CHECKING([whether bops->release() is void and takes 2 args]) | ||||||
| 	ZFS_LINUX_TEST_RESULT([block_device_operations_release_void], [ | 	ZFS_LINUX_TEST_RESULT([block_device_operations_release_void], [ | ||||||
| 		AC_MSG_RESULT(yes) | 		AC_MSG_RESULT(yes) | ||||||
|  | 	],[ | ||||||
|  | 		AC_MSG_RESULT(no) | ||||||
|  | 		AC_MSG_CHECKING([whether bops->release() is void and takes 1 arg]) | ||||||
|  | 		ZFS_LINUX_TEST_RESULT([block_device_operations_release_void_1arg], [ | ||||||
|  | 			AC_MSG_RESULT(yes) | ||||||
|  | 			AC_DEFINE([HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG], [1], | ||||||
|  | 				[Define if release() in block_device_operations takes 1 arg]) | ||||||
| 		],[ | 		],[ | ||||||
| 			ZFS_LINUX_TEST_ERROR([bops->release()]) | 			ZFS_LINUX_TEST_ERROR([bops->release()]) | ||||||
| 		]) | 		]) | ||||||
| 	]) | 	]) | ||||||
|  | ]) | ||||||
| 
 | 
 | ||||||
| dnl # | dnl # | ||||||
| dnl # 5.13 API change | dnl # 5.13 API change | ||||||
| @ -92,6 +122,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [ | |||||||
| AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS], [ | AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS], [ | ||||||
| 	ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS | 	ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS | ||||||
| 	ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID | 	ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID | ||||||
|  | 	ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG | ||||||
| 	ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK | 	ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK | ||||||
| ]) | ]) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -387,6 +387,12 @@ vdev_lookup_bdev(const char *path, dev_t *dev) | |||||||
| #endif | #endif | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #if defined(HAVE_BLK_MODE_T) | ||||||
|  | #define	blk_mode_is_open_write(flag)	((flag) & BLK_OPEN_WRITE) | ||||||
|  | #else | ||||||
|  | #define	blk_mode_is_open_write(flag)	((flag) & FMODE_WRITE) | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
| /*
 | /*
 | ||||||
|  * Kernels without bio_set_op_attrs use bi_rw for the bio flags. |  * Kernels without bio_set_op_attrs use bi_rw for the bio flags. | ||||||
|  */ |  */ | ||||||
|  | |||||||
| @ -74,9 +74,22 @@ typedef struct dio_request { | |||||||
| 	struct bio		*dr_bio[0];	/* Attached bio's */ | 	struct bio		*dr_bio[0];	/* Attached bio's */ | ||||||
| } dio_request_t; | } dio_request_t; | ||||||
| 
 | 
 | ||||||
|  | #ifdef HAVE_BLK_MODE_T | ||||||
|  | static blk_mode_t | ||||||
|  | #else | ||||||
| static fmode_t | static fmode_t | ||||||
|  | #endif | ||||||
| vdev_bdev_mode(spa_mode_t spa_mode) | vdev_bdev_mode(spa_mode_t spa_mode) | ||||||
| { | { | ||||||
|  | #ifdef HAVE_BLK_MODE_T | ||||||
|  | 	blk_mode_t mode = 0; | ||||||
|  | 
 | ||||||
|  | 	if (spa_mode & SPA_MODE_READ) | ||||||
|  | 		mode |= BLK_OPEN_READ; | ||||||
|  | 
 | ||||||
|  | 	if (spa_mode & SPA_MODE_WRITE) | ||||||
|  | 		mode |= BLK_OPEN_WRITE; | ||||||
|  | #else | ||||||
| 	fmode_t mode = 0; | 	fmode_t mode = 0; | ||||||
| 
 | 
 | ||||||
| 	if (spa_mode & SPA_MODE_READ) | 	if (spa_mode & SPA_MODE_READ) | ||||||
| @ -84,6 +97,7 @@ vdev_bdev_mode(spa_mode_t spa_mode) | |||||||
| 
 | 
 | ||||||
| 	if (spa_mode & SPA_MODE_WRITE) | 	if (spa_mode & SPA_MODE_WRITE) | ||||||
| 		mode |= FMODE_WRITE; | 		mode |= FMODE_WRITE; | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 	return (mode); | 	return (mode); | ||||||
| } | } | ||||||
| @ -191,12 +205,47 @@ vdev_disk_kobj_evt_post(vdev_t *v) | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #if !defined(HAVE_BLKDEV_GET_BY_PATH_4ARG) | ||||||
|  | /*
 | ||||||
|  |  * Define a dummy struct blk_holder_ops for kernel versions | ||||||
|  |  * prior to 6.5. | ||||||
|  |  */ | ||||||
|  | struct blk_holder_ops {}; | ||||||
|  | #endif | ||||||
|  | 
 | ||||||
|  | static struct block_device * | ||||||
|  | vdev_blkdev_get_by_path(const char *path, spa_mode_t mode, void *holder, | ||||||
|  |     const struct blk_holder_ops *hops) | ||||||
|  | { | ||||||
|  | #ifdef HAVE_BLKDEV_GET_BY_PATH_4ARG | ||||||
|  | 	return (blkdev_get_by_path(path, | ||||||
|  | 	    vdev_bdev_mode(mode) | BLK_OPEN_EXCL, holder, hops)); | ||||||
|  | #else | ||||||
|  | 	return (blkdev_get_by_path(path, | ||||||
|  | 	    vdev_bdev_mode(mode) | FMODE_EXCL, holder)); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void | ||||||
|  | vdev_blkdev_put(struct block_device *bdev, spa_mode_t mode, void *holder) | ||||||
|  | { | ||||||
|  | #ifdef HAVE_BLKDEV_PUT_HOLDER | ||||||
|  | 	return (blkdev_put(bdev, holder)); | ||||||
|  | #else | ||||||
|  | 	return (blkdev_put(bdev, vdev_bdev_mode(mode) | FMODE_EXCL)); | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  | 
 | ||||||
| static int | static int | ||||||
| vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize, | vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize, | ||||||
|     uint64_t *logical_ashift, uint64_t *physical_ashift) |     uint64_t *logical_ashift, uint64_t *physical_ashift) | ||||||
| { | { | ||||||
| 	struct block_device *bdev; | 	struct block_device *bdev; | ||||||
|  | #ifdef HAVE_BLK_MODE_T | ||||||
|  | 	blk_mode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa)); | ||||||
|  | #else | ||||||
| 	fmode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa)); | 	fmode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa)); | ||||||
|  | #endif | ||||||
| 	hrtime_t timeout = MSEC2NSEC(zfs_vdev_open_timeout_ms); | 	hrtime_t timeout = MSEC2NSEC(zfs_vdev_open_timeout_ms); | ||||||
| 	vdev_disk_t *vd; | 	vdev_disk_t *vd; | ||||||
| 
 | 
 | ||||||
| @ -246,15 +295,15 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize, | |||||||
| 					reread_part = B_TRUE; | 					reread_part = B_TRUE; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			blkdev_put(bdev, mode | FMODE_EXCL); | 			vdev_blkdev_put(bdev, mode, zfs_vdev_holder); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		if (reread_part) { | 		if (reread_part) { | ||||||
| 			bdev = blkdev_get_by_path(disk_name, mode | FMODE_EXCL, | 			bdev = vdev_blkdev_get_by_path(disk_name, mode, | ||||||
| 			    zfs_vdev_holder); | 			    zfs_vdev_holder, NULL); | ||||||
| 			if (!IS_ERR(bdev)) { | 			if (!IS_ERR(bdev)) { | ||||||
| 				int error = vdev_bdev_reread_part(bdev); | 				int error = vdev_bdev_reread_part(bdev); | ||||||
| 				blkdev_put(bdev, mode | FMODE_EXCL); | 				vdev_blkdev_put(bdev, mode, zfs_vdev_holder); | ||||||
| 				if (error == 0) { | 				if (error == 0) { | ||||||
| 					timeout = MSEC2NSEC( | 					timeout = MSEC2NSEC( | ||||||
| 					    zfs_vdev_open_timeout_ms * 2); | 					    zfs_vdev_open_timeout_ms * 2); | ||||||
| @ -299,8 +348,8 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize, | |||||||
| 	hrtime_t start = gethrtime(); | 	hrtime_t start = gethrtime(); | ||||||
| 	bdev = ERR_PTR(-ENXIO); | 	bdev = ERR_PTR(-ENXIO); | ||||||
| 	while (IS_ERR(bdev) && ((gethrtime() - start) < timeout)) { | 	while (IS_ERR(bdev) && ((gethrtime() - start) < timeout)) { | ||||||
| 		bdev = blkdev_get_by_path(v->vdev_path, mode | FMODE_EXCL, | 		bdev = vdev_blkdev_get_by_path(v->vdev_path, mode, | ||||||
| 		    zfs_vdev_holder); | 		    zfs_vdev_holder, NULL); | ||||||
| 		if (unlikely(PTR_ERR(bdev) == -ENOENT)) { | 		if (unlikely(PTR_ERR(bdev) == -ENOENT)) { | ||||||
| 			/*
 | 			/*
 | ||||||
| 			 * There is no point of waiting since device is removed | 			 * There is no point of waiting since device is removed | ||||||
| @ -376,8 +425,8 @@ vdev_disk_close(vdev_t *v) | |||||||
| 		return; | 		return; | ||||||
| 
 | 
 | ||||||
| 	if (vd->vd_bdev != NULL) { | 	if (vd->vd_bdev != NULL) { | ||||||
| 		blkdev_put(vd->vd_bdev, | 		vdev_blkdev_put(vd->vd_bdev, spa_mode(v->vdev_spa), | ||||||
| 		    vdev_bdev_mode(spa_mode(v->vdev_spa)) | FMODE_EXCL); | 		    zfs_vdev_holder); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	rw_destroy(&vd->vd_lock); | 	rw_destroy(&vd->vd_lock); | ||||||
|  | |||||||
| @ -198,7 +198,7 @@ zfs_open(struct inode *ip, int mode, int flag, cred_t *cr) | |||||||
| 	ZFS_VERIFY_ZP(zp); | 	ZFS_VERIFY_ZP(zp); | ||||||
| 
 | 
 | ||||||
| 	/* Honor ZFS_APPENDONLY file attribute */ | 	/* Honor ZFS_APPENDONLY file attribute */ | ||||||
| 	if ((mode & FMODE_WRITE) && (zp->z_pflags & ZFS_APPENDONLY) && | 	if (blk_mode_is_open_write(mode) && (zp->z_pflags & ZFS_APPENDONLY) && | ||||||
| 	    ((flag & O_APPEND) == 0)) { | 	    ((flag & O_APPEND) == 0)) { | ||||||
| 		ZFS_EXIT(zfsvfs); | 		ZFS_EXIT(zfsvfs); | ||||||
| 		return (SET_ERROR(EPERM)); | 		return (SET_ERROR(EPERM)); | ||||||
|  | |||||||
| @ -40,7 +40,7 @@ | |||||||
| static int | static int | ||||||
| zpl_common_open(struct inode *ip, struct file *filp) | zpl_common_open(struct inode *ip, struct file *filp) | ||||||
| { | { | ||||||
| 	if (filp->f_mode & FMODE_WRITE) | 	if (blk_mode_is_open_write(filp->f_mode)) | ||||||
| 		return (-EACCES); | 		return (-EACCES); | ||||||
| 
 | 
 | ||||||
| 	return (generic_file_open(ip, filp)); | 	return (generic_file_open(ip, filp)); | ||||||
|  | |||||||
| @ -492,7 +492,11 @@ out: | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static int | static int | ||||||
|  | #ifdef HAVE_BLK_MODE_T | ||||||
|  | zvol_open(struct gendisk *disk, blk_mode_t flag) | ||||||
|  | #else | ||||||
| zvol_open(struct block_device *bdev, fmode_t flag) | zvol_open(struct block_device *bdev, fmode_t flag) | ||||||
|  | #endif | ||||||
| { | { | ||||||
| 	zvol_state_t *zv; | 	zvol_state_t *zv; | ||||||
| 	int error = 0; | 	int error = 0; | ||||||
| @ -507,10 +511,14 @@ retry: | |||||||
| 	/*
 | 	/*
 | ||||||
| 	 * Obtain a copy of private_data under the zvol_state_lock to make | 	 * Obtain a copy of private_data under the zvol_state_lock to make | ||||||
| 	 * sure that either the result of zvol free code path setting | 	 * sure that either the result of zvol free code path setting | ||||||
| 	 * bdev->bd_disk->private_data to NULL is observed, or zvol_free() | 	 * disk->private_data to NULL is observed, or zvol_os_free() | ||||||
| 	 * is not called on this zv because of the positive zv_open_count. | 	 * is not called on this zv because of the positive zv_open_count. | ||||||
| 	 */ | 	 */ | ||||||
|  | #ifdef HAVE_BLK_MODE_T | ||||||
|  | 	zv = disk->private_data; | ||||||
|  | #else | ||||||
| 	zv = bdev->bd_disk->private_data; | 	zv = bdev->bd_disk->private_data; | ||||||
|  | #endif | ||||||
| 	if (zv == NULL) { | 	if (zv == NULL) { | ||||||
| 		rw_exit(&zvol_state_lock); | 		rw_exit(&zvol_state_lock); | ||||||
| 		return (SET_ERROR(-ENXIO)); | 		return (SET_ERROR(-ENXIO)); | ||||||
| @ -590,14 +598,15 @@ retry: | |||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		error = -zvol_first_open(zv, !(flag & FMODE_WRITE)); | 		error = -zvol_first_open(zv, !(blk_mode_is_open_write(flag))); | ||||||
| 
 | 
 | ||||||
| 		if (drop_namespace) | 		if (drop_namespace) | ||||||
| 			mutex_exit(&spa_namespace_lock); | 			mutex_exit(&spa_namespace_lock); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if (error == 0) { | 	if (error == 0) { | ||||||
| 		if ((flag & FMODE_WRITE) && (zv->zv_flags & ZVOL_RDONLY)) { | 		if ((blk_mode_is_open_write(flag)) && | ||||||
|  | 		    (zv->zv_flags & ZVOL_RDONLY)) { | ||||||
| 			if (zv->zv_open_count == 0) | 			if (zv->zv_open_count == 0) | ||||||
| 				zvol_last_close(zv); | 				zvol_last_close(zv); | ||||||
| 
 | 
 | ||||||
| @ -612,14 +621,25 @@ retry: | |||||||
| 		rw_exit(&zv->zv_suspend_lock); | 		rw_exit(&zv->zv_suspend_lock); | ||||||
| 
 | 
 | ||||||
| 	if (error == 0) | 	if (error == 0) | ||||||
|  | #ifdef HAVE_BLK_MODE_T | ||||||
|  | 		disk_check_media_change(disk); | ||||||
|  | #else | ||||||
| 		zfs_check_media_change(bdev); | 		zfs_check_media_change(bdev); | ||||||
|  | #endif | ||||||
| 
 | 
 | ||||||
| 	return (error); | 	return (error); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void | static void | ||||||
| zvol_release(struct gendisk *disk, fmode_t mode) | #ifdef HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG | ||||||
|  | zvol_release(struct gendisk *disk) | ||||||
|  | #else | ||||||
|  | zvol_release(struct gendisk *disk, fmode_t unused) | ||||||
|  | #endif | ||||||
| { | { | ||||||
|  | #if !defined(HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG) | ||||||
|  | 	(void) unused; | ||||||
|  | #endif | ||||||
| 	zvol_state_t *zv; | 	zvol_state_t *zv; | ||||||
| 	boolean_t drop_suspend = B_TRUE; | 	boolean_t drop_suspend = B_TRUE; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Coleman Kane
						Coleman Kane