From 8e1df6c9dbbfc7916de949c26821663aef5f09c4 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sun, 27 Apr 2008 21:07:15 +0000 Subject: [PATCH] HAMMER 38F/Many: Undo/Synchronization and crash recovery, stabilization pass * Fix a bug in the front-end's cached truncation off (ip->trunc_off). * Fix a bug in the memory record visibility check when called from the backend. --- sys/vfs/hammer/hammer_inode.c | 5 +++-- sys/vfs/hammer/hammer_object.c | 22 +++++++++++++++------- sys/vfs/hammer/hammer_vnops.c | 17 +++++++++++++---- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/sys/vfs/hammer/hammer_inode.c b/sys/vfs/hammer/hammer_inode.c index 0592df0fb..eeb44b46d 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.41 2008/04/27 00:45:37 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_inode.c,v 1.42 2008/04/27 21:07:15 dillon Exp $ */ #include "hammer.h" @@ -229,9 +229,9 @@ loop: ip->obj_asof = iinfo.obj_asof; ip->hmp = hmp; ip->flags = flags & HAMMER_INODE_RO; - ip->trunc_off = 0x7FFFFFFFFFFFFFFFLL; if (hmp->ronly) ip->flags |= HAMMER_INODE_RO; + ip->trunc_off = 0x7FFFFFFFFFFFFFFFLL; RB_INIT(&ip->rec_tree); TAILQ_INIT(&ip->bio_list); TAILQ_INIT(&ip->bio_alt_list); @@ -330,6 +330,7 @@ hammer_create_inode(hammer_transaction_t trans, struct vattr *vap, HAMMER_INODE_ITIMES; ip->flags |= HAMMER_INODE_NEW; + ip->trunc_off = 0x7FFFFFFFFFFFFFFFLL; RB_INIT(&ip->rec_tree); TAILQ_INIT(&ip->bio_list); TAILQ_INIT(&ip->bio_alt_list); diff --git a/sys/vfs/hammer/hammer_object.c b/sys/vfs/hammer/hammer_object.c index 8624df34b..08b352cb0 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.46 2008/04/27 00:45:37 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_object.c,v 1.47 2008/04/27 21:07:15 dillon Exp $ */ #include "hammer.h" @@ -204,7 +204,10 @@ hammer_flush_record_done(hammer_record_t record, int error) */ } else if (record->flags & HAMMER_RECF_CONVERT_DELETE_ONDISK) { /* - * + * deleted-record to delete-on-disk conversion, occurs when + * we sync a record to disk which is marked deleted by the + * frontend, but not deleted from the point of view of the + * backend. */ if (record->flags & HAMMER_RECF_DELETED_BE) { record->flags |= HAMMER_RECF_DELETED_FE; @@ -288,18 +291,23 @@ hammer_rel_mem_record(struct hammer_record *record) } /* - * The deletion state of a record will appear different to the backend - * then it does to the frontend. + * Record visibility depends on whether the record is being accessed by + * the backend or the frontend. + * + * Return non-zero if the record is visible, zero if it isn't or if it is + * deleted. */ static __inline int -hammer_ip_iterate_mem_good(hammer_cursor_t cursor, hammer_record_t rec) +hammer_ip_iterate_mem_good(hammer_cursor_t cursor, hammer_record_t record) { if (cursor->flags & HAMMER_CURSOR_BACKEND) { - if (rec->flags & HAMMER_RECF_INTERLOCK_BE) + if (record->flags & HAMMER_RECF_DELETED_BE) + return(0); + if ((record->flags & HAMMER_RECF_INTERLOCK_BE) == 0) return(0); } else { - if (rec->flags & HAMMER_RECF_DELETED_FE) + if (record->flags & HAMMER_RECF_DELETED_FE) return(0); } return(1); diff --git a/sys/vfs/hammer/hammer_vnops.c b/sys/vfs/hammer/hammer_vnops.c index 1b8ec892c..ad311a635 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.41 2008/04/27 00:45:37 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_vnops.c,v 1.42 2008/04/27 21:07:15 dillon Exp $ */ #include @@ -330,13 +330,18 @@ hammer_vop_write(struct vop_write_args *ap) } } else if (offset == 0 && uio->uio_resid >= HAMMER_BUFSIZE) { /* - * entirely overwrite the buffer + * Even though we are entirely overwriting the buffer + * we may still have to zero it out to avoid a + * mmap/write visibility issue. */ bp = getblk(ap->a_vp, uio->uio_offset - offset, HAMMER_BUFSIZE, GETBLK_BHEAVY, 0); - } else if (offset == 0 && uio->uio_offset >= ip->ino_rec.ino_size) { + if ((bp->b_flags & B_CACHE) == 0) + vfs_bio_clrbuf(bp); + } else if (uio->uio_offset - offset >= ip->ino_rec.ino_size) { /* - * XXX + * If the base offset of the buffer is beyond the + * file EOF, we don't have to issue a read. */ bp = getblk(ap->a_vp, uio->uio_offset - offset, HAMMER_BUFSIZE, GETBLK_BHEAVY, 0); @@ -1959,9 +1964,13 @@ hammer_dowrite(hammer_transaction_t trans, hammer_inode_t ip, struct bio *bio) KKASSERT(limit_size >= 0); limit_size = (limit_size + 63) & ~63; } + error = hammer_ip_sync_data(trans, ip, bio->bio_offset, bp->b_data, limit_size); + } + if (error) + Debugger("hammer_dowrite: error"); if (error) { bp->b_resid = bp->b_bufsize; -- 2.11.4.GIT