166325755SMatthew Dillon /*
2*b84de5afSMatthew Dillon  * Copyright (c) 2007-2008 The DragonFly Project.  All rights reserved.
366325755SMatthew Dillon  *
466325755SMatthew Dillon  * This code is derived from software contributed to The DragonFly Project
566325755SMatthew Dillon  * by Matthew Dillon <dillon@backplane.com>
666325755SMatthew Dillon  *
766325755SMatthew Dillon  * Redistribution and use in source and binary forms, with or without
866325755SMatthew Dillon  * modification, are permitted provided that the following conditions
966325755SMatthew Dillon  * are met:
1066325755SMatthew Dillon  *
1166325755SMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
1266325755SMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
1366325755SMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
1466325755SMatthew Dillon  *    notice, this list of conditions and the following disclaimer in
1566325755SMatthew Dillon  *    the documentation and/or other materials provided with the
1666325755SMatthew Dillon  *    distribution.
1766325755SMatthew Dillon  * 3. Neither the name of The DragonFly Project nor the names of its
1866325755SMatthew Dillon  *    contributors may be used to endorse or promote products derived
1966325755SMatthew Dillon  *    from this software without specific, prior written permission.
2066325755SMatthew Dillon  *
2166325755SMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2266325755SMatthew Dillon  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2366325755SMatthew Dillon  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
2466325755SMatthew Dillon  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
2566325755SMatthew Dillon  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
2666325755SMatthew Dillon  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
2766325755SMatthew Dillon  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2866325755SMatthew Dillon  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2966325755SMatthew Dillon  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
3066325755SMatthew Dillon  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
3166325755SMatthew Dillon  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3266325755SMatthew Dillon  * SUCH DAMAGE.
3366325755SMatthew Dillon  *
34*b84de5afSMatthew Dillon  * $DragonFly: src/sys/vfs/hammer/hammer_transaction.c,v 1.12 2008/04/24 21:20:33 dillon Exp $
3566325755SMatthew Dillon  */
3666325755SMatthew Dillon 
3766325755SMatthew Dillon #include "hammer.h"
3866325755SMatthew Dillon 
39*b84de5afSMatthew Dillon /*
40*b84de5afSMatthew Dillon  * Start a standard transaction.
41*b84de5afSMatthew Dillon  */
4266325755SMatthew Dillon void
438cd0a023SMatthew Dillon hammer_start_transaction(struct hammer_transaction *trans,
448cd0a023SMatthew Dillon 			 struct hammer_mount *hmp)
4566325755SMatthew Dillon {
46a89aec1bSMatthew Dillon 	int error;
4766325755SMatthew Dillon 
48*b84de5afSMatthew Dillon 	trans->type = HAMMER_TRANS_STD;
4966325755SMatthew Dillon 	trans->hmp = hmp;
50a89aec1bSMatthew Dillon 	trans->rootvol = hammer_get_root_volume(hmp, &error);
51a89aec1bSMatthew Dillon 	KKASSERT(error == 0);
52*b84de5afSMatthew Dillon 	trans->tid = 0;
53*b84de5afSMatthew Dillon 	trans->time = hammer_alloc_tid(trans);
5466325755SMatthew Dillon }
5566325755SMatthew Dillon 
56*b84de5afSMatthew Dillon /*
57*b84de5afSMatthew Dillon  * Start a simple read-only transaction.  This will not stall.
58*b84de5afSMatthew Dillon  */
5966325755SMatthew Dillon void
6036f82b23SMatthew Dillon hammer_simple_transaction(struct hammer_transaction *trans,
6136f82b23SMatthew Dillon 			  struct hammer_mount *hmp)
6236f82b23SMatthew Dillon {
6336f82b23SMatthew Dillon 	int error;
6436f82b23SMatthew Dillon 
65*b84de5afSMatthew Dillon 	trans->type = HAMMER_TRANS_RO;
6636f82b23SMatthew Dillon 	trans->hmp = hmp;
6736f82b23SMatthew Dillon 	trans->rootvol = hammer_get_root_volume(hmp, &error);
6836f82b23SMatthew Dillon 	KKASSERT(error == 0);
69*b84de5afSMatthew Dillon 	trans->tid = 0;
70*b84de5afSMatthew Dillon 	trans->time = hammer_alloc_tid(trans);
7136f82b23SMatthew Dillon }
7236f82b23SMatthew Dillon 
73*b84de5afSMatthew Dillon /*
74*b84de5afSMatthew Dillon  * Start a transaction using a particular TID.  Used by the sync code.
75*b84de5afSMatthew Dillon  * This does not stall.
76*b84de5afSMatthew Dillon  */
7736f82b23SMatthew Dillon void
78*b84de5afSMatthew Dillon hammer_start_transaction_fls(struct hammer_transaction *trans,
79*b84de5afSMatthew Dillon 			     struct hammer_mount *hmp)
80d113fda1SMatthew Dillon {
81d113fda1SMatthew Dillon 	int error;
82d113fda1SMatthew Dillon 
83*b84de5afSMatthew Dillon 	trans->type = HAMMER_TRANS_FLS;
84d113fda1SMatthew Dillon 	trans->hmp = hmp;
85d113fda1SMatthew Dillon 	trans->rootvol = hammer_get_root_volume(hmp, &error);
86d113fda1SMatthew Dillon 	KKASSERT(error == 0);
87*b84de5afSMatthew Dillon 	trans->tid = hammer_alloc_tid(trans);
88*b84de5afSMatthew Dillon 	trans->time = trans->tid;
89d113fda1SMatthew Dillon }
90d113fda1SMatthew Dillon 
91d113fda1SMatthew Dillon void
92*b84de5afSMatthew Dillon hammer_done_transaction(struct hammer_transaction *trans)
9366325755SMatthew Dillon {
94a89aec1bSMatthew Dillon 	hammer_rel_volume(trans->rootvol, 0);
95*b84de5afSMatthew Dillon 	trans->rootvol = NULL;
9666325755SMatthew Dillon }
9766325755SMatthew Dillon 
98d113fda1SMatthew Dillon /*
99d113fda1SMatthew Dillon  * Note: Successive transaction ids must be at least 2 apart so the
100d113fda1SMatthew Dillon  * B-Tree code can make a separator that does not match either the
101d113fda1SMatthew Dillon  * left or right hand sides.
102d113fda1SMatthew Dillon  */
103a89aec1bSMatthew Dillon hammer_tid_t
104a89aec1bSMatthew Dillon hammer_alloc_tid(hammer_transaction_t trans)
105a89aec1bSMatthew Dillon {
106a89aec1bSMatthew Dillon 	struct timespec ts;
107a89aec1bSMatthew Dillon 	hammer_tid_t tid;
108a89aec1bSMatthew Dillon 
109a89aec1bSMatthew Dillon 	getnanotime(&ts);
110a89aec1bSMatthew Dillon 	tid = ts.tv_sec * 1000000000LL + ts.tv_nsec;
111*b84de5afSMatthew Dillon 	if (tid < trans->hmp->next_tid)
112*b84de5afSMatthew Dillon 		tid = trans->hmp->next_tid;
113*b84de5afSMatthew Dillon #if 0
11436f82b23SMatthew Dillon 	hammer_modify_volume(trans, trans->rootvol, NULL, 0);
115a89aec1bSMatthew Dillon 	ondisk = trans->rootvol->ondisk;
11647197d71SMatthew Dillon 	if (tid < ondisk->vol0_next_tid)
11747197d71SMatthew Dillon 		tid = ondisk->vol0_next_tid;
118*b84de5afSMatthew Dillon #endif
119855942b6SMatthew Dillon 	if (tid >= 0xFFFFFFFFFFFFFFF0ULL)
120a89aec1bSMatthew Dillon 		panic("hammer_start_transaction: Ran out of TIDs!");
121d113fda1SMatthew Dillon 	if (hammer_debug_tid) {
122d113fda1SMatthew Dillon 		kprintf("alloc_tid %016llx (0x%08x)\n",
123d113fda1SMatthew Dillon 			tid, (int)(tid / 1000000000LL));
124d113fda1SMatthew Dillon 	}
125*b84de5afSMatthew Dillon #if 0
12647197d71SMatthew Dillon 	ondisk->vol0_next_tid = tid + 2;
127*b84de5afSMatthew Dillon #endif
128*b84de5afSMatthew Dillon 	trans->hmp->next_tid = tid + 2;
129a89aec1bSMatthew Dillon 	return(tid);
130a89aec1bSMatthew Dillon }
131a89aec1bSMatthew Dillon 
132