From 732a1697dfcc0a1f481a020eae3a51b8b54094cf Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Sat, 19 Jul 2008 18:44:49 +0000 Subject: [PATCH] HAMMER 65/Many: PFS cleanups and confusion removal * Simplify master/slave operation. Remove the master=, slave, and no-mirror options from pfs-update. Retain pfs-master, pfs-slave, pfs-upgrade, and pfs-downgrade for dealing with master and slave operation. Move the master= and nomirror specifications back to hammer_mount. They have to be mount-wide anyhow, the current code does not support different master ID's on a PFS-by-PFS basis. * Add some additional failsafes to the mount code. The master id cannot be allowed to change by a mount update (-u). * Fix a bug in hammer pfs-upgrade operation that could result in a livelock during the B-Tree iteration. --- sys/vfs/hammer/hammer.h | 4 +-- sys/vfs/hammer/hammer_btree.c | 13 +++------ sys/vfs/hammer/hammer_disk.h | 4 +-- sys/vfs/hammer/hammer_mount.h | 6 ++-- sys/vfs/hammer/hammer_pfs.c | 10 ++----- sys/vfs/hammer/hammer_transaction.c | 8 ++--- sys/vfs/hammer/hammer_vfsops.c | 45 +++++++++++++++++++++-------- 7 files changed, 51 insertions(+), 39 deletions(-) diff --git a/sys/vfs/hammer/hammer.h b/sys/vfs/hammer/hammer.h index 03e964246c..27334470c3 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.120 2008/07/18 00:19:53 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer.h,v 1.121 2008/07/19 18:44:49 dillon Exp $ */ /* * This header file contains structures used internally by the HAMMERFS @@ -690,7 +690,7 @@ struct hammer_mount { int ronly; int nvolumes; int volume_iterator; - int masterid; /* -1 or 0-15 - clustering and mirroring */ + int master_id; /* -1 or 0-15 - clustering and mirroring */ int rsv_inodes; /* reserved space due to dirty inodes */ int64_t rsv_databytes; /* reserved space due to record data */ int rsv_recs; /* reserved space due to dirty records */ diff --git a/sys/vfs/hammer/hammer_btree.c b/sys/vfs/hammer/hammer_btree.c index 2392eba961..f9a1a80748 100644 --- a/sys/vfs/hammer/hammer_btree.c +++ b/sys/vfs/hammer/hammer_btree.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_btree.c,v 1.73 2008/07/15 22:13:16 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_btree.c,v 1.74 2008/07/19 18:44:49 dillon Exp $ */ /* @@ -2221,16 +2221,11 @@ hammer_btree_do_propagation(hammer_cursor_t cursor, int error; /* - * We only propagate the mirror_tid up if we are in master or slave - * mode. We do not bother if we are in no-mirror mode. - * - * If pfsm is NULL we propagate (from mirror_write). + * We do not propagate a mirror_tid if the filesystem was mounted + * in no-mirror mode. */ - if (pfsm && - pfsm->pfsd.master_id < 0 && - (pfsm->pfsd.mirror_flags & HAMMER_PFSD_SLAVE) == 0) { + if (cursor->trans->hmp->master_id < 0) return; - } /* * This is a bit of a hack because we cannot deadlock or return diff --git a/sys/vfs/hammer/hammer_disk.h b/sys/vfs/hammer/hammer_disk.h index 1f6a1f08db..08c83ccc44 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 2008/07/12 02:47:39 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_disk.h,v 1.51 2008/07/19 18:44:49 dillon Exp $ */ #ifndef VFS_HAMMER_DISK_H_ @@ -681,7 +681,7 @@ struct hammer_pseudofs_data { u_int64_t sync_end_ts; /* initiation of current sync cycle */ uuid_t shared_uuid; /* shared uuid (match required) */ uuid_t unique_uuid; /* unique uuid of this master/slave */ - int32_t master_id; /* 0-15 (-1 if slave) */ + 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 */ diff --git a/sys/vfs/hammer/hammer_mount.h b/sys/vfs/hammer/hammer_mount.h index a301291608..28bb8da364 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 2008/07/14 03:20:49 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_mount.h,v 1.10 2008/07/19 18:44:49 dillon Exp $ */ #ifndef _SYS_TYPES_H_ @@ -49,14 +49,14 @@ struct hammer_mount_info { const char **volumes; /* array of pointers to device names */ int nvolumes; /* number of devices */ int hflags; /* extended hammer mount flags */ - int masterid; + 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]; }; #define HMNT_NOHISTORY 0x00000001 -#define HMNT_MASTERID 0x00000002 /* masterid field set */ +#define HMNT_MASTERID 0x00000002 /* master_id field set */ #define HMNT_EXPORTREQ 0x00000004 #define HMNT_UNDO_DIRTY 0x00000008 diff --git a/sys/vfs/hammer/hammer_pfs.c b/sys/vfs/hammer/hammer_pfs.c index bb1cc15a7f..639c53a4d0 100644 --- a/sys/vfs/hammer/hammer_pfs.c +++ b/sys/vfs/hammer/hammer_pfs.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_pfs.c,v 1.3 2008/07/19 04:49:39 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_pfs.c,v 1.4 2008/07/19 18:44:49 dillon Exp $ */ /* * HAMMER PFS ioctls - Manage pseudo-fs configurations @@ -158,10 +158,6 @@ hammer_ioc_upgrade_pseudofs(hammer_transaction_t trans, hammer_inode_t ip, * A master id must be set when upgrading */ pfsm = hammer_load_pseudofs(trans, localization, &error); - if ((pfsm->pfsd.mirror_flags & HAMMER_PFSD_SLAVE) == 0 && - pfsm->pfsd.master_id < 0) { - error = EINVAL; - } if (error == 0) { if ((pfsm->pfsd.mirror_flags & HAMMER_PFSD_SLAVE) != 0) { error = hammer_pfs_rollback(trans, pfsm, @@ -183,8 +179,7 @@ hammer_ioc_upgrade_pseudofs(hammer_transaction_t trans, hammer_inode_t ip, /* * Downgrade a master to a slave * - * This is really easy to do, just set the SLAVE flag. The master_id is - * left intact. + * This is really easy to do, just set the SLAVE flag. * * We also leave sync_end_tid intact... the field is not used in master * mode (vol0_next_tid overrides it), but if someone switches to master @@ -357,6 +352,7 @@ retry: * in mirror-filtered mode (they are used to generate SKIP * mrecords), but we don't need them for this code. */ + cursor.flags |= HAMMER_CURSOR_ATEDISK; if (cursor.node->ondisk->type == HAMMER_BTREE_TYPE_LEAF) { key_cur = cursor.node->ondisk->elms[cursor.index].base; error = hammer_pfs_delete_at_cursor(&cursor, trunc_tid); diff --git a/sys/vfs/hammer/hammer_transaction.c b/sys/vfs/hammer/hammer_transaction.c index 500a7f8ec7..2098b53b55 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.23 2008/07/19 04:49:39 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_transaction.c,v 1.24 2008/07/19 18:44:49 dillon Exp $ */ #include "hammer.h" @@ -142,14 +142,14 @@ hammer_alloc_tid(hammer_mount_t hmp, int count) { hammer_tid_t tid; - if (hmp->masterid < 0) { + if (hmp->master_id < 0) { tid = hmp->next_tid + 1; hmp->next_tid = tid + count; } else { tid = (hmp->next_tid + HAMMER_MAX_MASTERS) & ~(hammer_tid_t)(HAMMER_MAX_MASTERS - 1); hmp->next_tid = tid + count * HAMMER_MAX_MASTERS; - tid |= hmp->masterid; + tid |= hmp->master_id; } if (tid >= 0xFFFFFFFFFF000000ULL) panic("hammer_start_transaction: Ran out of TIDs!"); @@ -194,7 +194,7 @@ hammer_alloc_objid(hammer_mount_t hmp, hammer_inode_t dip) * mount is operating in. */ tid = ocp->next_tid; - ocp->next_tid += (hmp->masterid < 0) ? 1 : HAMMER_MAX_MASTERS; + ocp->next_tid += (hmp->master_id < 0) ? 1 : HAMMER_MAX_MASTERS; if (--ocp->count == 0) { dip->objid_cache = NULL; diff --git a/sys/vfs/hammer/hammer_vfsops.c b/sys/vfs/hammer/hammer_vfsops.c index bb77bbf7d7..f49d6875f2 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.65 2008/07/18 00:19:53 dillon Exp $ + * $DragonFly: src/sys/vfs/hammer/hammer_vfsops.c,v 1.66 2008/07/19 18:44:49 dillon Exp $ */ #include @@ -286,25 +286,47 @@ hammer_vfs_mount(struct mount *mp, char *mntpt, caddr_t data, char *path; /* volume name in system space */ int error; int i; + int master_id; if ((error = copyin(data, &info, sizeof(info))) != 0) return (error); - if ((mp->mnt_flag & MNT_UPDATE) == 0) { + + /* + * updating or new mount + */ + if (mp->mnt_flag & MNT_UPDATE) { + hmp = (void *)mp->mnt_data; + KKASSERT(hmp != NULL); + } else { if (info.nvolumes <= 0 || info.nvolumes >= 32768) return (EINVAL); + hmp = NULL; } - if ((info.hflags & HMNT_MASTERID) && - (info.masterid < -1 || info.masterid >= HAMMER_MAX_MASTERS)) { + + /* + * master-id validation. The master id may not be changed by a + * mount update. + */ + if (info.hflags & HMNT_MASTERID) { + if (hmp && hmp->master_id != info.master_id) { + kprintf("hammer: cannot change master id " + "with mount update\n"); + return(EINVAL); + } + master_id = info.master_id; + if (master_id < -1 || master_id >= HAMMER_MAX_MASTERS) return (EINVAL); + } else { + if (hmp) + master_id = hmp->master_id; + else + master_id = 0; } /* * Interal mount data structure */ - if (mp->mnt_flag & MNT_UPDATE) { - hmp = (void *)mp->mnt_data; - KKASSERT(hmp != NULL); - } else { + if (hmp == NULL) { hmp = kmalloc(sizeof(*hmp), M_HAMMER, M_WAITOK | M_ZERO); mp->mnt_data = (qaddr_t)hmp; hmp->mp = mp; @@ -343,10 +365,9 @@ hammer_vfs_mount(struct mount *mp, char *mntpt, caddr_t data, } hmp->hflags &= ~HMNT_USERFLAGS; hmp->hflags |= info.hflags & HMNT_USERFLAGS; - if (info.hflags & HMNT_MASTERID) - hmp->masterid = info.masterid; - else - hmp->masterid = -1; + + hmp->master_id = master_id; + if (info.asof) { kprintf("ASOF\n"); mp->mnt_flag |= MNT_RDONLY; -- 2.41.0