From 0a72edae664cad814539641857083615d76748e1 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Wed, 9 Jan 2008 04:05:37 +0000 Subject: [PATCH] HAMMER 16B/many: Fix data overwrite case. HAMMER will often write out data records for an inode before writing out the newly created inode itself. This is desireable because it allows HAMMER to avoid replacing the on-disk inode record every time the file size changes. Fix a bug related to this issue where HAMMER was not checking for on-disk data records in the data overwrite case prior to the inode being written out. --- sys/vfs/hammer/hammer.h | 3 ++- sys/vfs/hammer/hammer_object.c | 17 +++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/sys/vfs/hammer/hammer.h b/sys/vfs/hammer/hammer.h index ed4015b540..c5ab479795 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.20 2008/01/09 00:46:22 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer.h,v 1.21 2008/01/09 04:05:37 dillon Exp $ */ /* * This header file contains structures used internally by the HAMMERFS @@ -172,6 +172,7 @@ typedef struct hammer_inode *hammer_inode_t; #define HAMMER_INODE_DELONDISK 0x0100 /* delete synchronized to disk */ #define HAMMER_INODE_RO 0x0200 /* read-only (because of as-of) */ #define HAMMER_INODE_GONE 0x0400 /* delete flushed out */ +#define HAMMER_INODE_DONDISK 0x0800 /* data records may be on disk */ #define HAMMER_INODE_MODMASK (HAMMER_INODE_DDIRTY|HAMMER_INODE_RDIRTY| \ HAMMER_INODE_XDIRTY|\ diff --git a/sys/vfs/hammer/hammer_object.c b/sys/vfs/hammer/hammer_object.c index 822587b0c1..9c12c1987b 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.16 2008/01/09 00:46:22 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_object.c,v 1.17 2008/01/09 04:05:37 dillon Exp $ */ #include "hammer.h" @@ -494,6 +494,13 @@ hammer_ip_sync_data(hammer_transaction_t trans, hammer_inode_t ip, elm.leaf.data_len = bytes; elm.leaf.data_crc = rec->base.data_crc; + /* + * Data records can wind up on-disk before the inode itself is + * on-disk. One must assume data records may be on-disk if either + * HAMMER_INODE_DONDISK or HAMMER_INODE_ONDISK is set + */ + ip->flags |= HAMMER_INODE_DONDISK; + error = hammer_btree_insert(&cursor, &elm); if (error == 0) { hammer_update_syncid(cursor.record_buffer->cluster, trans->tid); @@ -849,7 +856,7 @@ hammer_ip_lookup(hammer_cursor_t cursor, struct hammer_inode *ip) /* * If the inode has on-disk components search the on-disk B-Tree. */ - if ((ip->flags & HAMMER_INODE_ONDISK) == 0) + if ((ip->flags & (HAMMER_INODE_ONDISK|HAMMER_INODE_DONDISK)) == 0) return(error); error = hammer_btree_lookup(cursor); if (error == 0) @@ -890,7 +897,7 @@ hammer_ip_first(hammer_cursor_t cursor, struct hammer_inode *ip) * whether it must index forwards or not. It is also used here * to select the next record from in-memory or on-disk. */ - if (ip->flags & HAMMER_INODE_ONDISK) { + if (ip->flags & (HAMMER_INODE_ONDISK|HAMMER_INODE_DONDISK)) { error = hammer_btree_lookup(cursor); if (error == ENOENT) { cursor->flags &= ~HAMMER_CURSOR_ATEDISK; @@ -1167,10 +1174,8 @@ hammer_ip_delete_range(hammer_transaction_t trans, hammer_inode_t ip, * could overflow. */ if (base->key - 1 > ran_end) { - if (base->key - rec->base.data_len > ran_end) { - kprintf("right edge OOB\n"); + if (base->key - rec->base.data_len > ran_end) break; - } panic("hammer right edge case\n"); } } -- 2.11.4.GIT