diff --git a/include/sys/zfs_vfsops.h b/include/sys/zfs_vfsops.h index c4db2a911d3e..f480ce687e44 100644 --- a/include/sys/zfs_vfsops.h +++ b/include/sys/zfs_vfsops.h @@ -93,6 +93,7 @@ typedef struct zfs_sb { sa_attr_type_t *z_attr_table; /* SA attr mapping->id */ #define ZFS_OBJ_MTX_SZ 256 kmutex_t *z_hold_mtx; /* znode hold locks */ + fstrans_cookie_t *z_hold_cookie; /* znode hold cookie */ } zfs_sb_t; #define ZFS_SUPER_MAGIC 0x2fc12fc1 diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index 4bb8a77617f9..3002d9347c0e 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -279,11 +279,16 @@ typedef struct znode { #define ZFS_OBJ_HASH(obj_num) ((obj_num) & (ZFS_OBJ_MTX_SZ - 1)) #define ZFS_OBJ_MUTEX(zsb, obj_num) \ (&(zsb)->z_hold_mtx[ZFS_OBJ_HASH(obj_num)]) +#define ZFS_OBJ_COOKIE(zsb, obj_num) \ + (&(zsb)->z_hold_cookie[ZFS_OBJ_HASH(obj_num)]) #define ZFS_OBJ_HOLD_ENTER(zsb, obj_num) \ - mutex_enter(ZFS_OBJ_MUTEX((zsb), (obj_num))) + mutex_enter(ZFS_OBJ_MUTEX((zsb), (obj_num))) \ + (ZFS_OBJ_COOKIE(zsb, (obj_num))) = spl_fstrans_mark(); + #define ZFS_OBJ_HOLD_TRYENTER(zsb, obj_num) \ mutex_tryenter(ZFS_OBJ_MUTEX((zsb), (obj_num))) #define ZFS_OBJ_HOLD_EXIT(zsb, obj_num) \ + spl_fstrans_unmark(ZFS_OBJ_COOKIE(zsb, (obj_num))); \ mutex_exit(ZFS_OBJ_MUTEX((zsb), (obj_num))) #define ZFS_OBJ_HOLD_OWNED(zsb, obj_num) \ mutex_owned(ZFS_OBJ_MUTEX((zsb), (obj_num))) diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c index 41a1c4d8849d..64c3ea926079 100644 --- a/module/zfs/zfs_vfsops.c +++ b/module/zfs/zfs_vfsops.c @@ -779,6 +779,8 @@ zfs_sb_create(const char *osname, zfs_sb_t **zsbp) zsb->z_hold_mtx = vmem_zalloc(sizeof (kmutex_t) * ZFS_OBJ_MTX_SZ, KM_SLEEP); + zsb->z_hold_cookie = vmem_zalloc(sizeof (fstrans_cookie_t) * + ZFS_OBJ_MTX_SZ, KM_SLEEP); for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) mutex_init(&zsb->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL); @@ -898,6 +900,8 @@ zfs_sb_free(zfs_sb_t *zsb) for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) mutex_destroy(&zsb->z_hold_mtx[i]); vmem_free(zsb->z_hold_mtx, sizeof (kmutex_t) * ZFS_OBJ_MTX_SZ); + vmem_free(zsb->z_hold_cookie, sizeof (fstrans_cookie_t) * + ZFS_OBJ_MTX_SZ); mutex_destroy(&zsb->z_ctldir_lock); avl_destroy(&zsb->z_ctldir_snaps); kmem_free(zsb, sizeof (zfs_sb_t));