From: Matthew Dillon Date: Thu, 25 Sep 2008 01:42:52 +0000 (+0000) Subject: HAMMER: MFC all changes through 20080924 X-Git-Url: https://gitweb.dragonflybsd.org/~mneumann/dragonfly.git/commitdiff_plain/bcac89658e95179eeb3f528424b94ff143505453 HAMMER: MFC all changes through 20080924 * Flush performance adjustments. * Unlink performance adjustments (remove double flush). * Improved reclaim performance. * Snapshots[] path configuration support in PFS data. * Add disk cache flush support. * NFS support. --- diff --git a/sys/vfs/hammer/hammer.h b/sys/vfs/hammer/hammer.h index 4b18b6359a..c300c32499 100644 --- a/sys/vfs/hammer/hammer.h +++ b/sys/vfs/hammer/hammer.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer.h,v 1.117.2.6 2008/08/02 21:24:27 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer.h,v 1.117.2.7 2008/09/25 01:42:52 dillon Exp $ */ /* * This header file contains structures used internally by the HAMMERFS @@ -110,11 +110,14 @@ struct hammer_transaction { u_int64_t time; u_int32_t time32; int sync_lock_refs; + int flags; struct hammer_volume *rootvol; }; typedef struct hammer_transaction *hammer_transaction_t; +#define HAMMER_TRANSF_NEWINODE 0x0001 + /* * HAMMER locks */ @@ -484,6 +487,7 @@ struct hammer_io { struct hammer_lock lock; enum hammer_io_type type; struct hammer_mount *hmp; + struct hammer_volume *volume; TAILQ_ENTRY(hammer_io) mod_entry; /* list entry if modified */ hammer_io_list_t mod_list; struct buf *bp; @@ -541,7 +545,6 @@ struct hammer_buffer { struct hammer_io io; RB_ENTRY(hammer_buffer) rb_node; void *ondisk; - struct hammer_volume *volume; hammer_off_t zoneX_offset; hammer_off_t zone2_offset; struct hammer_reserve *resv; @@ -821,6 +824,7 @@ extern int hammer_bio_count; extern int hammer_verify_zone; extern int hammer_verify_data; extern int hammer_write_mode; +extern int hammer_autoflush; extern int64_t hammer_contention_count; void hammer_critical_error(hammer_mount_t hmp, hammer_inode_t ip, @@ -1099,7 +1103,7 @@ void hammer_rel_pseudofs(hammer_mount_t hmp, hammer_pseudofs_inmem_t pfsm); int hammer_ioctl(hammer_inode_t ip, u_long com, caddr_t data, int fflag, struct ucred *cred); -void hammer_io_init(hammer_io_t io, hammer_mount_t hmp, +void hammer_io_init(hammer_io_t io, hammer_volume_t volume, enum hammer_io_type type); int hammer_io_read(struct vnode *devvp, struct hammer_io *io, hammer_off_t limit); @@ -1120,6 +1124,8 @@ void hammer_io_write_interlock(hammer_io_t io); void hammer_io_done_interlock(hammer_io_t io); void hammer_io_clear_modify(struct hammer_io *io, int inval); void hammer_io_clear_modlist(struct hammer_io *io); +void hammer_io_flush_sync(hammer_mount_t hmp); + void hammer_modify_volume(hammer_transaction_t trans, hammer_volume_t volume, void *base, int len); void hammer_modify_buffer(hammer_transaction_t trans, hammer_buffer_t buffer, diff --git a/sys/vfs/hammer/hammer_disk.h b/sys/vfs/hammer/hammer_disk.h index 9a5e4f5270..6d0ee7e4ea 100644 --- a/sys/vfs/hammer/hammer_disk.h +++ b/sys/vfs/hammer/hammer_disk.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_disk.h,v 1.50.2.2 2008/08/02 21:24:28 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_disk.h,v 1.50.2.3 2008/09/25 01:42:52 dillon Exp $ */ #ifndef VFS_HAMMER_DISK_H_ @@ -518,6 +518,7 @@ typedef struct hammer_volume_ondisk *hammer_volume_ondisk_t; #define HAMMER_VOLF_VALID 0x0001 /* valid entry */ #define HAMMER_VOLF_OPEN 0x0002 /* volume is open */ +#define HAMMER_VOLF_NEEDFLUSH 0x0004 /* volume needs flush */ #define HAMMER_VOL_CRCSIZE1 \ offsetof(struct hammer_volume_ondisk, vol_crc) @@ -684,7 +685,7 @@ struct hammer_pseudofs_data { int32_t reserved01; /* reserved for future master_id */ int32_t mirror_flags; /* misc flags */ char label[64]; /* filesystem space label */ - char prune_path[64]; /* softlink dir for pruning */ + char snapshots[64]; /* softlink dir for pruning */ int16_t prune_time; /* how long to spend pruning */ int16_t prune_freq; /* how often we prune */ int16_t reblock_time; /* how long to spend reblocking */ diff --git a/sys/vfs/hammer/hammer_inode.c b/sys/vfs/hammer/hammer_inode.c index cbded3a4f1..e0657d217d 100644 --- a/sys/vfs/hammer/hammer_inode.c +++ b/sys/vfs/hammer/hammer_inode.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_inode.c,v 1.103.2.5 2008/08/10 17:01:08 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_inode.c,v 1.103.2.6 2008/09/25 01:42:52 dillon Exp $ */ #include "hammer.h" @@ -220,15 +220,6 @@ hammer_vop_reclaim(struct vop_reclaim_args *ap) ++hammer_count_reclaiming; ++hmp->inode_reclaims; ip->flags |= HAMMER_INODE_RECLAIM; - - /* - * Poke the flusher. If we don't do this programs - * will start to stall on the reclaiming count. - */ - if (hmp->inode_reclaims > HAMMER_RECLAIM_FLUSH && - (hmp->inode_reclaims & 255) == 0) { - hammer_flusher_async(hmp, NULL); - } } hammer_rel_inode(ip, 1); } @@ -293,12 +284,16 @@ hammer_get_vnode(struct hammer_inode *ip, struct vnode **vpp) * confused. The other half of the special handling * is in hammer_vop_nlookupdotdot(). * - * Pseudo-filesystem roots also do not count. + * Pseudo-filesystem roots can be accessed via + * non-root filesystem paths and setting VROOT may + * confuse the namecache. Set VPFSROOT instead. */ if (ip->obj_id == HAMMER_OBJID_ROOT && - ip->obj_asof == hmp->asof && - ip->obj_localization == 0) { - vp->v_flag |= VROOT; + ip->obj_asof == hmp->asof) { + if (ip->obj_localization == 0) + vp->v_flag |= VROOT; + else + vp->v_flag |= VPFSROOT; } vp->v_data = (void *)ip; @@ -489,6 +484,7 @@ retry: ip = NULL; } hammer_done_cursor(&cursor); + trans->flags |= HAMMER_TRANSF_NEWINODE; return (ip); } @@ -1163,7 +1159,7 @@ retry: void hammer_rel_inode(struct hammer_inode *ip, int flush) { - hammer_mount_t hmp = ip->hmp; + /*hammer_mount_t hmp = ip->hmp;*/ /* * Handle disposition when dropping the last ref. @@ -1177,12 +1173,7 @@ hammer_rel_inode(struct hammer_inode *ip, int flush) KKASSERT(ip->vp == NULL); hammer_inode_unloadable_check(ip, 0); if (ip->flags & HAMMER_INODE_MODMASK) { - if (hmp->rsv_inodes > desiredvnodes) { - hammer_flush_inode(ip, - HAMMER_FLUSH_SIGNAL); - } else { - hammer_flush_inode(ip, 0); - } + hammer_flush_inode(ip, 0); } else if (ip->lock.refs == 1) { hammer_unload_inode(ip); break; @@ -1661,6 +1652,13 @@ hammer_flush_inode_core(hammer_inode_t ip, hammer_flush_group_t flg, int flags) ++hammer_count_iqueued; ++flg->total_count; + /* + * If the flush group reaches the autoflush limit we want to signal + * the flusher. This is particularly important for remove()s. + */ + if (flg->total_count == hammer_autoflush) + flags |= HAMMER_FLUSH_SIGNAL; + /* * We need to be able to vfsync/truncate from the backend. */ @@ -2059,9 +2057,17 @@ hammer_flush_inode_done(hammer_inode_t ip, int error) /* * Do not lose track of inodes which no longer have vnode * assocations, otherwise they may never get flushed again. + * + * The reflush flag can be set superfluously, causing extra pain + * for no reason. If the inode is no longer modified it no longer + * needs to be flushed. */ - if ((ip->flags & HAMMER_INODE_MODMASK) && ip->vp == NULL) - ip->flags |= HAMMER_INODE_REFLUSH; + if (ip->flags & HAMMER_INODE_MODMASK) { + if (ip->vp == NULL) + ip->flags |= HAMMER_INODE_REFLUSH; + } else { + ip->flags &= ~HAMMER_INODE_REFLUSH; + } /* * Adjust the flush state. @@ -2641,9 +2647,14 @@ hammer_inode_unloadable_check(hammer_inode_t ip, int getvp) * The backend will clear DELETING (a mod flag) and set DELETED * (a state flag) when it is actually able to perform the * operation. + * + * Don't reflag the deletion if the flusher is currently syncing + * one that was already flagged. A previously set DELETING flag + * may bounce around flags and sync_flags until the operation is + * completely done. */ if (ip->ino_data.nlinks == 0 && - (ip->flags & (HAMMER_INODE_DELETING|HAMMER_INODE_DELETED)) == 0) { + ((ip->flags | ip->sync_flags) & (HAMMER_INODE_DELETING|HAMMER_INODE_DELETED)) == 0) { ip->flags |= HAMMER_INODE_DELETING; ip->flags |= HAMMER_INODE_TRUNCATED; ip->trunc_off = 0; @@ -2738,7 +2749,7 @@ hammer_inode_waitreclaims(hammer_mount_t hmp) if (reclaim.okydoky == 0) { delay = (hmp->inode_reclaims - HAMMER_RECLAIM_WAIT) * hz / - HAMMER_RECLAIM_WAIT; + (HAMMER_RECLAIM_WAIT * 5); if (delay >= 0) tsleep(&reclaim, 0, "hmrrcm", delay + 1); if (reclaim.okydoky == 0) diff --git a/sys/vfs/hammer/hammer_io.c b/sys/vfs/hammer/hammer_io.c index 2f71c5bf54..c49809b4c8 100644 --- a/sys/vfs/hammer/hammer_io.c +++ b/sys/vfs/hammer/hammer_io.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_io.c,v 1.49.2.5 2008/09/15 17:10:03 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_io.c,v 1.49.2.6 2008/09/25 01:42:52 dillon Exp $ */ /* * IO Primitives and buffer cache management @@ -60,15 +60,19 @@ static void hammer_io_direct_read_complete(struct bio *nbio); static void hammer_io_direct_write_complete(struct bio *nbio); static int hammer_io_direct_uncache_callback(hammer_inode_t ip, void *data); static void hammer_io_set_modlist(struct hammer_io *io); +static void hammer_io_flush_mark(hammer_volume_t volume); +static void hammer_io_flush_sync_done(struct bio *bio); + /* * Initialize a new, already-zero'd hammer_io structure, or reinitialize * an existing hammer_io structure which may have switched to another type. */ void -hammer_io_init(hammer_io_t io, hammer_mount_t hmp, enum hammer_io_type type) +hammer_io_init(hammer_io_t io, hammer_volume_t volume, enum hammer_io_type type) { - io->hmp = hmp; + io->volume = volume; + io->hmp = volume->io.hmp; io->type = type; } @@ -150,6 +154,7 @@ hammer_io_wait(hammer_io_t io) void hammer_io_wait_all(hammer_mount_t hmp, const char *ident) { + hammer_io_flush_sync(hmp); crit_enter(); while (hmp->io_running_space) tsleep(&hmp->io_running_space, 0, ident, 0); @@ -509,6 +514,7 @@ hammer_io_flush(struct hammer_io *io) io->hmp->io_running_space += io->bytes; hammer_count_io_running_write += io->bytes; bawrite(bp); + hammer_io_flush_mark(io->volume); } /************************************************************************ @@ -1203,6 +1209,7 @@ hammer_io_direct_write(hammer_mount_t hmp, hammer_record_t record, zone2_offset; hammer_stats_disk_write += bp->b_bufsize; vn_strategy(volume->devvp, nbio); + hammer_io_flush_mark(volume); } hammer_rel_volume(volume, 0); } else { @@ -1392,3 +1399,66 @@ hammer_io_direct_uncache_callback(hammer_inode_t ip, void *data) return(0); } + +/* + * This function is called when writes may have occured on the volume, + * indicating that the device may be holding cached writes. + */ +static void +hammer_io_flush_mark(hammer_volume_t volume) +{ + volume->vol_flags |= HAMMER_VOLF_NEEDFLUSH; +} + +/* + * This function ensures that the device has flushed any cached writes out. + */ +void +hammer_io_flush_sync(hammer_mount_t hmp) +{ + hammer_volume_t volume; + struct buf *bp_base = NULL; + struct buf *bp; + + RB_FOREACH(volume, hammer_vol_rb_tree, &hmp->rb_vols_root) { + if (volume->vol_flags & HAMMER_VOLF_NEEDFLUSH) { + volume->vol_flags &= ~HAMMER_VOLF_NEEDFLUSH; + bp = getpbuf(NULL); + bp->b_bio1.bio_offset = 0; + bp->b_bufsize = 0; + bp->b_bcount = 0; + bp->b_cmd = BUF_CMD_FLUSH; + bp->b_bio1.bio_caller_info1.cluster_head = bp_base; + bp->b_bio1.bio_done = hammer_io_flush_sync_done; + bp->b_flags |= B_ASYNC; + bp_base = bp; + vn_strategy(volume->devvp, &bp->b_bio1); + } + } + while ((bp = bp_base) != NULL) { + bp_base = bp->b_bio1.bio_caller_info1.cluster_head; + while (bp->b_cmd != BUF_CMD_DONE) { + crit_enter(); + tsleep_interlock(&bp->b_cmd); + if (bp->b_cmd != BUF_CMD_DONE) + tsleep(&bp->b_cmd, 0, "hmrFLS", 0); + crit_exit(); + } + bp->b_flags &= ~B_ASYNC; + relpbuf(bp, NULL); + } +} + +/* + * Callback to deal with completed flush commands to the device. + */ +static void +hammer_io_flush_sync_done(struct bio *bio) +{ + struct buf *bp; + + bp = bio->bio_buf; + bp->b_cmd = BUF_CMD_DONE; + wakeup(&bp->b_cmd); +} + diff --git a/sys/vfs/hammer/hammer_mount.h b/sys/vfs/hammer/hammer_mount.h index 1d03143303..7d7fefedef 100644 --- a/sys/vfs/hammer/hammer_mount.h +++ b/sys/vfs/hammer/hammer_mount.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_mount.h,v 1.9.2.2 2008/08/02 21:24:28 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_mount.h,v 1.9.2.3 2008/09/25 01:42:52 dillon Exp $ */ #ifndef _SYS_TYPES_H_ @@ -51,8 +51,8 @@ struct hammer_mount_info { int hflags; /* extended hammer mount flags */ int master_id; /* -1=no-mirror mode, or 0-15 */ u_int64_t asof; /* asof - HAMMER_MAX_TID is current */ - struct export_args export; /* export arguments */ - u_int64_t reserved[15]; + char reserved1[136]; /* was struct export_args */ + u_int64_t reserved2[15]; }; #define HMNT_NOHISTORY 0x00000001 diff --git a/sys/vfs/hammer/hammer_object.c b/sys/vfs/hammer/hammer_object.c index e84592a660..a686d7feb3 100644 --- a/sys/vfs/hammer/hammer_object.c +++ b/sys/vfs/hammer/hammer_object.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_object.c,v 1.90.2.5 2008/08/10 17:01:08 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_object.c,v 1.90.2.6 2008/09/25 01:42:52 dillon Exp $ */ #include "hammer.h" @@ -778,6 +778,8 @@ hammer_ip_del_directory(struct hammer_transaction *trans, */ if (error == 0) { --ip->ino_data.nlinks; + dip->ino_data.mtime = trans->time; + hammer_modify_inode(dip, HAMMER_INODE_MTIME); hammer_modify_inode(ip, HAMMER_INODE_DDIRTY); if (ip->ino_data.nlinks == 0 && (ip->vp == NULL || (ip->vp->v_flag & VINACTIVE))) { @@ -785,8 +787,6 @@ hammer_ip_del_directory(struct hammer_transaction *trans, hammer_inode_unloadable_check(ip, 1); hammer_flush_inode(ip, 0); } - dip->ino_data.mtime = trans->time; - hammer_modify_inode(dip, HAMMER_INODE_MTIME); } return(error); diff --git a/sys/vfs/hammer/hammer_ondisk.c b/sys/vfs/hammer/hammer_ondisk.c index 021cddf52f..a6364a2648 100644 --- a/sys/vfs/hammer/hammer_ondisk.c +++ b/sys/vfs/hammer/hammer_ondisk.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_ondisk.c,v 1.69.2.5 2008/08/06 15:41:56 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_ondisk.c,v 1.69.2.6 2008/09/25 01:42:52 dillon Exp $ */ /* * Manage HAMMER's on-disk structures. These routines are primarily @@ -119,7 +119,8 @@ hammer_install_volume(struct hammer_mount *hmp, const char *volname, ++hammer_count_volumes; volume = kmalloc(sizeof(*volume), M_HAMMER, M_WAITOK|M_ZERO); volume->vol_name = kstrdup(volname, M_HAMMER); - hammer_io_init(&volume->io, hmp, HAMMER_STRUCTURE_VOLUME); + volume->io.hmp = hmp; /* bootstrap */ + hammer_io_init(&volume->io, volume, HAMMER_STRUCTURE_VOLUME); volume->io.offset = 0LL; volume->io.bytes = HAMMER_BUFSIZE; @@ -614,9 +615,8 @@ again: M_WAITOK|M_ZERO|M_USE_RESERVE); buffer->zone2_offset = zone2_offset; buffer->zoneX_offset = buf_offset; - buffer->volume = volume; - hammer_io_init(&buffer->io, hmp, iotype); + hammer_io_init(&buffer->io, volume, iotype); buffer->io.offset = volume->ondisk->vol_buf_beg + (zone2_offset & HAMMER_OFF_SHORT_MASK); buffer->io.bytes = bytes; @@ -723,7 +723,7 @@ hammer_del_buffers(hammer_mount_t hmp, hammer_off_t base_offset, hammer_io_clear_modify(&buffer->io, 1); buffer->io.reclaim = 1; buffer->io.waitdep = 1; - KKASSERT(buffer->volume == volume); + KKASSERT(buffer->io.volume == volume); hammer_rel_buffer(buffer, 0); } } else { @@ -745,7 +745,7 @@ hammer_load_buffer(hammer_buffer_t buffer, int isnew) /* * Load the buffer's on-disk info */ - volume = buffer->volume; + volume = buffer->io.volume; ++buffer->io.loading; hammer_lock_ex(&buffer->io.lock); @@ -885,8 +885,8 @@ hammer_rel_buffer(hammer_buffer_t buffer, int flush) RB_REMOVE(hammer_buf_rb_tree, &buffer->io.hmp->rb_bufs_root, buffer); - volume = buffer->volume; - buffer->volume = NULL; /* sanity */ + volume = buffer->io.volume; + buffer->io.volume = NULL; /* sanity */ hammer_rel_volume(volume, 0); hammer_io_clear_modlist(&buffer->io); hammer_flush_buffer_nodes(buffer); diff --git a/sys/vfs/hammer/hammer_prune.c b/sys/vfs/hammer/hammer_prune.c index ec56d5d920..a43d00c1de 100644 --- a/sys/vfs/hammer/hammer_prune.c +++ b/sys/vfs/hammer/hammer_prune.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_prune.c,v 1.18.2.1 2008/08/02 21:24:28 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_prune.c,v 1.18.2.2 2008/09/25 01:42:52 dillon Exp $ */ #include "hammer.h" @@ -319,6 +319,7 @@ prune_check_nlinks(hammer_cursor_t cursor, hammer_btree_leaf_elm_t elm) elm->base.obj_id); } hammer_rel_inode(ip, 0); + hammer_inode_waitreclaims(cursor->trans->hmp); } else { kprintf("unable to prune disconnected inode %016llx\n", elm->base.obj_id); diff --git a/sys/vfs/hammer/hammer_transaction.c b/sys/vfs/hammer/hammer_transaction.c index 5c722af2be..5f994f6f65 100644 --- a/sys/vfs/hammer/hammer_transaction.c +++ b/sys/vfs/hammer/hammer_transaction.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_transaction.c,v 1.22.2.3 2008/08/02 21:24:28 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_transaction.c,v 1.22.2.4 2008/09/25 01:42:52 dillon Exp $ */ #include "hammer.h" @@ -55,6 +55,7 @@ hammer_start_transaction(struct hammer_transaction *trans, KKASSERT(error == 0); trans->tid = 0; trans->sync_lock_refs = 0; + trans->flags = 0; getmicrotime(&tv); trans->time = (unsigned long)tv.tv_sec * 1000000ULL + tv.tv_usec; @@ -77,6 +78,7 @@ hammer_simple_transaction(struct hammer_transaction *trans, KKASSERT(error == 0); trans->tid = 0; trans->sync_lock_refs = 0; + trans->flags = 0; getmicrotime(&tv); trans->time = (unsigned long)tv.tv_sec * 1000000ULL + tv.tv_usec; @@ -106,6 +108,7 @@ hammer_start_transaction_fls(struct hammer_transaction *trans, KKASSERT(error == 0); trans->tid = hammer_alloc_tid(hmp, 1); trans->sync_lock_refs = 1; + trans->flags = 0; getmicrotime(&tv); trans->time = (unsigned long)tv.tv_sec * 1000000ULL + tv.tv_usec; @@ -122,6 +125,8 @@ hammer_done_transaction(struct hammer_transaction *trans) expected_lock_refs = (trans->type == HAMMER_TRANS_FLS) ? 1 : 0; KKASSERT(trans->sync_lock_refs == expected_lock_refs); trans->sync_lock_refs = 0; + if (trans->flags & HAMMER_TRANSF_NEWINODE) + hammer_inode_waitreclaims(trans->hmp); } /* diff --git a/sys/vfs/hammer/hammer_vfsops.c b/sys/vfs/hammer/hammer_vfsops.c index 406e4b0785..463b5392aa 100644 --- a/sys/vfs/hammer/hammer_vfsops.c +++ b/sys/vfs/hammer/hammer_vfsops.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_vfsops.c,v 1.63.2.6 2008/08/02 21:24:28 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_vfsops.c,v 1.63.2.7 2008/09/25 01:42:52 dillon Exp $ */ #include @@ -94,6 +94,7 @@ int hammer_count_io_locked; int hammer_limit_dirtybufspace; /* per-mount */ int hammer_limit_recs; /* as a whole XXX */ int hammer_limit_iqueued; /* per-mount */ +int hammer_autoflush = 2000; /* auto flush */ int hammer_bio_count; int hammer_verify_zone; int hammer_verify_data = 1; @@ -201,6 +202,8 @@ SYSCTL_QUAD(_vfs_hammer, OID_AUTO, zone_limit, CTLFLAG_RW, &hammer_zone_limit, 0, ""); SYSCTL_QUAD(_vfs_hammer, OID_AUTO, contention_count, CTLFLAG_RW, &hammer_contention_count, 0, ""); +SYSCTL_INT(_vfs_hammer, OID_AUTO, autoflush, CTLFLAG_RW, + &hammer_autoflush, 0, ""); SYSCTL_INT(_vfs_hammer, OID_AUTO, verify_zone, CTLFLAG_RW, &hammer_verify_zone, 0, ""); SYSCTL_INT(_vfs_hammer, OID_AUTO, verify_data, CTLFLAG_RW, @@ -227,8 +230,8 @@ static int hammer_vfs_sync(struct mount *mp, int waitfor); static int hammer_vfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp); static int hammer_vfs_init(struct vfsconf *conf); -static int hammer_vfs_fhtovp(struct mount *mp, struct fid *fhp, - struct vnode **vpp); +static int hammer_vfs_fhtovp(struct mount *mp, struct vnode *rootvp, + struct fid *fhp, struct vnode **vpp); static int hammer_vfs_vptofh(struct vnode *vp, struct fid *fhp); static int hammer_vfs_checkexp(struct mount *mp, struct sockaddr *nam, int *exflagsp, struct ucred **credanonp); @@ -900,9 +903,13 @@ hammer_vfs_vptofh(struct vnode *vp, struct fid *fhp) /* * Convert a file handle back to a vnode. + * + * Use rootvp to enforce PFS isolation when a PFS is exported via a + * null mount. */ static int -hammer_vfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) +hammer_vfs_fhtovp(struct mount *mp, struct vnode *rootvp, + struct fid *fhp, struct vnode **vpp) { struct hammer_transaction trans; struct hammer_inode *ip; @@ -912,7 +919,10 @@ hammer_vfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) bcopy(fhp->fid_data + 0, &info.obj_id, sizeof(info.obj_id)); bcopy(fhp->fid_data + 8, &info.obj_asof, sizeof(info.obj_asof)); - localization = (u_int32_t)fhp->fid_ext << 16; + if (rootvp) + localization = VTOI(rootvp)->obj_localization; + else + localization = (u_int32_t)fhp->fid_ext << 16; hammer_simple_transaction(&trans, (void *)mp->mnt_data); diff --git a/sys/vfs/hammer/hammer_vnops.c b/sys/vfs/hammer/hammer_vnops.c index 2ff9f11be5..5beecb0a40 100644 --- a/sys/vfs/hammer/hammer_vnops.c +++ b/sys/vfs/hammer/hammer_vnops.c @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/vfs/hammer/hammer_vnops.c,v 1.91.2.5 2008/08/10 17:01:09 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_vnops.c,v 1.91.2.6 2008/09/25 01:42:52 dillon Exp $ */ #include @@ -186,8 +186,11 @@ hammer_vop_fsync(struct vop_fsync_args *ap) ++hammer_count_fsyncs; vfsync(ap->a_vp, ap->a_waitfor, 1, NULL, NULL); hammer_flush_inode(ip, HAMMER_FLUSH_SIGNAL); - if (ap->a_waitfor == MNT_WAIT) + if (ap->a_waitfor == MNT_WAIT) { + vn_unlock(ap->a_vp); hammer_wait_inode(ip); + vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY); + } return (ip->error); } @@ -565,10 +568,7 @@ static int hammer_vop_close(struct vop_close_args *ap) { - hammer_inode_t ip = VTOI(ap->a_vp); - - if ((ip->flags | ip->sync_flags) & HAMMER_INODE_MODMASK) - hammer_inode_waitreclaims(ip->hmp); + /*hammer_inode_t ip = VTOI(ap->a_vp);*/ return (vop_stdclose(ap)); } @@ -2027,7 +2027,8 @@ hammer_vop_mountctl(struct vop_mountctl_args *ap) case MOUNTCTL_SET_EXPORT: if (ap->a_ctllen != sizeof(struct export_args)) error = EINVAL; - error = hammer_vfs_export(mp, ap->a_op, + else + error = hammer_vfs_export(mp, ap->a_op, (const struct export_args *)ap->a_ctl); break; default: @@ -2577,8 +2578,13 @@ hammer_vop_strategy_write(struct vop_strategy_args *ap) * topology visibility). If we queue new IO while trying to * destroy the inode we can deadlock the vtrunc call in * hammer_inode_unloadable_check(). + * + * Besides, there's no point flushing a bp associated with an + * inode that is being destroyed on-media and has no kernel + * references. */ - if (ip->flags & (HAMMER_INODE_DELETING|HAMMER_INODE_DELETED)) { + if ((ip->flags | ip->sync_flags) & + (HAMMER_INODE_DELETING|HAMMER_INODE_DELETED)) { bp->b_resid = 0; biodone(ap->a_bio); return(0); @@ -2764,7 +2770,6 @@ retry: } else { hammer_done_cursor(&cursor); } - hammer_inode_waitreclaims(dip->hmp); if (error == EDEADLK) goto retry;