X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/5c67d9f046c3eb827e77e8cb068c6c325e33b3ab..3bf6fec386b09ee8846e7093b18975148d9da2cc:/sys/vfs/hammer/hammer_pfs.c diff --git a/sys/vfs/hammer/hammer_pfs.c b/sys/vfs/hammer/hammer_pfs.c index e92b05f2ef..6699a53a91 100644 --- a/sys/vfs/hammer/hammer_pfs.c +++ b/sys/vfs/hammer/hammer_pfs.c @@ -74,7 +74,7 @@ hammer_ioc_get_pseudofs(hammer_transaction_t trans, hammer_inode_t ip, /* * If the PFS is a master the sync tid is set by normal operation - * rather then the mirroring code, and will always track the + * rather than the mirroring code, and will always track the * real HAMMER filesystem. * * We use flush_tid1, which is the highest fully committed TID. @@ -125,9 +125,14 @@ hammer_ioc_set_pseudofs(hammer_transaction_t trans, hammer_inode_t ip, /* * Save it back, create a root inode if we are in master * mode and no root exists. + * + * We do not create root inodes for slaves, the root inode + * must be mirrored from the master. */ - if (error == 0) + if (error == 0 && + (pfsm->pfsd.mirror_flags & HAMMER_PFSD_SLAVE) == 0) { error = hammer_mkroot_pseudofs(trans, cred, pfsm); + } if (error == 0) error = hammer_save_pseudofs(trans, pfsm); @@ -188,14 +193,12 @@ 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. + * This is really easy to do, just set the SLAVE flag and update sync_end_tid. * - * 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 - * mode accidently and then back to slave mode we don't want it to change. - * Eventually it will be used as the cross-synchronization TID in - * multi-master mode, and we don't want to mess with it for that feature - * either. + * We previously did not update sync_end_tid in consideration for a slave + * upgraded to a master and then downgraded again, but this completely breaks + * the case where one starts with a master and then downgrades to a slave, + * then upgrades again. * * NOTE: The ip used for ioctl is not necessarily related to the PFS */ @@ -203,6 +206,7 @@ int hammer_ioc_downgrade_pseudofs(hammer_transaction_t trans, hammer_inode_t ip, struct hammer_ioc_pseudofs_rw *pfs) { + hammer_mount_t hmp = trans->hmp; hammer_pseudofs_inmem_t pfsm; u_int32_t localization; int error; @@ -217,6 +221,8 @@ hammer_ioc_downgrade_pseudofs(hammer_transaction_t trans, hammer_inode_t ip, if (error == 0) { if ((pfsm->pfsd.mirror_flags & HAMMER_PFSD_SLAVE) == 0) { pfsm->pfsd.mirror_flags |= HAMMER_PFSD_SLAVE; + if (pfsm->pfsd.sync_end_tid < hmp->flush_tid1) + pfsm->pfsd.sync_end_tid = hmp->flush_tid1; error = hammer_save_pseudofs(trans, pfsm); } } @@ -402,6 +408,8 @@ retry: * We only care about leafs. Internal nodes can be returned * in mirror-filtered mode (they are used to generate SKIP * mrecords), but we don't need them for this code. + * + * WARNING: See warnings in hammer_unlock_cursor() function. */ cursor.flags |= HAMMER_CURSOR_ATEDISK; if (cursor.node->ondisk->type == HAMMER_BTREE_TYPE_LEAF) { @@ -411,9 +419,9 @@ retry: while (hammer_flusher_meta_halflimit(trans->hmp) || hammer_flusher_undo_exhausted(trans, 2)) { - hammer_unlock_cursor(&cursor, 0); + hammer_unlock_cursor(&cursor); hammer_flusher_wait(trans->hmp, seq); - hammer_lock_cursor(&cursor, 0); + hammer_lock_cursor(&cursor); seq = hammer_flusher_async_one(trans->hmp); }