diff -r 3bb9678e7c6c -r b6e87f0e9632 src/sys/amd64/conf/MASSHOSTING_7_64 --- a/src/sys/amd64/conf/MASSHOSTING_7_64 Tue Jan 22 15:17:45 2008 +0300 +++ b/src/sys/amd64/conf/MASSHOSTING_7_64 Thu Feb 21 13:18:37 2008 +0300 @@ -42,6 +42,7 @@ options ADAPTIVE_GIANT # Giant mutex i options ADAPTIVE_GIANT # Giant mutex is adaptive. options STOP_NMI # Stop CPUS using NMI instead of IPI options AUDIT # Security event auditing +options SUIDDIR options MAC diff -r 3bb9678e7c6c -r b6e87f0e9632 src/sys/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h --- a/src/sys/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h Tue Jan 22 15:17:45 2008 +0300 +++ b/src/sys/contrib/opensolaris/uts/common/fs/zfs/sys/zil.h Thu Feb 21 13:18:37 2008 +0300 @@ -222,10 +222,12 @@ typedef struct itx { * zgd_t is passed through dmu_sync() to the callback routine zfs_get_done() * to handle the cleanup of the dmu_sync() buffer write */ -typedef struct { +typedef struct zgd { zilog_t *zgd_zilog; /* zilog */ blkptr_t *zgd_bp; /* block pointer */ struct rl *zgd_rl; /* range lock */ + vnode_t *zgd_vnode; + TAILQ_ENTRY(zgd) zgd_next; } zgd_t; @@ -267,6 +269,9 @@ extern void zil_resume(zilog_t *zilog); extern void zil_add_vdev(zilog_t *zilog, uint64_t vdev); +extern void zgd_done_init(void); +extern void zgd_done_fini(void); + extern int zil_disable; #ifdef __cplusplus diff -r 3bb9678e7c6c -r b6e87f0e9632 src/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c --- a/src/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Tue Jan 22 15:17:45 2008 +0300 +++ b/src/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c Thu Feb 21 13:18:37 2008 +0300 @@ -1025,6 +1025,8 @@ zfs_init(void) printf("ZFS filesystem version " ZFS_VERSION_STRING "\n"); + zgd_done_init(); + /* * Initialize .zfs directory structures */ @@ -1049,6 +1051,7 @@ zfs_fini(void) zfsctl_fini(); zfs_znode_fini(); zfs_vnodes_adjust_back(); + zgd_done_fini(); } int diff -r 3bb9678e7c6c -r b6e87f0e9632 src/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c --- a/src/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Tue Jan 22 15:17:45 2008 +0300 +++ b/src/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c Thu Feb 21 13:18:37 2008 +0300 @@ -856,21 +856,79 @@ zfs_write(vnode_t *vp, uio_t *uio, int i return (0); } +static TAILQ_HEAD(, zgd) zgd_done = TAILQ_HEAD_INITIALIZER(zgd_done); +static struct mtx zgd_done_mtx; +static int zgd_done_exit = 0; +MTX_SYSINIT(zgd_done, &zgd_done_mtx, "zgd", MTX_DEF); +static int zfs_done_count = 0; +SYSCTL_DECL(_vfs_zfs); +SYSCTL_INT(_vfs_zfs, OID_AUTO, zgd_done_count, CTLFLAG_RW, &zfs_done_count, 0, ""); + +static void +zgd_done_worker(void *arg) +{ + zgd_t *zgd; + vnode_t *vp; + int vfslocked; + + for (;;) { + mtx_lock(&zgd_done_mtx); + zgd = TAILQ_FIRST(&zgd_done); + if (zgd == NULL) { + if (zgd_done_exit) { + zgd_done_exit = 2; + mtx_unlock(&zgd_done_mtx); + wakeup(&zgd_done_exit); + kproc_exit(0); + } + msleep(&zgd_done, &zgd_done_mtx, PRIBIO | PDROP, "zgd", 0); + continue; + } + TAILQ_REMOVE(&zgd_done, zgd, zgd_next); + zfs_done_count++; + mtx_unlock(&zgd_done_mtx); + vp = zgd->zgd_vnode; + vfslocked = VFS_LOCK_GIANT(vp->v_vfsp); + VN_RELE(vp); + VFS_UNLOCK_GIANT(vfslocked); + kmem_free(zgd, sizeof (zgd_t)); + } +} + +void +zgd_done_init(void) +{ + + kproc_create(zgd_done_worker, NULL, NULL, 0, 0, "zgd_done"); +} + +void +zgd_done_fini(void) +{ + + mtx_lock(&zgd_done_mtx); + zgd_done_exit = 1; + wakeup(&zgd_done); + while (zgd_done_exit != 2) + msleep(&zgd_done_exit, &zgd_done_mtx, PRIBIO, "zgd_fini", 0); + mtx_unlock(&zgd_done_mtx); +} + void zfs_get_done(dmu_buf_t *db, void *vzgd) { zgd_t *zgd = (zgd_t *)vzgd; rl_t *rl = zgd->zgd_rl; vnode_t *vp = ZTOV(rl->r_zp); - int vfslocked; - vfslocked = VFS_LOCK_GIANT(vp->v_vfsp); dmu_buf_rele(db, vzgd); zfs_range_unlock(rl); - VN_RELE(vp); + zgd->zgd_vnode = vp; zil_add_vdev(zgd->zgd_zilog, DVA_GET_VDEV(BP_IDENTITY(zgd->zgd_bp))); - kmem_free(zgd, sizeof (zgd_t)); - VFS_UNLOCK_GIANT(vfslocked); + mtx_lock(&zgd_done_mtx); + TAILQ_INSERT_TAIL(&zgd_done, zgd, zgd_next); + mtx_unlock(&zgd_done_mtx); + wakeup(&zgd_done); } /*